Calendar=function(_1,_2,_3,_4){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.getDateToolTip=null;this.getDateText=null;this.timeout=null;this.onSelected=_3||null;this.onClose=_4||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT["DEF_DATE_FORMAT"];this.ttDateFormat=Calendar._TT["TT_DATE_FORMAT"];this.isPopup=true;this.weekNumbers=true;this.firstDayOfWeek=typeof _1=="number"?_1:Calendar._FD;this.showsOtherMonths=false;this.dateStr=_2;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.hiliteToday=true;this.multiple=null;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined"){Calendar._SDN_len=3;}var ar=new Array();for(var i=8;i>0;){ar[--i]=Calendar._DN[i].substr(0,Calendar._SDN_len);}Calendar._SDN=ar;if(typeof Calendar._SMN_len=="undefined"){Calendar._SMN_len=3;}ar=new Array();for(var i=12;i>0;){ar[--i]=Calendar._MN[i].substr(0,Calendar._SMN_len);}Calendar._SMN=ar;}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_ie5=(Calendar.is_ie&&/msie 5\.0/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(el){var SL=0,ST=0;var _a=/^div$/i.test(el.tagName);if(_a&&el.scrollLeft){SL=el.scrollLeft;}if(_a&&el.scrollTop){ST=el.scrollTop;}var r={x:el.offsetLeft-SL,y:el.offsetTop-ST};if(el.offsetParent){var _c=this.getAbsolutePos(el.offsetParent);r.x+=_c.x;r.y+=_c.y;}return r;};Calendar.isRelated=function(el,_e){var _f=_e.relatedTarget;if(!_f){var _10=_e.type;if(_10=="mouseover"){_f=_e.fromElement;}else{if(_10=="mouseout"){_f=_e.toElement;}}}while(_f){if(_f==el){return true;}_f=_f.parentNode;}return false;};Calendar.removeClass=function(el,_12){if(!(el&&el.className)){return;}var cls=el.className.split(" ");var ar=new Array();for(var i=cls.length;i>0;){if(cls[--i]!=_12){ar[ar.length]=cls[i];}}el.className=ar.join(" ");};Calendar.addClass=function(el,_17){Calendar.removeClass(el,_17);el.className+=" "+_17;};Calendar.getElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.currentTarget;while(f.nodeType!=1||/^div$/i.test(f.tagName)){f=f.parentNode;}return f;};Calendar.getTargetElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.target;while(f.nodeType!=1){f=f.parentNode;}return f;};Calendar.stopEvent=function(ev){ev||(ev=window.event);if(Calendar.is_ie){ev.cancelBubble=true;ev.returnValue=false;}else{ev.preventDefault();ev.stopPropagation();}return false;};Calendar.addEvent=function(el,_1e,_1f){if(el.attachEvent){el.attachEvent("on"+_1e,_1f);}else{if(el.addEventListener){el.addEventListener(_1e,_1f,true);}else{el["on"+_1e]=_1f;}}};Calendar.removeEvent=function(el,_21,_22){if(el.detachEvent){el.detachEvent("on"+_21,_22);}else{if(el.removeEventListener){el.removeEventListener(_21,_22,true);}else{el["on"+_21]=null;}}};Calendar.createElement=function(_23,_24){var el=null;if(document.createElementNS){el=document.createElementNS("http://www.w3.org/1999/xhtml",_23);}else{el=document.createElement(_23);}if(typeof _24!="undefined"){_24.appendChild(el);}return el;};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true);}}};Calendar.findMonth=function(el){if(typeof el.month!="undefined"){return el;}else{if(typeof el.parentNode.month!="undefined"){return el.parentNode;}}return null;};Calendar.findYear=function(el){if(typeof el.year!="undefined"){return el;}else{if(typeof el.parentNode.year!="undefined"){return el.parentNode;}}return null;};Calendar.showMonthsCombo=function(){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var mc=cal.monthsCombo;if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}if(cal.activeMonth){Calendar.removeClass(cal.activeMonth,"active");}var mon=cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];Calendar.addClass(mon,"active");cal.activeMonth=mon;var s=mc.style;s.display="block";if(cd.navtype<0){s.left=cd.offsetLeft+"px";}else{var mcw=mc.offsetWidth;if(typeof mcw=="undefined"){mcw=50;}s.left=(cd.offsetLeft+cd.offsetWidth-mcw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";};Calendar.showYearsCombo=function(fwd){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var yc=cal.yearsCombo;if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}if(cal.activeYear){Calendar.removeClass(cal.activeYear,"active");}cal.activeYear=null;var Y=cal.date.getFullYear()+(fwd?1:-1);var yr=yc.firstChild;var _37=false;for(var i=12;i>0;--i){if(Y>=cal.minYear&&Y<=cal.maxYear){yr.innerHTML=Y;yr.year=Y;yr.style.display="block";_37=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?cal.yearStep:-cal.yearStep;}if(_37){var s=yc.style;s.display="block";if(cd.navtype<0){s.left=cd.offsetLeft+"px";}else{var ycw=yc.offsetWidth;if(typeof ycw=="undefined"){ycw=50;}s.left=(cd.offsetLeft+cd.offsetWidth-ycw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false;}if(cal.timeout){clearTimeout(cal.timeout);}var el=cal.activeDiv;if(!el){return false;}var _3e=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(_3e==el||_3e.parentNode==el){Calendar.cellClick(el,ev);}var mon=Calendar.findMonth(_3e);var _40=null;if(mon){_40=new Date(cal.date);if(mon.month!=_40.getMonth()){_40.setMonth(mon.month);cal.setDate(_40);cal.dateClicked=false;cal.callHandler();}}else{var _41=Calendar.findYear(_3e);if(_41){_40=new Date(cal.date);if(_41.year!=_40.getFullYear()){_40.setFullYear(_41.year);cal.setDate(_40);cal.dateClicked=false;cal.callHandler();}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev);}};Calendar.tableMouseOver=function(ev){var cal=Calendar._C;if(!cal){return;}var el=cal.activeDiv;var _45=Calendar.getTargetElement(ev);if(_45==el||_45.parentNode==el){Calendar.addClass(el,"hilite active");Calendar.addClass(el.parentNode,"rowhilite");}else{if(typeof el.navtype=="undefined"||(el.navtype!=50&&(el.navtype==0||Math.abs(el.navtype)>2))){Calendar.removeClass(el,"active");}Calendar.removeClass(el,"hilite");Calendar.removeClass(el.parentNode,"rowhilite");}ev||(ev=window.event);if(el.navtype==50&&_45!=el){var pos=Calendar.getAbsolutePos(el);var w=el.offsetWidth;var x=ev.clientX;var dx;var _4a=true;if(x>pos.x+w){dx=x-pos.x-w;_4a=false;}else{dx=pos.x-x;}if(dx<0){dx=0;}var _4b=el._range;var _4c=el._current;var _4d=Math.floor(dx/10)%_4b.length;for(var i=_4b.length;--i>=0;){if(_4b[i]==_4c){break;}}while(_4d-->0){if(_4a){if(--i<0){i=_4b.length-1;}}else{if(++i>=_4b.length){i=0;}}}var _4f=_4b[i];el.innerHTML=_4f;cal.onUpdateTime();}var mon=Calendar.findMonth(_45);if(mon){if(mon.month!=cal.date.getMonth()){if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}Calendar.addClass(mon,"hilite");cal.hilitedMonth=mon;}else{if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}}}else{if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}var _51=Calendar.findYear(_45);if(_51){if(_51.year!=cal.date.getFullYear()){if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}Calendar.addClass(_51,"hilite");cal.hilitedYear=_51;}else{if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}}else{if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}}return Calendar.stopEvent(ev);};Calendar.tableMouseDown=function(ev){if(Calendar.getTargetElement(ev)==Calendar.getElement(ev)){return Calendar.stopEvent(ev);}};Calendar.calDragIt=function(ev){var cal=Calendar._C;if(!(cal&&cal.dragging)){return false;}var _55;var _56;if(Calendar.is_ie){_56=window.event.clientY+document.body.scrollTop;_55=window.event.clientX+document.body.scrollLeft;}else{_55=ev.pageX;_56=ev.pageY;}cal.hideShowCovered();var st=cal.element.style;st.left=(_55-cal.xOffs)+"px";st.top=(_56-cal.yOffs)+"px";return Calendar.stopEvent(ev);};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false;}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev);}cal.hideShowCovered();};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false;}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300){with(Calendar){if(el.navtype==50){el._current=el.innerHTML;addEvent(document,"mousemove",tableMouseOver);}else{addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver);}addClass(el,"hilite active");addEvent(document,"mouseup",tableMouseUp);}}else{if(cal.isPopup){cal._dragStart(ev);}}if(el.navtype==-1||el.navtype==1){if(cal.timeout){clearTimeout(cal.timeout);}cal.timeout=setTimeout("Calendar.showMonthsCombo()",250);}else{if(el.navtype==-2||el.navtype==2){if(cal.timeout){clearTimeout(cal.timeout);}cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250);}else{cal.timeout=null;}}return Calendar.stopEvent(ev);};Calendar.dayMouseDblClick=function(ev){Calendar.cellClick(Calendar.getElement(ev),ev||window.event);if(Calendar.is_ie){document.selection.empty();}};Calendar.dayMouseOver=function(ev){var el=Calendar.getElement(ev);if(Calendar.isRelated(el,ev)||Calendar._C||el.disabled){return false;}if(el.ttip){if(el.ttip.substr(0,1)=="_"){el.ttip=el.caldate.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.innerHTML=el.ttip;}if(el.navtype!=300){Calendar.addClass(el,"hilite");if(el.caldate){Calendar.addClass(el.parentNode,"rowhilite");}}return Calendar.stopEvent(ev);};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled){return false;}removeClass(el,"hilite");if(el.caldate){removeClass(el.parentNode,"rowhilite");}if(el.calendar){el.calendar.tooltips.innerHTML=_TT["SEL_DATE"];}return stopEvent(ev);}};Calendar.cellClick=function(el,ev){var cal=el.calendar;var _65=false;var _66=false;var _67=null;if(typeof el.navtype=="undefined"){if(cal.currentDateEl){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");_65=(cal.currentDateEl==el);if(!_65){cal.currentDateEl=el;}}cal.date.setDateOnly(el.caldate);_67=cal.date;var _68=!(cal.dateClicked=!el.otherMonth);if(!_68&&!cal.currentDateEl){cal._toggleMultipleDate(new Date(_67));}else{_66=!el.disabled;}if(_68){cal._init(cal.firstDayOfWeek,_67);}}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}_67=new Date(cal.date);if(el.navtype==0){_67.setDateOnly(new Date());}cal.dateClicked=false;var _69=_67.getFullYear();var mon=_67.getMonth();function setMonth(m){var day=_67.getDate();var max=_67.getMonthDays(m);if(day>max){_67.setDate(max);}_67.setMonth(m);}switch(el.navtype){case 400:Calendar.removeClass(el,"hilite");var _6e=Calendar._TT["ABOUT"];if(typeof _6e!="undefined"){_6e+=cal.showsTime?Calendar._TT["ABOUT_TIME"]:"";}else{_6e="Help and about box text is not translated into this language.\n"+"If you know this language and you feel generous please update\n"+"the corresponding file in \"lang\" subdir to match calendar-en.js\n"+"and send it back to <mihai_bazon@yahoo.com> to get it into the distribution  ;-)\n\n"+"Thank you!\n"+"http://dynarch.com/mishoo/calendar.epl\n";}alert(_6e);return;case -2:if(_69>cal.minYear){_67.setFullYear(_69-1);}break;case -1:if(mon>0){setMonth(mon-1);}else{if(_69-->cal.minYear){_67.setFullYear(_69);setMonth(11);}}break;case 1:if(mon<11){setMonth(mon+1);}else{if(_69<cal.maxYear){_67.setFullYear(_69+1);setMonth(0);}}break;case 2:if(_69<cal.maxYear){_67.setFullYear(_69+1);}break;case 100:cal.setFirstDayOfWeek(el.fdow);return;case 50:var _6f=el._range;var _70=el.innerHTML;for(var i=_6f.length;--i>=0;){if(_6f[i]==_70){break;}}if(ev&&ev.shiftKey){if(--i<0){i=_6f.length-1;}}else{if(++i>=_6f.length){i=0;}}var _72=_6f[i];el.innerHTML=_72;cal.onUpdateTime();return;case 0:if((typeof cal.getDateStatus=="function")&&cal.getDateStatus(_67,_67.getFullYear(),_67.getMonth(),_67.getDate())){return false;}break;}if(!_67.equalsTo(cal.date)){cal.setDate(_67);_66=true;}else{if(el.navtype==0){_66=_65=true;}}}if(_66){ev&&cal.callHandler();}if(_65){Calendar.removeClass(el,"hilite");ev&&cal.callCloseHandler();}};Calendar.prototype.create=function(_73){var _74=null;if(!_73){_74=document.getElementsByTagName("body")[0];this.isPopup=true;}else{_74=_73;this.isPopup=false;}this.date=this.dateStr?new Date(this.dateStr):new Date();var _75=Calendar.createElement("table");this.table=_75;_75.cellSpacing=0;_75.cellPadding=0;_75.calendar=this;Calendar.addEvent(_75,"mousedown",Calendar.tableMouseDown);var div=Calendar.createElement("div");this.element=div;div.className="calendar";if(this.isPopup){div.style.position="absolute";div.style.display="none";}div.appendChild(_75);var _77=Calendar.createElement("thead",_75);var _78=null;var row=null;var cal=this;var hh=function(_7c,cs,_7e){_78=Calendar.createElement("td",row);_78.colSpan=cs;_78.className="jscalendar-button";if(_7e!=0&&Math.abs(_7e)<=2){_78.className+=" nav";}Calendar._add_evs(_78);_78.calendar=cal;_78.navtype=_7e;_78.innerHTML="<div unselectable='on'>"+_7c+"</div>";return _78;};row=Calendar.createElement("tr",_77);var _7f=6;(this.isPopup)&&--_7f;(this.weekNumbers)&&++_7f;hh("?",1,400).ttip=Calendar._TT["INFO"];this.title=hh("",_7f,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT["DRAG_TO_MOVE"];this.title.style.cursor="move";hh("&#x00d7;",1,200).ttip=Calendar._TT["CLOSE"];}row=Calendar.createElement("tr",_77);row.className="headrow";this._nav_py=hh("&#x00ab;",1,-2);this._nav_py.ttip=Calendar._TT["PREV_YEAR"];this._nav_pm=hh("&#x2039;",1,-1);this._nav_pm.ttip=Calendar._TT["PREV_MONTH"];this._nav_now=hh(Calendar._TT["TODAY"],this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT["GO_TODAY"];this._nav_nm=hh("&#x203a;",1,1);this._nav_nm.ttip=Calendar._TT["NEXT_MONTH"];this._nav_ny=hh("&#x00bb;",1,2);this._nav_ny.ttip=Calendar._TT["NEXT_YEAR"];row=Calendar.createElement("tr",_77);row.className="daynames";if(this.weekNumbers){_78=Calendar.createElement("td",row);_78.className="name wn";_78.innerHTML=Calendar._TT["WK"];}for(var i=7;i>0;--i){_78=Calendar.createElement("td",row);if(!i){_78.navtype=100;_78.calendar=this;Calendar._add_evs(_78);}}this.firstdayname=(this.weekNumbers)?row.firstChild.nextSibling:row.firstChild;this._displayWeekdays();var _81=Calendar.createElement("tbody",_75);this.tbody=_81;for(i=6;i>0;--i){row=Calendar.createElement("tr",_81);if(this.weekNumbers){_78=Calendar.createElement("td",row);}for(var j=7;j>0;--j){_78=Calendar.createElement("td",row);_78.calendar=this;Calendar._add_evs(_78);}}if(this.showsTime){row=Calendar.createElement("tr",_81);row.className="time";_78=Calendar.createElement("td",row);_78.className="time";_78.colSpan=2;_78.innerHTML=Calendar._TT["TIME"]||"&#160;";_78=Calendar.createElement("td",row);_78.className="time";_78.colSpan=this.weekNumbers?4:3;(function(){function makeTimePart(_83,_84,_85,_86){var _87=Calendar.createElement("span",_78);_87.className=_83;_87.innerHTML=_84;_87.calendar=cal;_87.ttip=Calendar._TT["TIME_PART"];_87.navtype=50;_87._range=[];if(typeof _85!="number"){_87._range=_85;}else{for(var i=_85;i<=_86;++i){var txt;if(i<10&&_86>=10){txt="0"+i;}else{txt=""+i;}_87._range[_87._range.length]=txt;}}Calendar._add_evs(_87);return _87;}var hrs=cal.date.getHours();var _8b=cal.date.getMinutes();var t12=!cal.time24;var pm=(hrs>12);if(t12&&pm){hrs-=12;}var H=makeTimePart("hour",hrs,t12?1:0,t12?12:23);var _8f=Calendar.createElement("span",_78);_8f.innerHTML=":";_8f.className="colon";var M=makeTimePart("minute",_8b,0,59);var AP=null;_78=Calendar.createElement("td",row);_78.className="time";_78.colSpan=2;if(t12){AP=makeTimePart("ampm",pm?"pm":"am",["am","pm"]);}else{_78.innerHTML="&#160;";}cal.onSetTime=function(){var pm,hrs=this.date.getHours(),_8b=this.date.getMinutes();if(t12){pm=(hrs>=12);if(pm){hrs-=12;}if(hrs==0){hrs=12;}AP.innerHTML=pm?"pm":"am";}H.innerHTML=(hrs<10)?("0"+hrs):hrs;M.innerHTML=(_8b<10)?("0"+_8b):_8b;};cal.onUpdateTime=function(){var _93=this.date;var h=parseInt(H.innerHTML,10);if(t12){if(/pm/i.test(AP.innerHTML)&&h<12){h+=12;}else{if(/am/i.test(AP.innerHTML)&&h==12){h=0;}}}var d=_93.getDate();var m=_93.getMonth();var y=_93.getFullYear();_93.setHours(h);_93.setMinutes(parseInt(M.innerHTML,10));_93.setFullYear(y);_93.setMonth(m);_93.setDate(d);this.dateClicked=false;this.callHandler();};})();}else{this.onSetTime=this.onUpdateTime=function(){};}var _98=Calendar.createElement("tfoot",_75);row=Calendar.createElement("tr",_98);row.className="footrow";_78=hh(Calendar._TT["SEL_DATE"],this.weekNumbers?8:7,300);_78.className="ttip";if(this.isPopup){_78.ttip=Calendar._TT["DRAG_TO_MOVE"];_78.style.cursor="move";}this.tooltips=_78;div=Calendar.createElement("div",this.element);this.monthsCombo=div;div.className="combo";for(i=0;i<Calendar._MN.length;++i){var mn=Calendar.createElement("div");mn.className=Calendar.is_ie?"label-IEfix":"label";mn.month=i;mn.innerHTML=Calendar._SMN[i];div.appendChild(mn);}div=Calendar.createElement("div",this.element);this.yearsCombo=div;div.className="combo";for(i=12;i>0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";div.appendChild(yr);}this._init(this.firstDayOfWeek,this.date);_74.appendChild(this.element);};Calendar._keyEvent=function(ev){var cal=window._dynarch_popupCalendar;if(!cal||cal.multiple){return false;}(Calendar.is_ie)&&(ev=window.event);var act=(Calendar.is_ie||ev.type=="keypress"),K=ev.keyCode;if(ev.ctrlKey){switch(K){case 37:act&&Calendar.cellClick(cal._nav_pm);break;case 38:act&&Calendar.cellClick(cal._nav_py);break;case 39:act&&Calendar.cellClick(cal._nav_nm);break;case 40:act&&Calendar.cellClick(cal._nav_ny);break;default:return false;}}else{switch(K){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.callCloseHandler();break;case 37:case 38:case 39:case 40:if(act){var _9e,x,y,ne,el,step;_9e=K==37||K==38;step=(K==37||K==39)?1:7;function setVars(){el=cal.currentDateEl;var p=el.pos;x=p&15;y=p>>4;ne=cal.ar_days[y][x];}setVars();function prevMonth(){var _a0=new Date(cal.date);_a0.setDate(_a0.getDate()-step);cal.setDate(_a0);}function nextMonth(){var _a1=new Date(cal.date);_a1.setDate(_a1.getDate()+step);cal.setDate(_a1);}while(1){switch(K){case 37:if(--x>=0){ne=cal.ar_days[y][x];}else{x=6;K=38;continue;}break;case 38:if(--y>=0){ne=cal.ar_days[y][x];}else{prevMonth();setVars();}break;case 39:if(++x<7){ne=cal.ar_days[y][x];}else{x=0;K=40;continue;}break;case 40:if(++y<cal.ar_days.length){ne=cal.ar_days[y][x];}else{nextMonth();setVars();}break;}break;}if(ne){if(!ne.disabled){Calendar.cellClick(ne);}else{if(_9e){prevMonth();}else{nextMonth();}}}}break;case 13:if(act){Calendar.cellClick(cal.currentDateEl,ev);}break;default:return false;}}return Calendar.stopEvent(ev);};Calendar.prototype._init=function(_a2,_a3){var _a4=new Date(),TY=_a4.getFullYear(),TM=_a4.getMonth(),TD=_a4.getDate();this.table.style.visibility="hidden";var _a5=_a3.getFullYear();if(_a5<this.minYear){_a5=this.minYear;_a3.setFullYear(_a5);}else{if(_a5>this.maxYear){_a5=this.maxYear;_a3.setFullYear(_a5);}}this.firstDayOfWeek=_a2;this.date=new Date(_a3);var _a6=_a3.getMonth();var _a7=_a3.getDate();var _a8=_a3.getMonthDays();_a3.setDate(1);var _a9=(_a3.getDay()-this.firstDayOfWeek)%7;if(_a9<0){_a9+=7;}_a3.setDate(-_a9);_a3.setDate(_a3.getDate()+1);var row=this.tbody.firstChild;var MN=Calendar._SMN[_a6];var _ac=this.ar_days=new Array();var _ad=Calendar._TT["WEEKEND"];var _ae=this.multiple?(this.datesCells={}):null;for(var i=0;i<6;++i,row=row.nextSibling){var _b0=row.firstChild;if(this.weekNumbers){_b0.className="day wn";_b0.innerHTML=_a3.getWeekNumber();_b0=_b0.nextSibling;}row.className="daysrow";var _b1=false,iday,dpos=_ac[i]=[];for(var j=0;j<7;++j,_b0=_b0.nextSibling,_a3.setDate(iday+1)){iday=_a3.getDate();var _b3=_a3.getDay();_b0.className="day";_b0.pos=i<<4|j;dpos[j]=_b0;var _b4=(_a3.getMonth()==_a6);if(!_b4){if(this.showsOtherMonths){_b0.className+=" othermonth";_b0.otherMonth=true;}else{_b0.className="emptycell";_b0.innerHTML="&#160;";_b0.disabled=true;continue;}}else{_b0.otherMonth=false;_b1=true;}_b0.disabled=false;_b0.innerHTML=this.getDateText?this.getDateText(_a3,iday):iday;if(_ae){_ae[_a3.print("%Y%m%d")]=_b0;}if(this.getDateStatus){var _b5=this.getDateStatus(_a3,_a5,_a6,iday);if(this.getDateToolTip){var _b6=this.getDateToolTip(_a3,_a5,_a6,iday);if(_b6){_b0.title=_b6;}}if(_b5===true){_b0.className+=" disabled";_b0.disabled=true;}else{if(/disabled/i.test(_b5)){_b0.disabled=true;}_b0.className+=" "+_b5;}}if(!_b0.disabled){_b0.caldate=new Date(_a3);_b0.ttip="_";if(!this.multiple&&_b4&&iday==_a7&&this.hiliteToday){_b0.className+=" selected";this.currentDateEl=_b0;}if(_a3.getFullYear()==TY&&_a3.getMonth()==TM&&iday==TD){_b0.className+=" today";_b0.ttip+=Calendar._TT["PART_TODAY"];}if(_ad.indexOf(_b3.toString())!=-1){_b0.className+=_b0.otherMonth?" oweekend":" weekend";}}}if(!(_b1||this.showsOtherMonths)){row.className="emptyrow";}}this.title.innerHTML=Calendar._MN[_a6]+", "+_a5;this.onSetTime();this.table.style.visibility="visible";this._initMultipleDates();};Calendar.prototype._initMultipleDates=function(){if(this.multiple){for(var i in this.multiple){var _b8=this.datesCells[i];var d=this.multiple[i];if(!d){continue;}if(_b8){_b8.className+=" selected";}}}};Calendar.prototype._toggleMultipleDate=function(_ba){if(this.multiple){var ds=_ba.print("%Y%m%d");var _bc=this.datesCells[ds];if(_bc){var d=this.multiple[ds];if(!d){Calendar.addClass(_bc,"selected");this.multiple[ds]=_ba;}else{Calendar.removeClass(_bc,"selected");delete this.multiple[ds];}}}};Calendar.prototype.setDateToolTipHandler=function(_be){this.getDateToolTip=_be;};Calendar.prototype.setDate=function(_bf){if(!_bf.equalsTo(this.date)){this._init(this.firstDayOfWeek,_bf);}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date);};Calendar.prototype.setFirstDayOfWeek=function(_c0){this._init(_c0,this.date);this._displayWeekdays();};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(_c1){this.getDateStatus=_c1;};Calendar.prototype.setRange=function(a,z){this.minYear=a;this.maxYear=z;};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.print(this.dateFormat));}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this);}this.hideShowCovered();};Calendar.prototype.destroy=function(){var el=this.element.parentNode;el.removeChild(this.element);Calendar._C=null;window._dynarch_popupCalendar=null;};Calendar.prototype.reparent=function(_c5){var el=this.element;el.parentNode.removeChild(el);_c5.appendChild(el);};Calendar._checkCalendar=function(ev){var _c8=window._dynarch_popupCalendar;if(!_c8){return false;}var el=Calendar.is_ie?Calendar.getElement(ev):Calendar.getTargetElement(ev);for(;el!=null&&el!=_c8.element;el=el.parentNode){}if(el==null){window._dynarch_popupCalendar.callCloseHandler();return Calendar.stopEvent(ev);}};Calendar.prototype.show=function(){var _ca=this.table.getElementsByTagName("tr");for(var i=_ca.length;i>0;){var row=_ca[--i];Calendar.removeClass(row,"rowhilite");var _cd=row.getElementsByTagName("td");for(var j=_cd.length;j>0;){var _cf=_cd[--j];Calendar.removeClass(_cf,"hilite");Calendar.removeClass(_cf,"active");}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window._dynarch_popupCalendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar);}this.hideShowCovered();};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar);}this.element.style.display="none";this.hidden=true;this.hideShowCovered();};Calendar.prototype.showAt=function(x,y){var s=this.element.style;s.left=x+"px";s.top=y+"px";this.show();};Calendar.prototype.showAtElement=function(el,_d4){var _d5=this;var p=Calendar.getAbsolutePos(el);if(!_d4||typeof _d4!="string"){this.showAt(p.x,p.y+el.offsetHeight);return true;}function fixPosition(box){if(box.x<0){box.x=0;}if(box.y<0){box.y=0;}var cp=document.createElement("div");var s=cp.style;s.position="absolute";s.right=s.bottom=s.width=s.height="0px";document.body.appendChild(cp);var br=Calendar.getAbsolutePos(cp);document.body.removeChild(cp);if(Calendar.is_ie){br.y+=document.body.scrollTop;br.x+=document.body.scrollLeft;}else{br.y+=window.scrollY;br.x+=window.scrollX;}var tmp=box.x+box.width-br.x;if(tmp>0){box.x-=tmp;}tmp=box.y+box.height-br.y;if(tmp>0){box.y-=tmp;}}this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var w=_d5.element.offsetWidth;var h=_d5.element.offsetHeight;_d5.element.style.display="none";var _de=_d4.substr(0,1);var _df="l";if(_d4.length>1){_df=_d4.substr(1,1);}switch(_de){case "T":p.y-=h;break;case "B":p.y+=el.offsetHeight;break;case "C":p.y+=(el.offsetHeight-h)/2;break;case "t":p.y+=el.offsetHeight-h;break;case "b":break;}switch(_df){case "L":p.x-=w;break;case "R":p.x+=el.offsetWidth;break;case "C":p.x+=(el.offsetWidth-w)/2;break;case "l":p.x+=el.offsetWidth-w;break;case "r":break;}p.width=w;p.height=h+40;_d5.monthsCombo.style.display="none";fixPosition(p);_d5.showAt(p.x,p.y);};if(Calendar.is_khtml){setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);}else{Calendar.continuation_for_the_fucking_khtml_browser();}};Calendar.prototype.setDateFormat=function(str){this.dateFormat=str;};Calendar.prototype.setTtDateFormat=function(str){this.ttDateFormat=str;};Calendar.prototype.parseDate=function(str,fmt){if(!fmt){fmt=this.dateFormat;}this.setDate(Date.parseDate(str,fmt));};Calendar.prototype.hideShowCovered=function(){if(!Calendar.is_ie&&!Calendar.is_opera){return;}function getVisib(obj){var _e5=obj.style.visibility;if(!_e5){if(document.defaultView&&typeof (document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml){_e5=document.defaultView.getComputedStyle(obj,"").getPropertyValue("visibility");}else{_e5="";}}else{if(obj.currentStyle){_e5=obj.currentStyle.visibility;}else{_e5="";}}}return _e5;}var _e6=new Array("applet","iframe","select");var el=this.element;var p=Calendar.getAbsolutePos(el);var EX1=p.x;var EX2=el.offsetWidth+EX1;var EY1=p.y;var EY2=el.offsetHeight+EY1;for(var k=_e6.length;k>0;){var ar=document.getElementsByTagName(_e6[--k]);var cc=null;for(var i=ar.length;i>0;){cc=ar[--i];p=Calendar.getAbsolutePos(cc);var CX1=p.x;var CX2=cc.offsetWidth+CX1;var CY1=p.y;var CY2=cc.offsetHeight+CY1;if(this.hidden||(CX1>EX2)||(CX2<EX1)||(CY1>EY2)||(CY2<EY1)){if(!cc.__msh_save_visibility){cc.__msh_save_visibility=getVisib(cc);}cc.style.visibility=cc.__msh_save_visibility;}else{if(!cc.__msh_save_visibility){cc.__msh_save_visibility=getVisib(cc);}cc.style.visibility="hidden";}}}};Calendar.prototype._displayWeekdays=function(){var _f5=this.firstDayOfWeek;var _f6=this.firstdayname;var _f7=Calendar._TT["WEEKEND"];for(var i=0;i<7;++i){_f6.className="day name";var _f9=(i+_f5)%7;if(i){_f6.ttip=Calendar._TT["DAY_FIRST"].replace("%s",Calendar._DN[_f9]);_f6.navtype=100;_f6.calendar=this;_f6.fdow=_f9;Calendar._add_evs(_f6);}if(_f7.indexOf(_f9.toString())!=-1){Calendar.addClass(_f6,"weekend");}_f6.innerHTML=Calendar._SDN[(i+_f5)%7];_f6=_f6.nextSibling;}};Calendar.prototype._hideCombos=function(){this.monthsCombo.style.display="none";this.yearsCombo.style.display="none";};Calendar.prototype._dragStart=function(ev){if(this.dragging){return;}this.dragging=true;var _fb;var _fc;if(Calendar.is_ie){_fc=window.event.clientY+document.body.scrollTop;_fb=window.event.clientX+document.body.scrollLeft;}else{_fc=ev.clientY+window.scrollY;_fb=ev.clientX+window.scrollX;}var st=this.element.style;this.xOffs=_fb-parseInt(st.left);this.yOffs=_fc-parseInt(st.top);with(Calendar){addEvent(document,"mousemove",calDragIt);addEvent(document,"mouseup",calDragEnd);}};Date._MD=new Array(31,28,31,30,31,30,31,31,30,31,30,31);Date.SECOND=1000;Date.MINUTE=60*Date.SECOND;Date.HOUR=60*Date.MINUTE;Date.DAY=24*Date.HOUR;Date.WEEK=7*Date.DAY;Date.parseDate=function(str,fmt){var _100=new Date();var y=0;var m=-1;var d=0;var a=str.split(/\W+/);var b=fmt.match(/%./g);var i=0,j=0;var hr=0;var min=0;for(i=0;i<a.length;++i){if(!a[i]){continue;}switch(b[i]){case "%d":case "%e":d=parseInt(a[i],10);break;case "%m":m=parseInt(a[i],10)-1;break;case "%Y":case "%y":y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);break;case "%b":case "%B":for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}break;case "%H":case "%I":case "%k":case "%l":hr=parseInt(a[i],10);break;case "%P":case "%p":if(/pm/i.test(a[i])&&hr<12){hr+=12;}else{if(/am/i.test(a[i])&&hr>=12){hr-=12;}}break;case "%M":min=parseInt(a[i],10);break;}}if(isNaN(y)){y=_100.getFullYear();}if(isNaN(m)){m=_100.getMonth();}if(isNaN(d)){d=_100.getDate();}if(isNaN(hr)){hr=_100.getHours();}if(isNaN(min)){min=_100.getMinutes();}if(y!=0&&m!=-1&&d!=0){return new Date(y,m,d,hr,min,0);}y=0;m=-1;d=0;for(i=0;i<a.length;++i){if(a[i].search(/[a-zA-Z]+/)!=-1){var t=-1;for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){t=j;break;}}if(t!=-1){if(m!=-1){d=m+1;}m=t;}}else{if(parseInt(a[i],10)<=12&&m==-1){m=a[i]-1;}else{if(parseInt(a[i],10)>31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else{if(d==0){d=a[i];}}}}}if(y==0){y=_100.getFullYear();}if(m!=-1&&d!=0){return new Date(y,m,d,hr,min,0);}return _100;};Date.prototype.getMonthDays=function(_10a){var year=this.getFullYear();if(typeof _10a=="undefined"){_10a=this.getMonth();}if(((0==(year%4))&&((0!=(year%100))||(0==(year%400))))&&_10a==1){return 29;}else{return Date._MD[_10a];}};Date.prototype.getDayOfYear=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,0,0,0,0);var time=now-then;return Math.floor(time/Date.DAY);};Date.prototype.getWeekNumber=function(){var d=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var DoW=d.getDay();d.setDate(d.getDate()-(DoW+6)%7+3);var ms=d.valueOf();d.setMonth(0);d.setDate(4);return Math.round((ms-d.valueOf())/(7*86400000))+1;};Date.prototype.equalsTo=function(date){return ((this.getFullYear()==date.getFullYear())&&(this.getMonth()==date.getMonth())&&(this.getDate()==date.getDate())&&(this.getHours()==date.getHours())&&(this.getMinutes()==date.getMinutes()));};Date.prototype.setDateOnly=function(date){var tmp=new Date(date);this.setDate(1);this.setFullYear(tmp.getFullYear());this.setMonth(tmp.getMonth());this.setDate(tmp.getDate());};Date.prototype.print=function(str){var m=this.getMonth();var d=this.getDate();var y=this.getFullYear();var wn=this.getWeekNumber();var w=this.getDay();var s={};var hr=this.getHours();var pm=(hr>=12);var ir=(pm)?(hr-12):hr;var dy=this.getDayOfYear();if(ir==0){ir=12;}var min=this.getMinutes();var sec=this.getSeconds();s["%a"]=Calendar._SDN[w];s["%A"]=Calendar._DN[w];s["%b"]=Calendar._SMN[m];s["%B"]=Calendar._MN[m];s["%C"]=1+Math.floor(y/100);s["%d"]=(d<10)?("0"+d):d;s["%e"]=d;s["%H"]=(hr<10)?("0"+hr):hr;s["%I"]=(ir<10)?("0"+ir):ir;s["%j"]=(dy<100)?((dy<10)?("00"+dy):("0"+dy)):dy;s["%k"]=hr;s["%l"]=ir;s["%m"]=(m<9)?("0"+(1+m)):(1+m);s["%M"]=(min<10)?("0"+min):min;s["%n"]="\n";s["%p"]=pm?"PM":"AM";s["%P"]=pm?"pm":"am";s["%s"]=Math.floor(this.getTime()/1000);s["%S"]=(sec<10)?("0"+sec):sec;s["%t"]="\t";s["%U"]=s["%W"]=s["%V"]=(wn<10)?("0"+wn):wn;s["%u"]=w+1;s["%w"]=w;s["%y"]=(""+y).substr(2,2);s["%Y"]=y;s["%%"]="%";var re=/%./g;if(!Calendar.is_ie5&&!Calendar.is_khtml){return str.replace(re,function(par){return s[par]||par;});}var a=str.match(re);for(var i=0;i<a.length;i++){var tmp=s[a[i]];if(tmp){re=new RegExp(a[i],"g");str=str.replace(re,tmp);}}return str;};if(!Date.prototype.__msh_oldSetFullYear){Date.prototype.__msh_oldSetFullYear=Date.prototype.setFullYear;}Date.prototype.setFullYear=function(y){var d=new Date(this);d.__msh_oldSetFullYear(y);if(d.getMonth()!=this.getMonth()){this.setDate(28);}this.__msh_oldSetFullYear(y);};window._dynarch_popupCalendar=null;
Calendar._DN=new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");Calendar._SDN=new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun");Calendar._FD=0;Calendar._MN=new Array("January","February","March","April","May","June","July","August","September","October","November","December");Calendar._SMN=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");Calendar._TT={};Calendar._TT["INFO"]="About the calendar";Calendar._TT["ABOUT"]="DHTML Date/Time Selector\n"+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n"+"For latest version visit: http://www.dynarch.com/projects/calendar/\n"+"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details."+"\n\n"+"Date selection:\n"+"- Use the \xab, \xbb buttons to select year\n"+"- Use the "+String.fromCharCode(8249)+", "+String.fromCharCode(8250)+" buttons to select month\n"+"- Hold mouse button on any of the above buttons for faster selection.";Calendar._TT["ABOUT_TIME"]="\n\n"+"Time selection:\n"+"- Click on any of the time parts to increase it\n"+"- or Shift-click to decrease it\n"+"- or click and drag for faster selection.";Calendar._TT["PREV_YEAR"]="Prev. year (hold for menu)";Calendar._TT["PREV_MONTH"]="Prev. month (hold for menu)";Calendar._TT["GO_TODAY"]="Go Today";Calendar._TT["NEXT_MONTH"]="Next month (hold for menu)";Calendar._TT["NEXT_YEAR"]="Next year (hold for menu)";Calendar._TT["SEL_DATE"]="Select date";Calendar._TT["DRAG_TO_MOVE"]="Drag to move";Calendar._TT["PART_TODAY"]=" (today)";Calendar._TT["DAY_FIRST"]="Display %s first";Calendar._TT["WEEKEND"]="0,6";Calendar._TT["CLOSE"]="Close";Calendar._TT["TODAY"]="Today";Calendar._TT["TIME_PART"]="(Shift-)Click or drag to change value";Calendar._TT["DEF_DATE_FORMAT"]="%Y-%m-%d";Calendar._TT["TT_DATE_FORMAT"]="%a, %b %e";Calendar._TT["WK"]="wk";Calendar._TT["TIME"]="Time:";
Calendar.setup=function(_1){function param_default(_2,_3){if(typeof _1[_2]=="undefined"){_1[_2]=_3;}}param_default("inputField",null);param_default("displayArea",null);param_default("button",null);param_default("eventName","click");param_default("ifFormat","%Y/%m/%d");param_default("daFormat","%Y/%m/%d");param_default("singleClick",true);param_default("disableFunc",null);param_default("dateStatusFunc",_1["disableFunc"]);param_default("dateText",null);param_default("firstDay",null);param_default("align","Br");param_default("range",[1900,2999]);param_default("weekNumbers",true);param_default("flat",null);param_default("flatCallback",null);param_default("onSelect",null);param_default("onClose",null);param_default("onUpdate",null);param_default("date",null);param_default("showsTime",false);param_default("timeFormat","24");param_default("electric",true);param_default("step",2);param_default("position",null);param_default("cache",false);param_default("showOthers",false);param_default("multiple",null);var _4=["inputField","displayArea","button"];for(var i in _4){if(typeof _1[_4[i]]=="string"){_1[_4[i]]=document.getElementById(_1[_4[i]]);}}if(!(_1.flat||_1.multiple||_1.inputField||_1.displayArea||_1.button)){alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");return false;}function onSelect(_6){var p=_6.params;var _8=(_6.dateClicked||p.electric);if(_8&&p.inputField){p.inputField.value=_6.date.print(p.ifFormat);if(typeof p.inputField.onchange=="function"){p.inputField.onchange();}}if(_8&&p.displayArea){p.displayArea.innerHTML=_6.date.print(p.daFormat);}if(_8&&typeof p.onUpdate=="function"){p.onUpdate(_6);}if(_8&&p.flat){if(typeof p.flatCallback=="function"){p.flatCallback(_6);}}if(_8&&p.singleClick&&_6.dateClicked){_6.callCloseHandler();}}if(_1.flat!=null){if(typeof _1.flat=="string"){_1.flat=document.getElementById(_1.flat);}if(!_1.flat){alert("Calendar.setup:\n  Flat specified but can't find parent.");return false;}var _9=new Calendar(_1.firstDay,_1.date,_1.onSelect||onSelect);_9.showsOtherMonths=_1.showOthers;_9.showsTime=_1.showsTime;_9.time24=(_1.timeFormat=="24");_9.params=_1;_9.weekNumbers=_1.weekNumbers;_9.setRange(_1.range[0],_1.range[1]);_9.setDateStatusHandler(_1.dateStatusFunc);_9.getDateText=_1.dateText;if(_1.ifFormat){_9.setDateFormat(_1.ifFormat);}if(_1.inputField&&typeof _1.inputField.value=="string"){_9.parseDate(_1.inputField.value);}_9.create(_1.flat);_9.show();return false;}var _a=_1.button||_1.displayArea||_1.inputField;_a["on"+_1.eventName]=function(){var _b=_1.inputField||_1.displayArea;var _c=_1.inputField?_1.ifFormat:_1.daFormat;var _d=false;var _e=window.calendar;if(_b){_1.date=Date.parseDate(_b.value||_b.innerHTML,_c);}if(!(_e&&_1.cache)){window.calendar=_e=new Calendar(_1.firstDay,_1.date,_1.onSelect||onSelect,_1.onClose||function(_f){_f.hide();});_e.showsTime=_1.showsTime;_e.time24=(_1.timeFormat=="24");_e.weekNumbers=_1.weekNumbers;_d=true;}else{if(_1.date){_e.setDate(_1.date);}_e.hide();}if(_1.multiple){_e.multiple={};for(var i=_1.multiple.length;--i>=0;){var d=_1.multiple[i];var ds=d.print("%Y%m%d");_e.multiple[ds]=d;}}_e.showsOtherMonths=_1.showOthers;_e.yearStep=_1.step;_e.setRange(_1.range[0],_1.range[1]);_e.params=_1;_e.setDateStatusHandler(_1.dateStatusFunc);_e.getDateText=_1.dateText;_e.setDateFormat(_c);if(_d){_e.create();}_e.refresh();if(!_1.position){_e.showAtElement(_1.button||_1.displayArea||_1.inputField,_1.align);}else{_e.showAt(_1.position[0],_1.position[1]);}return false;};return _9;};
/* Copyright (c) 2006, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.net/yui/license.txt version: 0.12.0 */ if(typeof YAHOO=="undefined"){var YAHOO={};}YAHOO.namespace=function(){var a=arguments,o=null,i,j,d;for(i=0;i<a.length;++i){d=a[i].split(".");o=YAHOO;for(j=(d[0]=="YAHOO")?1:0;j<d.length;++j){o[d[j]]=o[d[j]]||{};o=o[d[j]];}}return o;};YAHOO.log=function(_2,_3,_4){var l=YAHOO.widget.Logger;if(l&&l.log){return l.log(_2,_3,_4);}else{return false;}};YAHOO.extend=function(_6,_7,_8){var F=function(){};F.prototype=_7.prototype;_6.prototype=new F();_6.prototype.constructor=_6;_6.superclass=_7.prototype;if(_7.prototype.constructor==Object.prototype.constructor){_7.prototype.constructor=_7;}if(_8){for(var i in _8){_6.prototype[i]=_8[i];}}};YAHOO.augment=function(r,s){var rp=r.prototype,sp=s.prototype,a=arguments,i,p;if(a[2]){for(i=2;i<a.length;++i){rp[a[i]]=sp[a[i]];}}else{for(p in sp){if(!rp[p]){rp[p]=sp[p];}}}};YAHOO.namespace("util","widget","example");
/* Copyright (c) 2006, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.net/yui/license.txt version: 0.12.0 */ YAHOO.util.CustomEvent=function(_1,_2,_3,_4){this.type=_1;this.scope=_2||window;this.silent=_3;this.signature=_4||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var _5="_YUICEOnSubscribe";if(_1!==_5){this.subscribeEvent=new YAHOO.util.CustomEvent(_5,this,true);}};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(fn,_7,_8){if(this.subscribeEvent){this.subscribeEvent.fire(fn,_7,_8);}this.subscribers.push(new YAHOO.util.Subscriber(fn,_7,_8));},unsubscribe:function(fn,_9){var _10=false;for(var i=0,len=this.subscribers.length;i<len;++i){var s=this.subscribers[i];if(s&&s.contains(fn,_9)){this._delete(i);_10=true;}}return _10;},fire:function(){var len=this.subscribers.length;if(!len&&this.silent){return true;}var _14=[],ret=true,i;for(i=0;i<arguments.length;++i){_14.push(arguments[i]);}var _15=_14.length;if(!this.silent){}for(i=0;i<len;++i){var s=this.subscribers[i];if(s){if(!this.silent){}var _16=s.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var _17=null;if(_14.length>0){_17=_14[0];}ret=s.fn.call(_16,_17,s.obj);}else{ret=s.fn.call(_16,this.type,_14,s.obj);}if(false===ret){if(!this.silent){}return false;}}}return true;},unsubscribeAll:function(){for(var i=0,len=this.subscribers.length;i<len;++i){this._delete(len-1-i);}},_delete:function(_18){var s=this.subscribers[_18];if(s){delete s.fn;delete s.obj;}this.subscribers.splice(_18,1);},toString:function(){return "CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(fn,obj,_20){this.fn=fn;this.obj=obj||null;this.override=_20;};YAHOO.util.Subscriber.prototype.getScope=function(_21){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return _21;};YAHOO.util.Subscriber.prototype.contains=function(fn,obj){if(obj){return (this.fn==fn&&this.obj==obj);}else{return (this.fn==fn);}};YAHOO.util.Subscriber.prototype.toString=function(){return "Subscriber { obj: "+(this.obj||"")+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var _22=false;var _23=[];var _24=[];var _25=[];var _26=[];var _27=0;var _28=[];var _29=[];var _30=0;return {POLL_RETRYS:200,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,OBJ:3,ADJ_SCOPE:4,isSafari:(/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),isIE:(!this.isSafari&&!navigator.userAgent.match(/opera/gi)&&navigator.userAgent.match(/msie/gi)),_interval:null,startInterval:function(){if(!this._interval){var _31=this;var _32=function(){_31._tryPreloadAttach();};this._interval=setInterval(_32,this.POLL_INTERVAL);}},onAvailable:function(_33,_34,_35,_36){_28.push({id:_33,fn:_34,obj:_35,override:_36,checkReady:false});_27=this.POLL_RETRYS;this.startInterval();},onContentReady:function(_37,_38,_39,_40){_28.push({id:_37,fn:_38,obj:_39,override:_40,checkReady:true});_27=this.POLL_RETRYS;this.startInterval();},addListener:function(el,_42,fn,obj,_43){if(!fn||!fn.call){return false;}if(this._isValidCollection(el)){var ok=true;for(var i=0,len=el.length;i<len;++i){ok=this.on(el[i],_42,fn,obj,_43)&&ok;}return ok;}else{if(typeof el=="string"){var oEl=this.getEl(el);if(oEl){el=oEl;}else{this.onAvailable(el,function(){YAHOO.util.Event.on(el,_42,fn,obj,_43);});return true;}}}if(!el){return false;}if("unload"==_42&&obj!==this){_24[_24.length]=[el,_42,fn,obj,_43];return true;}var _46=el;if(_43){if(_43===true){_46=obj;}else{_46=_43;}}var _47=function(e){return fn.call(_46,YAHOO.util.Event.getEvent(e),obj);};var li=[el,_42,fn,_47,_46];var _50=_23.length;_23[_50]=li;if(this.useLegacyEvent(el,_42)){var _51=this.getLegacyIndex(el,_42);if(_51==-1||el!=_25[_51][0]){_51=_25.length;_29[el.id+_42]=_51;_25[_51]=[el,_42,el["on"+_42]];_26[_51]=[];el["on"+_42]=function(e){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(e),_51);};}_26[_51].push(li);}else{this._simpleAdd(el,_42,_47,false);}return true;},fireLegacyEvent:function(e,_52){var ok=true;var le=_26[_52];for(var i=0,len=le.length;i<len;++i){var li=le[i];if(li&&li[this.WFN]){var _54=li[this.ADJ_SCOPE];var ret=li[this.WFN].call(_54,e);ok=(ok&&ret);}}return ok;},getLegacyIndex:function(el,_56){var key=this.generateId(el)+_56;if(typeof _29[key]=="undefined"){return -1;}else{return _29[key];}},useLegacyEvent:function(el,_58){if(!el.addEventListener&&!el.attachEvent){return true;}else{if(this.isSafari){if("click"==_58||"dblclick"==_58){return true;}}}return false;},removeListener:function(el,_59,fn){var i,len;if(typeof el=="string"){el=this.getEl(el);}else{if(this._isValidCollection(el)){var ok=true;for(i=0,len=el.length;i<len;++i){ok=(this.removeListener(el[i],_59,fn)&&ok);}return ok;}}if(!fn||!fn.call){return this.purgeElement(el,false,_59);}if("unload"==_59){for(i=0,len=_24.length;i<len;i++){var li=_24[i];if(li&&li[0]==el&&li[1]==_59&&li[2]==fn){_24.splice(i,1);return true;}}return false;}var _60=null;var _61=arguments[3];if("undefined"==typeof _61){_61=this._getCacheIndex(el,_59,fn);}if(_61>=0){_60=_23[_61];}if(!el||!_60){return false;}if(this.useLegacyEvent(el,_59)){var _62=this.getLegacyIndex(el,_59);var _63=_26[_62];if(_63){for(i=0,len=_63.length;i<len;++i){li=_63[i];if(li&&li[this.EL]==el&&li[this.TYPE]==_59&&li[this.FN]==fn){_63.splice(i,1);break;}}}}else{this._simpleRemove(el,_59,_60[this.WFN],false);}delete _23[_61][this.WFN];delete _23[_61][this.FN];_23.splice(_61,1);return true;},getTarget:function(ev,_65){var t=ev.target||ev.srcElement;return this.resolveTextNode(t);},resolveTextNode:function(_67){if(_67&&3==_67.nodeType){return _67.parentNode;}else{return _67;}},getPageX:function(ev){var x=ev.pageX;if(!x&&0!==x){x=ev.clientX||0;if(this.isIE){x+=this._getScrollLeft();}}return x;},getPageY:function(ev){var y=ev.pageY;if(!y&&0!==y){y=ev.clientY||0;if(this.isIE){y+=this._getScrollTop();}}return y;},getXY:function(ev){return [this.getPageX(ev),this.getPageY(ev)];},getRelatedTarget:function(ev){var t=ev.relatedTarget;if(!t){if(ev.type=="mouseout"){t=ev.toElement;}else{if(ev.type=="mouseover"){t=ev.fromElement;}}}return this.resolveTextNode(t);},getTime:function(ev){if(!ev.time){var t=new Date().getTime();try{ev.time=t;}catch(e){return t;}}return ev.time;},stopEvent:function(ev){this.stopPropagation(ev);this.preventDefault(ev);},stopPropagation:function(ev){if(ev.stopPropagation){ev.stopPropagation();}else{ev.cancelBubble=true;}},preventDefault:function(ev){if(ev.preventDefault){ev.preventDefault();}else{ev.returnValue=false;}},getEvent:function(e){var ev=e||window.event;if(!ev){var c=this.getEvent.caller;while(c){ev=c.arguments[0];if(ev&&Event==ev.constructor){break;}c=c.caller;}}return ev;},getCharCode:function(ev){return ev.charCode||ev.keyCode||0;},_getCacheIndex:function(el,_71,fn){for(var i=0,len=_23.length;i<len;++i){var li=_23[i];if(li&&li[this.FN]==fn&&li[this.EL]==el&&li[this.TYPE]==_71){return i;}}return -1;},generateId:function(el){var id=el.id;if(!id){id="yuievtautoid-"+_30;++_30;el.id=id;}return id;},_isValidCollection:function(o){return (o&&o.length&&typeof o!="string"&&!o.tagName&&!o.alert&&typeof o[0]!="undefined");},elCache:{},getEl:function(id){return document.getElementById(id);},clearCache:function(){},_load:function(e){_22=true;var EU=YAHOO.util.Event;if(this.isIE){EU._simpleRemove(window,"load",EU._load);}},_tryPreloadAttach:function(){if(this.locked){return false;}this.locked=true;var _75=!_22;if(!_75){_75=(_27>0);}var _76=[];for(var i=0,len=_28.length;i<len;++i){var _77=_28[i];if(_77){var el=this.getEl(_77.id);if(el){if(!_77.checkReady||_22||el.nextSibling||(document&&document.body)){var _78=el;if(_77.override){if(_77.override===true){_78=_77.obj;}else{_78=_77.override;}}_77.fn.call(_78,_77.obj);delete _28[i];}}else{_76.push(_77);}}}_27=(_76.length===0)?0:_27-1;if(_75){this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;return true;},purgeElement:function(el,_79,_80){var _81=this.getListeners(el,_80);if(_81){for(var i=0,len=_81.length;i<len;++i){var l=_81[i];this.removeListener(el,l.type,l.fn);}}if(_79&&el&&el.childNodes){for(i=0,len=el.childNodes.length;i<len;++i){this.purgeElement(el.childNodes[i],_79,_80);}}},getListeners:function(el,_83){var _84=[];if(_23&&_23.length>0){for(var i=0,len=_23.length;i<len;++i){var l=_23[i];if(l&&l[this.EL]===el&&(!_83||_83===l[this.TYPE])){_84.push({type:l[this.TYPE],fn:l[this.FN],obj:l[this.OBJ],adjust:l[this.ADJ_SCOPE],index:i});}}}return (_84.length)?_84:null;},_unload:function(e){var EU=YAHOO.util.Event,i,j,l,len,index;for(i=0,len=_24.length;i<len;++i){l=_24[i];if(l){var _85=window;if(l[EU.ADJ_SCOPE]){if(l[EU.ADJ_SCOPE]===true){_85=l[EU.OBJ];}else{_85=l[EU.ADJ_SCOPE];}}l[EU.FN].call(_85,EU.getEvent(e),l[EU.OBJ]);delete _24[i];l=null;_85=null;}}if(_23&&_23.length>0){j=_23.length;while(j){index=j-1;l=_23[index];if(l){EU.removeListener(l[EU.EL],l[EU.TYPE],l[EU.FN],index);}j=j-1;}l=null;EU.clearCache();}for(i=0,len=_25.length;i<len;++i){delete _25[i][0];delete _25[i];}EU._simpleRemove(window,"unload",EU._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var dd=document.documentElement,db=document.body;if(dd&&(dd.scrollTop||dd.scrollLeft)){return [dd.scrollTop,dd.scrollLeft];}else{if(db){return [db.scrollTop,db.scrollLeft];}else{return [0,0];}}},_simpleAdd:function(){if(window.addEventListener){return function(el,_87,fn,_88){el.addEventListener(_87,fn,(_88));};}else{if(window.attachEvent){return function(el,_89,fn,_90){el.attachEvent("on"+_89,fn);};}else{return function(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(el,_91,fn,_92){el.removeEventListener(_91,fn,(_92));};}else{if(window.detachEvent){return function(el,_93,fn){el.detachEvent("on"+_93,fn);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;if(document&&document.body){EU._load();}else{EU._simpleAdd(window,"load",EU._load);}EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(_94,_95,_96,_97){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[_94];if(ce){ce.subscribe(_95,_96,_97);}else{this.__yui_subscribers=this.__yui_subscribers||{};var _99=this.__yui_subscribers;if(!_99[_94]){_99[_94]=[];}_99[_94].push({fn:_95,obj:_96,override:_97});}},unsubscribe:function(_100,p_fn,_102){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[_100];if(ce){return ce.unsubscribe(p_fn,_102);}else{return false;}},createEvent:function(_103,_104){this.__yui_events=this.__yui_events||{};var opts=_104||{};var _106=this.__yui_events;if(_106[_103]){}else{var _107=opts.scope||this;var _108=opts.silent||null;var ce=new YAHOO.util.CustomEvent(_103,_107,_108,YAHOO.util.CustomEvent.FLAT);_106[_103]=ce;if(opts.onSubscribeCallback){ce.subscribeEvent.subscribe(opts.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var qs=this.__yui_subscribers[_103];if(qs){for(var i=0;i<qs.length;++i){ce.subscribe(qs[i].fn,qs[i].obj,qs[i].override);}}}return _106[_103];},fireEvent:function(_110,arg1,arg2,etc){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[_110];if(ce){var args=[];for(var i=1;i<arguments.length;++i){args.push(arguments[i]);}return ce.fire.apply(ce,args);}else{return null;}},hasEvent:function(type){if(this.__yui_events){if(this.__yui_events[type]){return true;}}return false;}};
/* Copyright (c) 2006, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.net/yui/license.txt version: 0.12.0 */(function(){var Y=YAHOO.util,getStyle,setStyle,id_counter=0,propertyCache={};var ua=navigator.userAgent.toLowerCase(),isOpera=(ua.indexOf('opera')>-1),isSafari=(ua.indexOf('safari')>-1),isGecko=(!isOpera&&!isSafari&&ua.indexOf('gecko')>-1),isIE=(!isOpera&&ua.indexOf('msie')>-1);var patterns={HYPHEN:/(-[a-z])/i};var toCamel=function(property){if(!patterns.HYPHEN.test(property)){return property;}if(propertyCache[property]){return propertyCache[property];}while(patterns.HYPHEN.exec(property)){property=property.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}propertyCache[property]=property;return property;};if(document.defaultView&&document.defaultView.getComputedStyle){getStyle=function(el,property){var value=null;var computed=document.defaultView.getComputedStyle(el,'');if(computed){value=computed[toCamel(property)];}return el.style[property]||value;};}else if(document.documentElement.currentStyle&&isIE){getStyle=function(el,property){switch(toCamel(property)){case'opacity':var val=100;try{val=el.filters['DXImageTransform.Microsoft.Alpha'].opacity;}catch(e){try{val=el.filters('alpha').opacity;}catch(e){}}return val/100;break;default:var value=el.currentStyle?el.currentStyle[property]:null;return(el.style[property]||value);}};}else{getStyle=function(el,property){return el.style[property];};}if(isIE){setStyle=function(el,property,val){switch(property){case'opacity':if(typeof el.style.filter=='string'){el.style.filter='alpha(opacity='+val*100+')';if(!el.currentStyle||!el.currentStyle.hasLayout){el.style.zoom=1;}}break;default:el.style[property]=val;}};}else{setStyle=function(el,property,val){el.style[property]=val;};}YAHOO.util.Dom={get:function(el){if(!el){return null;}if(typeof el!='string'&&!(el instanceof Array)){return el;}if(typeof el=='string'){return document.getElementById(el);}else{var collection=[];for(var i=0,len=el.length;i<len;++i){collection[collection.length]=Y.Dom.get(el[i]);}return collection;}return null;},getStyle:function(el,property){property=toCamel(property);var f=function(element){return getStyle(element,property);};return Y.Dom.batch(el,f,Y.Dom,true);},setStyle:function(el,property,val){property=toCamel(property);var f=function(element){setStyle(element,property,val);};Y.Dom.batch(el,f,Y.Dom,true);},getXY:function(el){var f=function(el){if(el.parentNode===null||el.offsetParent===null||this.getStyle(el,'display')=='none'){return false;}var parentNode=null;var pos=[];var box;if(el.getBoundingClientRect){box=el.getBoundingClientRect();var doc=document;if(!this.inDocument(el)&&parent.document!=document){doc=parent.document;if(!this.isAncestor(doc.documentElement,el)){return false;}}var scrollTop=Math.max(doc.documentElement.scrollTop,doc.body.scrollTop);var scrollLeft=Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft);return[box.left+scrollLeft,box.top+scrollTop];}else{pos=[el.offsetLeft,el.offsetTop];parentNode=el.offsetParent;if(parentNode!=el){while(parentNode){pos[0]+=parentNode.offsetLeft;pos[1]+=parentNode.offsetTop;parentNode=parentNode.offsetParent;}}if(isSafari&&this.getStyle(el,'position')=='absolute'){pos[0]-=document.body.offsetLeft;pos[1]-=document.body.offsetTop;}}if(el.parentNode){parentNode=el.parentNode;}else{parentNode=null;}while(parentNode&&parentNode.tagName.toUpperCase()!='BODY'&&parentNode.tagName.toUpperCase()!='HTML'){if(Y.Dom.getStyle(parentNode,'display')!='inline'){pos[0]-=parentNode.scrollLeft;pos[1]-=parentNode.scrollTop;}if(parentNode.parentNode){parentNode=parentNode.parentNode;}else{parentNode=null;}}return pos;};return Y.Dom.batch(el,f,Y.Dom,true);},getX:function(el){var f=function(el){return Y.Dom.getXY(el)[0];};return Y.Dom.batch(el,f,Y.Dom,true);},getY:function(el){var f=function(el){return Y.Dom.getXY(el)[1];};return Y.Dom.batch(el,f,Y.Dom,true);},setXY:function(el,pos,noRetry){var f=function(el){var style_pos=this.getStyle(el,'position');if(style_pos=='static'){this.setStyle(el,'position','relative');style_pos='relative';}var pageXY=this.getXY(el);if(pageXY===false){return false;}var delta=[parseInt(this.getStyle(el,'left'),10),parseInt(this.getStyle(el,'top'),10)];if(isNaN(delta[0])){delta[0]=(style_pos=='relative')?0:el.offsetLeft;}if(isNaN(delta[1])){delta[1]=(style_pos=='relative')?0:el.offsetTop;}if(pos[0]!==null){el.style.left=pos[0]-pageXY[0]+delta[0]+'px';}if(pos[1]!==null){el.style.top=pos[1]-pageXY[1]+delta[1]+'px';}var newXY=this.getXY(el);if(!noRetry&&(newXY[0]!=pos[0]||newXY[1]!=pos[1])){this.setXY(el,pos,true);}};Y.Dom.batch(el,f,Y.Dom,true);},setX:function(el,x){Y.Dom.setXY(el,[x,null]);},setY:function(el,y){Y.Dom.setXY(el,[null,y]);},getRegion:function(el){var f=function(el){var region=new Y.Region.getRegion(el);return region;};return Y.Dom.batch(el,f,Y.Dom,true);},getClientWidth:function(){return Y.Dom.getViewportWidth();},getClientHeight:function(){return Y.Dom.getViewportHeight();},getElementsByClassName:function(className,tag,root){var method=function(el){return Y.Dom.hasClass(el,className);};return Y.Dom.getElementsBy(method,tag,root);},hasClass:function(el,className){var re=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)');var f=function(el){return re.test(el['className']);};return Y.Dom.batch(el,f,Y.Dom,true);},addClass:function(el,className){var f=function(el){if(this.hasClass(el,className)){return;}el['className']=[el['className'],className].join(' ');};Y.Dom.batch(el,f,Y.Dom,true);},removeClass:function(el,className){var re=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)','g');var f=function(el){if(!this.hasClass(el,className)){return;}var c=el['className'];el['className']=c.replace(re,' ');if(this.hasClass(el,className)){this.removeClass(el,className);}};Y.Dom.batch(el,f,Y.Dom,true);},replaceClass:function(el,oldClassName,newClassName){if(oldClassName===newClassName){return false;}var re=new RegExp('(?:^|\\s+)'+oldClassName+'(?:\\s+|$)','g');var f=function(el){if(!this.hasClass(el,oldClassName)){this.addClass(el,newClassName);return;}el['className']=el['className'].replace(re,' '+newClassName+' ');if(this.hasClass(el,oldClassName)){this.replaceClass(el,oldClassName,newClassName);}};Y.Dom.batch(el,f,Y.Dom,true);},generateId:function(el,prefix){prefix=prefix||'yui-gen';el=el||{};var f=function(el){if(el){el=Y.Dom.get(el);}else{el={};}if(!el.id){el.id=prefix+id_counter++;}return el.id;};return Y.Dom.batch(el,f,Y.Dom,true);},isAncestor:function(haystack,needle){haystack=Y.Dom.get(haystack);if(!haystack||!needle){return false;}var f=function(needle){if(haystack.contains&&!isSafari){return haystack.contains(needle);}else if(haystack.compareDocumentPosition){return!!(haystack.compareDocumentPosition(needle)&16);}else{var parent=needle.parentNode;while(parent){if(parent==haystack){return true;}else if(!parent.tagName||parent.tagName.toUpperCase()=='HTML'){return false;}parent=parent.parentNode;}return false;}};return Y.Dom.batch(needle,f,Y.Dom,true);},inDocument:function(el){var f=function(el){return this.isAncestor(document.documentElement,el);};return Y.Dom.batch(el,f,Y.Dom,true);},getElementsBy:function(method,tag,root){tag=tag||'*';root=Y.Dom.get(root)||document;var nodes=[];var elements=root.getElementsByTagName(tag);if(!elements.length&&(tag=='*'&&root.all)){elements=root.all;}for(var i=0,len=elements.length;i<len;++i){if(method(elements[i])){nodes[nodes.length]=elements[i];}}return nodes;},batch:function(el,method,o,override){var id=el;el=Y.Dom.get(el);var scope=(override)?o:window;if(!el||el.tagName||!el.length){if(!el){return false;}return method.call(scope,el,o);}var collection=[];for(var i=0,len=el.length;i<len;++i){if(!el[i]){id=el[i];}collection[collection.length]=method.call(scope,el[i],o);}return collection;},getDocumentHeight:function(){var scrollHeight=(document.compatMode!='CSS1Compat')?document.body.scrollHeight:document.documentElement.scrollHeight;var h=Math.max(scrollHeight,Y.Dom.getViewportHeight());return h;},getDocumentWidth:function(){var scrollWidth=(document.compatMode!='CSS1Compat')?document.body.scrollWidth:document.documentElement.scrollWidth;var w=Math.max(scrollWidth,Y.Dom.getViewportWidth());return w;},getViewportHeight:function(){var height=self.innerHeight;var mode=document.compatMode;if((mode||isIE)&&!isOpera){height=(mode=='CSS1Compat')?document.documentElement.clientHeight:document.body.clientHeight;}return height;},getViewportWidth:function(){var width=self.innerWidth;var mode=document.compatMode;if(mode||isIE){width=(mode=='CSS1Compat')?document.documentElement.clientWidth:document.body.clientWidth;}return width;}};})();YAHOO.util.Region=function(t,r,b,l){this.top=t;this[1]=t;this.right=r;this.bottom=b;this.left=l;this[0]=l;};YAHOO.util.Region.prototype.contains=function(region){return(region.left>=this.left&&region.right<=this.right&&region.top>=this.top&&region.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(region){var t=Math.max(this.top,region.top);var r=Math.min(this.right,region.right);var b=Math.min(this.bottom,region.bottom);var l=Math.max(this.left,region.left);if(b>=t&&r>=l){return new YAHOO.util.Region(t,r,b,l);}else{return null;}};YAHOO.util.Region.prototype.union=function(region){var t=Math.min(this.top,region.top);var r=Math.max(this.right,region.right);var b=Math.max(this.bottom,region.bottom);var l=Math.min(this.left,region.left);return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(el){var p=YAHOO.util.Dom.getXY(el);var t=p[1];var r=p[0]+el.offsetWidth;var b=p[1]+el.offsetHeight;var l=p[0];return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Point=function(x,y){if(x instanceof Array){y=x[1];x=x[0];}this.x=this.right=this.left=this[0]=x;this.y=this.top=this.bottom=this[1]=y;};YAHOO.util.Point.prototype=new YAHOO.util.Region();
/* Copyright (c) 2006, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.net/yui/license.txt version: 0.12.0 */
YAHOO.util.Connect={_msxml_progid:['MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'],_http_header:{},_has_http_headers:false,_use_default_post_header:true,_default_post_header:'application/x-www-form-urlencoded',_isFormSubmit:false,_isFileUpload:false,_formNode:null,_sFormData:null,_poll:{},_timeOut:{},_polling_interval:50,_transaction_id:0,setProgId:function(id)
{this._msxml_progid.unshift(id);},setDefaultPostHeader:function(b)
{this._use_default_post_header=b;},setPollingInterval:function(i)
{if(typeof i=='number'&&isFinite(i)){this._polling_interval=i;}},createXhrObject:function(transactionId)
{var obj,http;try
{http=new XMLHttpRequest();obj={conn:http,tId:transactionId};}
catch(e)
{for(var i=0;i<this._msxml_progid.length;++i){try
{http=new ActiveXObject(this._msxml_progid[i]);obj={conn:http,tId:transactionId};break;}
catch(e){}}}
finally
{return obj;}},getConnectionObject:function()
{var o;var tId=this._transaction_id;try
{o=this.createXhrObject(tId);if(o){this._transaction_id++;}}
catch(e){}
finally
{return o;}},asyncRequest:function(method,uri,callback,postData)
{var o=this.getConnectionObject();if(!o){return null;}
else{if(this._isFormSubmit){if(this._isFileUpload){this.uploadFile(o.tId,callback,uri,postData);this.releaseObject(o);return;}
if(method=='GET'){if(this._sFormData.length!=0){uri+=((uri.indexOf('?')==-1)?'?':'&')+this._sFormData;}
else{uri+="?"+this._sFormData;}}
else if(method=='POST'){postData=postData?this._sFormData+"&"+postData:this._sFormData;}}
o.conn.open(method,uri,true);if(this._isFormSubmit||(postData&&this._use_default_post_header)){this.initHeader('Content-Type',this._default_post_header);if(this._isFormSubmit){this.resetFormState();}}
if(this._has_http_headers){this.setHeader(o);}
this.handleReadyState(o,callback);o.conn.send(postData||null);return o;}},handleReadyState:function(o,callback)
{var oConn=this;if(callback&&callback.timeout){this._timeOut[o.tId]=window.setTimeout(function(){oConn.abort(o,callback,true);},callback.timeout);}
this._poll[o.tId]=window.setInterval(function(){if(o.conn&&o.conn.readyState==4){window.clearInterval(oConn._poll[o.tId]);delete oConn._poll[o.tId];if(callback&&callback.timeout){delete oConn._timeOut[o.tId];}
oConn.handleTransactionResponse(o,callback);}},this._polling_interval);},handleTransactionResponse:function(o,callback,isAbort)
{if(!callback){this.releaseObject(o);return;}
var httpStatus,responseObject;try
{if(o.conn.status!==undefined&&o.conn.status!=0){httpStatus=o.conn.status;}
else{httpStatus=13030;}}
catch(e){httpStatus=13030;}
if(httpStatus>=200&&httpStatus<300){try
{responseObject=this.createResponseObject(o,callback.argument);if(callback.success){if(!callback.scope){callback.success(responseObject);}
else{callback.success.apply(callback.scope,[responseObject]);}}}
catch(e){}}
else{try
{switch(httpStatus){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:responseObject=this.createExceptionObject(o.tId,callback.argument,(isAbort?isAbort:false));if(callback.failure){if(!callback.scope){callback.failure(responseObject);}
else{callback.failure.apply(callback.scope,[responseObject]);}}
break;default:responseObject=this.createResponseObject(o,callback.argument);if(callback.failure){if(!callback.scope){callback.failure(responseObject);}
else{callback.failure.apply(callback.scope,[responseObject]);}}}}
catch(e){}}
this.releaseObject(o);responseObject=null;},createResponseObject:function(o,callbackArg)
{var obj={};var headerObj={};try
{var headerStr=o.conn.getAllResponseHeaders();var header=headerStr.split('\n');for(var i=0;i<header.length;i++){var delimitPos=header[i].indexOf(':');if(delimitPos!=-1){headerObj[header[i].substring(0,delimitPos)]=header[i].substring(delimitPos+2);}}}
catch(e){}
obj.tId=o.tId;obj.status=o.conn.status;obj.statusText=o.conn.statusText;obj.getResponseHeader=headerObj;obj.getAllResponseHeaders=headerStr;obj.responseText=o.conn.responseText;obj.responseXML=o.conn.responseXML;if(typeof callbackArg!==undefined){obj.argument=callbackArg;}
return obj;},createExceptionObject:function(tId,callbackArg,isAbort)
{var COMM_CODE=0;var COMM_ERROR='communication failure';var ABORT_CODE=-1;var ABORT_ERROR='transaction aborted';var obj={};obj.tId=tId;if(isAbort){obj.status=ABORT_CODE;obj.statusText=ABORT_ERROR;}
else{obj.status=COMM_CODE;obj.statusText=COMM_ERROR;}
if(callbackArg){obj.argument=callbackArg;}
return obj;},initHeader:function(label,value)
{if(this._http_header[label]===undefined){this._http_header[label]=value;}
else{this._http_header[label]=value+","+this._http_header[label];}
this._has_http_headers=true;},setHeader:function(o)
{for(var prop in this._http_header){if(this._http_header.hasOwnProperty(prop)){o.conn.setRequestHeader(prop,this._http_header[prop]);}}
delete this._http_header;this._http_header={};this._has_http_headers=false;},setForm:function(formId,isUpload,secureUri)
{this.resetFormState();var oForm;if(typeof formId=='string'){oForm=(document.getElementById(formId)||document.forms[formId]);}
else if(typeof formId=='object'){oForm=formId;}
else{return;}
if(isUpload){this.createFrame(secureUri?secureUri:null);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=oForm;return;}
var oElement,oName,oValue,oDisabled;var hasSubmit=false;for(var i=0;i<oForm.elements.length;i++){oElement=oForm.elements[i];oDisabled=oForm.elements[i].disabled;oName=oForm.elements[i].name;oValue=oForm.elements[i].value;if(!oDisabled&&oName)
{switch(oElement.type)
{case'select-one':case'select-multiple':for(var j=0;j<oElement.options.length;j++){if(oElement.options[j].selected){if(window.ActiveXObject){this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oElement.options[j].attributes['value'].specified?oElement.options[j].value:oElement.options[j].text)+'&';}
else{this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oElement.options[j].hasAttribute('value')?oElement.options[j].value:oElement.options[j].text)+'&';}}}
break;case'radio':case'checkbox':if(oElement.checked){this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oValue)+'&';}
break;case'file':case undefined:case'reset':case'button':break;case'submit':if(hasSubmit==false){this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oValue)+'&';hasSubmit=true;}
break;default:this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oValue)+'&';break;}}}
this._isFormSubmit=true;this._sFormData=this._sFormData.substr(0,this._sFormData.length-1);return this._sFormData;},resetFormState:function(){this._isFormSubmit=false;this._isFileUpload=false;this._formNode=null;this._sFormData="";},createFrame:function(secureUri){var frameId='yuiIO'+this._transaction_id;if(window.ActiveXObject){var io=document.createElement('<iframe id="'+frameId+'" name="'+frameId+'" />');if(typeof secureUri=='boolean'){io.src='javascript:false';}
else if(typeof secureURI=='string'){io.src=secureUri;}}
else{var io=document.createElement('iframe');io.id=frameId;io.name=frameId;}
io.style.position='absolute';io.style.top='-1000px';io.style.left='-1000px';document.body.appendChild(io);},appendPostData:function(postData)
{var formElements=new Array();var postMessage=postData.split('&');for(var i=0;i<postMessage.length;i++){var delimitPos=postMessage[i].indexOf('=');if(delimitPos!=-1){formElements[i]=document.createElement('input');formElements[i].type='hidden';formElements[i].name=postMessage[i].substring(0,delimitPos);formElements[i].value=postMessage[i].substring(delimitPos+1);this._formNode.appendChild(formElements[i]);}}
return formElements;},uploadFile:function(id,callback,uri,postData){var frameId='yuiIO'+id;var io=document.getElementById(frameId);this._formNode.action=uri;this._formNode.method='POST';this._formNode.target=frameId;if(this._formNode.encoding){this._formNode.encoding='multipart/form-data';}
else{this._formNode.enctype='multipart/form-data';}
if(postData){var oElements=this.appendPostData(postData);}
this._formNode.submit();if(oElements&&oElements.length>0){try
{for(var i=0;i<oElements.length;i++){this._formNode.removeChild(oElements[i]);}}
catch(e){}}
this.resetFormState();var uploadCallback=function()
{var obj={};obj.tId=id;obj.argument=callback.argument;try
{obj.responseText=io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;obj.responseXML=io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;}
catch(e){}
if(callback.upload){if(!callback.scope){callback.upload(obj);}
else{callback.upload.apply(callback.scope,[obj]);}}
if(YAHOO.util.Event){YAHOO.util.Event.removeListener(io,"load",uploadCallback);}
else if(window.detachEvent){io.detachEvent('onload',uploadCallback);}
else{io.removeEventListener('load',uploadCallback,false);}
setTimeout(function(){document.body.removeChild(io);},100);};if(YAHOO.util.Event){YAHOO.util.Event.addListener(io,"load",uploadCallback);}
else if(window.attachEvent){io.attachEvent('onload',uploadCallback);}
else{io.addEventListener('load',uploadCallback,false);}},abort:function(o,callback,isTimeout)
{if(this.isCallInProgress(o)){o.conn.abort();window.clearInterval(this._poll[o.tId]);delete this._poll[o.tId];if(isTimeout){delete this._timeOut[o.tId];}
this.handleTransactionResponse(o,callback,true);return true;}
else{return false;}},isCallInProgress:function(o)
{if(o.conn){return o.conn.readyState!=4&&o.conn.readyState!=0;}
else{return false;}},releaseObject:function(o)
{o.conn=null;o=null;}};
/* Copyright (c) 2006, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.net/yui/license.txt version: 0.12.0 */
YAHOO.util.Config=function(owner){if(owner){this.init(owner);}};YAHOO.util.Config.prototype={owner:null,queueInProgress:false,checkBoolean:function(val){if(typeof val=='boolean'){return true;}else{return false;}},checkNumber:function(val){if(isNaN(val)){return false;}else{return true;}}};YAHOO.util.Config.prototype.init=function(owner){this.owner=owner;this.configChangedEvent=new YAHOO.util.CustomEvent("configChanged");this.queueInProgress=false;var config={};var initialConfig={};var eventQueue=[];var fireEvent=function(key,value){key=key.toLowerCase();var property=config[key];if(typeof property!='undefined'&&property.event){property.event.fire(value);}};this.addProperty=function(key,propertyObject){key=key.toLowerCase();config[key]=propertyObject;propertyObject.event=new YAHOO.util.CustomEvent(key);propertyObject.key=key;if(propertyObject.handler){propertyObject.event.subscribe(propertyObject.handler,this.owner,true);}
this.setProperty(key,propertyObject.value,true);if(!propertyObject.suppressEvent){this.queueProperty(key,propertyObject.value);}};this.getConfig=function(){var cfg={};for(var prop in config){var property=config[prop];if(typeof property!='undefined'&&property.event){cfg[prop]=property.value;}}
return cfg;};this.getProperty=function(key){key=key.toLowerCase();var property=config[key];if(typeof property!='undefined'&&property.event){return property.value;}else{return undefined;}};this.resetProperty=function(key){key=key.toLowerCase();var property=config[key];if(typeof property!='undefined'&&property.event){if(initialConfig[key]&&initialConfig[key]!='undefined'){this.setProperty(key,initialConfig[key]);}
return true;}else{return false;}};this.setProperty=function(key,value,silent){key=key.toLowerCase();if(this.queueInProgress&&!silent){this.queueProperty(key,value);return true;}else{var property=config[key];if(typeof property!='undefined'&&property.event){if(property.validator&&!property.validator(value)){return false;}else{property.value=value;if(!silent){fireEvent(key,value);this.configChangedEvent.fire([key,value]);}
return true;}}else{return false;}}};this.queueProperty=function(key,value){key=key.toLowerCase();var property=config[key];if(typeof property!='undefined'&&property.event){if(typeof value!='undefined'&&property.validator&&!property.validator(value)){return false;}else{if(typeof value!='undefined'){property.value=value;}else{value=property.value;}
var foundDuplicate=false;for(var i=0;i<eventQueue.length;i++){var queueItem=eventQueue[i];if(queueItem){var queueItemKey=queueItem[0];var queueItemValue=queueItem[1];if(queueItemKey.toLowerCase()==key){eventQueue[i]=null;eventQueue.push([key,(typeof value!='undefined'?value:queueItemValue)]);foundDuplicate=true;break;}}}
if(!foundDuplicate&&typeof value!='undefined'){eventQueue.push([key,value]);}}
if(property.supercedes){for(var s=0;s<property.supercedes.length;s++){var supercedesCheck=property.supercedes[s];for(var q=0;q<eventQueue.length;q++){var queueItemCheck=eventQueue[q];if(queueItemCheck){var queueItemCheckKey=queueItemCheck[0];var queueItemCheckValue=queueItemCheck[1];if(queueItemCheckKey.toLowerCase()==supercedesCheck.toLowerCase()){eventQueue.push([queueItemCheckKey,queueItemCheckValue]);eventQueue[q]=null;break;}}}}}
return true;}else{return false;}};this.refireEvent=function(key){key=key.toLowerCase();var property=config[key];if(typeof property!='undefined'&&property.event&&typeof property.value!='undefined'){if(this.queueInProgress){this.queueProperty(key);}else{fireEvent(key,property.value);}}};this.applyConfig=function(userConfig,init){if(init){initialConfig=userConfig;}
for(var prop in userConfig){this.queueProperty(prop,userConfig[prop]);}};this.refresh=function(){for(var prop in config){this.refireEvent(prop);}};this.fireQueue=function(){this.queueInProgress=true;for(var i=0;i<eventQueue.length;i++){var queueItem=eventQueue[i];if(queueItem){var key=queueItem[0];var value=queueItem[1];var property=config[key];property.value=value;fireEvent(key,value);}}
this.queueInProgress=false;eventQueue=[];};this.subscribeToConfigEvent=function(key,handler,obj,override){key=key.toLowerCase();var property=config[key];if(typeof property!='undefined'&&property.event){if(!YAHOO.util.Config.alreadySubscribed(property.event,handler,obj)){property.event.subscribe(handler,obj,override);}
return true;}else{return false;}};this.unsubscribeFromConfigEvent=function(key,handler,obj){key=key.toLowerCase();var property=config[key];if(typeof property!='undefined'&&property.event){return property.event.unsubscribe(handler,obj);}else{return false;}};this.toString=function(){var output="Config";if(this.owner){output+=" ["+this.owner.toString()+"]";}
return output;};this.outputEventQueue=function(){var output="";for(var q=0;q<eventQueue.length;q++){var queueItem=eventQueue[q];if(queueItem){output+=queueItem[0]+"="+queueItem[1]+", ";}}
return output;};};YAHOO.util.Config.alreadySubscribed=function(evt,fn,obj){for(var e=0;e<evt.subscribers.length;e++){var subsc=evt.subscribers[e];if(subsc&&subsc.obj==obj&&subsc.fn==fn){return true;}}
return false;};YAHOO.widget.Module=function(el,userConfig){if(el){this.init(el,userConfig);}};YAHOO.widget.Module.IMG_ROOT="http://us.i1.yimg.com/us.yimg.com/i/";YAHOO.widget.Module.IMG_ROOT_SSL="https://a248.e.akamai.net/sec.yimg.com/i/";YAHOO.widget.Module.CSS_MODULE="module";YAHOO.widget.Module.CSS_HEADER="hd";YAHOO.widget.Module.CSS_BODY="bd";YAHOO.widget.Module.CSS_FOOTER="ft";YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL="javascript:false;";YAHOO.widget.Module.prototype={constructor:YAHOO.widget.Module,element:null,header:null,body:null,footer:null,id:null,imageRoot:YAHOO.widget.Module.IMG_ROOT,initEvents:function(){this.beforeInitEvent=new YAHOO.util.CustomEvent("beforeInit");this.initEvent=new YAHOO.util.CustomEvent("init");this.appendEvent=new YAHOO.util.CustomEvent("append");this.beforeRenderEvent=new YAHOO.util.CustomEvent("beforeRender");this.renderEvent=new YAHOO.util.CustomEvent("render");this.changeHeaderEvent=new YAHOO.util.CustomEvent("changeHeader");this.changeBodyEvent=new YAHOO.util.CustomEvent("changeBody");this.changeFooterEvent=new YAHOO.util.CustomEvent("changeFooter");this.changeContentEvent=new YAHOO.util.CustomEvent("changeContent");this.destroyEvent=new YAHOO.util.CustomEvent("destroy");this.beforeShowEvent=new YAHOO.util.CustomEvent("beforeShow");this.showEvent=new YAHOO.util.CustomEvent("show");this.beforeHideEvent=new YAHOO.util.CustomEvent("beforeHide");this.hideEvent=new YAHOO.util.CustomEvent("hide");},platform:function(){var ua=navigator.userAgent.toLowerCase();if(ua.indexOf("windows")!=-1||ua.indexOf("win32")!=-1){return"windows";}else if(ua.indexOf("macintosh")!=-1){return"mac";}else{return false;}}(),browser:function(){var ua=navigator.userAgent.toLowerCase();if(ua.indexOf('opera')!=-1){return'opera';}else if(ua.indexOf('msie 7')!=-1){return'ie7';}else if(ua.indexOf('msie')!=-1){return'ie';}else if(ua.indexOf('safari')!=-1){return'safari';}else if(ua.indexOf('gecko')!=-1){return'gecko';}else{return false;}}(),isSecure:function(){if(window.location.href.toLowerCase().indexOf("https")===0){return true;}else{return false;}}(),initDefaultConfig:function(){this.cfg.addProperty("visible",{value:true,handler:this.configVisible,validator:this.cfg.checkBoolean});this.cfg.addProperty("effect",{suppressEvent:true,supercedes:["visible"]});this.cfg.addProperty("monitorresize",{value:true,handler:this.configMonitorResize});},init:function(el,userConfig){this.initEvents();this.beforeInitEvent.fire(YAHOO.widget.Module);this.cfg=new YAHOO.util.Config(this);if(this.isSecure){this.imageRoot=YAHOO.widget.Module.IMG_ROOT_SSL;}
if(typeof el=="string"){var elId=el;el=document.getElementById(el);if(!el){el=document.createElement("DIV");el.id=elId;}}
this.element=el;if(el.id){this.id=el.id;}
var childNodes=this.element.childNodes;if(childNodes){for(var i=0;i<childNodes.length;i++){var child=childNodes[i];switch(child.className){case YAHOO.widget.Module.CSS_HEADER:this.header=child;break;case YAHOO.widget.Module.CSS_BODY:this.body=child;break;case YAHOO.widget.Module.CSS_FOOTER:this.footer=child;break;}}}
this.initDefaultConfig();YAHOO.util.Dom.addClass(this.element,YAHOO.widget.Module.CSS_MODULE);if(userConfig){this.cfg.applyConfig(userConfig,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.renderEvent,this.cfg.fireQueue,this.cfg)){this.renderEvent.subscribe(this.cfg.fireQueue,this.cfg,true);}
this.initEvent.fire(YAHOO.widget.Module);},initResizeMonitor:function(){if(this.browser!="opera"){var resizeMonitor=document.getElementById("_yuiResizeMonitor");if(!resizeMonitor){resizeMonitor=document.createElement("iframe");var bIE=(this.browser.indexOf("ie")===0);if(this.isSecure&&YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL&&bIE){resizeMonitor.src=YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL;}
resizeMonitor.id="_yuiResizeMonitor";resizeMonitor.style.visibility="hidden";document.body.appendChild(resizeMonitor);resizeMonitor.style.width="10em";resizeMonitor.style.height="10em";resizeMonitor.style.position="absolute";var nLeft=-1*resizeMonitor.offsetWidth,nTop=-1*resizeMonitor.offsetHeight;resizeMonitor.style.top=nTop+"px";resizeMonitor.style.left=nLeft+"px";resizeMonitor.style.borderStyle="none";resizeMonitor.style.borderWidth="0";YAHOO.util.Dom.setStyle(resizeMonitor,"opacity","0");resizeMonitor.style.visibility="visible";if(!bIE){var doc=resizeMonitor.contentWindow.document;doc.open();doc.close();}}
if(resizeMonitor&&resizeMonitor.contentWindow){this.resizeMonitor=resizeMonitor;YAHOO.util.Event.addListener(this.resizeMonitor.contentWindow,"resize",this.onDomResize,this,true);}}},onDomResize:function(e,obj){var nLeft=-1*this.resizeMonitor.offsetWidth,nTop=-1*this.resizeMonitor.offsetHeight;this.resizeMonitor.style.top=nTop+"px";this.resizeMonitor.style.left=nLeft+"px";},setHeader:function(headerContent){if(!this.header){this.header=document.createElement("DIV");this.header.className=YAHOO.widget.Module.CSS_HEADER;}
if(typeof headerContent=="string"){this.header.innerHTML=headerContent;}else{this.header.innerHTML="";this.header.appendChild(headerContent);}
this.changeHeaderEvent.fire(headerContent);this.changeContentEvent.fire();},appendToHeader:function(element){if(!this.header){this.header=document.createElement("DIV");this.header.className=YAHOO.widget.Module.CSS_HEADER;}
this.header.appendChild(element);this.changeHeaderEvent.fire(element);this.changeContentEvent.fire();},setBody:function(bodyContent){if(!this.body){this.body=document.createElement("DIV");this.body.className=YAHOO.widget.Module.CSS_BODY;}
if(typeof bodyContent=="string")
{this.body.innerHTML=bodyContent;}else{this.body.innerHTML="";this.body.appendChild(bodyContent);}
this.changeBodyEvent.fire(bodyContent);this.changeContentEvent.fire();},appendToBody:function(element){if(!this.body){this.body=document.createElement("DIV");this.body.className=YAHOO.widget.Module.CSS_BODY;}
this.body.appendChild(element);this.changeBodyEvent.fire(element);this.changeContentEvent.fire();},setFooter:function(footerContent){if(!this.footer){this.footer=document.createElement("DIV");this.footer.className=YAHOO.widget.Module.CSS_FOOTER;}
if(typeof footerContent=="string"){this.footer.innerHTML=footerContent;}else{this.footer.innerHTML="";this.footer.appendChild(footerContent);}
this.changeFooterEvent.fire(footerContent);this.changeContentEvent.fire();},appendToFooter:function(element){if(!this.footer){this.footer=document.createElement("DIV");this.footer.className=YAHOO.widget.Module.CSS_FOOTER;}
this.footer.appendChild(element);this.changeFooterEvent.fire(element);this.changeContentEvent.fire();},render:function(appendToNode,moduleElement){this.beforeRenderEvent.fire();if(!moduleElement){moduleElement=this.element;}
var me=this;var appendTo=function(element){if(typeof element=="string"){element=document.getElementById(element);}
if(element){element.appendChild(me.element);me.appendEvent.fire();}};if(appendToNode){appendTo(appendToNode);}else{if(!YAHOO.util.Dom.inDocument(this.element)){return false;}}
if(this.header&&!YAHOO.util.Dom.inDocument(this.header)){var firstChild=moduleElement.firstChild;if(firstChild){moduleElement.insertBefore(this.header,firstChild);}else{moduleElement.appendChild(this.header);}}
if(this.body&&!YAHOO.util.Dom.inDocument(this.body)){if(this.footer&&YAHOO.util.Dom.isAncestor(this.moduleElement,this.footer)){moduleElement.insertBefore(this.body,this.footer);}else{moduleElement.appendChild(this.body);}}
if(this.footer&&!YAHOO.util.Dom.inDocument(this.footer)){moduleElement.appendChild(this.footer);}
this.renderEvent.fire();return true;},destroy:function(){if(this.element){var parent=this.element.parentNode;}
if(parent){parent.removeChild(this.element);}
this.element=null;this.header=null;this.body=null;this.footer=null;this.destroyEvent.fire();},show:function(){this.cfg.setProperty("visible",true);},hide:function(){this.cfg.setProperty("visible",false);},configVisible:function(type,args,obj){var visible=args[0];if(visible){this.beforeShowEvent.fire();YAHOO.util.Dom.setStyle(this.element,"display","block");this.showEvent.fire();}else{this.beforeHideEvent.fire();YAHOO.util.Dom.setStyle(this.element,"display","none");this.hideEvent.fire();}},configMonitorResize:function(type,args,obj){var monitor=args[0];if(monitor){this.initResizeMonitor();}else{YAHOO.util.Event.removeListener(this.resizeMonitor,"resize",this.onDomResize);this.resizeMonitor=null;}}};YAHOO.widget.Module.prototype.toString=function(){return"Module "+this.id;};YAHOO.widget.Overlay=function(el,userConfig){YAHOO.widget.Overlay.superclass.constructor.call(this,el,userConfig);};YAHOO.extend(YAHOO.widget.Overlay,YAHOO.widget.Module);YAHOO.widget.Overlay.IFRAME_SRC="javascript:false;"
YAHOO.widget.Overlay.TOP_LEFT="tl";YAHOO.widget.Overlay.TOP_RIGHT="tr";YAHOO.widget.Overlay.BOTTOM_LEFT="bl";YAHOO.widget.Overlay.BOTTOM_RIGHT="br";YAHOO.widget.Overlay.CSS_OVERLAY="overlay";YAHOO.widget.Overlay.prototype.init=function(el,userConfig){YAHOO.widget.Overlay.superclass.init.call(this,el);this.beforeInitEvent.fire(YAHOO.widget.Overlay);YAHOO.util.Dom.addClass(this.element,YAHOO.widget.Overlay.CSS_OVERLAY);if(userConfig){this.cfg.applyConfig(userConfig,true);}
if(this.platform=="mac"&&this.browser=="gecko"){if(!YAHOO.util.Config.alreadySubscribed(this.showEvent,this.showMacGeckoScrollbars,this)){this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrollbars,this)){this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);}}
this.initEvent.fire(YAHOO.widget.Overlay);};YAHOO.widget.Overlay.prototype.initEvents=function(){YAHOO.widget.Overlay.superclass.initEvents.call(this);this.beforeMoveEvent=new YAHOO.util.CustomEvent("beforeMove",this);this.moveEvent=new YAHOO.util.CustomEvent("move",this);};YAHOO.widget.Overlay.prototype.initDefaultConfig=function(){YAHOO.widget.Overlay.superclass.initDefaultConfig.call(this);this.cfg.addProperty("x",{handler:this.configX,validator:this.cfg.checkNumber,suppressEvent:true,supercedes:["iframe"]});this.cfg.addProperty("y",{handler:this.configY,validator:this.cfg.checkNumber,suppressEvent:true,supercedes:["iframe"]});this.cfg.addProperty("xy",{handler:this.configXY,suppressEvent:true,supercedes:["iframe"]});this.cfg.addProperty("context",{handler:this.configContext,suppressEvent:true,supercedes:["iframe"]});this.cfg.addProperty("fixedcenter",{value:false,handler:this.configFixedCenter,validator:this.cfg.checkBoolean,supercedes:["iframe","visible"]});this.cfg.addProperty("width",{handler:this.configWidth,suppressEvent:true,supercedes:["iframe"]});this.cfg.addProperty("height",{handler:this.configHeight,suppressEvent:true,supercedes:["iframe"]});this.cfg.addProperty("zIndex",{value:null,handler:this.configzIndex});this.cfg.addProperty("constraintoviewport",{value:false,handler:this.configConstrainToViewport,validator:this.cfg.checkBoolean,supercedes:["iframe","x","y","xy"]});this.cfg.addProperty("iframe",{value:(this.browser=="ie"?true:false),handler:this.configIframe,validator:this.cfg.checkBoolean,supercedes:["zIndex"]});};YAHOO.widget.Overlay.prototype.moveTo=function(x,y){this.cfg.setProperty("xy",[x,y]);};YAHOO.widget.Overlay.prototype.hideMacGeckoScrollbars=function(){YAHOO.util.Dom.removeClass(this.element,"show-scrollbars");YAHOO.util.Dom.addClass(this.element,"hide-scrollbars");};YAHOO.widget.Overlay.prototype.showMacGeckoScrollbars=function(){YAHOO.util.Dom.removeClass(this.element,"hide-scrollbars");YAHOO.util.Dom.addClass(this.element,"show-scrollbars");};YAHOO.widget.Overlay.prototype.configVisible=function(type,args,obj){var visible=args[0];var currentVis=YAHOO.util.Dom.getStyle(this.element,"visibility");if(currentVis=="inherit"){var e=this.element.parentNode;while(e.nodeType!=9&&e.nodeType!=11){currentVis=YAHOO.util.Dom.getStyle(e,"visibility");if(currentVis!="inherit"){break;}
e=e.parentNode;}
if(currentVis=="inherit"){currentVis="visible";}}
var effect=this.cfg.getProperty("effect");var effectInstances=[];if(effect){if(effect instanceof Array){for(var i=0;i<effect.length;i++){var eff=effect[i];effectInstances[effectInstances.length]=eff.effect(this,eff.duration);}}else{effectInstances[effectInstances.length]=effect.effect(this,effect.duration);}}
var isMacGecko=(this.platform=="mac"&&this.browser=="gecko");if(visible){if(isMacGecko){this.showMacGeckoScrollbars();}
if(effect){if(visible){if(currentVis!="visible"||currentVis===""){this.beforeShowEvent.fire();for(var j=0;j<effectInstances.length;j++){var ei=effectInstances[j];if(j===0&&!YAHOO.util.Config.alreadySubscribed(ei.animateInCompleteEvent,this.showEvent.fire,this.showEvent)){ei.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,true);}
ei.animateIn();}}}}else{if(currentVis!="visible"||currentVis===""){this.beforeShowEvent.fire();YAHOO.util.Dom.setStyle(this.element,"visibility","visible");this.cfg.refireEvent("iframe");this.showEvent.fire();}}}else{if(isMacGecko){this.hideMacGeckoScrollbars();}
if(effect){if(currentVis=="visible"){this.beforeHideEvent.fire();for(var k=0;k<effectInstances.length;k++){var h=effectInstances[k];if(k===0&&!YAHOO.util.Config.alreadySubscribed(h.animateOutCompleteEvent,this.hideEvent.fire,this.hideEvent)){h.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,true);}
h.animateOut();}}else if(currentVis===""){YAHOO.util.Dom.setStyle(this.element,"visibility","hidden");}}else{if(currentVis=="visible"||currentVis===""){this.beforeHideEvent.fire();YAHOO.util.Dom.setStyle(this.element,"visibility","hidden");this.cfg.refireEvent("iframe");this.hideEvent.fire();}}}};YAHOO.widget.Overlay.prototype.doCenterOnDOMEvent=function(){if(this.cfg.getProperty("visible")){this.center();}};YAHOO.widget.Overlay.prototype.configFixedCenter=function(type,args,obj){var val=args[0];if(val){this.center();if(!YAHOO.util.Config.alreadySubscribed(this.beforeShowEvent,this.center,this)){this.beforeShowEvent.subscribe(this.center,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowResizeEvent,this.doCenterOnDOMEvent,this)){YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.doCenterOnDOMEvent,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowScrollEvent,this.doCenterOnDOMEvent,this)){YAHOO.widget.Overlay.windowScrollEvent.subscribe(this.doCenterOnDOMEvent,this,true);}}else{YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent,this);YAHOO.widget.Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent,this);}};YAHOO.widget.Overlay.prototype.configHeight=function(type,args,obj){var height=args[0];var el=this.element;YAHOO.util.Dom.setStyle(el,"height",height);this.cfg.refireEvent("iframe");};YAHOO.widget.Overlay.prototype.configWidth=function(type,args,obj){var width=args[0];var el=this.element;YAHOO.util.Dom.setStyle(el,"width",width);this.cfg.refireEvent("iframe");};YAHOO.widget.Overlay.prototype.configzIndex=function(type,args,obj){var zIndex=args[0];var el=this.element;if(!zIndex){zIndex=YAHOO.util.Dom.getStyle(el,"zIndex");if(!zIndex||isNaN(zIndex)){zIndex=0;}}
if(this.iframe){if(zIndex<=0){zIndex=1;}
YAHOO.util.Dom.setStyle(this.iframe,"zIndex",(zIndex-1));}
YAHOO.util.Dom.setStyle(el,"zIndex",zIndex);this.cfg.setProperty("zIndex",zIndex,true);};YAHOO.widget.Overlay.prototype.configXY=function(type,args,obj){var pos=args[0];var x=pos[0];var y=pos[1];this.cfg.setProperty("x",x);this.cfg.setProperty("y",y);this.beforeMoveEvent.fire([x,y]);x=this.cfg.getProperty("x");y=this.cfg.getProperty("y");this.cfg.refireEvent("iframe");this.moveEvent.fire([x,y]);};YAHOO.widget.Overlay.prototype.configX=function(type,args,obj){var x=args[0];var y=this.cfg.getProperty("y");this.cfg.setProperty("x",x,true);this.cfg.setProperty("y",y,true);this.beforeMoveEvent.fire([x,y]);x=this.cfg.getProperty("x");y=this.cfg.getProperty("y");YAHOO.util.Dom.setX(this.element,x,true);this.cfg.setProperty("xy",[x,y],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([x,y]);};YAHOO.widget.Overlay.prototype.configY=function(type,args,obj){var x=this.cfg.getProperty("x");var y=args[0];this.cfg.setProperty("x",x,true);this.cfg.setProperty("y",y,true);this.beforeMoveEvent.fire([x,y]);x=this.cfg.getProperty("x");y=this.cfg.getProperty("y");YAHOO.util.Dom.setY(this.element,y,true);this.cfg.setProperty("xy",[x,y],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([x,y]);};YAHOO.widget.Overlay.prototype.showIframe=function(){if(this.iframe){this.iframe.style.display="block";}};YAHOO.widget.Overlay.prototype.hideIframe=function(){if(this.iframe){this.iframe.style.display="none";}};YAHOO.widget.Overlay.prototype.configIframe=function(type,args,obj){var val=args[0];if(val){if(!YAHOO.util.Config.alreadySubscribed(this.showEvent,this.showIframe,this)){this.showEvent.subscribe(this.showIframe,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.hideEvent,this.hideIframe,this)){this.hideEvent.subscribe(this.hideIframe,this,true);}
var x=this.cfg.getProperty("x");var y=this.cfg.getProperty("y");if(!x||!y){this.syncPosition();x=this.cfg.getProperty("x");y=this.cfg.getProperty("y");}
if(!isNaN(x)&&!isNaN(y)){if(!this.iframe){this.iframe=document.createElement("iframe");if(this.isSecure){this.iframe.src=YAHOO.widget.Overlay.IFRAME_SRC;}
var parent=this.element.parentNode;if(parent){parent.appendChild(this.iframe);}else{document.body.appendChild(this.iframe);}
YAHOO.util.Dom.setStyle(this.iframe,"position","absolute");YAHOO.util.Dom.setStyle(this.iframe,"border","none");YAHOO.util.Dom.setStyle(this.iframe,"margin","0");YAHOO.util.Dom.setStyle(this.iframe,"padding","0");YAHOO.util.Dom.setStyle(this.iframe,"opacity","0");if(this.cfg.getProperty("visible")){this.showIframe();}else{this.hideIframe();}}
var iframeDisplay=YAHOO.util.Dom.getStyle(this.iframe,"display");if(iframeDisplay=="none"){this.iframe.style.display="block";}
YAHOO.util.Dom.setXY(this.iframe,[x,y]);var width=this.element.clientWidth;var height=this.element.clientHeight;YAHOO.util.Dom.setStyle(this.iframe,"width",(width+2)+"px");YAHOO.util.Dom.setStyle(this.iframe,"height",(height+2)+"px");if(iframeDisplay=="none"){this.iframe.style.display="none";}}}else{if(this.iframe){this.iframe.style.display="none";}
this.showEvent.unsubscribe(this.showIframe,this);this.hideEvent.unsubscribe(this.hideIframe,this);}};YAHOO.widget.Overlay.prototype.configConstrainToViewport=function(type,args,obj){var val=args[0];if(val){if(!YAHOO.util.Config.alreadySubscribed(this.beforeMoveEvent,this.enforceConstraints,this)){this.beforeMoveEvent.subscribe(this.enforceConstraints,this,true);}}else{this.beforeMoveEvent.unsubscribe(this.enforceConstraints,this);}};YAHOO.widget.Overlay.prototype.configContext=function(type,args,obj){var contextArgs=args[0];if(contextArgs){var contextEl=contextArgs[0];var elementMagnetCorner=contextArgs[1];var contextMagnetCorner=contextArgs[2];if(contextEl){if(typeof contextEl=="string"){this.cfg.setProperty("context",[document.getElementById(contextEl),elementMagnetCorner,contextMagnetCorner],true);}
if(elementMagnetCorner&&contextMagnetCorner){this.align(elementMagnetCorner,contextMagnetCorner);}}}};YAHOO.widget.Overlay.prototype.align=function(elementAlign,contextAlign){var contextArgs=this.cfg.getProperty("context");if(contextArgs){var context=contextArgs[0];var element=this.element;var me=this;if(!elementAlign){elementAlign=contextArgs[1];}
if(!contextAlign){contextAlign=contextArgs[2];}
if(element&&context){var elementRegion=YAHOO.util.Dom.getRegion(element);var contextRegion=YAHOO.util.Dom.getRegion(context);var doAlign=function(v,h){switch(elementAlign){case YAHOO.widget.Overlay.TOP_LEFT:me.moveTo(h,v);break;case YAHOO.widget.Overlay.TOP_RIGHT:me.moveTo(h-element.offsetWidth,v);break;case YAHOO.widget.Overlay.BOTTOM_LEFT:me.moveTo(h,v-element.offsetHeight);break;case YAHOO.widget.Overlay.BOTTOM_RIGHT:me.moveTo(h-element.offsetWidth,v-element.offsetHeight);break;}};switch(contextAlign){case YAHOO.widget.Overlay.TOP_LEFT:doAlign(contextRegion.top,contextRegion.left);break;case YAHOO.widget.Overlay.TOP_RIGHT:doAlign(contextRegion.top,contextRegion.right);break;case YAHOO.widget.Overlay.BOTTOM_LEFT:doAlign(contextRegion.bottom,contextRegion.left);break;case YAHOO.widget.Overlay.BOTTOM_RIGHT:doAlign(contextRegion.bottom,contextRegion.right);break;}}}};YAHOO.widget.Overlay.prototype.enforceConstraints=function(type,args,obj){var pos=args[0];var x=pos[0];var y=pos[1];var offsetHeight=this.element.offsetHeight;var offsetWidth=this.element.offsetWidth;var viewPortWidth=YAHOO.util.Dom.getViewportWidth();var viewPortHeight=YAHOO.util.Dom.getViewportHeight();var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;var topConstraint=scrollY+10;var leftConstraint=scrollX+10;var bottomConstraint=scrollY+viewPortHeight-offsetHeight-10;var rightConstraint=scrollX+viewPortWidth-offsetWidth-10;if(x<leftConstraint){x=leftConstraint;}else if(x>rightConstraint){x=rightConstraint;}
if(y<topConstraint){y=topConstraint;}else if(y>bottomConstraint){y=bottomConstraint;}
this.cfg.setProperty("x",x,true);this.cfg.setProperty("y",y,true);this.cfg.setProperty("xy",[x,y],true);};YAHOO.widget.Overlay.prototype.center=function(){var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;var viewPortWidth=YAHOO.util.Dom.getClientWidth();var viewPortHeight=YAHOO.util.Dom.getClientHeight();var elementWidth=this.element.offsetWidth;var elementHeight=this.element.offsetHeight;var x=(viewPortWidth/2)-(elementWidth/2)+scrollX;var y=(viewPortHeight/2)-(elementHeight/2)+scrollY;this.cfg.setProperty("xy",[parseInt(x,10),parseInt(y,10)]);this.cfg.refireEvent("iframe");};YAHOO.widget.Overlay.prototype.syncPosition=function(){var pos=YAHOO.util.Dom.getXY(this.element);this.cfg.setProperty("x",pos[0],true);this.cfg.setProperty("y",pos[1],true);this.cfg.setProperty("xy",pos,true);};YAHOO.widget.Overlay.prototype.onDomResize=function(e,obj){YAHOO.widget.Overlay.superclass.onDomResize.call(this,e,obj);var me=this;setTimeout(function(){me.syncPosition();me.cfg.refireEvent("iframe");me.cfg.refireEvent("context");},0);};YAHOO.widget.Overlay.prototype.destroy=function(){if(this.iframe){this.iframe.parentNode.removeChild(this.iframe);}
this.iframe=null;YAHOO.widget.Overlay.superclass.destroy.call(this);};YAHOO.widget.Overlay.prototype.toString=function(){return"Overlay "+this.id;};YAHOO.widget.Overlay.windowScrollEvent=new YAHOO.util.CustomEvent("windowScroll");YAHOO.widget.Overlay.windowResizeEvent=new YAHOO.util.CustomEvent("windowResize");YAHOO.widget.Overlay.windowScrollHandler=function(e){if(YAHOO.widget.Module.prototype.browser=="ie"||YAHOO.widget.Module.prototype.browser=="ie7"){if(!window.scrollEnd){window.scrollEnd=-1;}
clearTimeout(window.scrollEnd);window.scrollEnd=setTimeout(function(){YAHOO.widget.Overlay.windowScrollEvent.fire();},1);}else{YAHOO.widget.Overlay.windowScrollEvent.fire();}};YAHOO.widget.Overlay.windowResizeHandler=function(e){if(YAHOO.widget.Module.prototype.browser=="ie"||YAHOO.widget.Module.prototype.browser=="ie7"){if(!window.resizeEnd){window.resizeEnd=-1;}
clearTimeout(window.resizeEnd);window.resizeEnd=setTimeout(function(){YAHOO.widget.Overlay.windowResizeEvent.fire();},100);}else{YAHOO.widget.Overlay.windowResizeEvent.fire();}};YAHOO.widget.Overlay._initialized=null;if(YAHOO.widget.Overlay._initialized===null){YAHOO.util.Event.addListener(window,"scroll",YAHOO.widget.Overlay.windowScrollHandler);YAHOO.util.Event.addListener(window,"resize",YAHOO.widget.Overlay.windowResizeHandler);YAHOO.widget.Overlay._initialized=true;}
YAHOO.widget.OverlayManager=function(userConfig){this.init(userConfig);};YAHOO.widget.OverlayManager.CSS_FOCUSED="focused";YAHOO.widget.OverlayManager.prototype={constructor:YAHOO.widget.OverlayManager,overlays:null,initDefaultConfig:function(){this.cfg.addProperty("overlays",{suppressEvent:true});this.cfg.addProperty("focusevent",{value:"mousedown"});},init:function(userConfig){this.cfg=new YAHOO.util.Config(this);this.initDefaultConfig();if(userConfig){this.cfg.applyConfig(userConfig,true);}
this.cfg.fireQueue();var activeOverlay=null;this.getActive=function(){return activeOverlay;};this.focus=function(overlay){var o=this.find(overlay);if(o){this.blurAll();activeOverlay=o;YAHOO.util.Dom.addClass(activeOverlay.element,YAHOO.widget.OverlayManager.CSS_FOCUSED);this.overlays.sort(this.compareZIndexDesc);var topZIndex=YAHOO.util.Dom.getStyle(this.overlays[0].element,"zIndex");if(!isNaN(topZIndex)&&this.overlays[0]!=overlay){activeOverlay.cfg.setProperty("zIndex",(parseInt(topZIndex,10)+2));}
this.overlays.sort(this.compareZIndexDesc);}};this.remove=function(overlay){var o=this.find(overlay);if(o){var originalZ=YAHOO.util.Dom.getStyle(o.element,"zIndex");o.cfg.setProperty("zIndex",-1000,true);this.overlays.sort(this.compareZIndexDesc);this.overlays=this.overlays.slice(0,this.overlays.length-1);o.cfg.setProperty("zIndex",originalZ,true);o.cfg.setProperty("manager",null);o.focusEvent=null;o.blurEvent=null;o.focus=null;o.blur=null;}};this.blurAll=function(){activeOverlay=null;for(var o=0;o<this.overlays.length;o++){YAHOO.util.Dom.removeClass(this.overlays[o].element,YAHOO.widget.OverlayManager.CSS_FOCUSED);}};var overlays=this.cfg.getProperty("overlays");if(!this.overlays){this.overlays=[];}
if(overlays){this.register(overlays);this.overlays.sort(this.compareZIndexDesc);}},register:function(overlay){if(overlay instanceof YAHOO.widget.Overlay){overlay.cfg.addProperty("manager",{value:this});overlay.focusEvent=new YAHOO.util.CustomEvent("focus");overlay.blurEvent=new YAHOO.util.CustomEvent("blur");var mgr=this;overlay.focus=function(){mgr.focus(this);this.focusEvent.fire();};overlay.blur=function(){mgr.blurAll();this.blurEvent.fire();};var focusOnDomEvent=function(e,obj){overlay.focus();};var focusevent=this.cfg.getProperty("focusevent");YAHOO.util.Event.addListener(overlay.element,focusevent,focusOnDomEvent,this,true);var zIndex=YAHOO.util.Dom.getStyle(overlay.element,"zIndex");if(!isNaN(zIndex)){overlay.cfg.setProperty("zIndex",parseInt(zIndex,10));}else{overlay.cfg.setProperty("zIndex",0);}
this.overlays.push(overlay);return true;}else if(overlay instanceof Array){var regcount=0;for(var i=0;i<overlay.length;i++){if(this.register(overlay[i])){regcount++;}}
if(regcount>0){return true;}}else{return false;}},find:function(overlay){if(overlay instanceof YAHOO.widget.Overlay){for(var o=0;o<this.overlays.length;o++){if(this.overlays[o]==overlay){return this.overlays[o];}}}else if(typeof overlay=="string"){for(var p=0;p<this.overlays.length;p++){if(this.overlays[p].id==overlay){return this.overlays[p];}}}
return null;},compareZIndexDesc:function(o1,o2){var zIndex1=o1.cfg.getProperty("zIndex");var zIndex2=o2.cfg.getProperty("zIndex");if(zIndex1>zIndex2){return-1;}else if(zIndex1<zIndex2){return 1;}else{return 0;}},showAll:function(){for(var o=0;o<this.overlays.length;o++){this.overlays[o].show();}},hideAll:function(){for(var o=0;o<this.overlays.length;o++){this.overlays[o].hide();}},toString:function(){return"OverlayManager";}};YAHOO.util.KeyListener=function(attachTo,keyData,handler,event){if(!event){event=YAHOO.util.KeyListener.KEYDOWN;}
var keyEvent=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof attachTo=='string'){attachTo=document.getElementById(attachTo);}
if(typeof handler=='function'){keyEvent.subscribe(handler);}else{keyEvent.subscribe(handler.fn,handler.scope,handler.correctScope);}
function handleKeyPress(e,obj){if(!keyData.shift){keyData.shift=false;}
if(!keyData.alt){keyData.alt=false;}
if(!keyData.ctrl){keyData.ctrl=false;}
if(e.shiftKey==keyData.shift&&e.altKey==keyData.alt&&e.ctrlKey==keyData.ctrl){var dataItem;var keyPressed;if(keyData.keys instanceof Array){for(var i=0;i<keyData.keys.length;i++){dataItem=keyData.keys[i];if(dataItem==e.charCode){keyEvent.fire(e.charCode,e);break;}else if(dataItem==e.keyCode){keyEvent.fire(e.keyCode,e);break;}}}else{dataItem=keyData.keys;if(dataItem==e.charCode){keyEvent.fire(e.charCode,e);}else if(dataItem==e.keyCode){keyEvent.fire(e.keyCode,e);}}}}
this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(attachTo,event,handleKeyPress);this.enabledEvent.fire(keyData);}
this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(attachTo,event,handleKeyPress);this.disabledEvent.fire(keyData);}
this.enabled=false;};this.toString=function(){return"KeyListener ["+keyData.keys+"] "+attachTo.tagName+(attachTo.id?"["+attachTo.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.widget.ContainerEffect=function(overlay,attrIn,attrOut,targetElement,animClass){if(!animClass){animClass=YAHOO.util.Anim;}
this.overlay=overlay;this.attrIn=attrIn;this.attrOut=attrOut;this.targetElement=targetElement||overlay.element;this.animClass=animClass;};YAHOO.widget.ContainerEffect.prototype.init=function(){this.beforeAnimateInEvent=new YAHOO.util.CustomEvent("beforeAnimateIn");this.beforeAnimateOutEvent=new YAHOO.util.CustomEvent("beforeAnimateOut");this.animateInCompleteEvent=new YAHOO.util.CustomEvent("animateInComplete");this.animateOutCompleteEvent=new YAHOO.util.CustomEvent("animateOutComplete");this.animIn=new this.animClass(this.targetElement,this.attrIn.attributes,this.attrIn.duration,this.attrIn.method);this.animIn.onStart.subscribe(this.handleStartAnimateIn,this);this.animIn.onTween.subscribe(this.handleTweenAnimateIn,this);this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn,this);this.animOut=new this.animClass(this.targetElement,this.attrOut.attributes,this.attrOut.duration,this.attrOut.method);this.animOut.onStart.subscribe(this.handleStartAnimateOut,this);this.animOut.onTween.subscribe(this.handleTweenAnimateOut,this);this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut,this);};YAHOO.widget.ContainerEffect.prototype.animateIn=function(){this.beforeAnimateInEvent.fire();this.animIn.animate();};YAHOO.widget.ContainerEffect.prototype.animateOut=function(){this.beforeAnimateOutEvent.fire();this.animOut.animate();};YAHOO.widget.ContainerEffect.prototype.handleStartAnimateIn=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateIn=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateIn=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleStartAnimateOut=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateOut=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateOut=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.toString=function(){var output="ContainerEffect";if(this.overlay){output+=" ["+this.overlay.toString()+"]";}
return output;};YAHOO.widget.ContainerEffect.FADE=function(overlay,dur){var fade=new YAHOO.widget.ContainerEffect(overlay,{attributes:{opacity:{from:0,to:1}},duration:dur,method:YAHOO.util.Easing.easeIn},{attributes:{opacity:{to:0}},duration:dur,method:YAHOO.util.Easing.easeOut},overlay.element);fade.handleStartAnimateIn=function(type,args,obj){YAHOO.util.Dom.addClass(obj.overlay.element,"hide-select");if(!obj.overlay.underlay){obj.overlay.cfg.refireEvent("underlay");}
if(obj.overlay.underlay){obj.initialUnderlayOpacity=YAHOO.util.Dom.getStyle(obj.overlay.underlay,"opacity");obj.overlay.underlay.style.filter=null;}
YAHOO.util.Dom.setStyle(obj.overlay.element,"visibility","visible");YAHOO.util.Dom.setStyle(obj.overlay.element,"opacity",0);};fade.handleCompleteAnimateIn=function(type,args,obj){YAHOO.util.Dom.removeClass(obj.overlay.element,"hide-select");if(obj.overlay.element.style.filter){obj.overlay.element.style.filter=null;}
if(obj.overlay.underlay){YAHOO.util.Dom.setStyle(obj.overlay.underlay,"opacity",obj.initialUnderlayOpacity);}
obj.overlay.cfg.refireEvent("iframe");obj.animateInCompleteEvent.fire();};fade.handleStartAnimateOut=function(type,args,obj){YAHOO.util.Dom.addClass(obj.overlay.element,"hide-select");if(obj.overlay.underlay){obj.overlay.underlay.style.filter=null;}};fade.handleCompleteAnimateOut=function(type,args,obj){YAHOO.util.Dom.removeClass(obj.overlay.element,"hide-select");if(obj.overlay.element.style.filter){obj.overlay.element.style.filter=null;}
YAHOO.util.Dom.setStyle(obj.overlay.element,"visibility","hidden");YAHOO.util.Dom.setStyle(obj.overlay.element,"opacity",1);obj.overlay.cfg.refireEvent("iframe");obj.animateOutCompleteEvent.fire();};fade.init();return fade;};YAHOO.widget.ContainerEffect.SLIDE=function(overlay,dur){var x=overlay.cfg.getProperty("x")||YAHOO.util.Dom.getX(overlay.element);var y=overlay.cfg.getProperty("y")||YAHOO.util.Dom.getY(overlay.element);var clientWidth=YAHOO.util.Dom.getClientWidth();var offsetWidth=overlay.element.offsetWidth;var slide=new YAHOO.widget.ContainerEffect(overlay,{attributes:{points:{to:[x,y]}},duration:dur,method:YAHOO.util.Easing.easeIn},{attributes:{points:{to:[(clientWidth+25),y]}},duration:dur,method:YAHOO.util.Easing.easeOut},overlay.element,YAHOO.util.Motion);slide.handleStartAnimateIn=function(type,args,obj){obj.overlay.element.style.left=(-25-offsetWidth)+"px";obj.overlay.element.style.top=y+"px";};slide.handleTweenAnimateIn=function(type,args,obj){var pos=YAHOO.util.Dom.getXY(obj.overlay.element);var currentX=pos[0];var currentY=pos[1];if(YAHOO.util.Dom.getStyle(obj.overlay.element,"visibility")=="hidden"&&currentX<x){YAHOO.util.Dom.setStyle(obj.overlay.element,"visibility","visible");}
obj.overlay.cfg.setProperty("xy",[currentX,currentY],true);obj.overlay.cfg.refireEvent("iframe");};slide.handleCompleteAnimateIn=function(type,args,obj){obj.overlay.cfg.setProperty("xy",[x,y],true);obj.startX=x;obj.startY=y;obj.overlay.cfg.refireEvent("iframe");obj.animateInCompleteEvent.fire();};slide.handleStartAnimateOut=function(type,args,obj){var vw=YAHOO.util.Dom.getViewportWidth();var pos=YAHOO.util.Dom.getXY(obj.overlay.element);var yso=pos[1];var currentTo=obj.animOut.attributes.points.to;obj.animOut.attributes.points.to=[(vw+25),yso];};slide.handleTweenAnimateOut=function(type,args,obj){var pos=YAHOO.util.Dom.getXY(obj.overlay.element);var xto=pos[0];var yto=pos[1];obj.overlay.cfg.setProperty("xy",[xto,yto],true);obj.overlay.cfg.refireEvent("iframe");};slide.handleCompleteAnimateOut=function(type,args,obj){YAHOO.util.Dom.setStyle(obj.overlay.element,"visibility","hidden");obj.overlay.cfg.setProperty("xy",[x,y]);obj.animateOutCompleteEvent.fire();};slide.init();return slide;};
var ttBgColor="#e6ecff";var ttBgImg="";var ttBorderColor="#003399";var ttBorderWidth=1;var ttDelay=500;var ttFontColor="#000066";var ttFontFace="arial,helvetica,sans-serif";var ttFontSize="11px";var ttFontWeight="normal";var ttOffsetX=12;var ttOffsetY=15;var ttOpacity=100;var ttPadding=3;var ttShadowColor="";var ttShadowWidth=0;var ttTemp=0;var ttTextAlign="left";var ttTitleColor="#ffffff";var ttWidth=300;var tt_tags=new Array("a","area","b","big","caption","center","code","dd","div","dl","dt","em","h1","h2","h3","h4","h5","h6","i","img","input","li","map","ol","p","pre","s","small","span","strike","strong","sub","sup","table","td","th","tr","tt","u","var","ul","layer");var tt_obj,tt_objW=0,tt_objH=0,tt_objX=0,tt_objY=0,tt_offX=0,tt_offY=0,xlim=0,ylim=0,tt_sup=false,tt_sticky=false,tt_wait=false,tt_act=false,tt_sub=false,tt_u="undefined",tt_mf,tt_inputs=new Array(),tt_tag=null;var tt_db,tt_n=navigator.userAgent.toLowerCase();function tt_init(){tt_db=(document.compatMode&&document.compatMode!="BackCompat")?document.documentElement:document.body?document.body:null;tt_op=!!(window.opera&&document.getElementById),tt_op6=tt_op&&!document.defaultView,tt_op7=tt_op&&!tt_op6,tt_ie=tt_n.indexOf("msie")!=-1&&document.all&&tt_db&&!tt_op,tt_n4=(document.layers&&typeof document.classes!=tt_u)?true:false,tt_n6=(!tt_op&&document.defaultView&&typeof document.defaultView.getComputedStyle!=tt_u),tt_w3c=!tt_ie&&!tt_n6&&!tt_op&&document.getElementById;}function tt_Int(_1){var _2;return isNaN(_2=parseInt(_1))?0:_2;}function wzReplace(_3,_4){var _5="",t_str=this,t_xI;while((t_xI=t_str.indexOf(_3))!=-1){_5+=t_str.substring(0,t_xI)+_4;t_str=t_str.substring(t_xI+_3.length);}return _5+t_str;}String.prototype.wzReplace=wzReplace;function tt_N4Tags(_6,_7,_8){_7=_7||document;_8=_8||new Array();var _9=(_6=="a")?_7.links:_7.layers;for(var z=_9.length;z--;){_8[_8.length]=_9[z];}for(z=_7.layers.length;z--;){_8=tt_N4Tags(_6,_7.layers[z].document,_8);}return _8;}function tt_GetSelects(){if(!tt_op6&&!tt_ie){return;}var _b,t_s=tt_op6?"input":"select";if(document.all){_b=document.all.tags(t_s).length;while(_b--){tt_inputs[_b]=document.all.tags(t_s)[_b];}}else{if(document.getElementsByTagName){_b=document.getElementsByTagName(t_s).length;while(_b--){tt_inputs[_b]=document.getElementsByTagName(t_s)[_b];}}}_b=tt_inputs.length;while(_b--){tt_inputs[_b].vis="";tt_inputs[_b].x=0;tt_inputs[_b].y=0;var _c=tt_inputs[_b];while(_c){tt_inputs[_b].x+=_c.offsetLeft||0;tt_inputs[_b].y+=_c.offsetTop||0;_c=_c.offsetParent;}}}function tt_Htm(tt,_e,_f){var _10=(typeof tt.T_BGCOLOR!=tt_u)?tt.T_BGCOLOR:ttBgColor,t_bgimg=(typeof tt.T_BGIMG!=tt_u)?tt.T_BGIMG:ttBgImg,t_bc=(typeof tt.T_BORDERCOLOR!=tt_u)?tt.T_BORDERCOLOR:ttBorderColor,t_bw=(typeof tt.T_BORDERWIDTH!=tt_u)?tt.T_BORDERWIDTH:ttBorderWidth,t_ff=(typeof tt.T_FONTFACE!=tt_u)?tt.T_FONTFACE:ttFontFace,t_fc=(typeof tt.T_FONTCOLOR!=tt_u)?tt.T_FONTCOLOR:ttFontColor,t_fsz=(typeof tt.T_FONTSIZE!=tt_u)?tt.T_FONTSIZE:ttFontSize,t_fwght=(typeof tt.T_FONTWEIGHT!=tt_u)?tt.T_FONTWEIGHT:ttFontWeight,t_opa=(typeof tt.T_OPACITY!=tt_u)?tt.T_OPACITY:ttOpacity,t_padd=(typeof tt.T_PADDING!=tt_u)?tt.T_PADDING:ttPadding,t_shc=(typeof tt.T_SHADOWCOLOR!=tt_u)?tt.T_SHADOWCOLOR:(ttShadowColor||0),t_shw=(typeof tt.T_SHADOWWIDTH!=tt_u)?tt.T_SHADOWWIDTH:(ttShadowWidth||0),t_algn=(typeof tt.T_TEXTALIGN!=tt_u)?tt.T_TEXTALIGN:ttTextAlign,t_tit=(typeof tt.T_TITLE!=tt_u)?tt.T_TITLE:"",t_titc=(typeof tt.T_TITLECOLOR!=tt_u)?tt.T_TITLECOLOR:ttTitleColor,t_w=(typeof tt.T_WIDTH!=tt_u)?tt.T_WIDTH:ttWidth;if(t_shc||t_shw){t_shc=t_shc||"#cccccc";t_shw=t_shw||5;}if(tt_n4&&(t_fsz=="10px"||t_fsz=="11px")){t_fsz="12px";}var _11=(tt_n4?"":tt_n6?("-moz-opacity:"+(t_opa/100)):tt_ie?("filter:Alpha(opacity="+t_opa+")"):("opacity:"+(t_opa/100)))+";";var t_y="<div id=\""+_e+"\" style=\"position:absolute;z-index:1010;";t_y+="left:0px;top:0px;width:"+(t_w+t_shw)+"px;visibility:"+(tt_n4?"hide":"hidden")+";"+_11+"\">"+"<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\""+(t_bc?(" bgcolor=\""+t_bc+"\""):"")+" width=\""+t_w+"\">";if(t_tit){t_y+="<tr><td style=\"padding-left:3px;padding-right:3px;\" align=\""+t_algn+"\"><font color=\""+t_titc+"\" face=\""+t_ff+"\" "+"style=\"color:"+t_titc+";font-family:"+t_ff+";font-size:"+t_fsz+";\"><b>"+(tt_n4?"&nbsp;":"")+t_tit+"</b></font></td></tr>";}t_y+="<tr><td><table style=\"margin: 0 0 0 0\" border=\"0\" cellpadding=\""+t_padd+"\" cellspacing=\""+t_bw+"\" width=\"100%\">"+"<tr><td"+(_10?(" bgcolor=\""+_10+"\""):"")+(t_bgimg?" background=\""+t_bgimg+"\"":"");if(tt_n6){t_y+=" style=\"padding:"+t_padd+"px;\"";}t_y+=" align=\""+t_algn+"\"><font color=\""+t_fc+"\" face=\""+t_ff+"\""+" style=\"color:"+t_fc+";font-family:"+t_ff+";font-size:"+t_fsz+";font-weight:"+t_fwght+";\">";if(t_fwght=="bold"){t_y+="<b>";}t_y+=_f;if(t_fwght=="bold"){t_y+="</b>";}t_y+="</font></td></tr></table></td></tr></table>";if(t_shw){var _13=Math.round(t_shw*1.3);if(tt_n4){t_y+="<layer bgcolor=\""+t_shc+"\" left=\""+t_w+"\" top=\""+_13+"\" width=\""+t_shw+"\" height=\"0\"></layer>"+"<layer bgcolor=\""+t_shc+"\" left=\""+_13+"\" align=\"bottom\" width=\""+(t_w-_13)+"\" height=\""+t_shw+"\"></layer>";}else{_11=tt_n6?"-moz-opacity:0.85;":tt_ie?"filter:Alpha(opacity=85);":"opacity:0.85;";t_y+="<div id=\""+_e+"R\" style=\"position:absolute;background:"+t_shc+";left:"+t_w+"px;top:"+_13+"px;width:"+t_shw+"px;height:1px;overflow:hidden;"+_11+"\"></div>"+"<div style=\"position:relative;background:"+t_shc+";left:"+_13+"px;top:0px;width:"+(t_w-_13)+"px;height:"+t_shw+"px;overflow:hidden;"+_11+"\"></div>";}}return t_y+"</div>";}function tt_EvX(t_e){var t_y=tt_Int(t_e.pageX||t_e.clientX||0)+tt_Int(tt_ie?tt_db.scrollLeft:0)+tt_offX;if(t_y>xlim){t_y=xlim;}var _16=tt_Int(window.pageXOffset||(tt_db?tt_db.scrollLeft:0)||0);if(t_y<_16){t_y=_16;}return t_y;}function tt_EvY(t_e){var t_y=tt_Int(t_e.pageY||t_e.clientY||0)+tt_Int(tt_ie?tt_db.scrollTop:0);if(tt_sup){t_y-=(tt_objH+tt_offY-15);}else{if(t_y>ylim||!tt_sub&&t_y>ylim-24){t_y-=(tt_objH+5);tt_sub=false;}else{t_y+=tt_offY;tt_sub=true;}}if(t_y<0){t_y=0;}return t_y;}function tt_ReleasMov(){if(document.onmousemove==tt_Move){if(!tt_mf&&document.releaseEvents){document.releaseEvents(Event.MOUSEMOVE);}document.onmousemove=tt_mf;}}function tt_HideInput(){if(!(tt_ie||tt_op6)||!tt_inputs){return;}var t_o;var t_i=tt_inputs.length;while(t_i--){t_o=tt_inputs[t_i];if(tt_act&&!t_o.vis&&tt_objX+tt_objW>t_o.x&&tt_objX<t_o.x+t_o.offsetWidth&&tt_objY+tt_objH>t_o.y&&tt_objY<t_o.y+t_o.offsetHeight){t_o.vis=t_o.currentStyle?t_o.currentStyle.visibility:t_o.style.visibility;t_o.style.visibility="hidden";}else{if(t_o.vis){t_o.style.visibility=t_o.vis;t_o.vis="";}}}}function tt_GetDiv(_1b){return (tt_n4?(document.layers[_1b]||null):tt_ie?(document.all[_1b]||null):(document.getElementById(_1b)||null));}function tt_GetDivW(){return tt_Int(tt_n4?tt_obj.clip.width:(tt_obj.style.pixelWidth||tt_obj.offsetWidth));}function tt_GetDivH(){return tt_Int(tt_n4?tt_obj.clip.height:(tt_obj.style.pixelHeight||tt_obj.offsetHeight));}function tt_SetDivZ(){var t_i=tt_obj.style||tt_obj;if(window.dd&&dd.z){t_i.zIndex=Math.max(dd.z+1,t_i.zIndex);}}function tt_SetDivPos(t_x,t_y){var t_i=tt_obj.style||tt_obj;var _20=(tt_op6||tt_n4)?"":"px";t_i.left=(tt_objX=t_x)+_20;t_i.top=(tt_objY=t_y)+_20;}function tt_ShowDiv(t_x){if(tt_n4){tt_obj.visibility=t_x?"show":"hide";}else{tt_obj.style.visibility=t_x?"visible":"hidden";}tt_act=t_x;tt_HideInput();}function tt_OpDeHref(t_e){if(t_e&&t_e.target.hasAttribute("href")){tt_tag=t_e.target;tt_tag.t_href=tt_tag.getAttribute("href");tt_tag.removeAttribute("href");tt_tag.style.cursor="hand";tt_tag.onmousedown=tt_OpReHref;tt_tag.stats=window.status;window.status=tt_tag.t_href;}}function tt_OpReHref(){if(tt_tag){tt_tag.setAttribute("href",tt_tag.t_href);window.status=tt_tag.stats;tt_tag=null;}}function tt_Show(t_e,_24,_25,_26,_27,_28,_29,_2a,_2b,_2c,_2d){if(tt_obj){tt_Hide();}tt_mf=document.onmousemove||null;if(window.dd&&(window.DRAG&&tt_mf==DRAG||window.RESIZE&&tt_mf==RESIZE)){return;}var _2e=document.onmouseup||null;if(tt_mf&&_2e){_2e(t_e);}tt_obj=tt_GetDiv(_24);if(tt_obj){t_e=t_e||window.event;tt_sub=!(tt_sup=_25);tt_sticky=_2c;tt_objW=tt_GetDivW();tt_objH=tt_GetDivH();tt_offX=_28?-(tt_objW+_29):_29;tt_offY=_2a;if(tt_op7){tt_OpDeHref(t_e);}if(tt_n4){if(tt_obj.document.layers.length){var _2f=tt_obj.document.layers[0];_2f.clip.height=tt_objH-Math.round(_2f.clip.width*1.3);}}else{var _30=tt_GetDiv(_24+"R");if(_30){var t_h=tt_objH-tt_Int(_30.style.pixelTop||_30.style.top||0);if(typeof _30.style.pixelHeight!=tt_u){_30.style.pixelHeight=t_h;}else{_30.style.height=t_h+"px";}}}tt_GetSelects();xlim=tt_Int((tt_db&&tt_db.clientWidth)?tt_db.clientWidth:window.innerWidth)+tt_Int(window.pageXOffset||(tt_db?tt_db.scrollLeft:0)||0)-tt_objW-(tt_n4?21:0);ylim=tt_Int(window.innerHeight||tt_db.clientHeight)+tt_Int(window.pageYOffset||(tt_db?tt_db.scrollTop:0)||0)-tt_objH-tt_offY;tt_SetDivZ();if(_27){tt_SetDivPos(tt_Int((_27=_27.split(","))[0]),tt_Int(_27[1]));}else{tt_SetDivPos(tt_EvX(t_e),tt_EvY(t_e));}var _32="tt_ShowDiv('true');";if(_2c){_32+="{"+"tt_ReleasMov();"+"window.tt_upFunc = document.onmouseup || null;"+"if (document.captureEvents) document.captureEvents(Event.MOUSEUP);"+"document.onmouseup = new Function(\"window.setTimeout('tt_Hide();', 10);\");"+"}";}else{if(_2b){_32+="tt_ReleasMov();";}}if(_2d>0){_32+="window.tt_rtm = window.setTimeout('tt_sticky = false; tt_Hide();',"+_2d+");";}window.tt_rdl=window.setTimeout(_32,_26);if(!_27){if(document.captureEvents){document.captureEvents(Event.MOUSEMOVE);}document.onmousemove=tt_Move;}}}var tt_area=false;function tt_Move(_33){if(!tt_obj){return;}if(tt_n6||tt_w3c){if(tt_wait){return;}tt_wait=true;setTimeout("tt_wait = false;",5);}var t_e=_33||window.event;tt_SetDivPos(tt_EvX(t_e),tt_EvY(t_e));if(tt_op6){if(tt_area&&t_e.target.tagName!="AREA"){tt_Hide();}else{if(t_e.target.tagName=="AREA"){tt_area=true;}}}}function tt_Hide(){if(window.tt_obj){if(window.tt_rdl){window.clearTimeout(tt_rdl);}if(!tt_sticky||!tt_act){if(window.tt_rtm){window.clearTimeout(tt_rtm);}tt_ShowDiv(false);tt_SetDivPos(-tt_objW,-tt_objH);tt_obj=null;if(typeof window.tt_upFunc!=tt_u){document.onmouseup=window.tt_upFunc;}}tt_sticky=false;if(tt_op6&&tt_area){tt_area=false;}tt_ReleasMov();if(tt_op7){tt_OpReHref();}tt_HideInput();}}function tt_Init(){if(!(tt_op||tt_n4||tt_n6||tt_ie||tt_w3c)){return;}var htm=tt_n4?"<div style=\"position:absolute;\"></div>":"",tags,t_tj,over,esc="return escape(";var i=tt_tags.length;while(i--){tags=tt_ie?(document.all.tags(tt_tags[i])||1):document.getElementsByTagName?(document.getElementsByTagName(tt_tags[i])||1):(!tt_n4&&tt_tags[i]=="a")?document.links:1;if(tt_n4&&(tt_tags[i]=="a"||tt_tags[i]=="layer")){tags=tt_N4Tags(tt_tags[i]);}var j=tags.length;while(j--){if(typeof (t_tj=tags[j]).onmouseover=="function"&&t_tj.onmouseover.toString().indexOf(esc)!=-1&&!tt_n6||tt_n6&&(over=t_tj.getAttribute("onmouseover"))&&over.indexOf(esc)!=-1){if(over){t_tj.onmouseover=new Function(over);}var txt=unescape(t_tj.onmouseover());htm+=tt_Htm(t_tj,"tOoLtIp"+i+""+j,txt.wzReplace("& ","&"));t_tj.onmouseover=new Function("e","tt_Show(e,"+"\"tOoLtIp"+i+""+j+"\","+(typeof t_tj.T_ABOVE!=tt_u)+","+((typeof t_tj.T_DELAY!=tt_u)?t_tj.T_DELAY:ttDelay)+","+((typeof t_tj.T_FIX!=tt_u)?"\""+t_tj.T_FIX+"\"":"\"\"")+","+(typeof t_tj.T_LEFT!=tt_u)+","+((typeof t_tj.T_OFFSETX!=tt_u)?t_tj.T_OFFSETX:ttOffsetX)+","+((typeof t_tj.T_OFFSETY!=tt_u)?t_tj.T_OFFSETY:ttOffsetY)+","+(typeof t_tj.T_STATIC!=tt_u)+","+(typeof t_tj.T_STICKY!=tt_u)+","+((typeof t_tj.T_TEMP!=tt_u)?t_tj.T_TEMP:ttTemp)+");");t_tj.onmouseout=tt_Hide;if(t_tj.alt){t_tj.alt="";}if(t_tj.title){t_tj.title="";}}}}document.write(htm);}
function movebox(_1,_2,_3){var _4=_1.value.length;if(_4==_3){_2.focus();}}function updateTimeField(_5,_6,_7,_8){_5.value=_6.value+":"+_7.value+":"+_8.value;}function updateComponents(_9,_a,_b,_c){var _d=new StringTokenizer(_9.value,":");if(_d.hasMoreTokens()){_a.value=_d.nextToken();}if(_d.hasMoreTokens()){_b.value=_d.nextToken();}if(_d.hasMoreTokens()){_c.value=_d.nextToken();}}function upRange(_e,_f){var un=_e.value;if(un>_f){return false;}else{return true;}}function checkHour(_11){if(isNaN(_11.value)){alert("The Hour field can only contain numbers\n You entered: "+_11.value);_11.value="00";}if(_11.value.length==2){if(!upRange(_11,23)){alert("The hour field can only contain numbers between 0 and 23");_11.value=23;_11.focus();}}}function checkMinute(_12){if(isNaN(_12.value)){alert("The Minute field can only contain numbers\n You entered: "+_12.value);_12.value="00";}if(_12.value.length==2){if(!upRange(_12,59)){alert("The minute field can only contain numbers between 0 and 59");_12.value=59;_12.focus();}}}function checkSecond(_13){if(isNaN(_13.value)){alert("The Second field can only contain numbers\n You entered: "+_13.value);_13.value="00";}if(_13.value.length==2){if(!upRange(_13,59)){alert("The second field can only contain numbers between 0 and 59");_13.value=59;_13.focus();}}}function StringTokenizer(_14,_15){this.material=_14;this.separator=_15;this.getTokens=getTokens;this.nextToken=nextToken;this.countTokens=countTokens;this.hasMoreTokens=hasMoreTokens;this.tokensReturned=tokensReturned;this.tokens=this.getTokens();this.tokensReturned=0;}function getTokens(){var _16=new Array();var _17;if(this.material.indexOf(this.separator)<0){_16[0]=this.material;return _16;}start=0;end=this.material.indexOf(this.separator,start);var _18=0;var _19;while(this.material.length-start>=1){_17=this.material.substring(start,end);start=end+1;if(this.material.indexOf(this.separator,start+1)<0){end=this.material.length;}else{end=this.material.indexOf(this.separator,start+1);}_19=trim(_17);while(_19.substring(0,this.separator.length)==this.separator){_19=_19.substring(this.separator.length);}_19=trim(_19);if(_19==""){continue;}_16[_18]=_19;_18++;}return _16;}function countTokens(){return this.tokens.length;}function nextToken(){if(this.tokensReturned>=this.tokens.length){return null;}else{var _1a=this.tokens[this.tokensReturned];this.tokensReturned++;return _1a;}}function hasMoreTokens(){if(this.tokensReturned<this.tokens.length){return true;}else{return false;}}function tokensReturned(){return this.tokensReturned;}function trim(_1b){return (_1b.replace(/^\s+|\s+$/g,""));}
/**
 *  Copyright (C) 2006 Orbeon, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the
 *  GNU Lesser General Public License as published by the Free Software Foundation; either version
 *  2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Lesser General Public License for more details.
 *
 *  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */

/**
 * Parameters
 */
var XFORMS_DELAY_BEFORE_INCREMENTAL_REQUEST_IN_MS = 500;
var XFORMS_DELAY_BEFORE_FORCE_INCREMENTAL_REQUEST_IN_MS = 2000;
var XFORMS_DELAY_BEFORE_ANY_REQUEST_IN_MS = 10;
var XFORMS_DELAY_BEFORE_DISPLAY_LOADING_IN_MS = 500;
var XFORMS_DEBUG_WINDOW_HEIGHT = 600;
var XFORMS_DEBUG_WINDOW_WIDTH = 300;
var XFORMS_LOADING_MIN_TOP_PADDING = 10;

/**
 * Constants
 */
var XFORMS_SEPARATOR_1 = "\xB7";
var XFORMS_SEPARATOR_2 = "-";
var XXFORMS_NAMESPACE_URI = "http://orbeon.org/oxf/xml/xforms";
var BASE_URL = null;
var XFORMS_SERVER_URL = null;
var XFORMS_IS_GECKO = navigator.userAgent.toLowerCase().indexOf("gecko") != -1;
var ELEMENT_TYPE = document.createElement("dummy").nodeType;
var ATTRIBUTE_TYPE = document.createAttribute("dummy").nodeType;
var TEXT_TYPE = document.createTextNode("").nodeType;
var XFORMS_REGEXP_CR = new RegExp("\\r", "g");
var XFORMS_REGEXP_SINGLE_QUOTE = new RegExp("'", "g");
var XFORMS_REGEXP_OPEN_ANGLE = new RegExp("<", "g");
var XFORMS_REGEXP_AMPERSAND = new RegExp("&", "g");
var XFORMS_WIDE_TEXTAREA_MIN_ROWS = 5;

// These variables are not set by default, but if set will be used by this code:
//
//     FCK_CUSTOM_CONFIG
//     USER_LANGUAGE

/* * * * * * Utility functions * * * * * */

ORBEON = {};
ORBEON.util = {};
ORBEON.xforms = {};

/**
 * Global constants and variable
 */
ORBEON.xforms.Globals = {
    // Booleans used for browser detection
    isRenderingEnginePresto: navigator.userAgent.toLowerCase().indexOf("opera") != -1,    // Opera
    isRenderingEngineWebCore: navigator.userAgent.toLowerCase().indexOf("safari") != -1,  // Safari
    isRenderingEngineWebCore13: navigator.userAgent.indexOf("AppleWebKit/312") != -1,     // Safari 1.3
    isRenderingEngineTridend: navigator.userAgent.toLowerCase().indexOf("msie") != -1     // Internet Explorer
        && navigator.userAgent.toLowerCase().indexOf("opera") == -1,

    eventQueue: [],                      // Events to be sent to the server
    eventsFirstEventTime: 0,             // Time when the first event in the queue was added
    requestForm: null,                   // HTML for the request currently in progress
    requestInProgress: false,            // Indicates wether an Ajax request is currently in process
    lastRequestIsError: false,           // Whether the last XHR request returned an error
    executeEventFunctionQueued: 0,       // Number of ORBEON.xforms.Server.executeNextRequest waiting to be executed
    maskFocusEvents: false,              // Avoid catching focus event when we do it because the server told us to
    previousDOMFocusOut: null,           // We only send a focus out when we receive a focus in, or another focus out
    htmlAreaNames: [],                   // Names of the FCK editors, which we need to reenable them on Firefox
    repeatTreeChildToParent: [],         // Describes the repeat hierarchy
    repeatIndexes: {},                   // The current index for each repeat
    repeatTreeParentToAllChildren: {},   // Map from parent to array with children, used when highlight changes
    inputCalendarCreated: {},            // Maps input id to true when the calendar has been created for that input
    inputCalendarOnclick: {},            // Maps input id to the JSCalendar function that displays the calendar
    inputCalendarCommitedValue: {},      // Maps input id to the value of JSCalendar actually selected by the user
    tooltipLibraryInitialized: false,
    changedIdsRequest: {},               // Id of controls that have been touched by user since the last response was received
    serverValue: {},                     // Values on controls known to the server
    autoCompleteLastKeyCode: {},         // Stores the last key entered for each auto-complete field
    autoCompleteOpen: {},
    loadingOtherPage: false,             // Flag set when loading other page that revents the loading indicator to disappear
    activeControl: null,                 // The currently active control, used to disable hint
    autosizeTextareas: [],               // Ids of the autosize textareas on the page
    fckEditorLoading: false,             // True if  a FCK editor is currently loading
    fckEditorsToLoad: [],                // Queue of FCK editor to load
    dialogs: {},                         // Map for dialogs: id -> YUI dialog object
    debugDiv: null,                      // Points to the div when debug messages are displayed
    debugLastTime: new Date().getTime(), // Timestamp when the last debug message was printed
    pageLoadedRegistered: false,         // If the page loaded listener has been registered already, to avoid running it more than once
    menuItemsets: {},                    // Maps menu id to structure defining the content of the menu
    menuYui: {},                         // Maps menu id to the YUI object for that menu
    treeYui: {},                         // Maps tree id to the YUI object for that tree

    // Data relative to a form is stored in an array indexed by the position of the form on the page.
    // Use ORBEON.util.Dom.getFormIndex(form) to get the index of a given form on the page
    formLoadingLoadingOverlay: [],       // Overlay for the loading indicator
    formLoadingLoadingInitialRightTop:[],// Initial number of pixel between the loading indicator and the top of the page
    formLoadingError: [],                // HTML element with the markup displayed when there is an error
    formLoadingNone: [],                 // HTML element with the markup displayed when nothing is displayed
    formStaticState: [],                 // State that does not change for the life of the page
    formDynamicState: [],                // State that changes at every request
    formServerEvents: [],                // Server events information
    formClientState: []                  // Store for information we want to keep when the page reloaded
};

/**
 * The IE version of those methods does not store anything in the
 * elements as this has some negative side effects like IE reloading
 * background images set with CSS on the element.
 */
ORBEON.util.IEDom = {
    /**
     * Optimized version of YAHOO.util.Dom.hasClass(element, className).
     */
    hasClass: function(element, className) {
        if (element.className == className) {
            // Trivial true case
            return true;
        } else {
            var classes = element.className + XFORMS_SEPARATOR_1;
            if (classes.indexOf(className + " ") == 0) {
                // Starts with the class we look for
                return true;
            }
            if (classes.indexOf(" " + className + " ") != -1) {
                // The class we look for is in the middle
                return true;
            }
            if (classes.indexOf(" " + className + XFORMS_SEPARATOR_1) != -1) {
                // The class we look for is in the end
                return true;
            }
            return false;
        }
    },

    /**
     * Optimized version of YAHOO.util.Dom.addClass(element, className).
     */
    addClass: function(element, className) {
        if (!this.hasClass(element, className))
            element.className = element.className.length == 0 ? className
                    : (element.className + " " + className);
    },

    /**
     * Optimized version of YAHOO.util.Dom.removeClass(element, className).
     */
    removeClass: function(element, className) {
        if (this.hasClass(element, className)) {
            var classes = element.className.split(" ");
            var newClassName = "";
            for (var i = 0; i < classes.length; i++) {
                if (classes[i] != className) {
                    if (newClassName.length > 0) newClassName += " ";
                    newClassName += classes[i];
                }
            }
            element.className = newClassName;
        }
    }
};


/**
 * The hasClass, addClass and removeClass methods use a cache of the
 * classes for a give element for quick lookup. After having parsed the
 * className a first time we store that information in the orbeonClasses
 * map on the given element.
 */
ORBEON.util.MozDom = {
    /**
     * Changes the className on the element based on the information stored in
     * _elementToClasses.
     *
     * @private
     */
    _regenerateClassName: function(element) {
        var newClassName = "";
        for (var existingClassName in element.orbeonClasses) {
            if (element.orbeonClasses[existingClassName]) {
                if (newClassName.length > 0)
                    newClassName += " ";
                newClassName += existingClassName;
            }
        }
        element.className = newClassName;
    },

    /**
     * Optimized version of YAHOO.util.Dom.hasClass(element, className).
     */
    hasClass: function(element, className) {
        if (!element.orbeonClasses) {
            element.orbeonClasses = {};
            var classes = element.className.split(" ");
            for (var i = 0; i < classes.length; i++)
                element.orbeonClasses[classes[i]] = true;
        }
        return element.orbeonClasses[className] == true;
    },

    /**
     * Optimized version of YAHOO.util.Dom.addClass(element, className).
     */
    addClass: function(element, className) {
        if (!this.hasClass(element, className)) {
            element.orbeonClasses[className] = true;
            this._regenerateClassName(element);
        }
    },

    /**
     * Optimized version of YAHOO.util.Dom.removeClass(element, className).
     */
    removeClass: function(element, className) {
        if (this.hasClass(element, className)) {
            element.orbeonClasses[className] = false;
            this._regenerateClassName(element);
        }
    }
};

/**
 *  Utilities to deal with the DOM that supplement what is provided by YAHOO.util.Dom.
 */
ORBEON.util.Dom = {

    ELEMENT_TYPE: 1,

    isElement: function(node) {
        return node.nodeType == this.ELEMENT_TYPE;
    },

    /**
     * This gets around a bug in IE and Opera 8.2 where getElementById by return an element with name equal to
     * the specified id (instead of id equal to the specified id).
     * See: http://www.csb7.com/test/ie_getelementbyid_bug/index.php
     */
    getElementById: function(controlId) {
        var result = document.getElementById(controlId);
        if (result && (result.id != controlId) && document.all) {
            result = null;
            documentAll = document.all[controlId];
            if (documentAll) {
                if (documentAll.length) {
                    for (var i = 0; i < documentAll.length; i++) {
                        if (documentAll[i].id == controlId) {
                            result = documentAll[i];
                            break;
                        }
                    }
                } else {
                    result = documentAll;
                }
            }
        }
        return result;
    },

    getStringValue: function(element) {
        var result = "";
        for (var i = 0; i < element.childNodes.length; i++) {
            var child = element.childNodes[i];
            if (child.nodeType == TEXT_TYPE)
                result += child.nodeValue;
        }
        return result;
    },

    setStringValue: function(element, text) {
        // Remove content
        while (element.childNodes.length > 0)
            element.removeChild(element.firstChild);
        // Add specified text
        var textNode = element.ownerDocument.createTextNode(text);
        element.appendChild(textNode);
    },

    /**
     * Return null when the attribute is not there.
     */
    getAttribute: function(element, name) {
        if (ORBEON.xforms.Globals.isRenderingEngineTridend) {
            // IE incorrectly already return null when the attribute is not there,
            // but this happens to be what we want to do here
            return element.getAttribute(name);
        } else {
            // Other browsers that follow the spec return an empty string when the attribute is not there,
            // so we use hasAttribute() which is not implemented by IE to detect that case.
            if (element.hasAttribute(name)) {
                if (ORBEON.xforms.Globals.isRenderingEngineWebCore) {
                    return ORBEON.util.String.replace(element.getAttribute(name), "&#38;", "&");
                } else {
                    return element.getAttribute(name);
                }
            } else {
                return null;
            }
        }
    },

    getChildElementByIndex: function(parent, position) {
        for (var i = 0; i < parent.childNodes.length; i++) {
            var child = parent.childNodes[i];
            if (ORBEON.util.Dom.isElement(child)) {
                if (position == 0) return child;
                position--;
            }
        }
        return null;
    },

    getChildElementByClass: function(parent, clazz) {
        for (var i = 0; i < parent.childNodes.length; i++) {
            var child = parent.childNodes[i];
            if (ORBEON.util.Dom.isElement(child) && ORBEON.util.Dom.hasClass(child, clazz)) {
                return child;
            }
        }
        return null;
    },

    getFormIndex: function(form) {
        for (var formIndex = 0; formIndex < document.forms.length; formIndex++) {
            var candidateForm = document.forms[formIndex];
            if (form == candidateForm)
                return formIndex;
        }
        return null;
    },

    stringToDom: function(xmlString) {
        if (document.implementation.createDocument) {
            return (new DOMParser()).parseFromString(xmlString, "application/xml")
        } else if (window.ActiveXObject) {
            var dom  = new ActiveXObject("Microsoft.XMLDOM");
            dom.async="false";
            dom.loadXML(xmlString);
            return dom;
        }
        return null;
    },

    clearUploadControl: function(uploadElement) {

        var inputElement = ORBEON.util.Dom.getChildElementByClass(uploadElement, "xforms-upload-select");
        var parentElement = inputElement.parentNode;
        var newInputElement = document.createElement("input");
        ORBEON.util.Dom.addClass(newInputElement, inputElement.className);
        newInputElement.setAttribute("type", inputElement.type);
        newInputElement.setAttribute("name", inputElement.name);
        newInputElement.setAttribute("size", inputElement.size);
        parentElement.replaceChild(newInputElement, inputElement);

        return null;
    }
};

(function () {
    var methodsFrom = ORBEON.xforms.Globals.isRenderingEngineTridend ? ORBEON.util.IEDom : ORBEON.util.MozDom;
    for (var method in methodsFrom)
        ORBEON.util.Dom[method] = methodsFrom[method];
}());

/**
 * General purpose methods on string
 */
ORBEON.util.String = {
    replace: function(text, placeholder, replacement) {
        return text.replace(new RegExp(placeholder, "g"), replacement);
    }
}

/**
 * Utility methods that don't in any other category
 */
ORBEON.util.Utils = {
    logException: function(message, exception) {
        if (typeof console != "undefined") {
            console.log(message); // Normal use; do not remove
            console.log(exception);  // Normal use; do not remove
        }
    }
}

/**
 * This object contains function generally designed to be called from JavaScript code
 * embedded in forms.
 */
ORBEON.xforms.Document = {

    /**
     * Reference: http://www.w3.org/TR/xforms/slice10.html#action-dispatch
     */
    dispatchEvent: function(targetId, eventName, form, bubbles, cancelable, incremental) {

        // Use the first XForms form on the page when no form is provided
        if (form == undefined) {
            for (var formIndex = 0; formIndex < document.forms.length; formIndex++) {
                var candidateForm = document.forms[formIndex];
                if (ORBEON.util.Dom.hasClass(candidateForm, "xforms-form")) {
                    form = candidateForm;
                    break;
                }
            }
        }

        // Create event and fire
        var event = new ORBEON.xforms.Server.Event(form, targetId, null, null, eventName, bubbles, cancelable);
        ORBEON.xforms.Server.fireEvents([event], incremental == undefined ? false : incremental);
    },

    /**
     * Returns the value of an XForms control.
     *
     * @param {String} controlId    Id of the control
     */
    getValue: function(controlId) {
        var control = ORBEON.util.Dom.getElementById(controlId);
        return ORBEON.xforms.Controls.getCurrentValue(control);
    },

    /**
     * Set the value of an XForms control.
     *
     * @param {String} controlId    Id of the control
     * @param {String} newValue     New value for the control
     */
    setValue: function(controlId, newValue) {
        var control = ORBEON.util.Dom.getElementById(controlId);
        xformsFireEvents(new Array(xformsCreateEventArray
                (control, "xxforms-value-change-with-focus-change", String(newValue), null)), false);
    }
};

ORBEON.xforms.Controls = {

    // Returns MIP for a given control
    isRelevant: function (control) { return !ORBEON.util.Dom.hasClass(control, "xforms-disabled"); },
    isReadonly: function (control) { return  ORBEON.util.Dom.hasClass(control, "xforms-readonly"); },
    isRequired: function (control) { return  ORBEON.util.Dom.hasClass(control, "xforms-required"); },
    isValid:    function (control) { return !ORBEON.util.Dom.hasClass(control, "xforms-invalid"); },

    getForm: function(control) {
        if (typeof control.form == "undefined") {
            // There is a span around the control go through parents until we find the form element
            var candidateForm = control;
            while (candidateForm.tagName.toLowerCase() != "form")
                candidateForm = candidateForm.parentNode;
            return candidateForm;
        } else {
            // We have directly a form control
            return control.form;
        }
    },

    getCurrentValue: function(control) {
        if (ORBEON.util.Dom.hasClass(control, "xforms-input")) {
            return ORBEON.util.Dom.getChildElementByIndex(control, 1).value;
        } if (ORBEON.util.Dom.hasClass(control, "xforms-select1-open")) {
            return ORBEON.util.Dom.getChildElementByIndex(control, 0).value;
        } else if (ORBEON.util.Dom.hasClass(control, "xforms-select-appearance-full")
                || ORBEON.util.Dom.hasClass(control, "xforms-select1-appearance-full")) {
            var inputs = control.getElementsByTagName("input");
            var spanValue = "";
            for (var inputIndex = 0; inputIndex < inputs.length; inputIndex++) {
                var input = inputs[inputIndex];
                if (input.checked) {
                    if (spanValue != "") spanValue += " ";
                    spanValue += input.value;
                }
            }
            return spanValue;
        } else if (ORBEON.util.Dom.hasClass(control, "xforms-select-appearance-compact")
                || ORBEON.util.Dom.hasClass(control, "xforms-select1-appearance-minimal")
                || ORBEON.util.Dom.hasClass(control, "xforms-select1-appearance-compact")) {
            var options = control.options;
            var selectValue = "";
            for (var optionIndex = 0; optionIndex < options.length; optionIndex++) {
                var option = options[optionIndex];
                if (option.selected) {
                    if (selectValue != "") selectValue += " ";
                    selectValue += option.value;
                }
            }
            return selectValue;
        } else if (ORBEON.util.Dom.hasClass(control, "xforms-textarea")
                        && ORBEON.util.Dom.hasClass(control, "xforms-mediatype-text-html")) {
            var editorInstance = FCKeditorAPI.GetInstance(control.name);
            return editorInstance.GetXHTML();
        } else {
            return control.value;
        }
    },

    _getControlLabel: function(control, className) {
        var candidate = control;
        while (true) {
            if (candidate == null) break;
            if (ORBEON.util.Dom.isElement(candidate)
                    && ORBEON.util.Dom.hasClass(candidate, className)
                    && (candidate.htmlFor == null || candidate.htmlFor == control.id)) break;
            candidate = className == "xforms-label" ? candidate.previousSibling : candidate.nextSibling;
        }
        return candidate;
    },

    _setMessage: function(control, className, message) {
        var label = ORBEON.xforms.Controls._getControlLabel(control, className);
        if (label != null) {
            ORBEON.util.Dom.setStringValue(label, message);
            var helpImage = ORBEON.xforms.Controls._getControlLabel(control, "xforms-help-image");
            if (message == "") {
                ORBEON.util.Dom.addClass(label, "xforms-disabled");
                // If this is the help label, also disable help image
                if (className == "xforms-help")
                    ORBEON.util.Dom.addClass(helpImage, "xforms-disabled");
            } else {
                ORBEON.util.Dom.removeClass(label, "xforms-disabled");
                // If this is the help label, also enable the help image
                if (className == "xforms-help")
                    ORBEON.util.Dom.removeClass(helpImage, "xforms-disabled");
            }
        }
    },

    setLabelMessage: function(control, message) {
        if (ORBEON.util.Dom.hasClass(control, "xforms-trigger")
                || ORBEON.util.Dom.hasClass(control, "xforms-submit")) {
            if (control.tagName.toLowerCase() == "input") {
                // Image
                control.alt = message;
            } else {
                // Link or button
                control.innerHTML = message;
            }
        } else if (ORBEON.util.Dom.hasClass(control, "xforms-dialog")) {
            // Dialog
            var labelDiv = ORBEON.util.Dom.getChildElementByIndex(control, 0);
            ORBEON.util.Dom.setStringValue(labelDiv, message);
        } else {
            ORBEON.xforms.Controls._setMessage(control, "xforms-label", message);
        }
    },

    getHelpMessage: function(control) {
        var helpElement = ORBEON.xforms.Controls._getControlLabel(control, "xforms-help");
        return helpElement == null ? "" : ORBEON.util.Dom.getStringValue(helpElement);
    },

    setHelpMessage: function(control, message) {
        ORBEON.xforms.Controls._setMessage(control, "xforms-help", message);
    },

    setValid: function(control, isValid) {
        // Update class xforms-invalid on the control
        if (isValid) ORBEON.util.Dom.removeClass(control, "xforms-invalid");
        else ORBEON.util.Dom.addClass(control, "xforms-invalid");

        // Update class on alert label
        var alertElement = ORBEON.xforms.Controls._getControlLabel(control, "xforms-alert");
        if (alertElement != null) { // Some controls don't have validity indicator
            if (isValid) {
                ORBEON.util.Dom.removeClass(alertElement, "xforms-alert-active");
                ORBEON.util.Dom.addClass(alertElement, "xforms-alert-inactive");
            } else {
                ORBEON.util.Dom.removeClass(alertElement, "xforms-alert-inactive");
                ORBEON.util.Dom.addClass(alertElement, "xforms-alert-active");
            }
        }
    },

    setRelevant: function(control, isRelevant) {
        var elementsToUpdate = [ control,
            ORBEON.xforms.Controls._getControlLabel(control, "xforms-label"),
            ORBEON.xforms.Controls._getControlLabel(control, "xforms-alert")
        ];
        // Also show help if message is not empty
        if (!isRelevant || (isRelevant && ORBEON.xforms.Controls.getHelpMessage(control) != "")) {
            elementsToUpdate.push(ORBEON.xforms.Controls._getControlLabel(control, "xforms-help"));
            elementsToUpdate.push(ORBEON.xforms.Controls._getControlLabel(control, "xforms-help-image"));
        }
        // Also show hint if message is not empty
        if (!isRelevant || (isRelevant && ORBEON.xforms.Controls.getHintMessage(control) != ""))
            elementsToUpdate.push(ORBEON.xforms.Controls._getControlLabel(control, "xforms-hint"));
        for (var elementIndex = 0; elementIndex < elementsToUpdate.length; elementIndex++) {
            var element = elementsToUpdate[elementIndex];
            if (element != null) {
                if (isRelevant) ORBEON.util.Dom.removeClass(element, "xforms-disabled");
                else ORBEON.util.Dom.addClass(element, "xforms-disabled");
            }
        }
    },

    getAlertMessage: function(control) {
        var alertElement = ORBEON.xforms.Controls._getControlLabel(control, "xforms-alert");
        return ORBEON.util.Dom.getStringValue(alertElement);
    },

    setAlertMessage: function(control, message) {
        ORBEON.xforms.Controls._setMessage(control, "xforms-alert", message);
    },

    getHintMessage: function(control) {
        if (ORBEON.util.Dom.hasClass(control, "xforms-trigger")) {
            return control.title;
        } else {
            var hintElement = ORBEON.xforms.Controls._getControlLabel(control, "xforms-hint");
            return hintElement == null ? "" : ORBEON.util.Dom.getStringValue(hintElement);
        }
    },

    setHintMessage: function(control, message) {
        if (ORBEON.util.Dom.hasClass(control, "xforms-trigger")) {
            control.title = message;
        } else {
            ORBEON.xforms.Controls._setMessage(control, "xforms-hint", message);
        }
    },

    /**
     * Sets focus to the specified control. This is called by the JavaScript code
     * generated by the server, which we invoke on page load.
     */
    setFocus: function(controlId) {
        var control = ORBEON.util.Dom.getElementById(controlId);
        // To-do: getting elements by position is not very robust
        if (ORBEON.util.Dom.hasClass(control, "xforms-input")) {
            ORBEON.util.Dom.getChildElementByIndex(control, 1).focus();
        } else if (ORBEON.util.Dom.hasClass(control, "xforms-select-appearance-full")) {
            ORBEON.util.Dom.getChildElementByIndex(ORBEON.util.Dom.getChildElementByIndex(control, 0), 0).focus();
        } else if (ORBEON.util.Dom.hasClass(control, "xforms-select1-appearance-xxforms-autocomplete")) {
            ORBEON.util.Dom.getChildElementByIndex(control, 0).focus();
        } else if (typeof control.focus != "undefined") {
            control.focus();
        }
    },

    /**
     * Update the xforms-required-empty class as necessary.
     */
    updateRequiredEmpty: function(control) {
        if (ORBEON.util.Dom.hasClass(control, "xforms-required")) {
            if (ORBEON.xforms.Controls.getCurrentValue(control) == "") {
                ORBEON.util.Dom.addClass(control, "xforms-required-empty");
                ORBEON.util.Dom.removeClass(control, "xforms-required-filled");
            } else {
                ORBEON.util.Dom.addClass(control, "xforms-required-filled");
                ORBEON.util.Dom.removeClass(control, "xforms-required-empty");
            }
        } else {
            ORBEON.util.Dom.removeClass(control, "xforms-required-filled");
            ORBEON.util.Dom.removeClass(control, "xforms-required-empty");
        }
    },

    hintActive: function(control, active) {
        var hintLabel = ORBEON.xforms.Events._findHint(control);
        if (hintLabel != null) {
            if (active) {
                // Disable previously active control
                if (ORBEON.xforms.Globals.activeControl != null)
                    ORBEON.xforms.Controls.hintActive(ORBEON.xforms.Globals.activeControl, false);
                ORBEON.xforms.Globals.activeControl = control;
                ORBEON.util.Dom.removeClass(hintLabel, "xforms-hint");
                ORBEON.util.Dom.addClass(hintLabel, "xforms-hint-active");
            } else {
                ORBEON.xforms.Globals.activeControl = null;
                ORBEON.util.Dom.addClass(hintLabel, "xforms-hint");
                ORBEON.util.Dom.removeClass(hintLabel, "xforms-hint-active");
            }
        }
    },

    autosizeTextarea: function(textarea) {
        var scrollHeight = textarea.scrollHeight;
        var clientHeight = textarea.clientHeight;
        var rowHeight = clientHeight / textarea.rows;
        var linesAdded = 0;

        if (scrollHeight > clientHeight) {
            // Grow
            while (scrollHeight > clientHeight) {
                textarea.rows = textarea.rows + 1;
                clientHeight = textarea.clientHeight;
                linesAdded++;

            }
        } else if (scrollHeight < clientHeight) {
            // Shrink
            while (textarea.rows > XFORMS_WIDE_TEXTAREA_MIN_ROWS && scrollHeight < clientHeight - rowHeight) {
                textarea.rows = textarea.rows - 1;
                clientHeight = textarea.clientHeight;
                linesAdded--;
            }
        }
    },

    updateHTMLAreaClasses: function(textarea) {
        var iframe = textarea.previousSibling;
        while (iframe.nodeType != ORBEON.util.Dom.ELEMENT_TYPE) iframe = textarea.previousSibling;
        iframe.className = textarea.className;
    },

    updateLoadingPosition: function(formIndex) {
        // Compute new X
        var x; {
            var initialRight = ORBEON.xforms.Globals.formLoadingLoadingInitialRightTop[formIndex][0];
            var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
            x = scrollX + YAHOO.util.Dom.getViewportWidth() - initialRight;
        }
        // Compute new Y
        var y; {
            // Distance between top of viewport and top of the page. Initially 0 when we are at the top of the page.
            var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
            var initialTop = ORBEON.xforms.Globals.formLoadingLoadingInitialRightTop[formIndex][1];
            y = scrollY + XFORMS_LOADING_MIN_TOP_PADDING > initialTop
                    // Place indicator at a few pixels from the top of the viewport
                    ? scrollY + XFORMS_LOADING_MIN_TOP_PADDING
                    // Loading is visible left at its initial position, so leave it there
                    : initialTop;
        }
        // Position overlay
        var overlay = ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex];
        overlay.cfg.setProperty("x", x);
        overlay.cfg.setProperty("y", y);
    }
};

ORBEON.xforms.Events = {

    /**
     * Look for a hint label that follows the control
     */
    _findHint: function(control) {
        var hintLabel = control;
        while (true) {
            hintLabel = hintLabel.nextSibling;
            // No, we can't found a hint label
            if (hintLabel == null) return null;
            // Yes, we found the hint label
            if (ORBEON.util.Dom.isElement(hintLabel)
                    && (ORBEON.util.Dom.hasClass(hintLabel, "xforms-hint")
                        || ORBEON.util.Dom.hasClass(hintLabel, "xforms-hint-active"))
                    && hintLabel.htmlFor == control.id)
                return hintLabel;
        }
    },

    /**
     * Look for the first parent control which is an XForms control
     */
    _findParentXFormsControl: function(element) {
        while (true) {
            if (!element) return null; // No more parent, stop search
            if (element.xformsElement) {
                // HTML area on Gecko: event target is the document, return the textarea
                return element.xformsElement;
            } else if (element.ownerDocument && element.ownerDocument.xformsElement) {
                // HTML area on IS: event target is the body of the document, return the textarea
                return element.ownerDocument.xformsElement;
            } else if (element.className != null) {
                if (ORBEON.util.Dom.hasClass(element, "xforms-control")
                        || ORBEON.util.Dom.hasClass(element, "xforms-help-image")
                        || ORBEON.util.Dom.hasClass(element, "xforms-alert")) {
                    // We found our XForms element
                    return element;
                }
            }
            // Go to parent and continue search
            element = element.parentNode;
        }
    },

    _keyCodeModifiesField: function(c) {
        return c != 9 && c != 13 && c != 16 && c != 17 && c != 18;
    },

    focus: function(event) {
        if (!ORBEON.xforms.Globals.maskFocusEvents) {
            var target = ORBEON.xforms.Events._findParentXFormsControl(YAHOO.util.Event.getTarget(event));
            if (target != null) {
                // Save id of the control that received blur last
                ORBEON.xforms.Globals.lastFocusControlId = target.id;
                // Activate hint if we found one
                ORBEON.xforms.Controls.hintActive(target, true);
                // Store initial value of control
                if (typeof ORBEON.xforms.Globals.serverValue[target.id] == "undefined")
                    ORBEON.xforms.Globals.serverValue[target.id] = target.value;
                // Send focus events
                var previousDOMFocusOut = ORBEON.xforms.Globals.previousDOMFocusOut;
                if (previousDOMFocusOut) {
                    if (previousDOMFocusOut != target) {
                        // HTML area and trees does not throw value change event, so we throw it on blur
                        if (ORBEON.util.Dom.hasClass(previousDOMFocusOut, "xforms-textarea")
                                && ORBEON.util.Dom.hasClass(previousDOMFocusOut, "xforms-mediatype-text-html")) {
                            // To-do: would be nice to use the ORBEON.xforms.Controls.getCurrentValue() so we don't dupplicate the code here
                            var editorInstance = FCKeditorAPI.GetInstance(previousDOMFocusOut.name);
                            previousDOMFocusOut.value = editorInstance.GetXHTML();
                            xformsValueChanged(previousDOMFocusOut, null);
                        } else if (ORBEON.util.Dom.hasClass(previousDOMFocusOut, "xforms-select1-appearance-xxforms-tree")
                                || ORBEON.util.Dom.hasClass(previousDOMFocusOut, "xforms-select-appearance-xxforms-tree")) {
                            xformsValueChanged(previousDOMFocusOut, null);
                        }
                        // Send focus out/focus in events
                        var events = new Array();
                        events.push(xformsCreateEventArray(previousDOMFocusOut, "DOMFocusOut", null));
                        events.push(xformsCreateEventArray(target, "DOMFocusIn", null));
                        xformsFireEvents(events, true);
                    }
                    ORBEON.xforms.Globals.previousDOMFocusOut = null;
                } else {
                    if (document.xformsPreviousDOMFocusIn != target) {
                        xformsFireEvents(new Array(xformsCreateEventArray(target, "DOMFocusIn", null)), true);
                    }
                }
            }
            document.xformsPreviousDOMFocusIn = target;
        } else {
            ORBEON.xforms.Globals.maskFocusEvents = false;
        }
    },

    blur: function(event) {
        if (!ORBEON.xforms.Globals.maskFocusEvents) {
            var target = ORBEON.xforms.Events._findParentXFormsControl(YAHOO.util.Event.getTarget(event));
            if (target != null) {
                // Save id of the control that received blur last
                ORBEON.xforms.Globals.lastBlurControlId = target.id;
                // De-activate hint if we found one
                ORBEON.xforms.Controls.hintActive(target, false);
                // This is an event for an XForms control
                ORBEON.xforms.Globals.previousDOMFocusOut = target;
            }
        }
    },

    change: function(event) {
        var target = ORBEON.xforms.Events._findParentXFormsControl(YAHOO.util.Event.getTarget(event));
        if (target != null) {
            if (ORBEON.util.Dom.hasClass(target, "xforms-upload")) {
                // For upload controls, generate an xforms-select event when a file is selected
                xformsFireEvents(new Array(xformsCreateEventArray(target, "xforms-select", "")), false);
            } else {
                // When we move out from a field, we don't receive the keyup events corresponding to keypress
                // for that field (go figure!). Se we reset here the count for keypress without keyup for that field.
                if (ORBEON.xforms.Globals.changedIdsRequest[target.id] != null)
                    ORBEON.xforms.Globals.changedIdsRequest[target.id] = 0;

                // For select1 list, make sure we have exactly one value selected
                if (ORBEON.util.Dom.hasClass(target, "xforms-select1-appearance-compact")) {
                    if (target.value == "") {
                        // Stop end-user from deselecting last selected value
                        target.options[0].selected = true;
                        //target.value = target.options[0].value;
                    } else {
                        // Unselect options other than the first one
                        var foundSelected = false;
                        for (var optionIndex = 0; optionIndex < target.options.length; optionIndex++) {
                            var option = target.options[optionIndex];
                            if (option.selected) {
                                if (foundSelected) option.selected = false;
                                else foundSelected = true;
                            }
                        }
                    }
                }

                // Fire change event
                xformsFireEvents([xformsCreateEventArray(target, "xxforms-value-change-with-focus-change",
                    ORBEON.xforms.Controls.getCurrentValue(target))], false);
            }
        }
    },

    keydown: function(event) {
        var target = ORBEON.xforms.Events._findParentXFormsControl(YAHOO.util.Event.getTarget(event));
        if (target != null) {
            // Remember that the user is editing this field, so don't overwrite when we receive an event from the server
            // Ignore some key codes that won't modify the value of the field
            if (ORBEON.xforms.Events._keyCodeModifiesField(event.keyCode))
                ORBEON.xforms.Globals.changedIdsRequest[target.id] =
                    ORBEON.xforms.Globals.changedIdsRequest[target.id] == null ? 1
                    : ORBEON.xforms.Globals.changedIdsRequest[target.id] + 1;
        }
    },

    keypress: function(event) {
        var target = ORBEON.xforms.Events._findParentXFormsControl(YAHOO.util.Event.getTarget(event));
        if (target != null) {
            // Input field and auto-complete: trigger DOMActive when when enter is pressed
            if (ORBEON.util.Dom.hasClass(target, "xforms-select1-open")
                    || ORBEON.util.Dom.hasClass(target, "xforms-input")
                    || ORBEON.util.Dom.hasClass(target, "xforms-secret")) {
                if (event.keyCode == 10 || event.keyCode == 13) {
                    // Prevent default handling of enter, which might be equivalent as a click on some trigger in the form
                    YAHOO.util.Event.preventDefault(event);
                    // Send a value change and DOM activate
                    var events = [
                        xformsCreateEventArray(target, "xxforms-value-change-with-focus-change",
                            ORBEON.xforms.Controls.getCurrentValue(target)),
                        xformsCreateEventArray(target, "DOMActivate", null)
                    ];
                    xformsFireEvents(events, false);
                }
            }
        }
    },

    keyup: function(event) {
        var target = ORBEON.xforms.Events._findParentXFormsControl(YAHOO.util.Event.getTarget(event));
        if (target != null) {
            // Save keycode
            if (ORBEON.util.Dom.hasClass(target, "xforms-select1-open"))
                ORBEON.xforms.Globals.autoCompleteLastKeyCode[target.id] = event.keyCode;
            // Remember we have received the keyup for this element
            if (ORBEON.xforms.Events._keyCodeModifiesField(event.keyCode))
                ORBEON.xforms.Globals.changedIdsRequest[target.id]--;
            // Incremental control: treat keypress as a value change event
            if (ORBEON.util.Dom.hasClass(target, "xforms-incremental")) {
                xformsFireEvents([xformsCreateEventArray(target, "xxforms-value-change-with-focus-change",
                    ORBEON.xforms.Controls.getCurrentValue(target))], true);
            }

            // If value is required, add/remove xforms-required-empty appropriately
            ORBEON.xforms.Controls.updateRequiredEmpty(target);

            // Resize wide text area
            if (ORBEON.util.Dom.hasClass(target, "xforms-textarea-appearance-xxforms-autosize")) {
                ORBEON.xforms.Controls.autosizeTextarea(target);
            }
        }
    },

    resize: function(event) {
        for (var i = 0; i < ORBEON.xforms.Globals.autosizeTextareas.length; i++) {
            var textarea = ORBEON.xforms.Globals.autosizeTextareas[i];
            ORBEON.xforms.Controls.autosizeTextarea(textarea);
        }
    },


    _showToolTip: function(event, label, type, message) {
        // Initialize tooltip library
        if (!ORBEON.xforms.Globals.tooltipLibraryInitialized) {
            ORBEON.xforms.Globals.tooltipLibraryInitialized = true;
            tt_init();
        }

        // Figure out if we need to create a div
        // When there is an existing div, check if it has the same message
        var needToCreateDiv;
        var tooltipDivId = label.htmlFor + "-" + type;
        var existingDiv = ORBEON.util.Dom.getElementById(tooltipDivId);
        if (existingDiv != null) {
            if (existingDiv.message == message) {
                needToCreateDiv = false;
            } else {
                needToCreateDiv = true;
                existingDiv.parentNode.removeChild(existingDiv);
            }
        } else {
            needToCreateDiv = true;
        }

        // Create new div when necessary
        if (needToCreateDiv) {
            var divHTML = tt_Htm(this, tooltipDivId, message);
            var container = document.createElement("DIV");
            container.innerHTML = divHTML;
            var newDiv = container.firstChild;
            newDiv.message = message;
            document.body.appendChild(newDiv);
        }

        // Show the help div
        tt_Show(event, tooltipDivId, false, 0, false, false,
            ttOffsetX, ttOffsetY, false, false, ttTemp);
    },

    mouseover: function(event) {
        var target = ORBEON.xforms.Events._findParentXFormsControl(YAHOO.util.Event.getTarget(event));
        if (target != null) {

            if (ORBEON.util.Dom.hasClass(target, "xforms-help-image")) {
                // Show help tool-tip
                var label = target.nextSibling;
                while (!ORBEON.util.Dom.isElement(label)) label = target.nextSibling;
                var control = ORBEON.util.Dom.getElementById(label.htmlFor);
                ORBEON.xforms.Events._showToolTip(event, label, "xforms-help", ORBEON.xforms.Controls.getHelpMessage(control));
            } else if (ORBEON.util.Dom.hasClass(target, "xforms-alert-active")) {
                var control = ORBEON.util.Dom.getElementById(target.htmlFor);
                var message = ORBEON.xforms.Controls.getAlertMessage(control);
                if (message != "") {
                    // Show alert tool-tip
                    ORBEON.xforms.Events._showToolTip(event, target, "xforms-alert", ORBEON.xforms.Controls.getAlertMessage(control));
                }
            }
        }
    },

    mouseout: function(event) {
        var target = ORBEON.xforms.Events._findParentXFormsControl(YAHOO.util.Event.getTarget(event));
        if (target != null) {

            // Hide help
            if (ORBEON.util.Dom.hasClass(target, "xforms-help-image")
                    || ORBEON.util.Dom.hasClass(target, "xforms-alert-active"))
                tt_Hide();
        }
    },

    click: function(event) {
        var originalTarget = YAHOO.util.Event.getTarget(event);
        var target = ORBEON.xforms.Events._findParentXFormsControl(originalTarget);
        if (target != null) {
            // Activate hint
            ORBEON.xforms.Controls.hintActive(target, true);

            // Click on output
            if (ORBEON.util.Dom.hasClass(target, "xforms-output")) {
                xformsFireEvents([xformsCreateEventArray(target, "DOMFocusIn", null)], false);
            }

            // Click on trigger
            if ((ORBEON.util.Dom.hasClass(target, "xforms-trigger") || ORBEON.util.Dom.hasClass(target, "xforms-submit"))) {
                YAHOO.util.Event.preventDefault(event);
                if (!ORBEON.util.Dom.hasClass(target, "xforms-readonly")) {
                    // If this is an anchor and we didn't get a chance to register the focus event,
                    // send the focus event here. This is useful for anchors (we don't listen on the
                    // focus event on those, and for buttons on Safari which does not dispatch the focus
                    // event for buttons.
                    ORBEON.xforms.Events.focus(event);
                    xformsFireEvents([xformsCreateEventArray(target, "DOMActivate", null)], false);
                }
            }

            // Click on checkbox or radio button
            if (ORBEON.util.Dom.hasClass(target, "xforms-select1-appearance-full")
                    || ORBEON.util.Dom.hasClass(target, "xforms-select-appearance-full")) {
                xformsFireEvents(new Array(xformsCreateEventArray
                        (target, "xxforms-value-change-with-focus-change",
                                ORBEON.xforms.Controls.getCurrentValue(target), null)), false);
            }

            // Click on calendar inside input field
            if (ORBEON.util.Dom.hasClass(target, "xforms-input")) {

                // Initialize calendar when needed
                var displayField = ORBEON.util.Dom.getChildElementByIndex(target, 0);
                var inputField = ORBEON.util.Dom.getChildElementByIndex(target, 1);
                var showCalendar = ORBEON.util.Dom.getChildElementByIndex(target, 2);
                if (ORBEON.util.Dom.hasClass(inputField, "xforms-type-date")
                        && !ORBEON.util.Dom.hasClass(displayField, "xforms-readonly")) {

                    // Setup calendar library if not done already
                    if (!ORBEON.xforms.Globals.inputCalendarCreated[target.id]) {
                        Calendar.setup({
                            inputField     :    inputField.id,
                            ifFormat       :    "%Y-%m-%d",
                            showsTime      :    false,
                            button         :    target.id,
                            singleClick    :    true,
                            step           :    1,
                            onUpdate       :    ORBEON.xforms.Events.calendarUpdate,
                            onClose        :    ORBEON.xforms.Events.calendarClose,
                            electric       :    true
                        });
                        // JSCalendar sets his listener in the onclick attribute: save it so we can call it later
                        ORBEON.xforms.Globals.inputCalendarOnclick[target.id] = target.onclick;
                        target.onclick = null;
                        ORBEON.xforms.Globals.inputCalendarCreated[target.id] = true;
                        // Save initial value
                        ORBEON.xforms.Globals.inputCalendarCommitedValue[target.id] = ORBEON.xforms.Controls.getCurrentValue(target);
                    }

                    // Event can be received on calendar picker span, or on the containing span
                    ORBEON.xforms.Globals.inputCalendarOnclick[target.id]();
                }
            }

            // Click on remove icon in upload control
            if (ORBEON.util.Dom.hasClass(target, "xforms-upload") && ORBEON.util.Dom.hasClass(originalTarget, "xforms-upload-remove")) {
                xformsFireEvents(new Array(xformsCreateEventArray(target, "xxforms-value-change-with-focus-change", "")), false);
            }

            // Click on menu item
            if (ORBEON.util.Dom.hasClass(target, "xforms-select1-appearance-xxforms-menu")) {

                // Find what is the position in the hiearchy of the item
                var positions = [];
                var currentParent = originalTarget;
                while (true) {
                    if (currentParent.tagName.toLowerCase() == "li") {
                        // Get the position of this li, and add it to positions
                        var liPosition = 0;
                        while (true) {
                            var previousSibling = currentParent.previousSibling;
                            if (previousSibling == null) break;
                            currentParent = previousSibling;
                            if (currentParent.nodeType == ELEMENT_TYPE && currentParent.tagName.toLowerCase() == "li") liPosition++;
                        }
                        positions.push(liPosition);
                    } else if (currentParent.tagName.toLowerCase() == "div" && ORBEON.util.Dom.hasClass(currentParent, "yuimenubar")) {
                        // Got to the top of the tree
                        break;
                    }
                    currentParent = currentParent.parentNode;
                }
                positions = positions.reverse();

                // Find value for this item
                var currentLevel = ORBEON.xforms.Globals.menuItemsets[target.id];
                var increment = 0;
                for (var positionIndex = 0; positionIndex < positions.length; positionIndex++) {
                    var position = positions[positionIndex];
                    currentLevel = currentLevel[position + increment];
                    increment = 3;
                }

                // Send value change to server
                var itemValue = currentLevel[1];
                xformsFireEvents(new Array(xformsCreateEventArray(target, "xxforms-value-change-with-focus-change", itemValue)), false);
                // Close the menu
                ORBEON.xforms.Globals.menuYui[target.id].clearActiveItem();
            }
        }
    },

    /**
     * Upon scrolling or resizing, adjust position of loading indicators
     */
    scrollOrResize: function() {
        for (var formIndex = 0; formIndex < ORBEON.xforms.Globals.formLoadingLoadingOverlay.length; formIndex++) {
            var overlay = ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex];
            if (overlay && overlay.cfg.getProperty("visible"))
                ORBEON.xforms.Controls.updateLoadingPosition(formIndex);
        }
    },

    /**
     * Send notification to XForms engine end-user clicked on day.
     */
    calendarUpdate: function(calendar) {
        if (ORBEON.util.Dom.hasClass(calendar.activeDiv, "day")) {
            var inputField = calendar.params.inputField;
            var element = inputField.parentNode;
            var newValue = ORBEON.xforms.Controls.getCurrentValue(element);
            ORBEON.xforms.Globals.inputCalendarCommitedValue[element.id] = newValue;
            xformsFireEvents([xformsCreateEventArray(element, "xxforms-value-change-with-focus-change", newValue)], false);
        }
    },

    /**
     * Restore last value actualy selected by user in the input field, which at this point could
     * contain a value the user just browsed to, without selecting it.
     */
    calendarClose: function(calendar) {
        var inputField = calendar.params.inputField;
        var element = inputField.parentNode;
        inputField.value = ORBEON.xforms.Globals.inputCalendarCommitedValue[element.id];
        calendar.hide();
    },

    sliderValueChange: function (offset) {
        // Notify server that value changed
        var rangeControl = ORBEON.util.Dom.getElementById(this.id);
        rangeControl.value = offset / 200;
        xformsValueChanged(rangeControl, null);
    },

    /**
     * Called by the YUI menu library when a click happens a menu entry.
     */
    menuClick: function(eventType, arguments, userObject) {
        var menu = userObject["menu"];
        var value = userObject["value"];
        xformsFireEvents([xformsCreateEventArray(menu, "xxforms-value-change-with-focus-change", value)], false);
    },

    /**
     * Event listener on dialogs called by YUI when the dialog is closed. If the dialog was closed by the user (not
     * because the server told use to close the dialog), then we want to notify the server that this happened.
     */
    dialogClose: function(type, args, me) {
        var dialogId = me;
        var dialog = ORBEON.util.Dom.getElementById(dialogId);
        xformsFireEvents([xformsCreateEventArray(dialog, "xxforms-dialog-close")], false);
    },

    /**
     * xforms:select tree: handle click on check box
     */
    treeCheckClick: function() {
        var tree = this.tree;
        var control = ORBEON.util.Dom.getElementById(tree.id);
        control.value = "";
        for (nodeIndex in tree._nodes) {
            var node = tree._nodes[nodeIndex];
            if (node.checked) {
                if (control.value != "") control.value += " ";
                control.value += node.data.value;
            }
        }
        // Always do this, as we can't detect yet focus/blur events on trees
        //if (ORBEON.util.Dom.hasClass(control, "xforms-incremental"))
            xformsValueChanged(control);
    },

    /**
     * xforms:select tree: handle click on label
     */
    treeSelectSelect: function(id, value) {
        var control = ORBEON.util.Dom.getElementById(id);
        var yuiTree = ORBEON.xforms.Globals.treeYui[control.id];
        var yuiNode = yuiTree.getNodeByProperty("value", value);

        // If checked uncheck, if unchecked check
        if (yuiNode.checked) {
            yuiNode.uncheck();
        } else {
            yuiNode.check();
        }

        // Call listener on check event
        yuiNode.onCheckClick();
    },

    /**
     * xforms:select1 tree: handle click on label
     */
    treeSelect1Select: function(id, value) {
        var control = ORBEON.util.Dom.getElementById(id);
        control.value = value;
        // Always do this, as we can't detect yet focus/blur events on trees
        //if (ORBEON.util.Dom.hasClass(control, "xforms-incremental"))
            xformsValueChanged(control);
    }
};

ORBEON.xforms.Init = {

    /**
     * Functions used to initialize special controls
     */
    _specialControlsInitFunctions: null,
    _getSpecialControlsInitFunctions: function () {
        ORBEON.xforms.Init._specialControlsInitFunctions = ORBEON.xforms.Init._specialControlsInitFunctions || {
            "select1": {
                "compact" : ORBEON.xforms.Init._list,
                "{http://orbeon.org/oxf/xml/xforms}autocomplete": ORBEON.xforms.Init._autoComplete,
                "{http://orbeon.org/oxf/xml/xforms}menu": ORBEON.xforms.Init._menu,
                "{http://orbeon.org/oxf/xml/xforms}tree": ORBEON.xforms.Init._tree
            },
            "select": {
                "compact" : ORBEON.xforms.Init._list,
                "{http://orbeon.org/oxf/xml/xforms}tree": ORBEON.xforms.Init._tree
            },
            "range": { "": ORBEON.xforms.Init._range },
            "textarea": {
                "{http://orbeon.org/oxf/xml/xforms}autosize": ORBEON.xforms.Init._widetextArea,
                "text/html": ORBEON.xforms.Init._htmlArea
            },
            "dialog": { "": ORBEON.xforms.Init._dialog}
        };
        return ORBEON.xforms.Init._specialControlsInitFunctions;
    },

    _registerListerersOnFormElements: function() {
        for (var i = 0; i < document.forms.length; i++) {
            var form = document.forms[i];
            if (ORBEON.util.Dom.hasClass(form, "xforms-form")) {
                for (var j = 0; j < form.elements.length; j++) {
                    var element = form.elements[j];
                    YAHOO.util.Event.addListener(element, "focus", ORBEON.xforms.Events.focus);
                    YAHOO.util.Event.addListener(element, "blur", ORBEON.xforms.Events.blur);
                    YAHOO.util.Event.addListener(element, "change", ORBEON.xforms.Events.change);
                }
            }
        }
    },

    document: function() {

        // Register events in the capture phase for W3C-compliant browsers.
        // Avoid Safari 1.3 which is buggy.
        if (window.addEventListener && !ORBEON.xforms.Globals.isRenderingEngineWebCore13) {
            window.addEventListener("focus", ORBEON.xforms.Events.focus, true);
            window.addEventListener("blur", ORBEON.xforms.Events.blur, true);
            window.addEventListener("change", ORBEON.xforms.Events.change, true);
        } else {
            ORBEON.xforms.Init._registerListerersOnFormElements();
        }


        // Register events that bubble on document for all browsers
        YAHOO.util.Event.addListener(document, "keypress", ORBEON.xforms.Events.keypress);
        YAHOO.util.Event.addListener(document, "keydown", ORBEON.xforms.Events.keydown);
        YAHOO.util.Event.addListener(document, "keyup", ORBEON.xforms.Events.keyup);
        YAHOO.util.Event.addListener(document, "mouseover", ORBEON.xforms.Events.mouseover);
        YAHOO.util.Event.addListener(document, "mouseout", ORBEON.xforms.Events.mouseout);
        YAHOO.util.Event.addListener(document, "click", ORBEON.xforms.Events.click);
        YAHOO.util.Event.addListener(window, "resize", ORBEON.xforms.Events.resize);
        YAHOO.widget.Overlay.windowScrollEvent.subscribe(ORBEON.xforms.Events.scrollOrResize);
        YAHOO.widget.Overlay.windowResizeEvent.subscribe(ORBEON.xforms.Events.scrollOrResize);

        // Initialize XForms server URL
        if (!(window.opsXFormsServerBase === undefined)) {
            BASE_URL = window.opsXFormsServerBase;
            XFORMS_SERVER_URL = BASE_URL + "/xforms-server";
        }

        // Override image location for YUI to use local images
        var yuiBaseURL = BASE_URL + "/ops/images/yui/";
        if (YAHOO && YAHOO.widget) {
            if (YAHOO.widget.Module) {
                YAHOO.widget.Module.IMG_ROOT = yuiBaseURL;
                YAHOO.widget.Module.IMG_ROOT_SSL = yuiBaseURL;
            }
            if (YAHOO.widget.Calendar_Core) {
                YAHOO.widget.Calendar_Core.IMG_ROOT = yuiBaseURL;
                YAHOO.widget.Calendar_Core.IMG_ROOT_SSL = yuiBaseURL;
            }
            if (YAHOO.widget.MenuModuleItem) {
                YAHOO.widget.MenuModuleItem.prototype.IMG_ROOT = yuiBaseURL;
                YAHOO.widget.MenuModuleItem.prototype.IMG_ROOT_SSL = yuiBaseURL;
            }
        }

        // Initialize special controls
        if (!(window.opsXFormsControls === undefined)) {
            var initFunctions = ORBEON.xforms.Init._getSpecialControlsInitFunctions();
            // Iterate over controls
            for (var controlType in window.opsXFormsControls["controls"]) {
                if (initFunctions[controlType]) {
                    var controlAppearances = window.opsXFormsControls["controls"][controlType];
                    // Iterate over appearance for current control
                    for (var controlAppearance in controlAppearances) {
                        var initFunction = initFunctions[controlType][controlAppearance];
                        if (initFunction) {
                            var controlIds = controlAppearances[controlAppearance];
                            // Iterate over controls
                            for (var controlIndex = 0; controlIndex < controlIds.length; controlIndex++) {
                                var control = ORBEON.util.Dom.getElementById(controlIds[controlIndex]);
                                initFunction(control);
                            }
                        }
                    }
                }
            }
        }

        // Initialize attributes on form
        for (var formIndex = 0; formIndex < document.forms.length; formIndex++) {
            var form = document.forms[formIndex];
            // If this is an XForms form, procede with initialization
            if (ORBEON.util.Dom.hasClass(form, "xforms-form")) {

                // Initialize loading and error indicator
                ORBEON.xforms.Globals.formLoadingError[formIndex] = null;
                ORBEON.xforms.Globals.formLoadingNone[formIndex] = null;

                var xformsLoadingCount = 0;
                for (var formChildIndex = 0; formChildIndex < form.childNodes.length; formChildIndex++) {
                    if (xformsLoadingCount == 3) break;
                    var formChild = form.childNodes[formChildIndex];
                    if (formChild.className == "xforms-loading-loading") {
                        formChild.style.display = "block";
                        ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex] = new YAHOO.widget.Overlay(formChild);
                        ORBEON.xforms.Globals.formLoadingLoadingInitialRightTop[formIndex] = [
                            YAHOO.util.Dom.getViewportWidth() - YAHOO.util.Dom.getX(formChild),
                            YAHOO.util.Dom.getY(formChild)
                        ];
                        formChild.style.right = "auto";
                        ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex].cfg.setProperty("visible", false);
                        xformsLoadingCount++;
                        continue;
                    }
                    if (formChild.className == "xforms-loading-error") {
                        ORBEON.xforms.Globals.formLoadingError[formIndex] = formChild;
                        xformsLoadingCount++;
                        continue;
                    }
                    if (formChild.className == "xforms-loading-none") {
                        ORBEON.xforms.Globals.formLoadingNone[formIndex] = formChild;
                        xformsLoadingCount++;
                        continue;
                    }
                }

                var elements = form.elements;
                var xformsRepeatTree;
                var xformsRepeatIndices;
                for (var elementIndex = 0; elementIndex < elements.length; elementIndex++) {
                    var element = elements[elementIndex];
                    if (element.name.indexOf("$static-state") != -1) {
                        ORBEON.xforms.Globals.formStaticState[formIndex] = element;
                    } else if (element.name.indexOf("$dynamic-state") != -1) {
                        ORBEON.xforms.Globals.formDynamicState[formIndex] = element;
                    } else if (element.name.indexOf("$server-events") != -1) {
                        ORBEON.xforms.Globals.formServerEvents[formIndex] = element;
                    } else if (element.name.indexOf("$client-state") != -1) {
                        ORBEON.xforms.Globals.formClientState[formIndex] = element;
                        if (element.value == "")
                            xformsStoreInClientState(formIndex, "ajax-dynamic-state",
                                    ORBEON.xforms.Globals.formDynamicState[formIndex].value);
                    } else if (element.name.indexOf("$repeat-tree") != -1) {
                        xformsRepeatTree = element;
                    } else if (element.name.indexOf("$repeat-indexes") != -1) {
                        xformsRepeatIndices = element;
                        // This is the last input field we are interested in
                        break;
                    }
                }

                // Parse and store initial repeat hierarchy
                var repeatTreeString = xformsRepeatTree.value;
                var repeatTree = repeatTreeString.split(",");
                for (var repeatIndex = 0; repeatIndex < repeatTree.length; repeatIndex++) {
                    var repeatInfo = repeatTree[repeatIndex].split(" ");
                    var id = repeatInfo[0];
                    var parent = repeatInfo.length > 1 ? repeatInfo[repeatInfo.length - 1] : null;
                    ORBEON.xforms.Globals.repeatTreeChildToParent[id] = parent;
                }
                for (var child in ORBEON.xforms.Globals.repeatTreeChildToParent) {
                    var parent = ORBEON.xforms.Globals.repeatTreeChildToParent[child];
                    while (parent != null) {
                        if (!ORBEON.xforms.Globals.repeatTreeParentToAllChildren[parent])
                            ORBEON.xforms.Globals.repeatTreeParentToAllChildren[parent] = new Array();
                        ORBEON.xforms.Globals.repeatTreeParentToAllChildren[parent].push(child);
                        parent = ORBEON.xforms.Globals.repeatTreeChildToParent[parent];
                    }
                }

                // Parse and store initial repeat indexes
                var repeatIndexesString = xformsRepeatIndices.value;
                var repeatIndexes = repeatIndexesString.split(",");
                for (var repeatIndex = 0; repeatIndex < repeatIndexes.length; repeatIndex++) {
                    var repeatInfo = repeatIndexes[repeatIndex].split(" ");
                    var id = repeatInfo[0];
                    var index = repeatInfo[repeatInfo.length - 1];
                    ORBEON.xforms.Globals.repeatIndexes[id] = index;
                }

                // Ask server to resend events if this is not the first time load is called
                if (xformsGetFromClientState(formIndex, "load-did-run") == null) {
                    xformsStoreInClientState(formIndex, "load-did-run", "true");
                } else {
                    xformsFireEvents(new Array(xformsCreateEventArray(form, "xxforms-all-events-required", null, null)), false);
                }
            }
        }

        // Run code sent by server
        if (typeof xformsPageLoadedServer != "undefined" && !ORBEON.xforms.Globals.fckEditorLoading)
            xformsPageLoadedServer();
    },


    /**
     * Initialize a newly copied subtree.
     *
     * Some of the more advanced controls are initialized when the page first loads. The server sets the value of the
     * opsXFormsControls variable to tell the client the id of those controls and the type of each control. When new
     * controls are added, this function must be called so those the inserted advanced controls are initialized as
     * well.
     */
    insertedElement: function(element) {
        if (element.nodeType == ORBEON.util.Dom.ELEMENT_TYPE) {
            if (ORBEON.util.Dom.hasClass(element, "xforms-select1-appearance-xxforms-autocomplete")) {
                ORBEON.xforms.Init._autoComplete(element);
            }
            for (var childIndex = 0; childIndex < element.childNodes.length; childIndex++) {
                var child = element.childNodes[childIndex];
                if (child.nodeType == ORBEON.util.Dom.ELEMENT_TYPE)
                    ORBEON.xforms.Init.insertedElement(child);
            }
        }
    },

    _autoComplete: function(autoComplete) {
        var textfield = ORBEON.util.Dom.getChildElementByIndex(autoComplete, 0);
        var select = ORBEON.util.Dom.getChildElementByIndex(autoComplete, 1);
        // Get list of possible values from the select
        var values = new Array();
        for (var optionIndex = 1; optionIndex < select.options.length; optionIndex++)
            values.push(select.options[optionIndex].value);
        // Initialize auto-complete input
        var noFilter = ORBEON.util.Dom.hasClass(autoComplete, "xforms-select1-open-autocomplete-nofilter");
        ORBEON.xforms.Globals.autoCompleteOpen[autoComplete.id] = actb(textfield, values, noFilter);
    },

    _widetextArea: function(textarea) {
        ORBEON.xforms.Globals.autosizeTextareas.push(textarea);
        ORBEON.xforms.Controls.autosizeTextarea(textarea);
    },

    _range: function(range) {
        range.tabIndex = 0;
        range.previousValue = 0; // Will be modified once the initial value can be set
        var thumbDiv = range.firstChild;
        if (thumbDiv.nodeType != ELEMENT_TYPE) thumbDiv = thumbDiv.nextSibling;
        thumbDiv.id = range.id + XFORMS_SEPARATOR_1 + "thumb";
        var slider = YAHOO.widget.Slider.getHorizSlider(range.id, thumbDiv.id, 0, 200);
        slider.subscribe("change", ORBEON.xforms.Events.sliderValueChange);
    },

    _addToTree: function (tree, nameValueArray, treeNode, firstPosition) {
        for (var arrayIndex = firstPosition; arrayIndex < nameValueArray.length; arrayIndex++) {
            // Extract information from the first 3 position in the array
            var childArray = nameValueArray[arrayIndex];
            var name = childArray[0];
            var value = childArray[1];
            var selected = childArray[2];
            // Create node and add to tree
            var nodeInformation = { label: name, value: value, href: "javascript:ORBEON.xforms.Events.treeSelect"
                + (tree.xformsAllowMultipleSelection ? "" : 1)
                + "Select('"
                + tree.id + "', '"
                + value.replace(XFORMS_REGEXP_SINGLE_QUOTE, "\\'")
                + "')" };
            var childNode;
            if (tree.xformsAllowMultipleSelection) {
                childNode = new YAHOO.widget.TaskNode(nodeInformation, treeNode, false);
                childNode.onCheckClick = ORBEON.xforms.Events.treeCheckClick;
                if (selected) childNode.check();
            } else {
                childNode = new YAHOO.widget.TextNode(nodeInformation, treeNode, false);
            }
            ORBEON.xforms.Init._addToTree(tree, childArray, childNode, 3);
            // Add this value to the list if selected
            if (selected) {
                if (tree.value != "") tree.value += " ";
                tree.value += value;
            }
        }
    },

    _tree: function(tree) {

        // Save in the control if it allows multiple selection
        tree.xformsAllowMultipleSelection = ORBEON.util.Dom.hasClass(tree, "xforms-select");
        // Parse data put by the server in the div
        var treeString = ORBEON.util.Dom.getStringValue(tree);
        treeString = ORBEON.util.String.replace(treeString, "\n", " ");
        treeString = ORBEON.util.String.replace(treeString, "\r", " ");
        var treeArray = eval(treeString);
        ORBEON.util.Dom.setStringValue(tree, "");
        tree.value = "";
        // Create, populate, and show the tree
        var yuiTree = new YAHOO.widget.TreeView(tree.id);
        ORBEON.xforms.Globals.treeYui[tree.id] = yuiTree;
        var treeRoot = yuiTree.getRoot();
        ORBEON.xforms.Init._addToTree(tree, treeArray, treeRoot, 0);
        // Make selected nodes visible
        var values = tree.xformsAllowMultipleSelection ? tree.value.split(" ") : [ tree.value ];
        for (nodeIndex in yuiTree._nodes) {
            var node = yuiTree._nodes[nodeIndex];
            if (xformsArrayContains(values, node.data.value)) {
                var nodeParent = node.parent;
                while (nodeParent != null) {
                    nodeParent.expand();
                    nodeParent = nodeParent.parent;
                }
            }
        }
        // Save value in tree
        tree.previousValue = tree.value;
        yuiTree.draw();
        ORBEON.util.Dom.removeClass(tree, "xforms-initially-hidden");
    },

    /**
     * Create a sub-menu attached to the given menu item. In the nameValueArray we
     * ignore the first 3 items that correspond to the menuItem.
     */
    _addToMenuItem: function (menu, nameValueArray, menuItem) {
        // Assign id to menu item
        if (menuItem.element.id == "")
            YAHOO.util.Dom.generateId(menuItem.element);
        // Handle click on menu item
        menuItem.clickEvent.subscribe(ORBEON.xforms.Events.menuClick,
            {"menu": menu, "value": nameValueArray[1]});
        // Create sub-menu if necessary
        if (nameValueArray.length > 3) {
            // Create submenu
            var subMenu = new YAHOO.widget.Menu(menuItem.element.id + "menu");
            // Add menu items to submenu
            for (var arrayIndex = 3; arrayIndex < nameValueArray.length; arrayIndex++) {
                // Extract information from the first 3 position in the array
                var childArray = nameValueArray[arrayIndex];
                var name = childArray[0];
                var value = childArray[1];
                var selected = childArray[2];
                // Create menu item and add to menu
                var subMenuItem = new YAHOO.widget.MenuItem(name);
                subMenu.addItem(subMenuItem);
                // Add sub-sub menu
                ORBEON.xforms.Init._addToMenuItem(menu, childArray, subMenuItem)
            }
            menuItem.cfg.setProperty("submenu", subMenu);
        }
    },

    _menu: function (menu) {
        // Find the divs for the YUI menu and for the values inside the control
        var yuiMenuDiv;
        var valuesDiv;
        for (var j = 0; j < menu.childNodes.length; j++) {
            var childNode =  menu.childNodes[j];
            if (childNode.nodeType == ELEMENT_TYPE) {
                if (ORBEON.util.Dom.hasClass(childNode, "yuimenubar")) {
                    yuiMenuDiv = childNode;
                } else if (ORBEON.util.Dom.hasClass(childNode, "xforms-initially-hidden")) {
                    valuesDiv = childNode;
                }
            }
        }

        // Extract menu hierarchy from HTML
        var menuString = ORBEON.util.Dom.getStringValue(valuesDiv);
        menuString = ORBEON.util.String.replace(menuString, "\n", " ");
        menuString = ORBEON.util.String.replace(menuString, "\r", " ");
        ORBEON.xforms.Globals.menuItemsets[menu.id] = eval(menuString);

        // Initialize tree
        YAHOO.util.Dom.generateId(yuiMenuDiv);
        var yuiMenu = new YAHOO.widget.MenuBar(yuiMenuDiv.id, {
            autosubmenudisplay: true,
            hidedelay: 750,
            lazyload: true
        });
        yuiMenu.render();
        ORBEON.xforms.Globals.menuYui[menu.id] = yuiMenu;
    },

    /**
     * Initialize HTML areas.
     */
    _htmlArea: function (htmlArea) {
        var fckEditor = new FCKeditor(htmlArea.name);
        if (!xformsArrayContains(ORBEON.xforms.Globals.htmlAreaNames, htmlArea.name))
            ORBEON.xforms.Globals.htmlAreaNames.push(htmlArea.name);
        fckEditor.BasePath = BASE_URL + "/ops/fckeditor/";
        fckEditor.ToolbarSet = "OPS";

        // Change the language of the FCK Editor for its spellchecker, based on the USER_LANGUAGE variable
        var type_check = typeof USER_LANGUAGE;
        if (type_check != 'undefined') {
	        fckEditor.Config["AutoDetectLanguage"] = false;
    	    fckEditor.Config["DefaultLanguage"] = (USER_LANGUAGE != '') ? USER_LANGUAGE : 'en';
    	}
        // Change the path to a custom configuration, based on the FCK_CUSTOM_CONFIG variable
    	type_check = typeof FCK_CUSTOM_CONFIG;
    	if (type_check != 'undefined')
    		fckEditor.Config["CustomConfigurationsPath"] = FCK_CUSTOM_CONFIG;

        if (ORBEON.xforms.Globals.fckEditorLoading) {
            ORBEON.xforms.Globals.fckEditorsToLoad.push(fckEditor);
        } else {
            ORBEON.xforms.Globals.fckEditorLoading = true;
            fckEditor.ReplaceTextarea();
            ORBEON.xforms.Controls.updateHTMLAreaClasses(ORBEON.util.Dom.getElementById(fckEditor.InstanceName));
        }
    },

    /**
     * For all the controls except list, we figure out the initial value of the control when
     * receiving the first focus event. For the lists on Firefox, the value has already changed
     * when we receive the focus event. So here we save the value for lists when the page loads.
     */
    _list: function(list) {
        var value = "";
        for (var i = 0; i < list.options.length; i++) {
            var option = list.options[i];
            if (option.selected) {
                if (value != "") value += " ";
                value += option.value;
            }
        }
        ORBEON.xforms.Globals.serverValue[list.id] = value;
    },

    /**
     * Initialize dialogs
     */
    _dialog: function(dialog) {
        var isModal = ORBEON.util.Dom.hasClass(dialog, "xforms-dialog-modal");
        var hasClose = ORBEON.util.Dom.hasClass(dialog, "xforms-dialog-close-true");
        var draggable = ORBEON.util.Dom.hasClass(dialog, "xforms-dialog-draggable-true");
        ORBEON.util.Dom.removeClass(dialog, "xforms-initially-hidden");
        yuiDialog = new YAHOO.widget.Dialog(dialog.id, {
            modal: isModal,
            close: hasClose,
            visible: false,
            draggable: draggable,
            fixedcenter: true,
            constraintoviewport: true,
            underlay: "shadow"
        });
        yuiDialog.beforeHideEvent.subscribe(ORBEON.xforms.Events.dialogClose, dialog.id);
        yuiDialog.render();
        ORBEON.xforms.Globals.dialogs[dialog.id] = yuiDialog;
    }
};

ORBEON.xforms.Server = {

    Event: function(form, targetId, otherId, value, eventName, bubbles, cancelable) {
        this.form = form;
        this.targetId = targetId;
        this.otherId = otherId;
        this.value = value;
        this.eventName = eventName;
        this.bubbles = bubbles;
        this.cancelable = cancelable;
    },

    /**
     * When an exception happens while we communicate with the server, we catch it and show an error in the UI.
     * This is to prevent the UI from becoming totally unusable after an error.
     */
    exceptionWhenTalkingToServer: function(e, formIndex) {
        ORBEON.util.Utils.logException("JavaScript error", e);
        if (e.message != "") {
            ORBEON.xforms.Globals.lastRequestIsError = true;
            var errorContainer = ORBEON.xforms.Globals.formLoadingError[formIndex];
            var errorMessage = "Error while processing response: " + e.message;
            ORBEON.util.Dom.setStringValue(errorContainer, errorMessage);
            xformsDisplayIndicator("error");
        }
    },

    fireEvents: function(events, incremental) {
        // Store the time of the first event to be sent in the queue
        var currentTime = new Date().getTime();
        if (ORBEON.xforms.Globals.eventQueue.length == 0)
            ORBEON.xforms.Globals.eventsFirstEventTime = currentTime;

        // Store events to fire
        for (var eventIndex = 0; eventIndex < events.length; eventIndex++) {
            ORBEON.xforms.Globals.eventQueue.push(events[eventIndex]);
        }

        // Fire them with a delay to give us a change to aggregate events together
        ORBEON.xforms.Globals.executeEventFunctionQueued++;
        if (incremental && !(currentTime - ORBEON.xforms.Globals.eventsFirstEventTime >
                XFORMS_DELAY_BEFORE_FORCE_INCREMENTAL_REQUEST_IN_MS)) {
            // After a delay (e.g. 500 ms), run executeNextRequest() and send queued events to server
            // if there are no other executeNextRequest() that have been added to the queue after this
            // request.
            window.setTimeout(function() { ORBEON.xforms.Server.executeNextRequest(false); },
                XFORMS_DELAY_BEFORE_INCREMENTAL_REQUEST_IN_MS);
        } else {
            // After a very short delay (e.g. 20 ms), run executeNextRequest() and force queued events
            // to be sent to the server, even if there are other executeNextRequest() queued.
            // The small delay is here so we don't send multiple requests to the server when the
            // browser gives us a sequence of events (e.g. focus out, change, focus in).
            window.setTimeout(function() { ORBEON.xforms.Server.executeNextRequest(true); },
                XFORMS_DELAY_BEFORE_ANY_REQUEST_IN_MS);
        }
        return false;
    },

    executeNextRequest: function(bypassRequestQueue) {
        bypassRequestQueue = typeof(bypassRequestQueue) == "boolean"  && bypassRequestQueue == true;

        ORBEON.xforms.Globals.executeEventFunctionQueued--;
        var executedRequest = false;
        if (!ORBEON.xforms.Globals.requestInProgress
                && ORBEON.xforms.Globals.eventQueue.length > 0
                && (bypassRequestQueue || ORBEON.xforms.Globals.executeEventFunctionQueued == 0)) {

            // Collapse value change for the same control
            {
                var seenControlValue = {};
                var newEvents = [];
                for (var eventIndex = ORBEON.xforms.Globals.eventQueue.length - 1; eventIndex >= 0; eventIndex--) {
                    // Extract information from event array
                    var event = ORBEON.xforms.Globals.eventQueue[eventIndex];
                    if (event.eventName == "xxforms-value-change-with-focus-change") {
                        // Don't send change value if there is already a change value for the same control
                        if (!seenControlValue[event.targetId] == true) {
                            seenControlValue[event.targetId] = true;
                            // Don't send change value if the server already knows about the value of this control
                            if (ORBEON.util.Dom.hasClass(ORBEON.util.Dom.getElementById(event.targetId), "xforms-upload") ||
                                (ORBEON.xforms.Globals.serverValue[event.targetId] != "undefined"
                                    && ORBEON.xforms.Globals.serverValue[event.targetId] != event.value)) {
                                ORBEON.xforms.Globals.serverValue[event.targetId] = event.value;
                                newEvents.unshift(event);
                            }
                        }
                    } else {
                        newEvents.unshift(event);
                    }
                }
                ORBEON.xforms.Globals.eventQueue = newEvents;
            }

            // Check again that we have events to send after collapsing
            if (ORBEON.xforms.Globals.eventQueue.length > 0) {

                // Save the form for this request
                ORBEON.xforms.Globals.requestForm = ORBEON.xforms.Globals.eventQueue[0].form;
                var formIndex = ORBEON.util.Dom.getFormIndex(ORBEON.xforms.Globals.requestForm);

                // Mark this as loading
                ORBEON.xforms.Globals.requestInProgress = true;
                if (XFORMS_DELAY_BEFORE_DISPLAY_LOADING_IN_MS == 0) xformsDisplayLoading();
                else window.setTimeout(xformsDisplayLoading, XFORMS_DELAY_BEFORE_DISPLAY_LOADING_IN_MS);

                // Remove from this list of ids that changed the id of controls for
                // which we have received the keyup corresponding to the keydown
                for (var id  in ORBEON.xforms.Globals.changedIdsRequest) {
                    if (ORBEON.xforms.Globals.changedIdsRequest[id] == 0)
                        ORBEON.xforms.Globals.changedIdsRequest[id] = null;
                }

                // Build request
                var requestDocumentString = "";

                // Add entity declaration for nbsp. We are adding this as this entity is generated by the FCK editor.
                requestDocumentString += '<!DOCTYPE xxforms:event-request [<!ENTITY nbsp "&#160;">]>\n';

                var indent = "    ";
                {
                    // Start request
                    requestDocumentString += '<xxforms:event-request xmlns:xxforms="http://orbeon.org/oxf/xml/xforms">\n';

                    // Add static state
                    requestDocumentString += indent;
                    requestDocumentString += '<xxforms:static-state>';
                    requestDocumentString += ORBEON.xforms.Globals.formStaticState[formIndex].value;
                    requestDocumentString += '</xxforms:static-state>\n';

                    // Add dynamic state (element is just created and will be filled just before we send the request)
                    requestDocumentString += indent;
                    requestDocumentString += '<xxforms:dynamic-state>';
                    requestDocumentString += xformsGetFromClientState(formIndex, "ajax-dynamic-state");
                    requestDocumentString += '</xxforms:dynamic-state>\n';

                    // Start action
                    requestDocumentString += indent;
                    requestDocumentString += '<xxforms:action>\n';

                    // Add events
                    var handledEvents = [];
                    for (var i = 0; i < ORBEON.xforms.Globals.eventQueue.length; i++) {
                        var event = ORBEON.xforms.Globals.eventQueue[i];

                        // Only handle this event if it is for the form we chose
                        if (ORBEON.xforms.Controls.getForm(event.form) == ORBEON.xforms.Globals.requestForm) {
                            // Create <xxforms:event> element
                            requestDocumentString += indent + indent;
                            requestDocumentString += '<xxforms:event';
                            requestDocumentString += ' name="' + event.eventName + '"';
                            if (event.targetId != null)
                                requestDocumentString += ' source-control-id="' + event.targetId + '"';
                            if (event.otherId != null)
                                requestDocumentString += ' other-control-id="' + event.otherId + '"';
                            requestDocumentString += '>';
                            if (event.value != null) {
                                // When the range is used we get an int here when the page is first loaded
                                if (typeof event.value == "string") {
                                    event.value = event.value.replace(XFORMS_REGEXP_AMPERSAND, "&amp;");
                                    event.value = event.value.replace(XFORMS_REGEXP_OPEN_ANGLE, "&lt;");
                                }
                                requestDocumentString += event.value;
                            }
                            requestDocumentString += '</xxforms:event>\n';
                            handledEvents.unshift(i);
                        }
                    }

                    // End action
                    requestDocumentString += indent;
                    requestDocumentString += '</xxforms:action>\n';

                    // End request
                    requestDocumentString += '</xxforms:event-request>';

                    // Remove events we have handled from event queue
                    for (var i = 0; i < handledEvents.length; i++)
                        ORBEON.xforms.Globals.eventQueue.splice(handledEvents[i], 1);
                }

                // Send request
                executedRequest = true;
                try {
                    YAHOO.util.Connect.setDefaultPostHeader(false);
                    YAHOO.util.Connect.initHeader("Content-Type", "application/xml");
                    var callback = {
                        success: ORBEON.xforms.Server.handleResponse,
                        failure: ORBEON.xforms.Server.handleFailure
                    }
                    YAHOO.util.Connect.asyncRequest("POST", XFORMS_SERVER_URL, callback, requestDocumentString);
                } catch (e) {
                    ORBEON.xforms.Globals.requestInProgress = false;
                    ORBEON.xforms.Server.exceptionWhenTalkingToServer(e, formIndex);
                }
            }
        }

        // Hide loading indicator if we have not started a new request (nothing more to run)
        // and there are not events in the queue. However make sure not to hide the error message
        // if the last XHR query returned an error.
        if (!executedRequest && ORBEON.xforms.Globals.eventQueue.length == 0
                && !ORBEON.xforms.Globals.lastRequestIsError)
            xformsDisplayIndicator("none");
    },

    handleFailure: function(o) {
        ORBEON.xforms.Globals.requestInProgress = false;
        var formIndex = ORBEON.util.Dom.getFormIndex(ORBEON.xforms.Globals.requestForm);
        ORBEON.xforms.Globals.lastRequestIsError = true;
        if (typeof console != "undefined") {
            ORBEON.util.Utils.logException("Communication failure", o);
        }
        var errorContainer = ORBEON.xforms.Globals.formLoadingError[formIndex];
        var errorMessage = "Error while processing response: " + (o.responseText !== undefined ? o.responseText : "");
        ORBEON.util.Dom.setStringValue(errorContainer, errorMessage);
        xformsDisplayIndicator("error");
    },

    handleUploadResponse: function(o) {
        // Clear all the upload fields (currently we submit all of them, but in the future, should clear only the ones that have been submitted)
        var uploadElements = YAHOO.util.Dom.getElementsByClassName("xforms-upload", "span");
        for (var uploadIndex = 0; uploadIndex < uploadElements.length; uploadIndex++) {
            var uploadElement = uploadElements[uploadIndex];
            if (ORBEON.util.Dom.hasClass(uploadElement, "xforms-upload-state-empty"))// this also excludes templates
                ORBEON.util.Dom.clearUploadControl(uploadElement);
        }

        ORBEON.xforms.Server.handleResponse(o);
    },

    handleResponse: function(o) {

        var formIndex = ORBEON.util.Dom.getFormIndex(ORBEON.xforms.Globals.requestForm);
        var responseXML = o.responseXML;
        if (!responseXML || (responseXML && responseXML.documentElement && responseXML.documentElement.tagName.toLowerCase() == "html")) {
            // The XML docucment does not come in o.responseXML: parse o.responseText.
            // This happens in particular when we get a response after a background upload.
            var xmlString = o.responseText.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
            responseXML = ORBEON.util.Dom.stringToDom(xmlString);
        }

        var errorMessage = null;
        try {
            if (responseXML && responseXML.documentElement
                    && responseXML.documentElement.tagName.indexOf("event-response") != -1) {

                // Good: we received an XML document from the server
                var responseRoot = responseXML.documentElement;
                var newDynamicState = null;

                // Whether this response has triggered a load which will replace the current page.
                var newDynamicStateTriggersReplace = false;

                for (var i = 0; i < responseRoot.childNodes.length; i++) {

                    // Update instances
                    if (xformsGetLocalName(responseRoot.childNodes[i]) == "dynamic-state")
                        newDynamicState = ORBEON.util.Dom.getStringValue(responseRoot.childNodes[i]);

                    if (xformsGetLocalName(responseRoot.childNodes[i]) == "action") {
                        var actionElement = responseRoot.childNodes[i];

                        // Firt repeat and delete "lines" in repeat (as itemset changed below might be in a new line)
                        for (var actionIndex = 0; actionIndex < actionElement.childNodes.length; actionIndex++) {
                            var actionName = xformsGetLocalName(actionElement.childNodes[actionIndex]);
                            switch (actionName) {

                                case "control-values": {
                                    var controlValuesElement = actionElement.childNodes[actionIndex];
                                    for (var j = 0; j < controlValuesElement.childNodes.length; j++) {
                                        var controlValueAction = xformsGetLocalName(controlValuesElement.childNodes[j]);
                                        switch (controlValueAction) {

                                            // Copy repeat template
                                            case "copy-repeat-template": {
                                                var copyRepeatTemplateElement = controlValuesElement.childNodes[j];
                                                var repeatId = ORBEON.util.Dom.getAttribute(copyRepeatTemplateElement, "id");
                                                var parentIndexes = ORBEON.util.Dom.getAttribute(copyRepeatTemplateElement, "parent-indexes");
                                                var idSuffix = ORBEON.util.Dom.getAttribute(copyRepeatTemplateElement, "id-suffix");
                                                // Put nodes of the template in an array
                                                var templateNodes = new Array();
                                                {
                                                    // Locate end of the repeat
                                                    var delimiterTagName = null;
                                                    var templateRepeatEnd = ORBEON.util.Dom.getElementById("repeat-end-" + repeatId);
                                                    var templateNode = templateRepeatEnd.previousSibling;
                                                    var nestedRepeatLevel = 0;
                                                    while (!(nestedRepeatLevel == 0 && templateNode.nodeType == ELEMENT_TYPE
                                                             && ORBEON.util.Dom.hasClass(templateNode, "xforms-repeat-delimiter"))) {
                                                        var nodeCopy = templateNode.cloneNode(true);
                                                        if (templateNode.nodeType == ELEMENT_TYPE) {
                                                            // Save tag name to be used for delimiter
                                                            delimiterTagName = templateNode.tagName;
                                                            // Decrement nestedRepeatLevel when we we exit a nested repeat
                                                            if (ORBEON.util.Dom.hasClass(templateNode, "xforms-repeat-begin-end") &&
                                                                    templateNode.id.indexOf("repeat-begin-") == 0)
                                                                nestedRepeatLevel--;
                                                            // Add suffix to all the ids
                                                            xformsAddSuffixToIds(nodeCopy, parentIndexes == "" ? idSuffix : parentIndexes + XFORMS_SEPARATOR_2 + idSuffix, nestedRepeatLevel);
                                                            // Increment nestedRepeatLevel when we enter a nested repeat
                                                            if (ORBEON.util.Dom.hasClass(templateNode, "xforms-repeat-begin-end") &&
                                                                    templateNode.id.indexOf("repeat-end-") == 0)
                                                                nestedRepeatLevel++;
                                                            // Remove "xforms-repeat-template" from classes on copy of element
                                                            var nodeCopyClasses = nodeCopy.className.split(" ");
                                                            var nodeCopyNewClasses = new Array();
                                                            for (var nodeCopyClassIndex = 0; nodeCopyClassIndex < nodeCopyClasses.length; nodeCopyClassIndex++) {
                                                                var currentClass = nodeCopyClasses[nodeCopyClassIndex];
                                                                if (currentClass != "xforms-repeat-template")
                                                                    nodeCopyNewClasses.push(currentClass);
                                                            }
                                                            nodeCopy.className = nodeCopyNewClasses.join(" ");
                                                        }
                                                        templateNodes.push(nodeCopy);
                                                        templateNode = templateNode.previousSibling;
                                                    }
                                                    // Add a delimiter
                                                    var newDelimiter = document.createElement(delimiterTagName);
                                                    newDelimiter.className = "xforms-repeat-delimiter";
                                                    templateNodes.push(newDelimiter);
                                                    // Reverse nodes as they were inserted in reverse order
                                                    templateNodes = templateNodes.reverse();
                                                }
                                                // Find element after insertion point
                                                var afterInsertionPoint;
                                                {
                                                    if (parentIndexes == "") {
                                                        // Top level repeat: contains a template
                                                        var repeatEnd = ORBEON.util.Dom.getElementById("repeat-end-" + repeatId);
                                                        var cursor = repeatEnd.previousSibling;
                                                        while (!(cursor.nodeType == ELEMENT_TYPE
                                                                && ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-delimiter")
                                                                && !ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-template"))) {
                                                            cursor = cursor.previousSibling;
                                                        }
                                                        afterInsertionPoint = cursor;
                                                        // Nested repeat: does not contain a template
                                                    } else {
                                                        var repeatEnd = ORBEON.util.Dom.getElementById("repeat-end-" + xformsAppendRepeatSuffix(repeatId, parentIndexes));
                                                        afterInsertionPoint = repeatEnd;
                                                    }
                                                }
                                                // Insert copy of template nodes
                                                for (var templateNodeIndex = 0; templateNodeIndex < templateNodes.length; templateNodeIndex++) {
                                                    templateNode = templateNodes[templateNodeIndex];
                                                    afterInsertionPoint.parentNode.insertBefore(templateNode, afterInsertionPoint);
                                                    ORBEON.xforms.Init.insertedElement(templateNode);
                                                }
                                                // Initialize newly added form elements
                                                if (ORBEON.xforms.Globals.isRenderingEngineWebCore13)
                                                    ORBEON.xforms.Init._registerListerersOnFormElements();
                                                break;
                                            }


                                            // Delete element in repeat
                                            case "delete-repeat-elements": {
                                                // Extract data from server response
                                                var deleteElementElement = controlValuesElement.childNodes[j];
                                                var deleteId = ORBEON.util.Dom.getAttribute(deleteElementElement, "id");
                                                var parentIndexes = ORBEON.util.Dom.getAttribute(deleteElementElement, "parent-indexes");
                                                var count = ORBEON.util.Dom.getAttribute(deleteElementElement, "count");
                                                // Find end of the repeat
                                                var repeatEnd = ORBEON.util.Dom.getElementById("repeat-end-" + xformsAppendRepeatSuffix(deleteId, parentIndexes));
                                                // Find last element to delete
                                                var lastElementToDelete;
                                                {
                                                    lastElementToDelete = repeatEnd.previousSibling;
                                                    if (parentIndexes == "") {
                                                        // Top-level repeat: need to go over template
                                                        while (true) {
                                                            // Look for delimiter that comes just before the template
                                                            if (lastElementToDelete.nodeType == ELEMENT_TYPE
                                                                    && ORBEON.util.Dom.hasClass(lastElementToDelete, "xforms-repeat-delimiter")
                                                                    && !ORBEON.util.Dom.hasClass(lastElementToDelete, "xforms-repeat-template"))
                                                                break;
                                                            lastElementToDelete = lastElementToDelete.previousSibling;
                                                        }
                                                        lastElementToDelete = lastElementToDelete.previousSibling;
                                                    }
                                                }
                                                // Perform delete
                                                for (var countIndex = 0; countIndex < count; countIndex++) {
                                                    var nestedRepeatLevel = 0;
                                                    while (true) {
                                                        var wasDelimiter = false;
                                                        if (lastElementToDelete.nodeType == ELEMENT_TYPE) {
                                                            if (ORBEON.util.Dom.hasClass(lastElementToDelete, "xforms-repeat-begin-end") &&
                                                                    lastElementToDelete.id.indexOf("repeat-end-") == 0) {
                                                                // Entering nested repeat
                                                                nestedRepeatLevel++;
                                                            } else if (ORBEON.util.Dom.hasClass(lastElementToDelete, "xforms-repeat-begin-end") &&
                                                                    lastElementToDelete.id.indexOf("repeat-begin-") == 0) {
                                                                // Exiting nested repeat
                                                                nestedRepeatLevel--;
                                                            } else {
                                                                wasDelimiter = nestedRepeatLevel == 0 &&
                                                                   ORBEON.util.Dom.hasClass(lastElementToDelete, "xforms-repeat-delimiter");
                                                            }
                                                        }
                                                        var previous = lastElementToDelete.previousSibling;
                                                        lastElementToDelete.parentNode.removeChild(lastElementToDelete);
                                                        lastElementToDelete = previous;
                                                        if (wasDelimiter) break;
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        // Second handle the <xxforms:itemsets> actions (we want to do this before we set the value of
                        // controls as the value of the select might be in the new values of the itemset).
                        for (var actionIndex = 0; actionIndex < actionElement.childNodes.length; actionIndex++) {
                            // Change values in an itemset
                            if (xformsGetLocalName(actionElement.childNodes[actionIndex]) == "itemsets") {
                                var itemsetsElement = actionElement.childNodes[actionIndex];
                                for (var j = 0; j < itemsetsElement.childNodes.length; j++) {
                                    if (xformsGetLocalName(itemsetsElement.childNodes[j]) == "itemset") {
                                        var itemsetElement = itemsetsElement.childNodes[j];
                                        var controlId = ORBEON.util.Dom.getAttribute(itemsetElement, "id");
                                        var documentElement = ORBEON.util.Dom.getElementById(controlId);
                                        var documentElementClasses = documentElement.className.split(" ");

                                        if (ORBEON.util.Dom.hasClass(documentElement, "xforms-select1-open")) {
                                            // Build list with new values
                                            var newValues = new Array();
                                            for (var k = 0; k < itemsetElement.childNodes.length; k++) {
                                                var itemElement = itemsetElement.childNodes[k];
                                                if (itemElement.nodeType == ELEMENT_TYPE)
                                                    newValues.push(ORBEON.util.Dom.getAttribute(itemElement, "value"));
                                            }

                                            // Case of the auto-complete control
                                            var textfield = ORBEON.util.Dom.getChildElementByIndex(documentElement, 0);
                                            textfield.actb_keywords = newValues;
                                            // Reopen auto-complete if necessary
                                            var lastKeyCode = ORBEON.xforms.Globals.autoCompleteLastKeyCode[documentElement.id];
                                            if (lastKeyCode != null)
                                                ORBEON.xforms.Globals.autoCompleteOpen[documentElement.id](lastKeyCode);
                                        } else if (documentElement.tagName == "SELECT") {

                                            // Case of list / combobox
                                            var options = documentElement.options;

                                            // Remember selected values
                                            var selectedValueCount = 0;
                                            var selectedValues = new Array();
                                            for (var k = 0; k < options.length; k++) {
                                                if (options[k].selected) {
                                                    selectedValues[selectedValueCount] = options[k].value;
                                                    selectedValueCount++;
                                                }
                                            }

                                            // Update select per content of itemset
                                            var itemCount = 0;
                                            for (var k = 0; k < itemsetElement.childNodes.length; k++) {
                                                var itemElement = itemsetElement.childNodes[k];
                                                if (itemElement.nodeType == ELEMENT_TYPE) {
                                                    if (itemCount >= options.length) {
                                                        // Add a new option
                                                        var newOption = document.createElement("OPTION");
                                                        documentElement.appendChild(newOption);
                                                        newOption.text = ORBEON.util.Dom.getAttribute(itemElement, "label");
                                                        newOption.value = ORBEON.util.Dom.getAttribute(itemElement, "value");
                                                        newOption.selected = xformsArrayContains(selectedValues, newOption.value);
                                                    } else {
                                                        // Replace current label/value if necessary
                                                        var option = options[itemCount];
                                                        if (option.text != ORBEON.util.Dom.getAttribute(itemElement, "label")) {
                                                            option.text = ORBEON.util.Dom.getAttribute(itemElement, "label");
                                                        }
                                                        if (option.value != ORBEON.util.Dom.getAttribute(itemElement, "value")) {
                                                            option.value = ORBEON.util.Dom.getAttribute(itemElement, "value");
                                                        }
                                                        option.selected = xformsArrayContains(selectedValues, option.value);
                                                    }
                                                    itemCount++;
                                                }
                                            }

                                            // Remove options in select if necessary
                                            while (options.length > itemCount) {
                                                if (options.remove) {
                                                    // For IE
                                                    options.remove(options.length - 1);
                                                } else {
                                                    // For Firefox
                                                    var toRemove = options.item(options.length - 1);
                                                    toRemove.parentNode.removeChild(toRemove);
                                                }
                                            }
                                        } else {

                                            // Case of checkboxes / radio buttons

                                            // Actual values:
                                            //     <span>
                                            //         <input type="checkbox" checked="" value="v" name="xforms-element-97" id="element-97-opsitem0"/>
                                            //         <label for="xforms-element-97-opsitem0" id="xforms-element-99">Vanilla</label>
                                            //     </span>
                                            //
                                            // Template follows:
                                            //     <span>
                                            //         <input type="checkbox" value="$xforms-template-value$" name="xforms-element-97" id="xforms-element-97-opsitem0"/>
                                            //         <label for="xforms-element-97-opsitem0" id="xforms-element-99">$xforms-template-label$</label>
                                            //     </span>

                                            // Get element following control
                                            var template = documentElement.nextSibling;
                                            while (template.nodeType != ELEMENT_TYPE)
                                                template = template.nextSibling;

                                            // Get its child element (a span that contains an input)
                                            template = template.firstChild;
                                            while (template.nodeType != ELEMENT_TYPE)
                                                template = template.nextSibling;

                                            // Remove content and store current checked value
                                            var valueToChecked = new Array();
                                            while (documentElement.childNodes.length > 0) {
                                                var input = xformsGetInputUnderNode(documentElement.firstChild);
                                                valueToChecked[input.value] = input.checked;
                                                documentElement.removeChild(documentElement.firstChild);
                                            }

                                            // Recreate content based on template
                                            var itemIndex = 0;
                                            for (var k = 0; k < itemsetElement.childNodes.length; k++) {
                                                var itemElement = itemsetElement.childNodes[k];
                                                if (itemElement.nodeType == ELEMENT_TYPE) {
                                                    var templateClone = template.cloneNode(true);
                                                    xformsStringReplace(templateClone, "$xforms-template-label$",
                                                        ORBEON.util.Dom.getAttribute(itemElement, "label"));
                                                    xformsStringReplace(templateClone, "$xforms-template-value$",
                                                        ORBEON.util.Dom.getAttribute(itemElement, "value"));
                                                    xformsStringReplace(templateClone, "$xforms-item-index$", itemIndex);
                                                    documentElement.appendChild(templateClone);
                                                    // Restore checked state after copy
                                                    if (valueToChecked[ORBEON.util.Dom.getAttribute(itemElement, "value")] == true)
                                                        xformsGetInputUnderNode(templateClone).checked = true;
                                                    itemIndex++;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        // Handle other actions
                        var serverEventsIndex = -1;
                        for (var actionIndex = 0; actionIndex < actionElement.childNodes.length; actionIndex++) {

                            var actionName = xformsGetLocalName(actionElement.childNodes[actionIndex]);
                            switch (actionName) {

                                // Update controls
                                case "control-values": {
                                    var controlValuesElement = actionElement.childNodes[actionIndex];
                                    for (var j = 0; j < controlValuesElement.childNodes.length; j++) {
                                        var controlValueAction = xformsGetLocalName(controlValuesElement.childNodes[j]);
                                        switch (controlValueAction) {

                                            // Update control value and MIPs
                                            case "control": {
                                                var controlElement = controlValuesElement.childNodes[j];
                                                var newControlValue = ORBEON.util.Dom.getStringValue(controlElement);
                                                var controlId = ORBEON.util.Dom.getAttribute(controlElement, "id");
                                                var staticReadonly = ORBEON.util.Dom.getAttribute(controlElement, "static");
                                                var relevant = ORBEON.util.Dom.getAttribute(controlElement, "relevant");
                                                var readonly = ORBEON.util.Dom.getAttribute(controlElement, "readonly");
                                                var required = ORBEON.util.Dom.getAttribute(controlElement, "required");
                                                var displayValue = ORBEON.util.Dom.getAttribute(controlElement, "display-value");
                                                var type = ORBEON.util.Dom.getAttribute(controlElement, "type");
                                                var documentElement = ORBEON.util.Dom.getElementById(controlId);
                                                var documentElementClasses = documentElement.className.split(" ");

                                                // Save new value sent by server (upload controls don't carry their value the same way as other controls)
                                                var previousServerValue = ORBEON.xforms.Globals.serverValue[controlId];
                                                if (!ORBEON.util.Dom.hasClass(documentElement, "xforms-upload"))
                                                    ORBEON.xforms.Globals.serverValue[controlId] = newControlValue;

                                                // Handle migration of control from non-static to static if needed
                                                var isControl = ORBEON.util.Dom.hasClass(documentElement, "xforms-control");
                                                var isStaticReadonly = ORBEON.util.Dom.hasClass(documentElement, "xforms-static");
                                                if (!isStaticReadonly && staticReadonly == "true") {
                                                    if (isControl) {
                                                        // Replace existing element with span
                                                        var parentElement = documentElement.parentNode;
                                                        var newDocumentElement = document.createElement("span");
                                                        newDocumentElement.setAttribute("id", controlId);
                                                        newDocumentElement.setAttribute("class", documentElementClasses.join(" ") + " xforms-static");
                                                        parentElement.replaceChild(newDocumentElement, documentElement);
                                                        // Remove alert
                                                        var alertElement = ORBEON.xforms.Controls._getControlLabel(newDocumentElement, "xforms-alert");
                                                        if (alertElement != null)
                                                            parentElement.removeChild(alertElement);
                                                        // Remove hint
                                                        var hintLabel = ORBEON.xforms.Events._findHint(newDocumentElement);
                                                        if (hintLabel != null)
                                                            parentElement.removeChild(hintLabel);
                                                        // Update document element information
                                                        documentElement = newDocumentElement;
                                                    } else {
                                                        // Just add the new class
                                                        ORBEON.util.Dom.addClass(documentElement, "xforms-static");
                                                    }
                                                    isStaticReadonly = true;
                                                    documentElementClasses = documentElement.className.split(" ");
                                                }

                                                // We update the relevance and readonly before we update the value. If we don't, updating the value
                                                // can fail on IE in some cases. (The details about this issue have been lost.)

                                                // Handle relevance
                                                if (relevant != null) {
                                                    var isRelevant = relevant == "true";
                                                    ORBEON.xforms.Controls.setRelevant(documentElement, isRelevant);
                                                    // Autosize textarea
                                                    if (ORBEON.util.Dom.hasClass(documentElement, "xforms-textarea-appearance-xxforms-autosize")) {
                                                        ORBEON.xforms.Controls.autosizeTextarea(documentElement);
                                                    }
                                                }

                                                // Handle required
                                                if (required != null) {
                                                    var isRequired = required == "true";
                                                    if (isRequired) ORBEON.util.Dom.addClass(documentElement, "xforms-required");
                                                    else ORBEON.util.Dom.removeClass(documentElement, "xforms-required");
                                                }

                                                // Handle readonly
                                                if (readonly != null && !isStaticReadonly) {
                                                    function setReadonlyOnFormElement(element, isReadonly) {
                                                        if (isReadonly) {
                                                            element.setAttribute("disabled", "disabled");
                                                            ORBEON.util.Dom.addClass(element, "xforms-readonly");
                                                        } else {
                                                            element.removeAttribute("disabled");
                                                            ORBEON.util.Dom.removeClass(element, "xforms-readonly");
                                                        }
                                                    }

                                                    var isReadonly = readonly == "true";
                                                    if (ORBEON.util.Dom.hasClass(documentElement, "xforms-input")) {
                                                        // XForms input

                                                        // Display value
                                                        var displaySpan = documentElement.firstChild;
                                                        while (displaySpan.nodeType != ELEMENT_TYPE) displaySpan = displaySpan.nextSibling;
                                                        if (isReadonly) ORBEON.util.Dom.addClass(displaySpan, "xforms-readonly");
                                                        else ORBEON.util.Dom.removeClass(displaySpan, "xforms-readonly");

                                                        // Text field
                                                        var textField = displaySpan.nextSibling;
                                                        while (textField.nodeType != ELEMENT_TYPE) textField = textField.nextSibling;
                                                        if (isReadonly) textField.setAttribute("disabled", "disabled");
                                                        else textField.removeAttribute("disabled");

                                                        // Calendar picker
                                                        var showCalendar = textField.nextSibling;
                                                        while (showCalendar.nodeType != ELEMENT_TYPE) showCalendar = showCalendar.nextSibling;
                                                        if (isReadonly) ORBEON.util.Dom.addClass(showCalendar, "xforms-showcalendar-readonly");
                                                        else ORBEON.util.Dom.removeClass(showCalendar, "xforms-showcalendar-readonly");
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-output")
                                                            || ORBEON.util.Dom.hasClass(documentElement, "xforms-group")) {
                                                        // XForms output and group
                                                        if (isReadonly) ORBEON.util.Dom.addClass(documentElement, "xforms-readonly");
                                                        else ORBEON.util.Dom.removeClass(documentElement, "xforms-readonly");
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-select1-appearance-full")
                                                            || ORBEON.util.Dom.hasClass(documentElement, "xforms-select-appearance-full")) {
                                                        // XForms radio buttons
                                                        for (var spanIndex = 0; spanIndex < documentElement.childNodes.length; spanIndex++) {
                                                            var span = documentElement.childNodes[spanIndex];
                                                            var input = span.firstChild;
                                                            setReadonlyOnFormElement(input, isReadonly);
                                                        }
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-select1-appearance-xxforms-autocomplete")) {
                                                        // Auto-complete field
                                                        var input = ORBEON.util.Dom.getChildElementByIndex(documentElement, 0);
                                                        setReadonlyOnFormElement(input, isReadonly);
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-textarea") && ORBEON.util.Dom.hasClass(documentElement, "xforms-mediatype-text-html")) {
                                                        // XForms HTML area
                                                        var htmlEditor = FCKeditorAPI.GetInstance(documentElement.name);
                                                        if (isReadonly) {
                                                            htmlEditor.ToolbarSet.Collapse();
                                                            // TO-DO
                                                        } else {
                                                            htmlEditor.ToolbarSet.Expand();
                                                            // TO-DO
                                                        }
                                                    } else {
                                                        // Other controls
                                                        setReadonlyOnFormElement(documentElement, isReadonly);
                                                    }
                                                }

                                                // Update value
                                                if (isControl) {
                                                    if (ORBEON.util.Dom.hasClass(documentElement, "xforms-output") || isStaticReadonly) {
                                                        // XForms output or "static readonly" mode
                                                        var newOutputControlValue = displayValue != null ? displayValue : newControlValue;
                                                        if (ORBEON.util.Dom.hasClass(documentElement, "xforms-mediatype-image")) {
                                                            var image = ORBEON.util.Dom.getChildElementByIndex(documentElement, 0);
                                                            image.src = newOutputControlValue;
                                                        } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-mediatype-text-html")) {
                                                            documentElement.innerHTML = newOutputControlValue;
                                                        } else {
                                                            ORBEON.util.Dom.setStringValue(documentElement, newOutputControlValue);
                                                        }
                                                    } else if (ORBEON.xforms.Globals.changedIdsRequest[controlId] != null) {
                                                        // User has modified the value of this control since we sent our request:
                                                        // so don't try to update it
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-trigger")
                                                            || ORBEON.util.Dom.hasClass(documentElement, "xforms-submit")) {
                                                        // Triggers don't have a value: don't update them
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-select1-open")) {
                                                        // Auto-complete
                                                        if (documentElement.value != newControlValue) {
                                                            documentElement.value = newControlValue;
                                                            ORBEON.util.Dom.getChildElementByIndex(documentElement, 0).value = newControlValue;
                                                            documentElement.previousValue = newControlValue;
                                                        }
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-select-appearance-full")
                                                            || ORBEON.util.Dom.hasClass(documentElement, "xforms-select1-appearance-full")) {
                                                        // Handle checkboxes and radio buttons
                                                        var selectedValues = ORBEON.util.Dom.hasClass(documentElement, "xforms-select-appearance-full")
                                                            ? newControlValue.split(" ") : new Array(newControlValue);
                                                        var checkboxInputs = documentElement.getElementsByTagName("input");
                                                        for (var checkboxInputIndex = 0; checkboxInputIndex < checkboxInputs.length; checkboxInputIndex++) {
                                                            var checkboxInput = checkboxInputs[checkboxInputIndex];
                                                            checkboxInput.checked = xformsArrayContains(selectedValues, checkboxInput.value);
                                                        }
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-select-appearance-compact")
                                                            || ORBEON.util.Dom.hasClass(documentElement, "xforms-select1-appearance-compact")
                                                            || ORBEON.util.Dom.hasClass(documentElement, "xforms-select1-appearance-minimal")) {
                                                        // Handle lists and comboboxes
                                                        var selectedValues = ORBEON.util.Dom.hasClass(documentElement, "xforms-select-appearance-compact")
                                                            ? newControlValue.split(" ") : new Array(newControlValue);
                                                        var options = documentElement.options;
                                                        for (var optionIndex = 0; optionIndex < options.length; optionIndex++) {
                                                            var option = options[optionIndex];
                                                            try {
                                                                option.selected = xformsArrayContains(selectedValues, option.value);
                                                            } catch (e) {
                                                                // nop
                                                                //
                                                                // This is to prevent the error "Could not set the selected property. Unspecified error." in IE.
                                                                // Like noted in this blog entry: http://ianso.blogspot.com/2005_10_01_ianso_archive.html (search
                                                                // for the error message), it seems that DOM updates are somewhat asynchrous and that when you
                                                                // make an element visible and change a property right after that, it is sometimes as if the element
                                                                // is not visible yet, and so the property cannot be changed.
                                                            }
                                                        }
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-input")) {
                                                        // XForms input
                                                        var displayField = ORBEON.util.Dom.getChildElementByIndex(documentElement, 0);
                                                        var inputField = ORBEON.util.Dom.getChildElementByIndex(documentElement, 1);
                                                        var datePicker = ORBEON.util.Dom.getChildElementByIndex(documentElement, 2);

                                                        // Change classes on control and date pick based on type
                                                        if (type == "{http://www.w3.org/2001/XMLSchema}date") {
                                                            for (var childIndex = 0; childIndex < documentElement.childNodes.length; childIndex++) {
                                                                var child = documentElement.childNodes[childIndex];
                                                                ORBEON.util.Dom.addClass(child, "xforms-type-date");
                                                                ORBEON.util.Dom.removeClass(child, "xforms-type-string");
                                                            }
                                                        } else if (type != null && type != "{http://www.w3.org/2001/XMLSchema}date") {
                                                            for (var childIndex = 0; childIndex < documentElement.childNodes.length; childIndex++) {
                                                                var child = documentElement.childNodes[childIndex];
                                                                ORBEON.util.Dom.addClass(child, "xforms-type-string");
                                                                ORBEON.util.Dom.removeClass(child, "xforms-type-date");
                                                            }
                                                        }

                                                        // Populate values
                                                        if (ORBEON.util.Dom.hasClass(inputField, "xforms-type-date")) {
                                                            ORBEON.util.Dom.setStringValue(displayField, (displayValue == null || displayValue == "") ? "\u00a0" : displayValue);
                                                        }
                                                        if (documentElement.value != newControlValue) {
                                                            documentElement.previousValue = newControlValue;
                                                            documentElement.valueSetByXForms++;
                                                            documentElement.value = newControlValue;
                                                        }
                                                        if (inputField.value != newControlValue)
                                                            inputField.value = newControlValue;
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-textarea")
                                                            && ORBEON.util.Dom.hasClass(documentElement, "xforms-mediatype-text-html")) {
                                                        // HTML area
                                                        var htmlEditor = FCKeditorAPI.GetInstance(documentElement.name);
                                                        var doUpdate =
                                                                // Update only if the new value is different than the value already have in the HTML area
                                                                xformsNormalizeEndlines(htmlEditor.GetXHTML()) != xformsNormalizeEndlines(newControlValue)
                                                                // Also update only if the value in the HTML area is the same now as it was when we sent it to the server
                                                                // If there is no previousServerValue, go ahead and update field
                                                                && (previousServerValue == null || htmlEditor.GetXHTML() == previousServerValue);
                                                        if (doUpdate) {
                                                            // Directly modify the DOM instead of using SetHTML() provided by the FCKeditor,
                                                            // as we loose our listeners after using the later
                                                            htmlEditor.EditorDocument.body.innerHTML = newControlValue;
                                                            // Set again the server value based on the HTML as seen from the field. HTML changes slightly when it
                                                            // is pasted in the FCK editor. The server value will be compared to the field value, to (a) figure out
                                                            // if we need to send the value again to the server and (b) to figure out if the FCK editor has been edited
                                                            // since the last time we sent the value to the serer. The bottom line is that we are going to compare
                                                            // the server value to the content of the field. So storing the value as seen by the field vs. as seen by
                                                            // server accounts for the slight difference there might be in those 2 representations.
                                                            ORBEON.xforms.Globals.serverValue[controlId] = htmlEditor.GetXHTML();
                                                            documentElement.value = newControlValue;
                                                            documentElement.previousValue = newControlValue;
                                                        }
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-select-appearance-xxforms-tree")) {
                                                        // Tree
                                                        var values = newControlValue.split(" ");
                                                        var yuiTree = ORBEON.xforms.Globals.treeYui[documentElement.id];
                                                        for (nodeIndex in yuiTree._nodes) {
                                                            var node = yuiTree._nodes[nodeIndex];
                                                            if (node.children.length == 0) {
                                                                var checked = xformsArrayContains(values, node.data.value);
                                                                if (checked) node.check(); else node.uncheck();
                                                            }
                                                        }
                                                        documentElement.value = newControlValue;
                                                        documentElement.previousValue = newControlValue;
                                                    } else if (ORBEON.util.Dom.hasClass(documentElement, "xforms-upload")) {
                                                        // Upload

                                                        // <xxforms:control id="xforms-control-id"
                                                        //    state="empty|file"
                                                        //    filename="filename.txt" mediatype="text/plain" size="23kb"/>

                                                        // Get attributes from response
                                                        var state = ORBEON.util.Dom.getAttribute(controlElement, "state");
                                                        var filename = ORBEON.util.Dom.getAttribute(controlElement, "filename");
                                                        var mediatype = ORBEON.util.Dom.getAttribute(controlElement, "mediatype");
                                                        var size = ORBEON.util.Dom.getAttribute(controlElement, "size");
                                                        // Get elements we want to modify from the DOM
                                                        var fileInfoSpan = ORBEON.util.Dom.getChildElementByClass(documentElement, "xforms-upload-info");
                                                        var fileNameSpan = ORBEON.util.Dom.getChildElementByClass(fileInfoSpan, "xforms-upload-filename");
                                                        var mediatypeSpan = ORBEON.util.Dom.getChildElementByClass(fileInfoSpan, "xforms-upload-mediatype");
                                                        var sizeSpan = ORBEON.util.Dom.getChildElementByClass(fileInfoSpan, "xforms-upload-size");
                                                        // Set values in DOM
                                                        if (state == "empty") {
                                                            ORBEON.util.Dom.removeClass(documentElement, "xforms-upload-state-file")
                                                            ORBEON.util.Dom.addClass(documentElement, "xforms-upload-state-empty")
                                                        }
                                                        if (state == "file") {
                                                            ORBEON.util.Dom.removeClass(documentElement, "xforms-upload-state-empty")
                                                            ORBEON.util.Dom.addClass(documentElement, "xforms-upload-state-file")

                                                            // Clear upload input by replacing the control
                                                            ORBEON.util.Dom.clearUploadControl(documentElement);
                                                        }
                                                        if (filename != null)
                                                            ORBEON.util.Dom.setStringValue(fileNameSpan, filename);
                                                        if (mediatype != null)
                                                            ORBEON.util.Dom.setStringValue(mediatypeSpan, mediatype);
                                                        if (size != null)
                                                            ORBEON.util.Dom.setStringValue(sizeSpan, size);
                                                    } else if (typeof(documentElement.value) == "string") {
                                                        // Textarea, password
                                                        if (xformsNormalizeEndlines(documentElement.value) != xformsNormalizeEndlines(newControlValue)) {
                                                            documentElement.value = newControlValue;
                                                            documentElement.previousValue = newControlValue;
                                                            // Autosize textarea
                                                            if (ORBEON.util.Dom.hasClass(documentElement, "xforms-textarea-appearance-xxforms-autosize")) {
                                                                ORBEON.xforms.Controls.autosizeTextarea(documentElement);
                                                            }
                                                        }
                                                    }
                                                }

                                                // Update the required-empty/required-full even if the required has not changed or
                                                // is not specified as the value may have changed
                                                if (!isStaticReadonly) {
                                                    ORBEON.xforms.Controls.updateRequiredEmpty(documentElement);
                                                }

                                                // Store new label message in control attribute
                                                var newLabel = ORBEON.util.Dom.getAttribute(controlElement, "label");
                                                if (newLabel != null)
                                                    ORBEON.xforms.Controls.setLabelMessage(documentElement, newLabel);
                                                // Store new hint message in control attribute
                                                var newHint = ORBEON.util.Dom.getAttribute(controlElement, "hint");
                                                if (newHint != null)
                                                    ORBEON.xforms.Controls.setHintMessage(documentElement, newHint);
                                                // Store new help message in control attribute
                                                var newHelp = ORBEON.util.Dom.getAttribute(controlElement, "help");
                                                if (newHelp != null)
                                                    ORBEON.xforms.Controls.setHelpMessage(documentElement, newHelp);
                                                // Store new alert message in control attribute
                                                var newAlert = ORBEON.util.Dom.getAttribute(controlElement, "alert");
                                                if (newAlert != null)
                                                    ORBEON.xforms.Controls.setAlertMessage(documentElement, newAlert);
                                                // Store validity, label, hint, help in element
                                                var newValid = ORBEON.util.Dom.getAttribute(controlElement, "valid");
                                                if (newValid != null) {
                                                    var newIsValid = newValid != "false";
                                                    ORBEON.xforms.Controls.setValid(documentElement, newIsValid);
                                                }

                                                // After we update classes on textarea, copy those classes on the FCKeditor iframe
                                                if (ORBEON.util.Dom.hasClass(documentElement, "xforms-textarea")
                                                        && ORBEON.util.Dom.hasClass(documentElement, "xforms-mediatype-text-html")) {
                                                    ORBEON.xforms.Controls.updateHTMLAreaClasses(documentElement);
                                                }

                                                break;
                                            }

                                            // Model item properties on a repeat item
                                            case "repeat-iteration": {
                                                // Extract data from server response
                                                var repeatIterationElement = controlValuesElement.childNodes[j];
                                                var repeatId = ORBEON.util.Dom.getAttribute(repeatIterationElement, "id");
                                                var iteration = ORBEON.util.Dom.getAttribute(repeatIterationElement, "iteration");
                                                var relevant = ORBEON.util.Dom.getAttribute(repeatIterationElement, "relevant");
                                                // Remove or add xforms-disabled on elements after this delimiter
                                                var cursor = xformsFindRepeatDelimiter(repeatId, iteration).nextSibling;
                                                while (!(cursor.nodeType == ELEMENT_TYPE &&
                                                         (ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-delimiter")
                                                            || ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-begin-end")))) {
                                                    if (cursor.nodeType == ELEMENT_TYPE) {
                                                        if (relevant) {
                                                            if (relevant == "true") ORBEON.util.Dom.removeClass(cursor, "xforms-disabled");
                                                            else ORBEON.util.Dom.addClass(cursor, "xforms-disabled");
                                                        }
                                                    }
                                                    cursor = cursor.nextSibling;
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    break;
                                }

                                // Display or hide divs
                                case "divs": {
                                    var divsElement = actionElement.childNodes[actionIndex];
                                    for (var j = 0; j < divsElement.childNodes.length; j++) {
                                        if (xformsGetLocalName(divsElement.childNodes[j]) == "div") {
                                            var divElement = divsElement.childNodes[j];
                                            var controlId = ORBEON.util.Dom.getAttribute(divElement, "id");
                                            var visibile = ORBEON.util.Dom.getAttribute(divElement, "visibility") == "visible";

                                            var yuiDialog = ORBEON.xforms.Globals.dialogs[controlId];
                                            if (yuiDialog == null) {
                                                // This is a case, not a dialog
                                                var caseBeginId = "xforms-case-begin-" + controlId;
                                                var caseBegin = ORBEON.util.Dom.getElementById(caseBeginId);
                                                var caseBeginParent = caseBegin.parentNode;
                                                var foundCaseBegin = false;
                                                for (var childId = 0; caseBeginParent.childNodes.length; childId++) {
                                                    var cursor = caseBeginParent.childNodes[childId];
                                                    if (!foundCaseBegin) {
                                                        if (cursor.id == caseBegin.id) foundCaseBegin = true;
                                                        else continue;
                                                    }
                                                    if (cursor.nodeType == ELEMENT_TYPE) {
                                                        if (cursor.id == "xforms-case-end-" + controlId) break;
                                                        ORBEON.util.Dom.addClass(cursor, visibile ? "xforms-case-selected" : "xforms-case-deselected");
                                                        ORBEON.util.Dom.removeClass(cursor, visibile ? "xforms-case-deselected" : "xforms-case-selected");
                                                    }
                                                }
                                            } else {
                                                // This is a dialog
                                                if (visibile) yuiDialog.show();
                                                else yuiDialog.hide();
                                            }
                                        }
                                    }

                                    // After we display divs, we must reenable the HTML editors.
                                    // This is a workaround for a Gecko bug documented at:
                                    // http://wiki.fckeditor.net/Troubleshooting#gecko_hidden_div
                                    if (XFORMS_IS_GECKO && ORBEON.xforms.Globals.htmlAreaNames.length > 0) {
                                        for (var htmlAreaIndex = 0; htmlAreaIndex < ORBEON.xforms.Globals.htmlAreaNames.length; htmlAreaIndex++) {
                                            var name = ORBEON.xforms.Globals.htmlAreaNames[htmlAreaIndex];
                                            var editor = FCKeditorAPI.GetInstance(name);
                                            try {
                                                editor.EditorDocument.designMode = "on";
                                            } catch (e) {
                                                // Nop
                                            }
                                        }
                                    }

                                    break;
                                }

                                // Change highlighted section in repeat
                                case "repeat-indexes": {
                                    var repeatIndexesElement = actionElement.childNodes[actionIndex];
                                    var newRepeatIndexes = new Array();
                                    // Extract data from server response
                                    for (var j = 0; j < repeatIndexesElement.childNodes.length; j++) {
                                        if (xformsGetLocalName(repeatIndexesElement.childNodes[j]) == "repeat-index") {
                                            var repeatIndexElement = repeatIndexesElement.childNodes[j];
                                            var repeatId = ORBEON.util.Dom.getAttribute(repeatIndexElement, "id");
                                            var newIndex = ORBEON.util.Dom.getAttribute(repeatIndexElement, "new-index");
                                            newRepeatIndexes[repeatId] = newIndex;
                                        }
                                    }
                                    // For each repeat id that changes, see if all the children are also included in
                                    // newRepeatIndexes. If they are not, add an entry with the index unchanged.
                                    for (var repeatId in newRepeatIndexes) {
                                        if (typeof repeatId == "string") { // hack because repeatId may be trash when some libraries override Object
                                            var children = ORBEON.xforms.Globals.repeatTreeParentToAllChildren[repeatId];
                                            if (children != null) { // test on null is a hack because repeatId may be trash when some libraries override Object
                                                for (var childIndex in children) {
                                                    var child = children[childIndex];
                                                    if (!newRepeatIndexes[child])
                                                        newRepeatIndexes[child] = ORBEON.xforms.Globals.repeatIndexes[child];
                                                }
                                            }
                                        }
                                    }
                                    // Unhighlight items at old indexes
                                    for (var repeatId in newRepeatIndexes) {
                                        if (typeof repeatId == "string") { // hack because repeatId may be trash when some libraries override Object
                                            var oldIndex = ORBEON.xforms.Globals.repeatIndexes[repeatId];
                                            if (typeof oldIndex == "string" && oldIndex != 0) { // hack because repeatId may be trash when some libraries override Object
                                                var oldItemDelimiter = xformsFindRepeatDelimiter(repeatId, oldIndex);
                                                if (oldItemDelimiter != null) {
                                                    var cursor = oldItemDelimiter.nextSibling;
                                                    while (cursor.nodeType != ELEMENT_TYPE ||
                                                           (!ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-delimiter")
                                                           && !ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-begin-end"))) {
                                                        if (cursor.nodeType == ELEMENT_TYPE)
                                                            ORBEON.util.Dom.removeClass(cursor, xformsGetClassForRepeatId(repeatId));
                                                        cursor = cursor.nextSibling;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    // Store new indexes
                                    for (var repeatId in newRepeatIndexes) {
                                        var newIndex = newRepeatIndexes[repeatId];
                                        ORBEON.xforms.Globals.repeatIndexes[repeatId] = newIndex;
                                    }
                                    // Highlight item at new index
                                    for (var repeatId in newRepeatIndexes) {
                                        if (typeof repeatId == "string") { // hack because repeatId may be trash when some libraries override Object
                                            var newIndex = newRepeatIndexes[repeatId];
                                            if (typeof newIndex == "string" && newIndex != 0) { // hack because repeatId may be trash when some libraries override Object
                                                var newItemDelimiter = xformsFindRepeatDelimiter(repeatId, newIndex);
                                                var cursor = newItemDelimiter.nextSibling;
                                                while (cursor.nodeType != ELEMENT_TYPE ||
                                                       (!ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-delimiter")
                                                       && !ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-begin-end"))) {
                                                    if (cursor.nodeType == ELEMENT_TYPE)
                                                        ORBEON.util.Dom.addClass(cursor, xformsGetClassForRepeatId(repeatId));
                                                    cursor = cursor.nextSibling;
                                                }
                                            }
                                        }
                                    }
                                    break;
                                }

                                // Server events
                                case "server-events": {
                                    // If there is a "submission" element, this must always come first
                                    serverEventsIndex = actionIndex;
                                    break;
                                }

                                // Submit form
                                case "submission": {
                                    var submissionElement = actionElement.childNodes[actionIndex];
                                    var showProcess = ORBEON.util.Dom.getAttribute(submissionElement, "show-progress");
                                    var action = ORBEON.util.Dom.getAttribute(submissionElement, "action");
                                    var replace = ORBEON.util.Dom.getAttribute(submissionElement, "replace");
                                    if (replace == null) replace = "all";
                                    ORBEON.xforms.Globals.formDynamicState[formIndex].value = newDynamicState;
                                    if (serverEventsIndex != -1) {
                                        ORBEON.xforms.Globals.formServerEvents[formIndex].value = ORBEON.util.Dom.getStringValue(actionElement.childNodes[serverEventsIndex]);
                                    } else {
                                        ORBEON.xforms.Globals.formServerEvents[formIndex].value = "";
                                    }
                                    if (replace == "all") {
                                        // Go to another page
                                        if (showProcess != "false")
                                            // Display loading indicator unless the server tells us not to display it
                                            newDynamicStateTriggersReplace = true;
                                        ORBEON.xforms.Globals.requestForm.submit();
                                    } else {
                                        // Submit form in the background
                                        YAHOO.util.Connect.setForm(ORBEON.xforms.Globals.requestForm, true, true);
                                        var callback =  {
                                            upload: ORBEON.xforms.Server.handleUploadResponse,
                                            failure: ORBEON.xforms.Server.handleFailure
                                        }
                                        YAHOO.util.Connect.asyncRequest("POST", action, callback);
                                    }
                                    ORBEON.xforms.Globals.formServerEvents[formIndex].value = "";
                                    break;
                                }

                                // Display modal message
                                case "message": {
                                    var messageElement = actionElement.childNodes[actionIndex];
                                    var message = ORBEON.util.Dom.getStringValue(messageElement);
                                    if (ORBEON.util.Dom.getAttribute(messageElement, "level") == "modal")
                                        alert(message);
                                    break;
                                }

                                // Load another page
                                case "load": {
                                    var loadElement = actionElement.childNodes[actionIndex];
                                    var resource = ORBEON.util.Dom.getAttribute(loadElement, "resource");
                                    var show = ORBEON.util.Dom.getAttribute(loadElement, "show");
                                    var target = ORBEON.util.Dom.getAttribute(loadElement, "target");
                                    var showProcess = ORBEON.util.Dom.getAttribute(loadElement, "show-progress");
                                    if (show == "replace") {
                                        if (target == null) {
                                            // Display loading indicator unless the server tells us not to display it
                                            if (showProcess != "false")
                                                newDynamicStateTriggersReplace = true;
                                            window.location.href = resource;
                                        } else {
                                            window.open(resource, target);
                                        }
                                    } else {
                                        window.open(resource, "_blank");
                                    }
                                    break;
                                }

                                // Set focus to a control
                                case "setfocus": {
                                    var setfocusElement = actionElement.childNodes[actionIndex];
                                    var controlId = ORBEON.util.Dom.getAttribute(setfocusElement, "control-id");
                                    var control = ORBEON.util.Dom.getElementById(controlId);
                                    if (ORBEON.util.Dom.hasClass(control, "xforms-input")) {
                                        control = ORBEON.util.Dom.getChildElementByIndex(control, 1);
                                    } else if (ORBEON.util.Dom.hasClass(control, "xforms-select1-appearance-xxforms-autocomplete")) {
                                        control = ORBEON.util.Dom.getChildElementByIndex(control, 0);
                                    }
                                    ORBEON.xforms.Globals.maskFocusEvents = true;
                                    control.focus();
                                    break;
                                }

                                // Run JavaScript code
                                case "script": {
                                    var scriptElement = actionElement.childNodes[actionIndex];
                                    var functionName = ORBEON.util.Dom.getAttribute(scriptElement, "name");
                                    var targetId = ORBEON.util.Dom.getAttribute(scriptElement, "target-id");
                                    var observerId = ORBEON.util.Dom.getAttribute(scriptElement, "observer-id");
                                    ORBEON.xforms.Server.callUserScript(functionName, targetId, observerId);
                                    break;
                                }
                            }
                        }
                    }
                }

                // Store new dynamic state if that state did not trigger a post
                xformsStoreInClientState(formIndex, "ajax-dynamic-state", newDynamicState);

                if (newDynamicStateTriggersReplace) {
                    // Display loading indicator when we go to another page.
                    // Display it even if it was not displayed before as loading the page could take time.
                    xformsDisplayIndicator("loading");
                    ORBEON.xforms.Globals.loadingOtherPage = true;
                }
                ORBEON.xforms.Globals.lastRequestIsError = false;

                // Hack for instance inspector - need to see how to do this better
//                sourceResize();

            } else if (responseXML && responseXML.documentElement
                    && responseXML.documentElement.tagName.indexOf("exceptions") != -1) {
                // We received an error from the server
                ORBEON.xforms.Globals.lastRequestIsError = true;

                // Find an error message starting from the inner-most exception
                errorMessage = "XForms error";
                var messageElements = responseXML.getElementsByTagName("message");
                for (var messageIndex = messageElements.length - 1; messageIndex >= 0; messageIndex--) {
                    if (messageElements[messageIndex].firstChild != null) {
                        errorMessage += ": " + ORBEON.util.Dom.getStringValue(messageElements[messageIndex]);
                        break;
                    }
                }

            } else {
                // The server didn't send valid XML
                ORBEON.xforms.Globals.lastRequestIsError = true;
                errorMessage = "Unexpected response received from server";
            }
        } catch (e) {
            // Do nothing when there is an exception.
            ORBEON.xforms.Server.exceptionWhenTalkingToServer(e, formIndex);
        }

        // Display error if there is one
        if (errorMessage != null) {
            var errorContainer = ORBEON.xforms.Globals.formLoadingError[formIndex];
            ORBEON.util.Dom.setStringValue(errorContainer, errorMessage);
            xformsDisplayIndicator("error");
        }

        // Reset changes, as changes are included in this bach of events
        ORBEON.xforms.Globals.changedIdsRequest = {};

        // Go ahead with next request, if any
        ORBEON.xforms.Globals.requestInProgress = false;
        ORBEON.xforms.Globals.executeEventFunctionQueued++;
        ORBEON.xforms.Server.executeNextRequest(false);
    },

    callUserScript: function(functionName, targetId, observerId) {
        var targetElement = ORBEON.util.Dom.getElementById(targetId);
        var observer = ORBEON.util.Dom.getElementById(observerId);
        var event = { "target" : targetElement };
        var theFunction = eval(functionName);
        theFunction.call(observer, event);
    }
};

function xformsIsDefined(thing) {
    return typeof thing != "undefined";
}

function xformsDispatchEvent(target, eventName) {
    if (target.dispatchEvent) {
        var event = document.createEvent("HTMLEvents");
        event.initEvent(eventName.toLowerCase(), true, true);
        target.dispatchEvent(event);
    } else {
        target.fireEvent("on" + eventName);
    }
}

function xformsPreventDefault(event) {
    if (event.preventDefault) {
        // Firefox version
        event.preventDefault();
    } else {
        // IE version
        return false;
    }
}

function xformsArrayContains(array, element) {
    for (var i = 0; i < array.length; i++)
        if (array[i] == element)
            return true;
    return false;
}

function xformsStringReplaceWorker(node, placeholderRegExp, replacement) {
    switch (node.nodeType) {
        case ELEMENT_TYPE:
            for (var i = 0; i < node.attributes.length; i++) {
                var newValue = new String(node.attributes[i].value).replace(placeholderRegExp, replacement);
                if (newValue != node.attributes[i].value)
                    node.setAttribute(node.attributes[i].name, newValue);
            }
            for (var i = 0; i < node.childNodes.length; i++)
                xformsStringReplaceWorker(node.childNodes[i], placeholderRegExp, replacement);
            break;
        case TEXT_TYPE:
            var newValue = new String(node.nodeValue).replace(placeholderRegExp, replacement);
            if (newValue != node.nodeValue)
                node.nodeValue = newValue;
            break;
    }
}

// Replace in a tree a placeholder by some other string in text nodes and attribute values
function xformsStringReplace(node, placeholder, replacement) {
    var placeholderRegExp = new RegExp(placeholder.replace(new RegExp("\\$", "g"), "\\$"), "g");
    xformsStringReplaceWorker(node, placeholderRegExp, replacement);
}

function xformsNormalizeEndlines(text) {
    return text.replace(XFORMS_REGEXP_CR, "");
}

function xformsAppendRepeatSuffix(id, suffix) {
    if (suffix == "")
        return id;
    if (suffix.charAt(0) == XFORMS_SEPARATOR_2)
        suffix = suffix.substring(1);
    if (id.indexOf(XFORMS_SEPARATOR_1) == -1)
        return id + XFORMS_SEPARATOR_1 + suffix;
    else
        return id + XFORMS_SEPARATOR_2 + suffix;
}

/**
* Locate the delimiter at the given position starting from a repeat begin element.
*/
function xformsFindRepeatDelimiter(repeatId, index) {

    // Find id of repeat begin for the current repeatId
    var parentRepeatIndexes = "";
    {
        var currentId = repeatId;
        while (true) {
            var parent = ORBEON.xforms.Globals.repeatTreeChildToParent[currentId];
            if (parent == null) break;
            var grandParent = ORBEON.xforms.Globals.repeatTreeChildToParent[parent];
            parentRepeatIndexes = (grandParent == null ? XFORMS_SEPARATOR_1 : XFORMS_SEPARATOR_2)
                    + ORBEON.xforms.Globals.repeatIndexes[parent] + parentRepeatIndexes;
            currentId = parent;
        }
    }

    var beginElementId = "repeat-begin-" + repeatId + parentRepeatIndexes;
    var beginElement = ORBEON.util.Dom.getElementById(beginElementId);
    if (!beginElement) return null;
    var cursor = beginElement;
    var cursorPosition = 0;
    while (true) {
        while (cursor.nodeType != ELEMENT_TYPE || !ORBEON.util.Dom.hasClass(cursor, "xforms-repeat-delimiter")) {
            cursor = cursor.nextSibling;
            if (!cursor) return null;
        }
        cursorPosition++;
        if (cursorPosition == index) break;
        cursor = cursor.nextSibling;
    }

    return cursor;
}

function xformsLog(object) {
    var debugDiv = ORBEON.util.Dom.getElementById("xforms-debug");
    if (debugDiv == null) {
        // Figure out width and heigh of visible part of the page
        var visibleWidth;
        var visibleHeight;
        if (navigator.appName.indexOf("Microsoft")!=-1) {
            visibleWidth = document.body.offsetWidth;
            visibleHeight = document.body.offsetHeight;
        } else {
            visibleWidth = window.innerWidth;
            visibleHeight = window.innerHeight;
        }

        // Create div with appropriate size and position
        debugDiv = document.createElement("div");
        debugDiv.className = "xforms-debug";
        debugDiv.id = "xforms-debug";
        debugDiv.style.width = XFORMS_DEBUG_WINDOW_WIDTH + "px";
        debugDiv.style.left = visibleWidth - (XFORMS_DEBUG_WINDOW_WIDTH + 50) + "px";
        debugDiv.style.height = XFORMS_DEBUG_WINDOW_HEIGHT + "px";
        debugDiv.style.top = visibleHeight - (XFORMS_DEBUG_WINDOW_HEIGHT + 20) + "px";

        // Add "clear" button
        var clear = document.createElement("BUTTON");
        clear.appendChild(document.createTextNode("Clear"));
        debugDiv.appendChild(clear);
        document.body.insertBefore(debugDiv, document.body.firstChild);

        // Handle click on clear button
        YAHOO.util.Event.addListener(clear, "click", function (event) {
            var target = getEventTarget(event);
            alert("click");
            while (target.nextSibling)
                target.parentNode.removeChild(target.nextSibling);
            return false;
        });

        // Make it so user can move the debug window
        YAHOO.util.Event.addListener(debugDiv, "mousedown", function (event) {
            ORBEON.xforms.Globals.debugDiv = getEventTarget(event);
            return false;
        });
        YAHOO.util.Event.addListener(document, "mouseup", function (event) {
            ORBEON.xforms.Globals.debugDiv = null;
            return false;
        });
        YAHOO.util.Event.addListener(document, "mousemove", function (event) {
            if (ORBEON.xforms.Globals.debugDiv) {
                ORBEON.xforms.Globals.debugDiv.style.left = event.clientX;
                ORBEON.xforms.Globals.debugDiv.style.top = event.clientY;
            }
            return false;
        });
    }
    // Convert object to text
    text =
        object === undefined ? "undefined"
        : object === null ? "null"
        : typeof object == "string" && object == "" ? "empty string"
        : object.nodeType && object.nodeType == ORBEON.util.Dom.ELEMENT_TYPE ? "Element " + object.tagName
        : object.nodeType && object.nodeType == ORBEON.util.Dom.TEXT_TYPE ? "Text: " + ORBEON.util.Dom.getStringValue(object)
        : object;
    debugDiv.innerHTML += text + " | ";
}

function xformsLogTime(text) {
    var oldTime = ORBEON.xforms.Globals.debugLastTime;
    var currentTime = new Date().getTime();
    ORBEON.xforms.Globals.debugLastTime = currentTime;
    xformsLog((currentTime - oldTime) + ": " + text);
}

function xformsLogProperties(object) {
    var message = "[";
    var first = true;
    for (var p in object) {
        if (first) first = false; else message += ", ";
        message += p + ": " + object[p];
    }
    message += "]";
    xformsLog(message);
}

function xformsDisplayIndicator(state) {
    var form = ORBEON.xforms.Globals.requestForm;
    var formIndex = ORBEON.util.Dom.getFormIndex(form);
    switch (state) {
        case "loading":
            if (ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex] != null) {
                ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex].cfg.setProperty("visible", true);
                ORBEON.xforms.Controls.updateLoadingPosition(formIndex);
            }
            if (ORBEON.xforms.Globals.formLoadingError[formIndex] != null)
                ORBEON.xforms.Globals.formLoadingError[formIndex].style.display = "none";
            if (ORBEON.xforms.Globals.formLoadingNone[formIndex] != null)
                ORBEON.xforms.Globals.formLoadingNone[formIndex].style.display = "block";
            break;
        case "error":
            if (ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex] != null)
                ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex].cfg.setProperty("visible", false);
            if (ORBEON.xforms.Globals.formLoadingError[formIndex] != null)
                ORBEON.xforms.Globals.formLoadingError[formIndex].style.display = "block";
            if (ORBEON.xforms.Globals.formLoadingNone[formIndex] != null)
                ORBEON.xforms.Globals.formLoadingNone[formIndex].style.display = "none";
            break;
        case "none":
            if (!ORBEON.xforms.Globals.loadingOtherPage) {
                if (ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex] != null)
                    ORBEON.xforms.Globals.formLoadingLoadingOverlay[formIndex].cfg.setProperty("visible", false);
                if (ORBEON.xforms.Globals.formLoadingError[formIndex] != null)
                    ORBEON.xforms.Globals.formLoadingError[formIndex].style.display = "none";
                if (ORBEON.xforms.Globals.formLoadingNone[formIndex] != null)
                    ORBEON.xforms.Globals.formLoadingNone[formIndex].style.display = "block";
            }
            break;
    }
}

// Gets a value stored in the hidden client-state input field
function xformsGetFromClientState(formIndex, key) {
    var clientState = ORBEON.xforms.Globals.formClientState[formIndex];
    var keyValues = clientState.value.split("&");
    for (var i = 0; i < keyValues.length; i = i + 2)
        if (keyValues[i] == key)
            return unescape(keyValues[i + 1]);
    return null;
}

// Returns a value stored in the hidden client-state input field
function xformsStoreInClientState(formIndex, key, value) {
    var clientState = ORBEON.xforms.Globals.formClientState[formIndex];
    var keyValues = clientState.value == ""? new Array() : clientState.value.split("&");
    var found = false;
    // If we found the key, replace the value
    for (var i = 0; i < keyValues.length; i = i + 2) {
        if (keyValues[i] == key) {
            keyValues[i + 1] = escape(value);
            found = true;
            break;
        }
    }
    // If key is there already, replace it
    if (!found) {
        keyValues.push(key);
        keyValues.push(escape(value));
    }
    clientState.value = keyValues.join("&");
}

/**
 * Value change handling for all the controls. It is assumed that the "value" property of "target"
 * contain the current value for the control. We create a value change event and fire it by calling
 * xformsFireEvents().
 *
 * This function is in general called by xformsHandleValueChange(), and will be called directly by
 * other event handler for less usual events (e.g. slider, HTML area).
 */
function xformsValueChanged(target, other) {
    var valueChanged = target.value != target.previousValue;
    // We don't send value change events for the XForms upload control
    var isUploadControl = ORBEON.util.Dom.hasClass(target, "xforms-upload");
    if (valueChanged && !isUploadControl) {
        target.previousValue = target.value;
        var events = new Array(xformsCreateEventArray
                (target, "xxforms-value-change-with-focus-change", target.value, other));
        var incremental = other == null
                && ORBEON.util.Dom.hasClass(target, "xforms-incremental");
        xformsFireEvents(events, incremental);
    }
    return valueChanged;
}

// Handle click on trigger
function xformsHandleClick(event) {
    var target = getEventTarget(event);
    // Make sure the user really clicked on the trigger, instead of pressing enter in a nearby control
    if ((ORBEON.util.Dom.hasClass(target, "xforms-trigger") || ORBEON.util.Dom.hasClass(target, "xforms-trigger"))
            && !ORBEON.util.Dom.hasClass(target, "xforms-readonly"))
        xformsFireEvents(new Array(xformsCreateEventArray(target, "DOMActivate", null)), false);
    return false;
}

function xformsHandleAutoCompleteMouseChange(input) {
    input.parentNode.lastKeyCode = -1;
    input.parentNode.value = input.value;
    xformsValueChanged(input.parentNode, null);
}

/**
 * Root function called by any widget that wants an event to be sent to the server.
 *
 * @param events       Array of arrays with each array containing:
 *                     new Array(target, eventName, value, other)
 * @param incremental  Are these incremental events
 */
function xformsFireEvents(events, incremental) {
    var newEvents = [];
    for (var eventIndex = 0; eventIndex < events.length; eventIndex++) {
        var event = events[eventIndex];
        var target = event[0];
        var eventName = event[1];
        var value = event[2];
        var other = event[3];
        newEvents.push(new ORBEON.xforms.Server.Event(
                target == undefined ? null : ORBEON.xforms.Controls.getForm(target),
                target == undefined ? null : target.id,
                other == undefined ? null : other.id,
                value, eventName, null, null));
    }
    ORBEON.xforms.Server.fireEvents(newEvents, incremental);
}

function xformsCreateEventArray(target, eventName, value, other) {
    return new Array(target, eventName, value, other);
}

function getEventTarget(event) {
    if (event && event.LinkedField) {
        // Case of events coming from HTML area thrown by the HTML area library
        return event.LinkedField;
    } else {
        // Case of normal HTML DOM events
        event = event ? event : window.event;
        var target = event.srcElement ? event.srcElement : event.target;
        if (target.xformsElement) {
            // HTML area on Gecko: event target is the document, return the textarea
            return target.xformsElement;
        } else if (target.ownerDocument.xformsElement) {
            // HTML area on IS: event target is the body of the document, return the textarea
            return target.ownerDocument.xformsElement;
        } else {
            return target;
        }
    }
}

function xformsHtmlEditorChange(editorInstance) {
    editorInstance.LinkedField.value = editorInstance.GetXHTML();
    // Throw value change event if the field is in incremental mode
    if (ORBEON.util.Dom.hasClass(editorInstance.LinkedField, "xforms-incremental"))
        xformsValueChanged(editorInstance.LinkedField, null);
}

/**
 * Called by FCKeditor when an editor is fully loaded. This is our opportunity
 * to listen for events on this editor.
 */
function FCKeditor_OnComplete(editorInstance) {
    // Save reference to XForms element (textarea) in document for event handlers that receive the document
    editorInstance.EditorDocument.xformsElement = editorInstance.LinkedField;
    // Register value change handler when in incremental mode
    if (ORBEON.util.Dom.hasClass(editorInstance.LinkedField, "xforms-incremental"))
        editorInstance.Events.AttachEvent("OnSelectionChange", xformsHtmlEditorChange);
    // Register focus/blur events for Gecko
    YAHOO.util.Event.addListener(editorInstance.EditorDocument, "focus", ORBEON.xforms.Events.focus);
    YAHOO.util.Event.addListener(editorInstance.EditorDocument, "blur", ORBEON.xforms.Events.blur);
    // Register focus/blur events for IE
    YAHOO.util.Event.addListener(editorInstance.EditorDocument, "focusin", ORBEON.xforms.Events.focus);
    YAHOO.util.Event.addListener(editorInstance.EditorDocument, "focusout", ORBEON.xforms.Events.blur);
    // Load other editors in the queue
    if (ORBEON.xforms.Globals.fckEditorsToLoad.length > 0) {
        var fckEditor = ORBEON.xforms.Globals.fckEditorsToLoad.shift();
        fckEditor.ReplaceTextarea();
        ORBEON.xforms.Controls.updateHTMLAreaClasses(ORBEON.util.Dom.getElementById(fckEditor.InstanceName));
    } else {
        ORBEON.xforms.Globals.fckEditorLoading = false;
        if (typeof xformsPageLoadedServer != "undefined")
            xformsPageLoadedServer();
    }
}

function xformsGetLocalName(element) {
    if (element.nodeType == 1) {
        return element.tagName.indexOf(":") == -1
            ? element.tagName
            : element.tagName.substr(element.tagName.indexOf(":") + 1);
    } else {
        return null;
    }
}

function xformsAddSuffixToIds(element, idSuffix, repeatDepth) {
    var idSuffixWithDepth = idSuffix;
    for (var repeatDepthIndex = 0; repeatDepthIndex < repeatDepth; repeatDepthIndex++)
         idSuffixWithDepth += XFORMS_SEPARATOR_2 + "1";
    if (element.id)
        element.id = xformsAppendRepeatSuffix(element.id, idSuffixWithDepth);
    if (element.htmlFor)
        element.htmlFor = xformsAppendRepeatSuffix(element.htmlFor, idSuffixWithDepth);
    if (element.name) {
        var newName = xformsAppendRepeatSuffix(element.name, idSuffixWithDepth);
        if (element.tagName.toLowerCase() == "input" && element.type.toLowerCase() == "radio"
                && ORBEON.xforms.Globals.isRenderingEngineTridend) {
            // IE supports changing the name of elements, but according to the Microsoft documentation, "This does not
            // cause the name in the programming model to change in the collection of elements". This has a implication
            // for radio buttons where using a same name for a set of radio buttons is used to group them together.
            // http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/properties/name_2.asp
            var clone = document.createElement("<" + element.tagName + " name='" + newName + "'>");
            for (var attributeIndex = 0; attributeIndex < element.attributes.length; attributeIndex++) {
                var attribute = element.attributes[attributeIndex];
                if (attribute.nodeName.toLowerCase() != "name" && attribute.nodeName.toLowerCase() != "height" && attribute.nodeValue)
                    clone.setAttribute(attribute.nodeName, attribute.nodeValue);
            }
            YAHOO.util.Event.addListener(clone, "focus", ORBEON.xforms.Events.focus);
            YAHOO.util.Event.addListener(clone, "blur", ORBEON.xforms.Events.blur);
            YAHOO.util.Event.addListener(clone, "change", ORBEON.xforms.Events.change);
            element.replaceNode(clone);
        } else {
            element.name = newName;
        }
    }
    // Remove references to hint, help, alert, label as they might have changed
    for (var childIndex = 0; childIndex < element.childNodes.length; childIndex++) {
        var childNode = element.childNodes[childIndex];
        if (childNode.nodeType == ELEMENT_TYPE) {
            if (childNode.id && childNode.id.indexOf("repeat-end-") == 0) repeatDepth--;
            xformsAddSuffixToIds(childNode, idSuffix, repeatDepth);
            if (childNode.id && childNode.id.indexOf("repeat-begin-") == 0) repeatDepth++
        }
    }
}

// Function to find the input element below a given node
function xformsGetInputUnderNode(node) {
    if (node.nodeType == ELEMENT_TYPE) {
        if (node.tagName.toLowerCase() == "input") {
            return node;
        } else {
            for (var childIndex = 0; childIndex < node.childNodes.length; childIndex++) {
                var result = xformsGetInputUnderNode(node.childNodes[childIndex]);
                if (result != null) return result;
            }
        }
    } else {
        return null;
    }
}

function xformsGetClassForRepeatId(repeatId) {
    var depth = 1;
    var currentRepeatId = repeatId;
    while (true) {
        currentRepeatId = ORBEON.xforms.Globals.repeatTreeChildToParent[currentRepeatId];
        if (currentRepeatId == null) break;
        depth = (depth == 4) ? 1 : depth + 1;
    }
    return "xforms-repeat-selected-item-" + depth;
}

function xformsDisplayLoading() {
    if (ORBEON.xforms.Globals.requestInProgress == true)
        xformsDisplayIndicator("loading");
}

// Run xformsPageLoaded when the browser has finished loading the page
// In case this script is loaded twice, we still want to run the initialization only once
if (!ORBEON.xforms.Globals.pageLoadedRegistered) {
    ORBEON.xforms.Globals.pageLoadedRegistered = true;
    // If the browser does not provide a console object, create one which delegates log() to xformsLog()
    YAHOO.util.Event.addListener(window, "load", ORBEON.xforms.Init.document);
}
ORBEON.xforms.Globals.debugLastTime = new Date().getTime();
