










// Nextag DHTML Calendar and Date Picker
// Date: 6/21/2004
// Version: @{#}CVS versionInfo: $Id: picker.js,v 1.29.24.1 2009/03/04 05:02:29 etai Exp $

// months as they appear in the calendar's title
var ARR_MONTHS = ["January", "February", "March", "April", "May", "June",
		"July", "August", "September", "October", "November", "December"];
// week day titles as they appear on the calendar
var ARR_WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
// date delimiter
var DATE_DELIMITER = '/';

// Localization
var ARR_MONTHS_DE = [ "Januar", "Februar", "M&#228;rz", "April", "M&#246;gen", "Juni",
		"Juli", "August", "September", "Oktober", "November", "Dezember" ];
var ARR_WEEKDAYS_DE = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
var DATE_DELIMITER_DE = '.';

var ARR_MONTHS_FR = [ "Janvier", "F&#232;vrier", "Mars", "Avril", "Peuvent", "Juin",
		"Juillet", "Ao&#251;t", "Septembre", "Octobre", "Novembre", "D&#232;cembre" ] ;
var ARR_WEEKDAYS_FR = ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"];
var DATE_DELIMITER_FR = '.';

// path to the directory where calendar images are stored. trailing slash req.
var STR_ICONPATH = '/js/calendar/img';

var FormDate = (function(){

	function constFunc(params){
	  /** private static variables **/
		var mName = params["name"];
		this.locale = params["localeCode"];
		this.delimiter = DATE_DELIMITER;
		if ( this.locale == "DE" ){
			this.delimiter = DATE_DELIMITER_DE;
		} else if ( this.locale == "FR" ){
			this.delimiter = DATE_DELIMITER_FR;
		}
		var mDate = new Date();
		var autoAdjustYear =params["autoAdjustYear"];
		var mElementMonth = document.getElementById(params["elemMonthId"]);
		if (mElementMonth != null)
			mElementMonth.formDate = this;
		var mElementDay = document.getElementById(params["elemDayId"]);
		if (mElementDay != null)
			mElementDay.formDate = this;
		var mElementYear = document.getElementById(params["elemYearId"]);
		if (mElementYear != null)
			mElementYear.formDate = this;
		var mElementDate = document.getElementById(params["elemDateId"]);
		if (mElementDate != null)
			mElementDate.formDate = this;

		var showOneYear = params["showOneYear"];

		/** privileged instance methods **/
		this.setDate = function(d,clearUI){
			if (d instanceof Date){
				// special case where setting day to 31 will
				// increment the month (bug 22264)
				if (mDate.getDate() > 27){
					mDate.setDate(27);
				}
				mDate.setMonth(d.getMonth());
				mDate.setDate(d.getDate());
				mDate.setFullYear(d.getFullYear());
			} else {
				var arr = d.split(this.delimiter);
				var isNumeric = arr.length == 3 && !isNaN(arr[0]) && !isNaN(arr[1]) && !isNaN(arr[2]);
				if(!isNumeric) return;

				var proposedDate = new Date();
				var formatDate = params["formatDate"];
				if(arr[2].length == 2)
					arr[2] = 20 + arr[2];
				if ( this.locale != "US" ) {
					proposedDate = new Date(arr[2],parseInt(arr[1])-1,(arr[0]));		
				} else {
					proposedDate = new Date(arr[2],(arr[0]-1),arr[1]);
				}
				var currentDate = new Date();
				var oneYearAway = new Date();
				oneYearAway.setFullYear(oneYearAway.getFullYear() + 1);
				var isValid = currentDate.getTime() < proposedDate.getTime() &&
								proposedDate.getTime() < oneYearAway.getTime();
				if (isValid){
					this.setDate(proposedDate,clearUI);
				}
			}
			this.updateFormElements(clearUI);
		};

		this.getDate = function(){
			return mDate;
		};

		this.updateFormElements = function(clearValues){
			if (mElementMonth != null){
				if ( clearValues ) {
					mElementMonth.value = "";
				} else {
					mElementMonth.value = (mDate.getMonth()+1);
				}
			}
			if (mElementDay != null){
				if ( clearValues ) {
					mElementDay.value = "";
				} else {
					mElementDay.value = mDate.getDate();
				}
			}
			if (mElementYear != null){
				if ( clearValues ) {
					mElementYear.value = "";
				} else {
					mElementYear.value = mDate.getFullYear();
				}
			}
			if (mElementDate != null) {
				if ( clearValues ) {
					mElementDate.value = "";
				} else {
					var formatDate = params["formatDate"];
					var year = (params["shortYearFormat"]) ? (mDate.getFullYear() % 100) : mDate.getFullYear();
					if ( formatDate != 'mm/dd/yyyy' ) {
						mElementDate.value = (mDate.getDate() < 10 ? "0" : "") + mDate.getDate() + this.delimiter + (mDate.getMonth()+1 < 10 ? "0" : "") + (mDate.getMonth()+1) + this.delimiter + (year < 10 ? "0" : "") + year;
					} else {
						mElementDate.value = (mDate.getMonth()+1 < 10 ? "0" : "") + (mDate.getMonth()+1) + this.delimiter + (mDate.getDate() < 10 ? "0" : "") + mDate.getDate() + this.delimiter + (year < 10 ? "0" : "") + year;
					}
				}
			}
		};

		this.elementChanged = function(ev){
			var target = NextagDCalendar.getTargetElement(ev);
			if ( mElementMonth != undefined && target.id == mElementMonth.id)
				mDate.setMonth((mElementMonth.value-1));
			else if ( mElementDay != undefined && target.id == mElementDay.id)
				mDate.setDate(mElementDay.value);
			else if (mElementYear != undefined && target.id == mElementYear.id)
				mDate.setFullYear(mElementYear.value);
			else if ( mElementDate != undefined && target.id == mElementDate.id)
				target.formDate.setDate(mElementDate.value);

			var visMin = new Date(); visMin.setDate(visMin.getDate()-1);
			var visMax = new Date(); visMax.setDate(visMin.getDate()+(showOneYear?365:0));
			var d = null;
			if (showOneYear){	// if user wants to restrict days by a year starting from TODAY
				if(autoAdjustYear) {	// add a year if day < today i.e. autoAdjustYear
	                                if (target.formDate.getDate() < visMin){
	                                        d = new Date(target.formDate.getDate());
	                                        d.setFullYear(d.getFullYear()+1);
	                                        target.formDate.setDate(d);
	                                } else if (target.formDate.getDate() > visMax){   //subtract a year if day > a year later i.e. autoAdjustYear
	                                        d = new Date(target.formDate.getDate());
	                                        d.setFullYear(d.getFullYear()-1);
	                                        target.formDate.setDate(d);
	                                }
        	                } else {	// leave the day to visMin if day < today i.e. no autoadjust
	                                if ( target.formDate.getDate() < visMin)
	                                        target.formDate.setDate(visMin);
	                                else if ( target.formDate.getDate() > visMax) // leave the day to visMax if day > a year later i.e. noautoadjust
	                                        target.formDate.setDate(visMax);
	                        }

			}
			target.formDate.updateFormElements();
			if (target.parentCalendar){
				NextagDCalendar.fireDateChangeEvent(target.parentCalendar);
			}
		};

	    /** constructor body **/
	    if (params["date"] != null)
	    {
			this.setDate(params["date"],!params["initializeDates"]);
		}
		// need to register for onChange event for all form elements
		// on change, update this
		if (mElementMonth != null)
			NextagDCalendar.addEvent(mElementMonth, "change", this.elementChanged);
		if (mElementDay != null)
			NextagDCalendar.addEvent(mElementDay, "change", this.elementChanged);
		if (mElementYear != null)
			NextagDCalendar.addEvent(mElementYear, "change", this.elementChanged);
		if (mElementDate != null){
			NextagDCalendar.addEvent(mElementDate, "change", this.elementChanged);
			//NextagDCalendar.addEvent(mElementDate, "keyup", this.elementChanged);
		}
	};

	// constFunc.prototype = new Date();

	return constFunc;
})();


/**
 * Constructor parameter object
 * name						- required
 * date						- default today
 * leftOffset			- default 0
 * topOffset			- default 18
 * showOneYear		- default true
 * restrictView		- default true
 * autoAdjustYear	- default false
 * startWeek			- default 0 (Sunday)
 * localeCode			- default US. UK same as US. Currently supports US, UK, DE, FR
 * dateFormat       - default mm/dd/yyyy
 * elemMonthId		- default NAME_month
 * elemDayId			- default NAME_day
 * elemYearId			- default NAME_year
 * elemDateId			- default NAME_date
 * elemButtonId		- default NAME_button
 * clTable				- default #3366cc
 * clGrid					- default #ffffff
 * clTitleCell		- default #3366cc
 * clTitleText		- default #ffffff
 * clHeaderCell		- default #cccccc
 * clHeaderText		- default #3366cc
 * clWeekdayCell	- default #ffffff
 * clWeekdayText	- default #000000
 * clWeekendCell	- default #dbeaf5
 * clWeekendText	- default #000000
 * clSelectedCell	- default #99ccff
 * clSelectedText - default #000000
 * clRelText			- default #888888
 * clRelCell			- default #ffffff
 * zIndex 		- default 0           /adding this parameter to change zIndex if used on layers with higer than 0 zIndex
 * numMonths - default 1. The number of months the calendar should display
 * isHorizontal - default true. Whether or not the calendar should tile months horizontally
 * defaultBlank - Whether or not the calendar should clear the date boxes
 * initializeDates - Whether or not the calendar should show the dates on initialization
 */
var NextagDCalendar = (function(){
	/** private static variables **/
	var sCalendars = new Array();
	var sIndexedCalendars = new Array();
	var sCalendarCount = 0;
	var sVisibleCalendar = null;
	var sDateChangeListeners = new Array();

	/* constructor */
	function Calendar(params){
		function setParamDefaults(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

	  var mDisabled = false;
		var mName = params["name"];
		setParamDefaults("showOneYear",true);
		setParamDefaults("restrictView",true);
		setParamDefaults("autoAdjustYear",false);
		setParamDefaults("startWeek",0);
		setParamDefaults("date",new Date());
		setParamDefaults("leftOffset", 0);
		setParamDefaults("topOffset", 18);
		setParamDefaults("localeCode", "US");
		setParamDefaults("formatDate", "mm/dd/yyyy");
		setParamDefaults("elemMonthId", mName + "_month");
		setParamDefaults("elemDayId", mName + "_day");
		setParamDefaults("elemYearId", mName + "_year");
		setParamDefaults("elemDateId", mName + "_date");
		setParamDefaults("elemButtonId", mName + "_button");
		setParamDefaults("clTable","#3366CC");
		setParamDefaults("clGrid","#ffffff");
		setParamDefaults("clTitleCell","#3366cc");
		setParamDefaults("clTitleText","#ffffff");
 		setParamDefaults("clHeaderCell","#cccccc");
		setParamDefaults("clHeaderText","#3366CC");
 		setParamDefaults("clWeekdayCell","#ffffff");
 		setParamDefaults("clWeekdayText","#000000");
 		setParamDefaults("clWeekendCell","#dbeaf5");
 		setParamDefaults("clWeekendText","#000000");
 		setParamDefaults("clSelectedCell","#99ccff");
 		setParamDefaults("clSelectedText","#000000");
 		setParamDefaults("clRelText","#888888");
 		setParamDefaults("clRelCell","#ffffff");
		setParamDefaults("zIndex",0);
		setParamDefaults("numMonths",1);
		setParamDefaults("isHorizontal",true);
		setParamDefaults("shortYearFormat",false);
		setParamDefaults("monthsToScroll",1);
		setParamDefaults("isEditable",false);
		setParamDefaults("defaultBlank",false);
		setParamDefaults("initializeDates",true);
		setParamDefaults("tagsToHide", ['applet', 'iframe', 'select']);
		var mParams = params;

		this.showOneYear = params["showOneYear"];
		this.restrictView = params["restrictView"];
		this.autoAdjustYear = params["autoAdjustYear"];

		this.numMonths = parseInt(params["numMonths"]);
		this.isHorizontal = params["isHorizontal"];
		this.monthsToScroll = parseInt(params["monthsToScroll"]);
		var mTagsToHide = params["tagsToHide"];

		if(params["secondaryTriggers"] != null && params["secondaryTriggers"] != "")
		{
			var secondaryTriggers = new Array();
			for(i=0;i<params["secondaryTriggers"].length;i++)
			{
				elem = document.getElementById(params["secondaryTriggers"][i]);
				if(elem != null)
					secondaryTriggers[secondaryTriggers.length] = elem;
			}
		}

		this.currPage = 0;
		this.zIndex = params["zIndex"];

		// localize - only supports US/DE/FR -
		// everything else (including UK) will get US locale
		var mArr_Months = ARR_MONTHS;
		var mArr_Weekdays = ARR_WEEKDAYS;
		this.localeCode = params["localeCode"];
		if (this.localeCode == "DE"){
			mArr_Months = ARR_MONTHS_DE;
			mArr_Weekdays = ARR_WEEKDAYS_DE;
		} else if (this.localeCode == "FR"){
			mArr_Months = ARR_MONTHS_FR;
			mArr_Weekdays = ARR_WEEKDAYS_FR;
		} else {
			this.localeCode = "US";
		}
		var mStartWeekday = params["startWeek"];
		var mFormDate = new FormDate(params);

		var mElemButton = document.getElementById(params["elemButtonId"]);
		if (mElemButton != null)
			mElemButton.parentCalendar = this;
		var mElemMonth = document.getElementById(params["elemMonthId"]);
		if (mElemMonth != null)
			mElemMonth.parentCalendar = this;
		var mElemDay = document.getElementById(params["elemDayId"]);
		if (mElemDay != null)
			mElemDay.parentCalendar = this;
		var mElemYear = document.getElementById(params["elemYearId"]);
		if (mElemYear != null)
			mElemYear.parentCalendar = this;
		var mElemDate = document.getElementById(params["elemDateId"]);
		if (mElemDate != null)
			mElemDate.parentCalendar = this;

		var mCalPanel = null;

		/** privileged instance methods **/

		this.isDisabled = function() { return mDisabled; };
		this.setDisabled = function(d){
			mDisabled = d;
			if (!mDisabled){
				NextagDCalendar.fireDateChangeEvent(this);
			}
		};

		this.clickHandler = function(ev){
			var target = NextagDCalendar.getTargetElement(ev);
			var elem = NextagDCalendar.getElement(ev);

			isSecondaryTrigger = false;
			if(secondaryTriggers != null)
			{
				for(i=0;i<secondaryTriggers.length;i++)
					if(target.id == secondaryTriggers[i].id)
						isSecondaryTrigger = true;
			}

			if ((target.id == mElemButton.id || isSecondaryTrigger) && target.parentCalendar &&
					!target.parentCalendar.isDisabled()){
				if ( !params["isEditable"] || target.id != mElemDate.id ||
						NextagDCalendar.getVisible() == null || 
						NextagDCalendar.getVisible().getName() != target.parentCalendar.getName() ){
					Calendar.setVisible(target.parentCalendar);
				}
				return NextagDCalendar.stopEvent(ev);
			}
			return false;
		};

		this.getName = function(){ return mName; };

		this.getCalPanel = function(){ return mCalPanel; };

		this.getTagsToHide = function() { return mTagsToHide; };

		this.setNewDate = function(longDate,clearValues){
			mFormDate.setDate(new Date(longDate),clearValues);
		};

		this.show = function(){
			var pos = NextagDCalendar.getElementPosition(mElemButton);

			this.drawCalendarTable();

			mCalPanel.style.top = (pos.y+mParams["topOffset"]) + "px";
			mCalPanel.style.left = (pos.x+mParams["leftOffset"]) + "px";
			mCalPanel.style.display = "block";
			mCalPanel.style.zIndex = mParams["zIndex"];
			if (NextagDCalendar.is_ie)
				this.hideShowCovered();
		};

		this.hide = function(){
			var prevElem = document.getElementById('prevMonth');
			var nextElem = document.getElementById('nextMonth');
			if (prevElem != undefined && prevElem != null)
				NextagDCalendar.removeEvent(prevElem, "click", NextagDCalendar.monthNavHandler);
			if (nextElem != undefined && nextElem != null)
				NextagDCalendar.removeEvent(nextElem, "click", NextagDCalendar.monthNavHandler);
			this.currPage = 0;
			mCalPanel.innerHTML = '';
			mCalPanel.style.zIndex = 0;
			mCalPanel.style.display = "none";
			if (NextagDCalendar.is_ie)
				this.hideShowCovered();
			
			if ( mCalPanel != null ){
				mCalPanel.parentNode.removeChild(mCalPanel);
				mCalPanel = null;
			}
		};

		this.drawCalendarTable = function(){
			if (mCalPanel == null){
				mCalPanel = NextagDCalendar.createElement("div");
				mCalPanel.style.position = "absolute";
				mCalPanel.style.display = "none";
				mCalPanel.style.cursor = "default";
				document.body.appendChild(mCalPanel);
			}

			var ct = "";
			for(i=0;i<this.numMonths;i++)
			{
				monthToDisplayDate = new Date();
				monthToDisplayDate.setDate(1);
				newYear = Math.floor((mFormDate.getDate().getMonth()+this.currPage+i)/12);
				newMonth = (mFormDate.getDate().getMonth()+this.currPage+i)%12;
				monthToDisplayDate.setMonth(newMonth);
				monthToDisplayDate.setFullYear(mFormDate.getDate().getFullYear()+newYear);
				ct += this.makeMonthTable(mFormDate.getDate(),
											monthToDisplayDate,
											(i==0) ? true : false,
											(i==this.numMonths-1) ? true : false);
			}
			mCalPanel.innerHTML = ct;

			var prevElem = document.getElementById('prevMonth');
			var nextElem = document.getElementById('nextMonth');
			NextagDCalendar.removeEvent(prevElem, "click", NextagDCalendar.monthNavHandler);
			NextagDCalendar.removeEvent(nextElem, "click", NextagDCalendar.monthNavHandler);
			NextagDCalendar.addEvent(prevElem, "click", NextagDCalendar.monthNavHandler);
			NextagDCalendar.addEvent(nextElem, "click", NextagDCalendar.monthNavHandler);
		};

		this.makeMonthTable = function(selectedDate,monthToDisplayDate,showNavLeft,showNavRight)
		{
			var visMin = new Date(); visMin.setDate(visMin.getDate()-1);
			var visMax = new Date(); visMax.setFullYear(visMax.getFullYear()+1);

			monthToDisplayDate.setDate(1);

			var startDate = new Date(monthToDisplayDate);
			startDate.setDate( 1 - (7 + startDate.getDay() - mStartWeekday) % 7 );

			if(this.isHorizontal)
				style = "style='float:left'";
			else
				style = "style='float:left;clear:both;'";

			var ct = "<table border=0 " + style + " cellpadding=0 cellspacing=0><tr><td><table cellpadding=0 cellspacing=2 bgcolor=" + mParams["clTable"] + " border=0>";
			if(showNavLeft){
				ct += "<tr><td class=smallText style='cursor:pointer' align=left><img id='prevMonth' src='" + STR_ICONPATH + "/prev.gif'></td>";
			}else{
				ct += "<tr>";
			}

			ct += "<td style='color:" + mParams["clTitleText"] + "' class=smallText align=center><b>";
			ct += mArr_Months[monthToDisplayDate.getMonth()] + "&nbsp;" + monthToDisplayDate.getFullYear() + "</b></td>";
			if(showNavRight){
				ct += "<td class=smallText style='cursor:pointer' align=right><img id='nextMonth' src='" + STR_ICONPATH + "/next.gif'></td></tr>";
			}else{
				ct += "</tr>";
			}

			ct += "<tr><td colspan=3><table cellpadding=0 cellspacing=2 bgcolor=" + mParams["clGrid"] + " border=0><tr>";
			for (var n=0; n<7; n++){
				ct += '<td bgcolor=' + mParams["clHeaderCell"] + ' class=smallText width=20 align=center style="color:' + mParams["clHeaderText"] + '"><b>&nbsp;'+mArr_Weekdays[(mStartWeekday+n)%7]+'&nbsp;</b></td>';
			}
			ct += "</tr>";

			while (startDate.valueOf() < monthToDisplayDate.valueOf() || startDate.getMonth() == monthToDisplayDate.getMonth())
			{
				ct += "<tr>";
				for (var wkday=0; wkday<7; wkday++)
				{
					var day = startDate.getDate();
					var textColor = mParams["clWeekdayText"];
					var cellColor = mParams["clWeekdayCell"];
					var isWeekend = (startDate.getDay()==0 || startDate.getDay()==6);
					var isSelected = (day==selectedDate.getDate() && startDate.getMonth()==selectedDate.getMonth() && startDate.getFullYear()==selectedDate.getFullYear());
					var isCurrMonth = (startDate.getMonth() == monthToDisplayDate.getMonth());

					if (isWeekend) {
						cellColor = mParams["clWeekendCell"];
						textColor = mParams["clWeekendText"];
					}
					if (!isCurrMonth){
						textColor = mParams["clRelText"];
						if (!isWeekend) cellColor = mParams["clRelCell"];
					}
					if (isSelected){ // selected
						textColor = mParams["clSelectedText"];
						cellColor = mParams["clSelectedCell"];
					}

					if (this.restrictView && (startDate.valueOf() <= visMin.valueOf() || startDate.valueOf() > visMax.valueOf())){
						ct += "<td class=smallText width=20 align=center bgcolor=" +
							cellColor + " style='cursor:default;color:" + textColor + "'><s><b>&nbsp;" + day + "&nbsp;</b></s></td>";
					} else {
						ct += "<td nowrap class=smallText width=20 align=center onClick='NextagDCalendar.dateSelectHandler(" + startDate.valueOf() + ")' bgcolor=";
						ct += cellColor + " style='cursor:pointer;color:" + textColor + "'><b>";
						ct += "&nbsp;" + day + "&nbsp;";
						ct += "</b></td>";
					}
					startDate.setDate(day+1);
				}
				ct += "</tr>";
			}
			ct += "</table></td></tr></table></td></tr></table>";
			return ct;
		};

		/** privileged instance methods  **/
		this.getDate = function(){ return mFormDate.getDate(); };

		var jsS = this.clickHandler;

		/* constructor body */
		if (mElemButton != null){
			// register for click event on the main document
			NextagDCalendar.addEvent(mElemButton, "click", jsS);
			//NextagDCalendar.removeEvent(mElemButton, "click", this.clickHandler);
		}
		if(params["secondaryTriggers"] != null && params["secondaryTriggers"] != "")
		{
			for(i=0;i<params["secondaryTriggers"].length;i++)
			{
				trigger = document.getElementById(params["secondaryTriggers"][i]);
				trigger.parentCalendar = this;
				NextagDCalendar.addEvent(trigger,"click",this.clickHandler);
			}
		}

		this.killMe = function() {
		/*	var mElementMonth = document.getElementById(params["elemMonthId"]);
			var mElementDay = document.getElementById(params["elemDayId"]);
			var mElementYear = document.getElementById(params["elemYearId"]);
			var mElementDate = document.getElementById(params["elemDateId"]);
			var mElemButton = document.getElementById(params["elemButtonId"]);

			if (mElementMonth != null) {
				NextagDCalendar.removeEvent(mElementMonth, "change", mFormDate.elementChanged);
				mElementMonth.formDate = null;
			}
			if (mElementDay != null){
				NextagDCalendar.removeEvent(mElementDay, "change", mFormDate.elementChanged);
				mElementDay.formDate = null;
			}
			if (mElementYear != null) {
				NextagDCalendar.removeEvent(mElementYear, "change", mFormDate.elementChanged);
				mElementYear.formDate = null;
			}
			if (mElementDate != null) {
				NextagDCalendar.removeEvent(mElementDate, "change", mFormDate.elementChanged);
				mElementDate.formDate = null;
			}
			if (mElemButton != null) {
				NextagDCalendar.removeEvent(mElemButton, "click", jsS);
				mElemButton.parentCalendar = null;
			}*/
		};

		var win = document.defaultView || document.parentWindow;
		if (win && typeof win.attachEvent != "undefined") {
			win.attachEvent("onunload", this.killMe);
		}
		if(window) {
			window.onunload = this.killMe;
		}
		win = null;
	};

	/** private static methods **/

	/** privileged static methods **/
	Calendar.getCalendarItem = function(i){ return sIndexedCalendars!=null&&i<sCalendarCount?sIndexedCalendars[i]:null; };

	Calendar.getInstance = function(params){
		var cal = sCalendars[params["name"]];
		if (sCalendarCount == 0){
			// statically register for click event on the main document
			Calendar.addEvent(document, "click", NextagDCalendar.documentClickHandler);
		}
		if (cal == undefined){
			cal = new Calendar(params);
			sCalendars[params["name"]] = cal;
			sIndexedCalendars[sCalendarCount++] = cal;
		}
		return cal;
	};
	// adding this method if adding the same calendar button is required in which case first remove the calendar and then add it again
	Calendar.removeInstance = function(params) {
		var cal = sCalendars[params["name"]];
		if (cal != undefined) {
			var lsCalendarCount = sCalendarCount ;
			for(var i=0; i<lsCalendarCount; i++) {
				if (cal == sIndexedCalendars[i]){
					sCalendars[params["name"]]=null;
					sCalendarCount--;
					for(;i<lsCalendarCount-1;i++){
						sIndexedCalendars[i] = sIndexedCalendars[i+1];
					}
				}
			}
			return true;
		}
		return false;
	};

	Calendar.addDateChangeListener = function (listener){
		if (listener){
			sDateChangeListeners[sDateChangeListeners.length] = listener;
		}
	};

	Calendar.fireDateChangeEvent = function (cal){
		for (var i=0; i<sDateChangeListeners.length; i++){
			var listener = sDateChangeListeners[i];
			if (listener && listener.dispatchDateChange){
				listener.dispatchDateChange(cal);
			}
		}
	};

	Calendar.getVisible = function(){ return sVisibleCalendar; };

	Calendar.setVisible = function(cal){
		if (sVisibleCalendar == null){
			// show this calendar
			if (cal != null)
				cal.show();
			sVisibleCalendar = cal;
		} else {
			var visCal = sVisibleCalendar;
			// hide the visible calendar
			sVisibleCalendar.hide();
			sVisibleCalendar = null;
			if ((cal != null) && (cal.getName() != visCal.getName())){
				// show this calendar
				cal.show();
				sVisibleCalendar = cal;
			}
		}
	};

	/** privileged instance methods **/

	return Calendar;
})();

/** public static variables **/
// detect a special case of "web browser"
NextagDCalendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
		   !/opera/i.test(navigator.userAgent) );
NextagDCalendar.is_ie5 = ( NextagDCalendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
// detect Opera browser
NextagDCalendar.is_opera = /opera/i.test(navigator.userAgent);
// detect KHTML-based browsers
NextagDCalendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);


/** public static methods **/
NextagDCalendar.dateSelectHandler = function(longDate){
	if (NextagDCalendar.getVisible() == null)
		return true;

	NextagDCalendar.getVisible().setNewDate(longDate);
	NextagDCalendar.fireDateChangeEvent(NextagDCalendar.getVisible());
	return true;
};

NextagDCalendar.monthNavHandler = function(ev){
	var target = NextagDCalendar.getTargetElement(ev);
	var cal = NextagDCalendar.getVisible();
	if (cal == null)
		return true;

	if (target.id == 'prevMonth')
		cal.currPage -= cal.monthsToScroll;
	else
		cal.currPage += cal.monthsToScroll;

	cal.drawCalendarTable();
	return NextagDCalendar.stopEvent(ev);
};

NextagDCalendar.documentClickHandler = function(ev){
	//Delay documentClickHandler to give link's onclick a chance to handle first
	setTimeout(function() {
		if (NextagDCalendar.getVisible() != null)
			NextagDCalendar.setVisible();
	}, 100);
	return true;
};

NextagDCalendar.addEvent = function(el, evname, func) {
	if(el != null)
	{
		if (el.attachEvent) { // IE
			el.attachEvent("on" + evname, func);
		} else if (el.addEventListener) { // Gecko / W3C
			el.addEventListener(evname, func, false);
		} else {
			el["on" + evname] = func;
		}
	}
};

NextagDCalendar.removeEvent = function(el, evname, func) {
	if (el.detachEvent) { // IE
		el.detachEvent("on" + evname, func);
	} else if (el.removeEventListener) { // Gecko / W3C
		el.removeEventListener(evname, func, true);
	} else {
		el["on" + evname] = null;
	}
};

NextagDCalendar.stopEvent = function(ev) {
	ev || (ev = window.event);
	if (NextagDCalendar.is_ie) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
};

NextagDCalendar.getElement = function(ev) {
	if (NextagDCalendar.is_ie) {
		return window.event.srcElement;
	} else {
		return ev.currentTarget;
	}
};

NextagDCalendar.getTargetElement = function(ev) {
	if (NextagDCalendar.is_ie) {
		return window.event.srcElement;
	} else {
		return ev.target;
	}
};

NextagDCalendar.createElement = function(type, parent) {
	var el = null;
	if (document.createElementNS) {
		// use the XHTML namespace; IE won't normally get here unless
		// _they_ "fix" the DOM2 implementation.
		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
	} else {
		el = document.createElement(type);
	}
	if (typeof parent != "undefined") {
		parent.appendChild(el);
	}
	return el;
};

NextagDCalendar.getElementPosition = function(obj){
	var curleft = 0;
	var curtop = 0;
	if (obj.offsetParent){
		while (obj.offsetParent){
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
		if (obj){
			if (obj.offsetLeft)
				curleft += obj.offsetLeft;
			if (obj.offsetTop)
				curtop += obj.offsetTop;
		}
	} else if (obj.x){
		curleft += obj.x;
		curtop += obj.y;
	}
	return { x: curleft, y: curtop };
};

NextagDCalendar.prototype.hideShowCovered = function () {
	var self = this;
	NextagDCalendar.continuation_for_khtml_browser = function() {
		function getVisib(obj){
			var value = obj.style.visibility;
			if (!value) {
				if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
					if (!NextagDCalendar.is_khtml)
						value = document.defaultView.
							getComputedStyle(obj, "").getPropertyValue("visibility");
					else
						value = '';
				} else if (obj.currentStyle) { // IE
					value = obj.currentStyle.visibility;
				} else
					value = '';
			}
			return value;
		};

		var tags = self.getTagsToHide();
		var el = self.getCalPanel();

		var p = NextagDCalendar.getElementPosition(el);
		var EX1 = p.x;
		var EX2 = el.offsetWidth + EX1;
		var EY1 = p.y;
		var EY2 = el.offsetHeight + EY1;

		for (var k = tags.length; k > 0; ) {
			var ar = document.getElementsByTagName(tags[--k]);
			var cc = null;

			for (var i = ar.length; i > 0;) {
				cc = ar[--i];

				p = NextagDCalendar.getElementPosition(cc);
				var CX1 = p.x;
				var CX2 = cc.offsetWidth + CX1;
				var CY1 = p.y;
				var CY2 = cc.offsetHeight + CY1;

				if (self.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";
				}
			}
		}
	};
	if (NextagDCalendar.is_khtml)
		setTimeout("NextagDCalendar.continuation_for_khtml_browser()", 10);
	else
		NextagDCalendar.continuation_for_khtml_browser();
};

// helper - calendar pair listener
var CalendarPairChangeListener = (function(){
	function Listener(cal1, cal2, gap, noSameDay){
		var fromCal = cal1;
		var toCal = cal2;
		var diff = gap;
		var disallowSameDay = noSameDay;

		this.dispatchDateChange = function (cal){
			if (cal==null || fromCal == null || toCal == null)
				return;
			if (cal!=fromCal && cal!=toCal)
				return;

			var c1_date = fromCal.getDate();
			var c2_date = toCal.getDate();
			c1_date.setHours(0,0,0,0);
			c2_date.setHours(0,0,0,0);
			if ( (c1_date.valueOf() > c2_date.valueOf()) ||
				 ((c1_date.valueOf() >= c2_date.valueOf()) && disallowSameDay) ){
				c2_date = new Date(c1_date);
				c2_date.setDate(c2_date.getDate()+diff);
				toCal.setNewDate(c2_date);
			}
		};
	};

	return Listener;
})();

// helper - calendar pair listener for calendars with blank default dates
var BlankCalendarPairChangeListener = (function(){
	function Listener(cal1, cal2, gap, noSameDay){
		var fromCal = cal1;
		var toCal = cal2;
		var diff = gap;
		var disallowSameDay = noSameDay;
		
		this.dispatchDateChange = function (cal){
			if (cal==null || fromCal == null || toCal == null)
				return;
			if (cal!=fromCal && cal!=toCal)
				return;

			var fromCal_date = fromCal.getDate();
			var toCal_date = toCal.getDate();

			var moveToCalendarForward = false;
			var moveFromCalendarBackward = false;
			if ( cal.getName() == fromCal.getName() ){
				moveToCalendarForward = true;
			} else if ( cal.getName() == toCal.getName() ){
				moveFromCalendarBackward = true;
			}

			fromCal_date.setHours(0,0,0,0);
			toCal_date.setHours(0,0,0,0);
			var changeDatesForward = fromCal_date.valueOf() > toCal_date.valueOf() || (fromCal_date.valueOf() >= toCal_date.valueOf() && disallowSameDay);
			var changeDatesBackwards = toCal_date.valueOf() < fromCal_date.valueOf() || (toCal_date.valueOf() <= fromCal_date.valueOf() && disallowSameDay);
			if ( changeDatesForward && moveToCalendarForward ){
				toCal.setNewDate(fromCal_date,true);
			} else if ( changeDatesBackwards && moveFromCalendarBackward ){
				fromCal.setNewDate(toCal_date,true);
			}
		};
	};

	return Listener;
})();


var colourOfInactiveTab = "#bbbbbb";
var colourOfActiveTab = "#dddddd";
var colourOfInactiveLink = "#0000ff";
var colourOfActiveLink = "#ffffff";

function domTab(tab){
	if (document.getElementById){
		document.getElementById('air').style.display='none';
		document.getElementById('car').style.display='none';
		document.getElementById('hotel').style.display='none';
		document.getElementById('airTab').style.background=colourOfInactiveTab;
		document.getElementById('carTab').style.background=colourOfInactiveTab;
		document.getElementById('hotelTab').style.background=colourOfInactiveTab;
		document.getElementById('airAds').style.display='none';
		document.getElementById('carAds').style.display='none';
		document.getElementById('hotelAds').style.display='none';

		document.getElementById(tab).style.display='block';
		document.getElementById(tab+"Tab").style.background=colourOfActiveTab;
		document.getElementById(tab+"Ads").style.display='block';
	}
}

function roundTrip(r){
	if (r==true) {
		document.getElementById('returning').style.display='block';
	} else {
		document.getElementById('returning').style.display='none';
	}
}
function initializeDate(datefield, offsetdays){
	// Set the initial date
	var field = document.getElementById(datefield);
	if (field) {
		var d;
		var days;
		if (field.value=="") {
			d = new Date();
			days = d.getDate()+offsetdays;
		} else {
			d = new Date(field.value);
			days = d.getDate();
		}
		d.setDate(days);
		setFieldValue("secs",d.getTime());
		setDate1Copy(d);
	}
}
function initializeDate2(datefield, offsetdays){
	// Set the initial date
	var field = document.getElementById(datefield);
	if (field) {
		var d;
		var days;
		if (field.value=="") {
			d = new Date();
			days = d.getDate()+offsetdays;
		} else {
			d = new Date(field.value);
			days = d.getDate();
		}
		d.setDate(days);
		setDate2Copy(d);
	}
}
// Only let users select days between yesterday and a year from now
var yd=new Date();
var nyd=new Date();
yd.setDate(yd.getDate()-1);
nyd.setYear(nyd.getYear()+1);
var yt=yd.getTime();
var nyt=nyd.getTime();
function dateValid(date, y, m, d) {
	var dt=date.getTime()
	if ((dt<yt)||(dt>nyt)) {
		return true;
	} else {
		return false;
	}
}
function dateValid2(date, y, m, d) {
	var dt=date.getTime()
	if ((dt<document.getElementById("secs").value)||(dt>nyt)) {
		return true;
	} else {
		return false;
	}
}

function setFieldValue(f,v) {
	var field = document.getElementById(f);
	if (field) field.value = v;
}
function setFieldValueIfEmpty(f,v) {
	var field = document.getElementById(f);
	if (field) if (field.value=="") {
		field.value = v;
	}
}

// Set all of the from dates
function setDateText(fld,num) {
	var d = parseDate(fld.value,"%o/%e/%y");
	if (!d) {
		if (fld.value!="") alert("Unrecognized date '"+fld.value+"'");
		fld.value="";
		fld.focus();
	} else {
		eval("setDate"+num+"Copy(d);");
	}
}
function setDate1(cal) {
	var d = new Date(cal.date);
	return setDate1Copy(d);
}
function addYear(d) {
	// Normalize to 200x
	var yr=d.getYear();
	if (yr<99) yr+=2000;
	if (yr<199) yr+=1900;
	return(yr);
}
function setDate1Copy(d) {
	// Save # of seconds
	setFieldValue("secs",d.getTime());
	// Calculate year for NS and IE
	var year1=addYear(d);
	// Set all field1s
	setFieldValue("airDate1",d.print("%o/%e/%y"));
	setFieldValue("departingDay",d.getDate());
	setFieldValue("departingMonth",1+d.getMonth());
	setFieldValue("departingYear",year1);
	setFieldValue("hotelDate1",d.print("%o/%e/%y"));
	setFieldValue("checkinDay",d.getDate());
	setFieldValue("checkinMonth",1+d.getMonth());
	setFieldValue("checkinYear",year1);
	setFieldValue("carDate1",d.print("%o/%e/%y"));
	setFieldValue("pickupDay",d.getDate());
	setFieldValue("pickupMonth",1+d.getMonth());
	setFieldValue("pickupYear",year1);
	// Set date2s if not set
	var t2 = d.getTime();
	t2 += Date.DAY; // Add 1 day
	var d2 = new Date(t2);
	// Calculate year for NS and IE
	var year2=addYear(d2);
	setFieldValueIfEmpty("airDate2",d2.print("%o/%e/%y"));
	setFieldValueIfEmpty("returningDay",year2);
	setFieldValueIfEmpty("returningMonth",1+d2.getMonth());
	setFieldValueIfEmpty("returningYear",year2);
	setFieldValueIfEmpty("hotelDate2",d2.print("%o/%e/%y"));
	setFieldValueIfEmpty("checkoutDay",d2.getDate());
	setFieldValueIfEmpty("checkoutMonth",1+d2.getMonth());
	setFieldValueIfEmpty("checkoutYear",year2);
	setFieldValueIfEmpty("carDate2",d2.print("%o/%e/%y"));
	setFieldValueIfEmpty("dropoffDay",d2.getDate());
	setFieldValueIfEmpty("dropoffMonth",1+d2.getMonth());
	setFieldValueIfEmpty("dropoffYear",year2);
}

// Set all of the to dates
function setDate2(cal) {
	var d = new Date(cal.date);
	return setDate2Copy(d);
}
function setDate2Copy(d) {
	// Calculate year for NS and IE
	var year2=addYear(d);
	setFieldValue("airDate2",d.print("%o/%e/%y"));
	setFieldValue("returningDay",d.getDate());
	setFieldValue("returningMonth",1+d.getMonth());
	setFieldValue("returningYear",year2);
	setFieldValue("hotelDate2",d.print("%o/%e/%y"));
	setFieldValue("checkoutDay",d.getDate());
	setFieldValue("checkoutMonth",1+d.getMonth());
	setFieldValue("checkoutYear",year2);
	setFieldValue("carDate2",d.print("%o/%e/%y"));
	setFieldValue("dropoffDay",d.getDate());
	setFieldValue("dropoffMonth",1+d.getMonth());
	setFieldValue("dropoffYear",year2);
}

// Set all of the location1's
function setLocation1(loc) {
	setFieldValue("airLocation1",loc);
	setFieldValue("hotelLocation1",loc);
	setFieldValue("carLocation1",loc);
}

// Set all of the location2's
function setLocation2(loc) {
	setFieldValue("airLocation2",loc);
	setFieldValue("carLocation2",loc);
}

function setupCalendars() {
	// Car
	Calendar.setup({
		inputField	 :	"carDate1",
		button		 :	"carIcon1",
		ifFormat	   :	"%o/%e/%y",
		alignment	  :	"BL",
		dateStatusFunc :	dateValid,
		onUpdate	   :	setDate1
	});
	Calendar.setup({
		inputField	 :	"carDate2",
		button		 :	"carIcon2",
		ifFormat	   :	"%o/%e/%y",
		alignment	  :	"BL",
		dateStatusFunc :	dateValid2,
		onUpdate	   :	setDate2
	});
}

function initializePage() {
//	initializeDate('carDate1',21);
	setupCalendars();
}

function validateHotel(hotelForm, cityPrefill) {
	var city = hotelForm.city.value;
	if (city == cityPrefill) {
		city = hotelForm.suggested_cities.options[hotelForm.suggested_cities.selectedIndex].value;
	}
	if (city.length < 3) {
		alert("Please enter a city");
		hotelForm.city.focus();
		return false;
	}
	hotelForm.city.value = city;
	var checkInDate = new Date(hotelForm.hotelDate1.value);
	var checkOutDate = new Date(hotelForm.hotelDate2.value);
	if (!(checkInDate<checkOutDate)) {
		alert("Please check your dates.  The check-out date must be after the check-in date.");
		hotelForm.hotelDate1.focus();
		return false;
	}
	return true;
}


<!--
/**
 * This compares a set of parent elements and their children.  It assumes that
 * the comparison is only based on the attribute "id" and doesn't compare the contents
 * of the elements.  This should only be used with AJAX elements
 */
function ElementDiff(aParentElement, aChildrenTagName, aIdPrefix, aAttribute,
	bParentElement, bChildrenTagName, bIdPrefix, bAttribute) {
	this.NEW = 1;
	this.SAME = 0;
	this.REMOVED = -1;
	
	this.NEW_TEXT = "NEW";
	this.SAME_TEXT = "SAME";
	this.REMOVED_TEXT = "REMOVED";

	this.mAParentElement = aParentElement;
	this.mBParentElement = bParentElement;
	this.mAChildren = this.mAParentElement.getElementsByTagName(aChildrenTagName);
	this.mBChildren = this.mBParentElement.getElementsByTagName(bChildrenTagName);
	this.mAIdPrefix = aIdPrefix;
	this.mBIdPrefix = bIdPrefix;
	this.mAAttribute = aAttribute;
	this.mBAttribute = bAttribute;
	this.mDifferences = new Object();
	
	this.mNumNew = 0;
	this.mNumSame = 0;
	this.mNumRemoved = 0;
}



ElementDiff.prototype.hasChanges = function() {
	return ( this.mNumSame != this.mDifferences.length );
}

ElementDiff.prototype.diff = function() {
	//Assume every new bChild is new
	for( var i = 0; i < this.mBChildren.length; i++ ) {
		var bChildElement = this.mBChildren[i];

		if ( bChildElement.getAttribute(this.mBAttribute) != null ) {
			var bUniqueId = this.getBUniqueId(bChildElement.getAttribute(this.mBAttribute));
			this.mDifferences[bUniqueId] = this.NEW;
		}
	}
	
	for(var i = 0; i < this.mAChildren.length; i++ ) {
		var aChildElement = this.mAChildren[i];
		
		if ( aChildElement.getAttribute(this.mAAttribute) != null ) {
			var aUniqueId = this.getAUniqueId(aChildElement.getAttribute(this.mAAttribute));
			if ( this.mDifferences[aUniqueId] != null ) {
				this.mDifferences[aUniqueId] = this.SAME;
				this.mNumSame++;
			} else {
				this.mDifferences[aUniqueId] = this.REMOVED;
				this.mNumRemoved++;
			}
		}
	}
	
	this.mNumNew = this.mDifferences.length - ( this.mNumSame + this.mNumRemoved);
}

ElementDiff.prototype.getBUniqueId = function(id) {
	return this.mBIdPrefix + id;
}

ElementDiff.prototype.getAUniqueId = function(id) {
	return this.mAIdPrefix + id;
}

ElementDiff.prototype.getValue = function(differenceValue) {
	if ( differenceValue == this.NEW ) {
		return this.NEW_TEXT;
	} else if ( differenceValue == this.SAME ) {
		return this.SAME_TEXT;
	} else if ( differenceValue == this.REMOVED ) {
		return this.REMOVED_TEXT;
	}
	return "";
}

ElementDiff.prototype.getDifferences = function() {
	return this.mDifferences;
}

//-->

function utf8(wide) {
	var c, s;
	var enc = "";
	var i = 0;
	while(i<wide.length) {
		c= wide.charCodeAt(i++);
		// handle UTF-16 surrogates
		if (c>=0xDC00 && c<0xE000) continue;
		if (c>=0xD800 && c<0xDC00) {
			if (i>=wide.length) continue;
			s= wide.charCodeAt(i++);
			if (s<0xDC00 || c>=0xDE00) continue;
			c= ((c-0xD800)<<10)+(s-0xDC00)+0x10000;
		}
		// output value
		if (c<0x80) enc += String.fromCharCode(c);
		else if (c<0x800) enc += String.fromCharCode(0xC0+(c>>6),0x80+(c&0x3F));
		else if (c<0x10000) enc += String.fromCharCode(0xE0+(c>>12),0x80+(c>>6&0x3F),0x80+(c&0x3F));
		else enc += String.fromCharCode(0xF0+(c>>18),0x80+(c>>12&0x3F),0x80+(c>>6&0x3F),0x80+(c&0x3F));
	}
	return enc;
}

var hexchars = "0123456789ABCDEF";

function toHex(n) { return hexchars.charAt(n>>4)+hexchars.charAt(n & 0xF); }

var okURIchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.";

function nextagEncodeURI(s) {
	s = utf8(s);
	var c;
	var enc = "";
	if (typeof encodeURIComponent == "function") {
		// Use JavaScript built-in function IE 5.5+ and Netscape 6+ and Mozilla
		// Replace all %26amp%3B in s and after encoding
		return (encodeURIComponent(s.replace(/%26amp%3B/g, '%26')).replace(/%26amp%3B/g, '%26'));
	} 
	// Need to mimic the JavaScript version Netscape 4 and IE 4 and IE 5.0
	for (var i= 0; i<s.length; i++) {
		if (okURIchars.indexOf(s.charAt(i))==-1)
			enc += "%"+toHex(s.charCodeAt(i));
		else
			enc += s.charAt(i);
	}
	return enc.replace(/%26amp%3B/g, '%26');
}

function NextagBrowser(){
	var d = document;
	var nav=navigator;
	this.agt=nav.userAgent.toLowerCase();
	this.major = parseInt(nav.appVersion);
	this.ns=(d.layers);
	this.dom=(d.getElementById)?1:0;
	this.ns4up=(this.ns && this.major >=4);
	this.ns6=(this.agt.indexOf("Netscape6")!=-1);
	this.op=(window.opera? 1:0);
	this.ie=(d.all);
	this.ie5=(d.all&&this.dom);
	this.fb=(this.agt.indexOf("firebird")!=-1);
	this.sf=(this.agt.indexOf("safari")!=-1);
	this.win=((this.agt.indexOf("win")!=-1) || (this.agt.indexOf("16bit")!=-1));
	this.mac=(this.agt.indexOf("mac")!=-1);
};


var WindowUtils = {
	'getViewportDimensions': function(){
		var viewportwidth = 0;
		var viewportheight = 0;

		if (typeof window.innerWidth != 'undefined'){
			viewportwidth = window.innerWidth,
			viewportheight = window.innerHeight
		} else if (typeof document.documentElement != 'undefined'
					&& typeof document.documentElement.clientWidth != 'undefined' 
					&& document.documentElement.clientWidth != 0) {
			viewportwidth = document.documentElement.clientWidth,
			viewportheight = document.documentElement.clientHeight
		} else {
			viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
			viewportheight = document.getElementsByTagName('body')[0].clientHeight
		}
		return [viewportwidth,viewportheight];
	},
	
	'getScrollPosition': function(){
		var scrollTop = 0;
		var scrollLeft = 0;
		
		if (typeof window.pageYOffset != 'undefined') {
			 scrollTop = window.pageYOffset;
			 scrollLeft = window.pageXOffset;
		} else if (typeof document.documentElement.scrollTop != 'undefined' 
				&& document.documentElement.scrollTop > 0) {
			scrollTop = document.documentElement.scrollTop;
			scrollLeft = document.documentElement.scrollLeft;
		} else if (typeof document.body.scrollTop != 'undefined') {
			scrollTop = document.body.scrollTop;
			scrollLeft = document.body.scrollLeft;
		}
		
		return [scrollTop,scrollLeft];
	}
};

var NextagUtils = new Object();
NextagUtils.sVisibleDiv = null;
NextagUtils.sVisibleDivToggleFlag = 0;

NextagUtils.sCubeables = new Array();

/** public static variables **/
// detect a special case of "web browser"
NextagUtils.is_ie = ( /msie/i.test(navigator.userAgent) &&
		   !/opera/i.test(navigator.userAgent) );
NextagUtils.is_ie5 = ( NextagUtils.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
// detect Opera browser
NextagUtils.is_opera = /opera/i.test(navigator.userAgent);
// detect KHTML-based browsers
NextagUtils.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);

// Event methods
NextagUtils.addEvent = function(el, evname, func) {
	if (el.attachEvent) { // IE
		el.attachEvent("on" + evname, func);
	} else if (el.addEventListener) { // Gecko / W3C
		el.addEventListener(evname, func, false);
	} else {
		el["on" + evname] = func;
	}
};

NextagUtils.stopEvent = function(ev) {
	ev || (ev = window.event);
	if (NextagUtils.is_ie) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
};

NextagUtils.defaultDocumentOnClickHandler = function (ev){
	if (NextagUtils.sVisibleDiv != null){
		if (NextagUtils.sVisibleDivToggleFlag==0){
			NextagUtils.sVisibleDiv.style.display = 'none';
			NextagUtils.sVisibleDiv = null;
		} else
			NextagUtils.sVisibleDivToggleFlag = 0;
	}
	return true;
};

// DOM/Object methods
NextagUtils.createElement = function(type, parent) {
	var el = null;
	if (document.createElementNS) {
		// use the XHTML namespace; IE won't normally get here unless
		// _they_ "fix" the DOM2 implementation.
		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
	} else {
		el = document.createElement(type);
	}
	if (typeof parent != "undefined") {
		parent.appendChild(el);
	}
	return el;
};

// UI methods
NextagUtils.getElementPosition = function(obj){
	var curleft = 0;
	var curtop = 0;
	if (obj.offsetParent){
		while (obj.offsetParent){
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	} else if (obj.x){
		curleft += obj.x;
		curtop += obj.y;
	}
	return { x: curleft, y: curtop };
};

NextagUtils.getRelativePosition = function(obj, offsetX, offsetY){
	var pos = this.getElementPosition(obj);
	var left = pos.x + offsetX;
	var top = pos.y + offsetY;
  return { x: left, y: top };
};

// UI - Popup DIV methods
NextagUtils.toggleShowDiv = function(id, pos){
	// alert("-- in toggle");
	var elem = document.getElementById(id);
	if (!elem)
		return false;
	if (elem == NextagUtils.sVisibleDiv){
		NextagUtils.sVisibleDiv.style.display = 'none';
		NextagUtils.sVisibleDiv = null;
		return true;
	}
	if (pos){
		elem.style.top = pos.y + 'px';
		elem.style.left = pos.x + 'px';
	}
	if (NextagUtils.sVisibleDiv != null)
		NextagUtils.sVisibleDiv.style.display = 'none';
	NextagUtils.sVisibleDiv = elem;
	elem.style.display = 'block';
	NextagUtils.sVisibleDivToggleFlag = 1;

	return true;
};

NextagUtils.expandSearchRefineScrollDiv = function (prefix){
	var tagT = document.getElementById(prefix + '_T');
	var tagC = document.getElementById(prefix + '_C');
	var tagH = document.getElementById(prefix + '_H');
	var tagM = document.getElementById(prefix + '_M');

	if (tagC && (tagC.style.height == '' ||
			tagC.style.height == undefined))
		tagC.style.height = (tagC.offsetHeight-4) + 'px';

	if (tagT) tagT.className = 'advSRScrollTitle_HL';
	if (tagC) tagC.className = 'advSRScrollContainer_HL';
	if (tagH) tagH.className = 'advSRScrollHidden_HL';
	if (tagM) tagM.className = 'advSRScrollMore_HL';
};

NextagUtils.collapseSearchRefineScrollDiv = function (prefix){
	var tagT = document.getElementById(prefix + '_T');
	var tagC = document.getElementById(prefix + '_C');
	var tagH = document.getElementById(prefix + '_H');
	var tagM = document.getElementById(prefix + '_M');

	if (tagT) tagT.className = 'advSRScrollTitle';
	if (tagC) tagC.className = 'advSRScrollContainer';
	if (tagH) tagH.className = 'advSRScrollHidden';
	if (tagM) tagM.className = 'advSRScrollMore';
};


/**
 * element utilities like positioning and event functions
 * for NextagUtils.getPageX and NextagUtils.getPageY:
 * relatively positioned items will give you trouble, lots of it
 */

NextagUtils.getElementWidth = function(e,b) {return ((b.op)? e.style.pixelWidth:e.offsetWidth);};
NextagUtils.getElementHeight = function(e,b) { return ((b.op)? e.style.pixelHeight:e.offsetHeight); };

/** should provide more reliable element positions than getPageX/getPageY. 
* if inside containers w/ scrollbars, use overflown array 
* adapted from mootools. MIT-style license. MooTools Copyright: copyright (c) 2007 Valerio Proietti, <http://mad4milk.net>
*/
NextagUtils.getPosition = function(elem,overflown) {
	var left = 0, top = 0;
	do {
		left += elem.offsetLeft || 0;
		top += elem.offsetTop || 0;
		elem = elem.offsetParent;
	} while (elem);
	if (overflown) {
		for (var i=0;i<overflown.length;i++) {
			var element = overflown[i];
			if (element) {
				left -= element.scrollLeft || 0;
				top -= element.scrollTop || 0;
			}
		}
	}
	return {'x': left, 'y': top};
};

NextagUtils.getPageX = function(o,b) {
	if (b.op) {
		var x=0;
		while(eval(o)) {
			x+=o.style.pixelLeft;
			o=o.offsetParent;
		}
		return x;
	} else {
		var m=(b.mac&&b.ie)? document.body.leftMargin:0;
		var x=0;
		var incase=0;
		var hasBody=false;
		var hasHtml=false;
		while(eval(o)) {
			x+=o.offsetLeft;
			if (b.ie && o && o.tagName == 'TABLE'){
				incase = x;
				// break;
			} else if (b.ie && o.tagName == 'HTML') {
				hasHtml = true;
			} else if (b.ie && o.tagName == 'BODY') {
				hasBody = true;
			}
			o=o.offsetParent;
		}
		if (hasHtml && !hasBody)
		  x = incase;
		return parseInt(x)+parseInt(m)
	}
};

NextagUtils.getPageY = function(o,b) {
	if(b.ns) {
		var y=(o.pageY)? o.pageY:o.y;
		return y;
	} else if (b.op) {
		var y=0;
		while(eval(o)) {
			y+=o.style.pixelTop;
			o=o.offsetParent;
		}
		return y;
	} else {
		var m = (b.mac&&b.ie)? document.body.topMargin:0;
		var y=0;
		var incase=0;
		var hasBody=false;
		var hasHtml=false;
		while(eval(o)) {
			y+=o.offsetTop;
			if (b.ie && o.tagName == 'TABLE'){
				incase = y;
				// break;
			} else if (b.ie && o.tagName == 'HTML') {
				hasHtml = true;
			} else if (b.ie && o.tagName == 'BODY') {
				hasBody = true;
			}
			o=o.offsetParent;
		}
		if (hasHtml && !hasBody)
		  y = incase;
		return parseInt(y)+parseInt(m);
	}
};

NextagUtils.showElement = function(e,disp) {
	(!disp)? 0:e.style.display=disp;
	e.style.visibility='visible';
};

NextagUtils.hideElement = function(e,disp) {
	(!disp)? 0:e.style.display=disp;
	e.style.visibility='hidden';
};

NextagUtils.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);

NextagUtils.hideShowCovered = function (elem, tags) {
	NextagUtils.continuation_for_khtml_browser = function() {
		function getVisib(obj){
			var value = obj.style.visibility;
			if (!value) {
				if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
					if (!NextagUtils.is_khtml)
						value = document.defaultView.
							getComputedStyle(obj, "").getPropertyValue("visibility");
					else
						value = '';
				} else if (obj.currentStyle) { // IE
					value = obj.currentStyle.visibility;
				} else
					value = '';
			}
			return value;
		};

		var el = elem;

		var p = NextagUtils.getElementPosition(el);
		var EX1 = p.x;
		var EX2 = el.offsetWidth + EX1;
		var EY1 = p.y;
		var EY2 = el.offsetHeight + EY1;

		for (var k = tags.length; k > 0; ) {
			var tag = tags[--k];
			var filter = null;
			if (tag.indexOf('input.') == 0){
				filter = tag.replace('input.','');
				tag = 'input';
			}
			var ar = document.getElementsByTagName(tag);
			var cc = null;

			for (var i = ar.length; i > 0;) {
				cc = ar[--i];

				if (filter != null && filter != cc.type){
					continue;
				}

				p = NextagUtils.getElementPosition(cc);
				var CX1 = p.x;
				var CX2 = cc.offsetWidth + CX1;
				var CY1 = p.y;
				var CY2 = cc.offsetHeight + CY1;

				if (el.style.visibility == 'visible' || (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";
				}
			}
		}
	};
	if (NextagUtils.is_khtml)
		setTimeout("NextagUtils.continuation_for_khtml_browser()", 10);
	else
		NextagUtils.continuation_for_khtml_browser();
};

function bookmark(url, curl) {
	var title = document.title;
	if (window.sidebar) {
		//mozilla
		window.sidebar.addPanel(title, url,"");
	} else if (window.external) {
		//ie
		window.external.AddFavorite(url,title) 
	}
	var req = new NxtgHttpReq(curl, {'method':'GET'});
	req.send(null);
}

function resizeBannerAd(id, width, height){
	var frame = document.getElementById(id);
	if (id && frame){
		frame.style.width = width + "px";
		frame.style.height = height + "px";
		if(id.match("search") || id.match("product")){
			if(id.match("header")){
				frame.style.paddingBottom = "10px";
			}else if(id.match("footer")){
				frame.style.paddingTop = "15px";
			}
		}
	}
};

function showParams(start, end, attrs, prefix){
	for(var i=0; i<attrs; i++){
		var elmt = document.getElementById(prefix+i);
		if(elmt){
			if(i >= start && i <= end){
				elmt.style.display = "";
			}else{
				elmt.style.display = "none";
			}
		}
	}
	var back = document.getElementById(prefix+'back');
	var more = document.getElementById(prefix+'more');
	var more_beg = end+1;
	var more_end = more_beg+(end-start);
	var back_beg = (start-1)-(end-start);
	if(back_beg < 0) back_beg = 0;
	var back_end = back_beg+(end-start);

	if(start == 0){
		back.style.display = 'none';
	}else{
		back.style.display = '';
	}
	if(end >= attrs-1){
		more.style.display = 'none';
	}else{
		more.style.display = '';
	}
	more.href = "javascript:showParams(" + more_beg + "," + more_end + "," + attrs + ",'" + prefix + "')";
	back.href = "javascript:showParams(" + back_beg + "," + back_end + "," + attrs + ",'" + prefix + "')";
};

function resizeIFrame(id){
	var ifd;
	if (id && document.getElementById(id)){
		if (document.getElementById(id).contentWindow == undefined){
			ifd = document.getElementById(id).document;
		} else {
			ifd = document.getElementById(id).contentWindow.document;
		}
		document.getElementById(id).style.height = ifd.body.scrollHeight + "px";
		document.getElementById(id).style.width = "100%";
	}
};


NextagUtils.makeCubeable = function(o){
	NextagUtils.sCubeables[NextagUtils.sCubeables.length]=o;
}

var SLCTR = new Object();
SLCTR.incs = new Array();
SLCTR.register = function(id,url){ /* alert('SLCTR.register('+id+')');*/ SLCTR.incs[SLCTR.incs.length] = {i:id,u:url}; }
SLCTR.ldPrime = function(ik){
	// alert('SLCTR.ldPrime('+ik+') ' + SLCTR.incs.length);
	for (var i=0; i<SLCTR.incs.length; i++){
		try { document.getElementById(SLCTR.incs[i].i).src = SLCTR.incs[i].u;} 
		catch (e){}
	}
}

/* hideAll, writeBrowseMore and showMore are used for the Browse page */
function hideAll(tagname, classname, viewValue) {
    var elements = document.getElementsByTagName(tagname);
    for (var i=0; i < elements.length; i++) {
        if (elements[i].className == classname) {
            elements[i].style.display=viewValue;
        }
    }
}

/* hideAll, writeBrowseMore and showMore are used for the Browse page */
function showMore(node) {
	var spanId = 'span_' + node;
	var moreId = 'more_' + node;
	document.getElementById(spanId).style.display='inline';
	document.getElementById(moreId).style.display='none';
}
/* hideAll, writeBrowseMore and showMore are used for the Browse page */
function writeBrowseMore(node) {
	document.write('<span id="more_' + node + '" name="more_link">,&nbsp; <a href="javascript:showMore(\'' + node + '\')">more...</a></span>');
}


// requires NextagUtils.js and utils.js

var sTimeouts = new Array();
var sPopupGroups = new Array();
var sGroupPreShowCB = new Array();
var sGroupPostShowCB = new Array();
var sGroupPreHideCB = new Array();
var sGroupPostHideCB = new Array();
var sGroupPopupFixedPos = new Array();
var sWindowWidth;
var sWindowHeight;

var sHideElements = new Array("select","input.checkbox");
var sBrowser = new NextagBrowser();

/**
 * PopupManager constructor parameters
 * triggerPrefix	- default 'trigLink'
 * popupPrefix		- default 'popup'
 * leftOffset			- default 0
 * topOffset			- default 0
 * showEvent      - default mouseover
 * hideEvent      - default mouseout
 * delay          - default 250
 * hideOverlay    - default true
 * allowClicks    - default false
 * flipX          - default false
 * flipY          - default false
 * preShow        - default null
 * postShow       - default null
 * preHide        - default null
 * postHide       - default null
 * showProperty   - default visibility
 * autoHide       - ???
 * discoveryFunc  - default null
 * fixedPos		  - default null
 */
function PopupManager(params){
	function setParamDefaults(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

	setParamDefaults("triggerPrefix","trigLink");
	setParamDefaults("trigger","trigLink");
	setParamDefaults("popupPrefix","popup");
	setParamDefaults("leftOffset",0);
	setParamDefaults("topOffset",0);
	setParamDefaults("showEvent","mouseover");
	setParamDefaults("hideEvent","mouseout");
	setParamDefaults("delay", 250);
	setParamDefaults("hideOverlay", true);
	setParamDefaults("allowClicks", false);
	setParamDefaults("flipX", false);
	setParamDefaults("flipY", false);
	setParamDefaults('preShow', null);
	setParamDefaults('postShow', null);
	setParamDefaults('preHide', null);
	setParamDefaults('postHide', null);
	setParamDefaults('showProperty', 'visibility');
	setParamDefaults('autoHide', true);
	setParamDefaults("rightAlign",false);
	setParamDefaults('fixedPos', null);

	var mGrpId = sPopupGroups.length;
	var mParams = params;
	
	this.getProperty = function(prop){ return mParams[prop]; };
	this.positionPopup = function(popup,tr,adjust,fixedPos){
		if (!popup || !tr)
			return;
		var pos = fixedPos || tr;
		var top = 0;
		var left = 0;

		if (mParams['rightAlign']){
			mParams['leftOffset'] = NextagUtils.getElementWidth(tr,sBrowser) - NextagUtils.getElementWidth(popup,sBrowser);
		}

		if (!mParams['flipY']){
			//top = (NextagUtils.getPageY(pos,sBrowser) + mParams['topOffset']);
			top = (NextagUtils.getPosition(pos).y + mParams['topOffset']);
		} else {
			//top = (NextagUtils.getPageY(pos,sBrowser) + NextagUtils.getElementHeight(pos,sBrowser) + mParams['topOffset']);
			top = (NextagUtils.getPosition(pos).y + NextagUtils.getElementHeight(pos,sBrowser) + mParams['topOffset']);
		}
		if (!mParams['flipX']){
			//left = (NextagUtils.getPageX(pos,sBrowser) + mParams['leftOffset']);
			left = (NextagUtils.getPosition(pos).x + mParams['leftOffset']);
		} else {
			//left = (NextagUtils.getPageX(pos,sBrowser) + NextagUtils.getElementWidth(pos,sBrowser) + mParams['leftOffset']) ;
			left = (NextagUtils.getPosition(pos).x + NextagUtils.getElementWidth(pos,sBrowser) + mParams['leftOffset']) ;
		}

		popup.style.top = top + 'px';
		popup.style.left = left + 'px';
	};


	if (sBrowser.op)
	  return;

	sPopupGroups[sPopupGroups.length] = this;

	/** private instance methods **/
  var init = function(){
		if (!document.getElementById) {
			return false;
		}

		if( sBrowser.mac == 1 && sBrowser.ie5 == 1 ) {
			return false;
		}

		if (mParams['preShow'] != null)
			sGroupPreShowCB[mGrpId] = mParams['preShow'];
		if (mParams['postShow'] != null)
			sGroupPostShowCB[mGrpId] = mParams['postShow'];
		if (mParams['preHide'] != null)
			sGroupPreHideCB[mGrpId] = mParams['preHide'];
		if (mParams['postHide'] != null)
			sGroupPostHideCB[mGrpId] = mParams['postHide'];
		if (mParams['fixedPos'] != null )
			sGroupPopupFixedPos[mGrpId] = mParams['fixedPos'];

		var trigs = 0;
		var tr = null;
		var paramSplitToken = '|';
		
		while ((tr = document.getElementById(mParams['triggerPrefix'] + '_' + trigs)) ||
				(tr = document.getElementById(mParams['trigger']))) {
			var popup = document.getElementById(mParams['popupPrefix'] + '_' + trigs);
			if (popup == null)
				break;

			var fixedPos = document.getElementById(mParams['fixedPos']);
			sPopupGroups[mGrpId].positionPopup(popup, tr, false, fixedPos);

			if (mParams['showEvent'] == 'click' && mParams['hideEvent'] == 'click'){
				NextagUtils.addEvent(tr, 'click', funcShow(popup.id,trigs), true);
				if (mParams['allowClicks'])
					NextagUtils.addEvent(popup, 'click', funcShow(popup.id,trigs), true);
				if (mParams['autoHide'])
					NextagUtils.addEvent(document, 'click', funcClickHide(popup.id), true)
			} else if (mParams['showEvent'] == 'click' && mParams['hideEvent'] != 'click'){
				NextagUtils.addEvent(tr, 'click', funcClickShow(popup.id,trigs));
				NextagUtils.addEvent(popup, 'mouseover', funcClickShow(popup.id,trigs));
				var hideEvents = mParams['hideEvent'].split(paramSplitToken);
				for(var i = 0; i < hideEvents.length; i++) {	
					var hideEventType = hideEvents[i];			
					if (hideEventType.indexOf('element#.')==0){
						var heId = hideEventType.replace('element#.','');
						var hes = heId.split(',');
						for (var h=0; h<hes.length; h++){
							var he = document.getElementById(hes[h]+"_"+trigs);
							if (he){NextagUtils.addEvent(he, 'click', funcClickHide(popup.id));}
						}
					} else if (hideEventType.indexOf('element.')==0) {
						var heId = hideEventType.replace('element.','');
						var hes = heId.split(',');
						for (var h=0; h<hes.length; h++){
							var he = document.getElementById(hes[h]);
							if (he){NextagUtils.addEvent(he, 'click', funcClickHide(popup.id));}
						}
					} else {
						NextagUtils.addEvent(tr, hideEventType, funcHide(popup.id));
						NextagUtils.addEvent(popup, hideEventType, funcHide(popup.id));
					}
				}
			} else {
				NextagUtils.addEvent(tr, mParams['showEvent'], funcShow(popup.id,trigs), true);
				NextagUtils.addEvent(popup, mParams['showEvent'], funcShow(popup.id,trigs), true);
				var hideEvents = mParams['hideEvent'].split(paramSplitToken);
				for(var i = 0; i < hideEvents.length; i++) {	
					var hideEventType = hideEvents[i];		
					if (hideEventType.indexOf('element.')==0){
						var he = hideEventType.replace('element.','');
					} else {
						NextagUtils.addEvent(tr, hideEventType, funcHide(popup.id));
						NextagUtils.addEvent(popup, hideEventType, funcHide(popup.id));
					}
				}
			}
			trigs++;
		}
		sWindowWidth = document.body.clientWidth;
		sWindowHeight = document.body.clientHeight;

		return true;
  };

	var funcShow = function (id,num) {
		return new Function("event", "clearTimeout(sTimeouts['"+id+"']);sTimeouts['"+id+"'] = setTimeout(\"PopupManager.show('"+id+"',"+mGrpId+","+num+");\", " + mParams['delay'] + ");");
	};
	var funcHide = function (id) {
		return new Function("event", "clearTimeout(sTimeouts['"+id+"']);sTimeouts['"+id+"'] = setTimeout(\"PopupManager.hide('"+id+"',"+mGrpId+");\", " + mParams['delay'] + ");");
	};

	var funcClickShow = function (id,num) {
		return new Function("event", "clearTimeout(sTimeouts['"+id+"']);sTimeouts['"+id+"'] = setTimeout(\"PopupManager.show('"+id+"',"+mGrpId+","+num+");\", " + 0 + "); NextagUtils.stopEvent(event);");
	};

	var funcClickHide = function (id) {
		return new Function("PopupManager.hide('"+id+"',"+mGrpId+");");
	};

	/** privileged static methods **/
	PopupManager.show = function (id,grpId,pnum) {
		if (grpId >= sPopupGroups.length || pnum < 0)
			return;
		if (id == sTimeouts['lastshown'])
			return;
		var pm = sPopupGroups[grpId];
		if (pm.getProperty('autoHide'))
			PopupManager.hide(sTimeouts['lastshown'], sTimeouts['lastshown_grpid']);
		var fn = sGroupPreShowCB[grpId];
		if (fn != null){fn('preShow',id,grpId,pnum);}
		var tr = document.getElementById(pm.getProperty('triggerPrefix') + '_' + pnum);
		var popup = document.getElementById(pm.getProperty('popupPrefix') + '_' + pnum);
		var fixedPos = document.getElementById(sGroupPopupFixedPos[grpId]);
		pm.positionPopup(popup,tr,true,fixedPos);
		sTimeouts['lastshown'] = id;
		sTimeouts['lastshown_grpid'] = grpId;
		var el = document.getElementById(id);
		if (el) {
			if (NextagUtils.is_ie && pm.getProperty('hideOverlay'))
				NextagUtils.hideShowCovered(el,sHideElements);
			if (pm.getProperty('showProperty') == 'display'){
				el.style.display = "block";
			} else {
				el.style.visibility = "visible";
			}
		}
		try {
			if (tr && tr.blur)
				tr.blur();
		} catch (err){}
		fn = sGroupPostShowCB[grpId];
		if (fn != null){fn('postShow',id,grpId,pnum);}
	};

	PopupManager.hide = function (id,grpId) {
		if (grpId >= sPopupGroups.length)
			return;
		var fn = sGroupPreHideCB[grpId];
		if (fn != null){fn('preHide',id,grpId);}
		var pm = sPopupGroups[grpId];
		var el = document.getElementById(id);
		if (el) {
			if (NextagUtils.is_ie && pm.getProperty('hideOverlay') && el.style.visibility == 'visible')
				NextagUtils.hideShowCovered(el,sHideElements);

			if (pm.getProperty('showProperty') == 'display'){
				el.style.display = "none";
			} else {
				el.style.visibility = "hidden";
			}

			sTimeouts['lastshown'] = null;
			sTimeouts['lastshown_grpid'] = null;
		}
		fn = sGroupPostHideCB[grpId];
		if (fn != null){fn('postHide',id,grpId);}
	};


	/** constructor body */
	init();
};

PopupManager.newPopupGroup = function (params){
	new PopupManager(params);
};



// Taken from: http://www.kryogenix.org/code/browser/sorttable/
// Made modifications to specify which rows to sort by and which rows to ignore, maintain order of items with same values
//  and fix sorting for mixed numeric and non-numeric data
// modifications to allow a user to specify an element in the <td> tag that has the value to sort by
// e.g. <span class="sort-value>$20</span> will sort by $20
// now requires mootools so will be travel specific

addEvent(window, "load", sortables_init);

var SORT_COLUMN_INDEX;
var REVERSE;

function sortables_init() {
    // Find all tables with class sortable and make them sortable
    if (!document.getElementsByTagName) return;
    tbls = document.getElementsByTagName("table");
    for (ti=0;ti<tbls.length;ti++) {
        thisTbl = tbls[ti];
        if (((' '+thisTbl.className+' ').indexOf("sortable") != -1) && (thisTbl.id)) {
            //initTable(thisTbl.id);
            ts_makeSortable(thisTbl);
        }
    }
}

function ts_makeSortable(table) {
	// Find all rows with class sortrow and make its contents clickable links
    if (table.rows && table.rows.length > 0) {
        for (var row = 0; row < table.rows.length; row++) {
            if ((' '+table.rows[row].className+' ').indexOf("sortrow") != -1) {
		        var sortRow = table.rows[row];
			    for (var i=0;i<sortRow.cells.length;i++) {
                    var cell = sortRow.cells[i];
                    var txt = ts_getInnerText(cell);
			        if (cell.className.indexOf('nosort') == -1) {
                        cell.innerHTML = '<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;">'+txt+'</a><span class="sortarrow">&nbsp;&nbsp;</span>';
                    }
                }
            }
        }
    }
}

function ts_getInnerText(el) {
	if (typeof el == "string") return el;
	if (typeof el == "undefined") { return el };
	if (el.innerText) return el.innerText;	//Not needed but it is faster
	var str = "";
	
	var overrideValue = el.getElementsBySelector('.sort-value');
	if(overrideValue.length > 0){//clears whitespace before returning
		return overrideValue[0].innerHTML.replace(/^\s*|\s*$/g,'');
	}
		
	var cs = el.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				str += ts_getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;
				break;
		}
	}
	return str;
}

function ts_resortTable(lnk) {
    // get the span
    var span;
    var td = lnk.parentNode;
    for (var ci = 0; ci < td.childNodes.length; ci++) {
        if (td.childNodes[ci].tagName && td.childNodes[ci].tagName.toLowerCase() == 'span')
            span = td.childNodes[ci];
    }
    REVERSE = span.getAttribute("sortdir") == 'down';
    var spantext = ts_getInnerText(span);
    var column = td.cellIndex;
    var table = getParent(td,'TABLE');

    if (table.rows.length <= 1) return;
    SORT_COLUMN_INDEX = column;
    var sortRows = new Array();
    var bottomRows = new Array();
    var i = 0;
    lastSort = 0;
    for (j = 0; j < table.rows.length; j++) {
		if ((table.rows[j].className.indexOf('nosort') == -1) && (table.rows[j].className.indexOf('sortrow') == -1)) {
            sortRows[i] = table.rows[j];
            sortRows[i].position = i++;
            lastSort = j;
        }
    }
    i = 0;
    for (j = lastSort + 1; j < table.rows.length; j++) {
        bottomRows[i++] = table.rows[j];
    }

    sortRows.sort(ts_sortRows);

    if (REVERSE) {
        ARROW = '&nbsp;&uarr;';
        sortRows.reverse();
        span.setAttribute('sortdir','up');
    } else {
        ARROW = '&nbsp;&darr;';
        span.setAttribute('sortdir','down');
    }

    // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
    for (i = 0; i < sortRows.length; i++) {
        if ((' '+table.className+' ').indexOf("nocolor") == -1) {
            /*if (i % 2 == 1) {
                sortRows[i].style.backgroundColor = "#f0f0f0";
            } else {
                sortRows[i].style.backgroundColor = "#fffffc";
            }*/
        }
        table.tBodies[0].appendChild(sortRows[i]);
    }

    // append sortbottom rows
    for (i = 0; i < bottomRows.length; i++) {
        table.tBodies[0].appendChild(bottomRows[i]);
    }

    // Delete any other arrows there may be showing
    var allspans = document.getElementsByTagName("span");
    for (var ci=0;ci<allspans.length;ci++) {
        if (allspans[ci].className == 'sortarrow') {
            if (getParent(allspans[ci],"table") == getParent(lnk,"table")) { // in the same table as us?
                allspans[ci].innerHTML = '&nbsp;&nbsp;&nbsp;';
            }
        }
    }

    span.innerHTML = ARROW;
}

function getParent(el, pTagName) {
	if (el == null) return null;
	else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())	// Gecko bug, supposed to be uppercase
		return el;
	else
		return getParent(el.parentNode, pTagName);
}

function ts_sortRows(a,b) {
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
    sortOrder = ts_sort(aa,bb);
    return sortOrder != 0 ? sortOrder : ts_sort_tiebreaker(a,b);
}

function ts_sort(a,b) {
    if (a == null && b == null || a == '' && b == '') return 0;
    if (a == null || a == '') return -1;
    if (b == null || b == '') return 1;
    // Work out a type for the column
    var sortfn = ts_sort_caseinsensitive;
    var currencyRegEx = /^[ï¿½$£]/;
    var numericRegEx = /^[-]?[\d\.]+/;
    var dateRegEx = /^\s*\d\d?[\/-]\d\d?[\/-](\d\d){1,2}/;
    var timeRegEx = /^\s*\d\d?:\d\d([\s]*[AP]M)?/i;
    if (a.match(currencyRegEx) || b.match(currencyRegEx)) sortfn = ts_sort_currency;
    if (a.match(numericRegEx) || b.match(numericRegEx)) sortfn = ts_sort_numeric;
    if (a.match(dateRegEx) || b.match(dateRegEx)) sortfn = ts_sort_date;
    if (a.match(timeRegEx) || b.match(timeRegEx)) sortfn = ts_sort_time;

    return sortfn(a,b);
}

function ts_sort_date(a,b) {
    // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
    aa = a.split(/[\/\s-]/);
    bb = b.split(/[\/\s-]/);
    dt1 = ts_get_date(aa[0], aa[1], aa[2]);
    dt2 = ts_get_date(bb[0], bb[1], bb[2]);
    if (dt1 == dt2) return ts_sort(a.substring(a.indexOf(' ')), b.substring(a.indexOf(' ')));
    if (dt1 < dt2) return -1;
    return 1;
}

function ts_get_date(month, day, year) {
    y = year.length == 4 ? year : parseInt(year) < 50 ? '20' + year : '19' + year;
    m = month.length == 2 ? month : '0' + month;
    d = day.length == 2 ? day : '0' + day;
    return y + m + d;
}

function ts_sort_time(a,b) {
    aa = a.replace(/[^\d:]/g, '').split(/[:]/);
    bb = b.replace(/[^\d:]/g, '').split(/[:]/);
    tm1 = ts_get_time(aa, a.indexOf('AM') > 0, a.indexOf('PM') > 0);
    tm2 = ts_get_time(bb, b.indexOf('AM') > 0, b.indexOf('PM') > 0);
    if (tm1 == tm2) return ts_sort(a.substring(a.indexOf('M') + 1), b.substring(a.indexOf('M')) + 1);
    if (tm1 < tm2) return -1;
    return 1;
}

function ts_get_time(time, am, pm) {
    hour = parseFloat(time[0]);
    if (am && hour == 12) hour = 0;
    if (pm && hour != 12) hour += 12;
    min = parseFloat(time[1]);
    sec = parseFloat(time[2]);
    if (isNaN(sec)) sec = 0;
    return (hour * 60 + min) * 60 + sec;
}

function ts_sort_currency(a,b) {
    aa = a.replace(/[^0-9.]/g,'').replace(/^$/,'0');
    bb = b.replace(/[^0-9.]/g,'').replace(/^$/,'0');
    diff = parseFloat(aa) - parseFloat(bb);
    return diff != 0 ? diff : ts_sort(a.replace(/[\dï¿½$£]/g, ''), b.replace(/[\dï¿½$£]/g, ''));
}

function ts_sort_numeric(a,b) {
    aa = parseFloat(a.match(/^[-]?[0-9.]+/));
    bb = parseFloat(b.match(/^[-]?[0-9.]+/));
    if (isNaN(aa) && isNaN(bb)) return ts_sort_caseinsensitive(a,b);
    if (isNaN(aa)) return 1;
    if (isNaN(bb)) return -1;
    var diff = aa - bb;
    return diff != 0 ? diff : ts_sort(a.replace(/^[-]?[0-9.]+/,''), b.replace(/^[-]?[0-9.]+/,''));
}

function ts_sort_caseinsensitive(a,b) {
    aa = a.toLowerCase();
    bb = b.toLowerCase();
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}

function ts_sort_default(a,b) {
    if (a==b) return 0;
    if (a<b) return -1;
    return 1;
}

function ts_sort_tiebreaker(a,b) {
	var diff = a.position - b.position;
	return REVERSE ? -diff : diff;
}

function addEvent(elm, evType, fn, useCapture)
// addEvent and removeEvent
// cross-browser event handling for IE5+,  NS6 and Mozilla
// By Scott Andrew
{
  if (elm.addEventListener){
    elm.addEventListener(evType, fn, useCapture);
    return true;
  } else if (elm.attachEvent){
    var r = elm.attachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be removed");
  }
}


/* These java functions are shared across NexTag's site */
/* From the header */
window.onerror=handleError;
function handleError(msg, url, line) {
  return (msg == "Not implemented" || msg.indexOf("Access is denied") != -1);
}

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g,'');
}

/*  convert search term into static link on header and footer search form submission */
function submitStaticSearchLink(sid,nid,url){
	var nodeDropdown = document.getElementById(nid);
	if(nodeDropdown && nodeDropdown[nodeDropdown.selectedIndex].value != '0') return true;
	if (document.getElementById(sid) != null){
		var sKeyword = document.getElementById(sid).value;
		if (/[^\w\-\s,]/.test(sKeyword) || sKeyword.search(/\S/)==-1 || !url) return true;
                sKeyword = sKeyword.trim();
		sKeyword = sKeyword.replace(/-/g, '_-_');
		sKeyword = sKeyword.replace(/\s+/g, ' ');
		sKeyword = sKeyword.replace(/\s/g, '-');
		var func = typeof(encodeURIComponent) != "undefined" ? encodeURIComponent : escape;
		url = url.replace(/KEYWORD/g, func(sKeyword));
		location.href = url;
		return false;
	}
	return true;
}

/* Opens merchant link in a new window */
function openMerchantLink(linkUrl) {
    window.open(linkUrl,'','');
    return false;
}

function showHideSQBox(element,divId,iFrameId,url, displayMessage, hideMessage){
	var expand = displayMessage.replace(/</,"&lt;");
	expand = expand.replace(/>/,"&gt;");
	if (document.getElementById(divId).style.display == 'none'){
		document.getElementById(divId).style.display = '';
		document.getElementById(iFrameId).src=url;
		element.innerHTML = '<image src="/images/minusBox.gif"/> <font color="blue"><b>' + hideMessage + '</b></font>';
	} else {
		document.getElementById(divId).style.display = 'none';
		element.innerHTML='<image src="/images/plusBox.gif"/> <font color="blue"><b>' + expand + '</b></font>';
	}
}



var CommonUtils = {
	getValue: function(collection, param, defaultValue) {
		var value = null;
		if ( collection && param ) {
			if ( collection[param] != undefined ) value = collection[param];
			else if ( defaultValue != undefined ) value = defaultValue;
		}
		return value;
	},
	
	getSafeValue: function(variable, defaultValue) {
		return variable != undefined ? variable : defaultValue;
	},

	isEmpty: function(collection) {
		if(!collection) return true;
		
		for(var key in collection) {
			return false;
		}
		
		return true;
	},
	
	isEmptyValue: function(collection, param) {
		return this.getValue(collection, param, undefined) == undefined;		
	},
	
	getFirst: function(collection) {
		if(!collection) return null;
		var first = {};
		for(var key in collection) {
			first[key] = collection[key];
			return first;
		}
		return null;
	},
	
	equals: function(object1, object2) {
		if(object1 == object2) return true;
		if(object1 == null || object2 == null) return false;
		if(typeof(object1) != typeof(object2)) return false;
		if(typeof(object1) == 'object') {
			for(var key in object1) {
				if(!this.equals(object1[key], object2[key])) return false;
			}
			for(var key in object2) {
				if(!this.equals(object1[key], object2[key])) return false;
			}
			return true;
		}
		return false;
	},
	
	/**/
	getObjectProperty: function(obj, path, propertyName) {
    	if ( !obj ) return null;
    	if ( !path && propertyName ) return obj[propertyName];
    	if ( !path ) return obj;
    	
    	
    	//if the path is a regular property, just return the property
    	if ( $type(path) == 'string') return obj[path];
    	
    	//if the path is an array, then iterate through it until we get the 
    	//property
    	var item = obj;
		for(var i = 0; i < path.length; i++) {
			var nextItem = item[path[i]];
			if ( nextItem ) item = nextItem;
			else return null;
		}
		
		if ( propertyName && path && item[propertyName]) return item[propertyName];
		
		return item;    		
	},
	
	isOptionTrue: function(array, index, def){
		if(array[index] != null){
			var type = typeof array[index];
			if(type == 'boolean') return array[index];
			if(type == 'string'){
				if(array[index].matches(/true/i)) return true;
				else if(array[index].matches(/false/i)) return false;
			}
		}
		return def;
	},
	
	cleanupObject: function(object){
		for(key in object)
			if(typeof(object[key]) != 'function')
				this[key] = null;
	},
	
	cleanupElement: function(d) {
	    var a = d.attributes, i, l, n;
	    if (a) {
	        l = a.length;
	        for (i = 0; i < l; i += 1) {
	            n = a[i].name;
	            if (typeof d[n] === 'function') {
	                d[n] = null;
	            }
	        }
	    }
	    a = d.childNodes;
	    if (a) {
	        l = a.length;
	        for (i = 0; i < l; i += 1) {
	            this.cleanupElement(d.childNodes[i]);
	        }
        }
    },
    
    getElementsByClassName: function(objContElm, strClass, strTag) {
		strTag = strTag || "*";
		objContElm = objContElm || document;    
		var objColl = (objContElm.getElementsByTagName(strTag)) ? objContElm.getElementsByTagName(strTag) : document.all;
		var arr = new Array();                              
		var delim = strClass.indexOf('|') != -1  ? '|' : ' ';   
		var arrClass = strClass.split(delim);    
		for (var i = 0, j = objColl.length; i < j; i++) {                         
			var arrObjClass = objColl[i].className.split(' ');   
			if (delim == ' ' && arrClass.length > arrObjClass.length) continue;
			var c = 0;
			comparisonLoop:
			for (var k = 0, l = arrObjClass.length; k < l; k++) {
				for (var m = 0, n = arrClass.length; m < n; m++) {
					if (arrClass[m] == arrObjClass[k]) c++;
					if ((delim == '|' && c == 1) || (delim == ' ' && c == arrClass.length)) {
						arr.push(objColl[i]); 
						break comparisonLoop;
					}
				}
			}
		}
		return arr; 
	}
    
};

/* 
 * 

 */
var CookieUtils = {

	set: function(key, value, options){
		if ( !options ) options = {};
		if ( CommonUtils.isEmptyValue(options, 'domain') ) options['domain'] = false;
		if ( CommonUtils.isEmptyValue(options, 'path') ) options['path'] = false;
		if ( CommonUtils.isEmptyValue(options, 'duration') ) options['duration'] = 365;

		value = escape(value);
		if (options.domain) value += "; domain=" + options.domain;
		if (options.path) value += "; path=" + options.path;
		if (options.duration){
			var date = new Date();
			date.setTime(date.getTime() + (options.duration * 86400000));
			value += "; expires=" + date.toGMTString();
		}
		document.cookie = key + "=" + value;
	},

	get: function(key){
		var value = document.cookie.match('(?:^|;)\\s*'+key+'=([^;]*)');
		return value ? unescape(value[1]) : false;
	},

	remove: function(key){
		this.set(key, '', {duration: -1});
	}

};

var FormUtils = {
	getFormValue: function() {
		
	},
	
	getRadioValue: function(formId, paramName) {
		var f = document.getElementById(formId);
		for ( var i = 0; i < f[paramName].length; i++ ) {
			if ( f[paramName][i]['checked'] ) {
				return f[paramName][i]['value'];
			}
		}
		return undefined;
	}
};

//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

var MooTools={version:'1.1dev'};var Class=function(properties){var klass=function(){if(arguments[0]!==null&&this.initialize&&$type(this.initialize)=='function')return this.initialize.apply(this,arguments);else return this;};$extend(klass,this);klass.prototype=properties;return klass;};Class.empty=function(){};Class.prototype={extend:function(properties){var proto=new this(null);for(var property in properties){var pp=proto[property];proto[property]=$mergeClass(pp,properties[property]);}
return new Class(proto);},implement:function(properties){$extend(this.prototype,properties);}};function $type(obj){if(obj==undefined)return false;var type=typeof obj;if(type=='object'){if(obj.htmlElement)return'element';if(obj.push)return'array';if(obj.nodeName){switch(obj.nodeType){case 1:return'element';case 3:return obj.nodeValue.test(/\S/)?'textnode':'whitespace';}}}
if((type=='object'||type=='function')&&obj.exec)return'regexp';return type;};function $merge(){var mix={};for(var i=0;i<arguments.length;i++){for(var property in arguments[i]){var ap=arguments[i][property];var mp=mix[property];if(mp&&$type(ap)=='object'&&$type(mp)=='object')mix[property]=$merge(mp,ap);else mix[property]=ap;}}
return mix;};function $mergeClass(previous,current){if(previous&&previous!=current){var ptype=$type(previous);var ctype=$type(current);if(ptype=='function'&&ctype=='function'){var merged=function(){this.parent=arguments.callee.parent;return current.apply(this,arguments);};merged.parent=previous;return merged;}else if(ptype=='object'&&ctype=='object'){return $merge(previous,current);}}
return current;};var $extend=Object.extend=function(){var args=arguments;if(!args[1])args=[this,args[0]];for(var property in args[1])args[0][property]=args[1][property];return args[0];};var $native=Object.Native=function(){for(var i=0;i<arguments.length;i++)arguments[i].extend=$native.extend;};$native.extend=function(props){for(var prop in props){if(!this.prototype[prop])this.prototype[prop]=props[prop];}};$native(Function,Array,String,Number,Class);var Abstract=function(obj){obj=obj||{};obj.extend=$extend;return obj;};var Window=new Abstract(window);var Document=new Abstract(document);document.head=document.getElementsByTagName('head')[0];function $chk(obj){return!!(obj||obj===0);};function $pick(obj,picked){return(obj!=undefined)?obj:picked;};function $random(min,max){return Math.floor(Math.random()*(max-min+1)+min);};function $time(){return new Date().getTime();};function $clear(timer){clearTimeout(timer);clearInterval(timer);return null;};if(window.ActiveXObject)window.ie=window[window.XMLHttpRequest?'ie7':'ie6']=true;else if(document.childNodes&&!document.all&&!navigator.taintEnabled)window.khtml=true;else if(document.getBoxObjectFor!=null)window.gecko=true;window.xpath=!!(document.evaluate);if(typeof HTMLElement=='undefined'){var HTMLElement=Class.empty;if(window.khtml)document.createElement("iframe");HTMLElement.prototype=(window.khtml)?window["[[DOMElement.prototype]]"]:{};}
HTMLElement.prototype.htmlElement=true;if(window.ie6)try{document.execCommand("BackgroundImageCache",false,true);}catch(e){};var Chain=new Class({chain:function(fn){this.chains=this.chains||[];this.chains.push(fn);return this;},callChain:function(){if(this.chains&&this.chains.length)this.chains.shift().delay(10,this);},clearChain:function(){this.chains=[];}});var Events=new Class({addEvent:function(type,fn){if(fn!=Class.empty){this.$events=this.$events||{};this.$events[type]=this.$events[type]||[];this.$events[type].include(fn);}
return this;},fireEvent:function(type,args,delay){if(this.$events&&this.$events[type]){this.$events[type].each(function(fn){fn.create({'bind':this,'delay':delay,'arguments':args})();},this);}
return this;},removeEvent:function(type,fn){if(this.$events&&this.$events[type])this.$events[type].remove(fn);return this;}});var Options=new Class({setOptions:function(){var args=(arguments.length==1)?[this.options,arguments[0]]:arguments;this.options=$merge.apply(this,args);if(this.addEvent){for(var option in this.options){if(($type(this.options[option])=='function')&&option.test(/^on[A-Z]/))this.addEvent(option,this.options[option]);}}
return this;}});Array.extend({forEach:function(fn,bind){for(var i=0,j=this.length;i<j;i++)fn.call(bind,this[i],i,this);},filter:function(fn,bind){var results=[];for(var i=0,j=this.length;i<j;i++){if(fn.call(bind,this[i],i,this))results.push(this[i]);}
return results;},map:function(fn,bind){var results=[];for(var i=0,j=this.length;i<j;i++)results[i]=fn.call(bind,this[i],i,this);return results;},every:function(fn,bind){for(var i=0,j=this.length;i<j;i++){if(!fn.call(bind,this[i],i,this))return false;}
return true;},some:function(fn,bind){for(var i=0,j=this.length;i<j;i++){if(fn.call(bind,this[i],i,this))return true;}
return false;},indexOf:function(item,from){var len=this.length;for(var i=(from<0)?Math.max(0,len+from):from||0;i<len;i++){if(this[i]===item)return i;}
return-1;},copy:function(start,length){start=start||0;if(start<0)start=this.length+start;length=length||(this.length-start);var newArray=[];for(var i=0;i<length;i++)newArray[i]=this[start++];return newArray;},remove:function(item){var i=0;var len=this.length;while(i<len){if(this[i]===item){this.splice(i,1);len--;}else{i++;}}
return this;},contains:function(item,from){return this.indexOf(item,from)!=-1;},associate:function(keys){var obj={},length=Math.min(this.length,keys.length);for(var i=0;i<length;i++)obj[keys[i]]=this[i];return obj;},extend:function(array){for(var i=0,j=array.length;i<j;i++)this.push(array[i]);return this;},merge:function(array){for(var i=0,l=array.length;i<l;i++)this.include(array[i]);return this;},include:function(item){if(!this.length||!this.contains(item))this.push(item);return this;},getRandom:function(){return this[$random(0,this.length-1)];},getLast:function(){return this[this.length-1];}});Array.prototype.each=Array.prototype.forEach;Array.prototype.test=Array.prototype.contains;Array.prototype.removeItem=Array.prototype.remove;function $A(array,start,length){return Array.prototype.copy.call(array,start,length);};function $each(iterable,fn,bind){if(iterable.length!=undefined)Array.prototype.forEach.call(iterable,fn,bind);else for(var name in iterable)fn.call(bind||iterable,iterable[name],name);};String.extend({test:function(regex,params){return((typeof regex=='string')?new RegExp(regex,params):regex).test(this);},toInt:function(){return parseInt(this,10);},toFloat:function(){return parseFloat(this);},camelCase:function(){return this.replace(/-\D/g,function(match){return match.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/\w[A-Z]/g,function(match){return(match.charAt(0)+'-'+match.charAt(1).toLowerCase());});},capitalize:function(){return this.replace(/\b[a-z]/g,function(match){return match.toUpperCase();});},trim:function(){return this.replace(/^\s+|\s+$/g,'');},clean:function(){return this.replace(/\s{2,}/g,' ').trim();},rgbToHex:function(array){var rgb=this.match(/\d{1,3}/g);return(rgb)?rgb.rgbToHex(array):false;},hexToRgb:function(array){var hex=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);return(hex)?hex.slice(1).hexToRgb(array):false;},contains:function(string,s){return(s)?(s+this+s).indexOf(s+string+s)>-1:this.indexOf(string)>-1;},escapeRegExp:function(){return this.replace(/([.*+?^${}()|[\]\/\\])/g,'\$1');}});Array.extend({rgbToHex:function(array){if(this.length<3)return false;if(this[3]&&(this[3]==0)&&!array)return'transparent';var hex=[];for(var i=0;i<3;i++){var bit=(this[i]-0).toString(16);hex.push((bit.length==1)?'0'+bit:bit);}
return array?hex:'#'+hex.join('');},hexToRgb:function(array){if(this.length!=3)return false;var rgb=[];for(var i=0;i<3;i++){rgb.push(parseInt((this[i].length==1)?this[i]+this[i]:this[i],16));}
return array?rgb:'rgb('+rgb.join(',')+')';}});Number.extend({toInt:function(){return parseInt(this);},toFloat:function(){return parseFloat(this);}});Function.extend({create:function(options){var fn=this;options=$merge({'bind':fn,'event':false,'arguments':null,'delay':false,'periodical':false,'attempt':false},options);if($chk(options.arguments)&&$type(options.arguments)!='array')options.arguments=[options.arguments];return function(event){var args;if(options.event){event=event||window.event;args=[(options.event===true)?event:new options.event(event)];if(options.arguments)args=args.concat(options.arguments);}
else args=options.arguments||arguments;var returns=function(){return fn.apply($pick(options.bind,fn),args);};if(options.delay)return setTimeout(returns,options.delay);if(options.periodical)return setInterval(returns,options.periodical);if(options.attempt)try{return returns();}catch(err){return false;};return returns();};},pass:function(args,bind){return this.create({'arguments':args,'bind':bind});},attempt:function(args,bind){return this.create({'arguments':args,'bind':bind,'attempt':true})();},bind:function(bind,args){return this.create({'bind':bind,'arguments':args});},bindAsEventListener:function(bind,args){return this.create({'bind':bind,'event':true,'arguments':args});},delay:function(delay,bind,args){return this.create({'delay':delay,'bind':bind,'arguments':args})();},periodical:function(interval,bind,args){return this.create({'periodical':interval,'bind':bind,'arguments':args})();}});var Element=new Class({initialize:function(el,props){if($type(el)=='string'){if(window.ie&&props&&(props.name||props.type)){var name=(props.name)?' name="'+props.name+'"':'';var type=(props.type)?' type="'+props.type+'"':'';delete props.name;delete props.type;el='<'+el+name+type+'>';}
el=document.createElement(el);}
el=$(el);if(!props||!el)return el;for(var prop in props){var val=props[prop];switch(prop){case'styles':el.setStyles(val);break;case'events':if(el.addEvents)el.addEvents(val);break;case'properties':el.setProperties(val);break;default:el.setProperty(prop,val);}}
return el;}});var Elements=new Class({});Elements.extend=Class.prototype.implement;function $(el){if(!el)return false;if(el.htmlElement)return Garbage.collect(el);if([window,document].contains(el))return el;var type=$type(el);if(type=='string'){el=document.getElementById(el);type=(el)?'element':false;}
if(type!='element')return false;if(el.htmlElement)return Garbage.collect(el);if(['object','embed'].contains(el.tagName.toLowerCase()))return el;$extend(el,Element.prototype);el.htmlElement=true;return Garbage.collect(el);};document.getElementsBySelector=document.getElementsByTagName;function $$(){if(!arguments)return false;var elements=[];for(var i=0,j=arguments.length;i<j;i++){var selector=arguments[i];switch($type(selector)){case'element':elements.push(selector);case'boolean':case false:break;case'string':selector=document.getElementsBySelector(selector,true);default:elements=elements.concat((selector.push)?selector:$A(selector));}}
return $$.unique(elements);};$$.unique=function(array){var elements=[];for(var i=0,l=array.length;i<l;i++){if(array[i].$included)continue;var element=$(array[i]);if(element&&!element.$included){element.$included=true;elements.push(element);}}
for(var i=0,l=elements.length;i<l;i++)elements[i].$included=null;return $extend(elements,new Elements);};Elements.Multi=function(property){return function(){var args=arguments;var items=[];var elements=true;for(var i=0,j=this.length,returns;i<j;i++){returns=this[i][property].apply(this[i],args);if($type(returns)!='element')elements=false;items.push(returns);};return(elements)?$$.unique(items):items;};};Element.extend=function(properties){for(var property in properties){HTMLElement.prototype[property]=properties[property];Element.prototype[property]=properties[property];Elements.prototype[property]=Elements.Multi(property);}};Element.extend({inject:function(el,where){el=$(el);switch(where){case'before':el.parentNode.insertBefore(this,el);break;case'after':var next=el.getNext();if(!next)el.parentNode.appendChild(this);else el.parentNode.insertBefore(this,next);break;case'top':var first=el.firstChild;if(first){el.insertBefore(this,first);break;}
default:el.appendChild(this);}
return this;},injectBefore:function(el){return this.inject(el,'before');},injectAfter:function(el){return this.inject(el,'after');},injectInside:function(el){return this.inject(el,'bottom');},injectTop:function(el){return this.inject(el,'top');},adopt:function(){$$.unique(arguments).injectInside(this);return this;},remove:function(){return this.parentNode.removeChild(this);},clone:function(contents){return $(this.cloneNode(contents!==false));},replaceWith:function(el){el=$(el);this.parentNode.replaceChild(el,this);return el;},appendText:function(text){if(window.ie){switch(this.getTag()){case'style':this.styleSheet.cssText=text;return this;case'script':return this.setProperty('text',text);}}
this.appendChild(document.createTextNode(text));return this;},hasClass:function(className){return this.className.contains(className,' ');},addClass:function(className){if(!this.hasClass(className))this.className=(this.className+' '+className).clean();return this;},removeClass:function(className){this.className=this.className.replace(new RegExp('(^|\\s)'+className+'(?:\\s|$)'),'$1').clean();return this;},toggleClass:function(className){return this.hasClass(className)?this.removeClass(className):this.addClass(className);},setStyle:function(property,value){switch(property){case'opacity':return this.setOpacity(parseFloat(value));case'float':property=(window.ie)?'styleFloat':'cssFloat';}
property=property.camelCase();switch($type(value)){case'number':if(!['zIndex','zoom'].contains(property))value+='px';break;case'array':value='rgb('+value.join(',')+')';}
this.style[property]=value;return this;},setStyles:function(source){switch($type(source)){case'object':Element.setMany(this,'setStyle',source);break;case'string':this.style.cssText=source;}
return this;},setOpacity:function(opacity){if(opacity==0){if(this.style.visibility!="hidden")this.style.visibility="hidden";}else{if(this.style.visibility!="visible")this.style.visibility="visible";}
if(!this.currentStyle||!this.currentStyle.hasLayout)this.style.zoom=1;if(window.ie)this.style.filter=(opacity==1)?'':"alpha(opacity="+opacity*100+")";this.style.opacity=this.$.opacity=opacity;return this;},getStyle:function(property){property=property.camelCase();var result=this.style[property];if(!$chk(result)){if(property=='opacity')return this.$.opacity;var result=[];for(var style in Element.Styles){if(property==style){Element.Styles[style].each(function(s){result.push(this.getStyle(s));},this);if(property=='border'){var every=result.every(function(bit){return(bit==result[0]);});return(every)?result[0]:false;}
return result.join(' ');}}
if(Element.Styles.border.contains(property)){['Width','Color','Style'].each(function(p){result.push(this.getStyle(property+p));},this);return result.join(' ');}
if(document.defaultView)result=document.defaultView.getComputedStyle(this,null).getPropertyValue(property.hyphenate());else if(this.currentStyle)result=this.currentStyle[property];}
if(window.ie)result=Element.fixStyle(property,result,this);return(result&&property.test(/color/i)&&result.contains('rgb'))?result.rgbToHex():result;},getStyles:function(){return Element.getMany(this,'getStyle',arguments);},walk:function(brother,start){brother+='Sibling';var el=(start)?this[start]:this[brother];while(el&&$type(el)!='element')el=el[brother];return $(el);},getPrevious:function(){return this.walk('previous');},getNext:function(){return this.walk('next');},getFirst:function(){return this.walk('next','firstChild');},getLast:function(){return this.walk('previous','lastChild');},getParent:function(){return $(this.parentNode);},getChildren:function(){return $$(this.childNodes);},hasChild:function(el){return!!$A(this.getElementsByTagName('*')).contains(el);},getProperty:function(property){var index=Element.Properties[property];return(index)?this[index]:this.getAttribute(property);},removeProperty:function(property){var index=Element.Properties[property];if(index)this[index]='';else this.removeAttribute(property);return this;},getProperties:function(){return Element.getMany(this,'getProperty',arguments);},setProperty:function(property,value){var index=Element.Properties[property];if(index)this[index]=value;else this.setAttribute(property,value);return this;},setProperties:function(source){return Element.setMany(this,'setProperty',source);},setHTML:function(){this.innerHTML=$A(arguments).join('');return this;},getTag:function(){return this.tagName.toLowerCase();},empty:function(){Garbage.trash(this.getElementsByTagName('*'));return this.setHTML('');}});Element.fixStyle=function(property,result,element){if($chk(parseInt(result)))return result;if(['height','width'].contains(property)){var values=(property=='width')?['left','right']:['top','bottom'];var size=0;values.each(function(value){size+=element.getStyle('border-'+value+'-width').toInt()+element.getStyle('padding-'+value).toInt();});return element['offset'+property.capitalize()]-size+'px';}else if(property.test(/border(.+)Width/)){return'0px';}
return result;};Element.Styles={'border':[],'padding':[],'margin':[]};['Top','Right','Bottom','Left'].each(function(direction){for(var style in Element.Styles)Element.Styles[style].push(style+direction);});Element.getMany=function(el,method,keys){var result={};$each(keys,function(key){result[key]=el[method](key);});return result;};Element.setMany=function(el,method,pairs){for(var key in pairs)el[method](key,pairs[key]);return el;};Element.Properties=new Abstract({'class':'className','for':'htmlFor','colspan':'colSpan','rowspan':'rowSpan','accesskey':'accessKey','tabindex':'tabIndex','maxlength':'maxLength','readonly':'readOnly','value':'value','disabled':'disabled','checked':'checked','multiple':'multiple'});Element.listenerMethods={addListener:function(type,fn){if(this.addEventListener)this.addEventListener(type,fn,false);else this.attachEvent('on'+type,fn);return this;},removeListener:function(type,fn){if(this.removeEventListener)this.removeEventListener(type,fn,false);else this.detachEvent('on'+type,fn);return this;}};window.extend(Element.listenerMethods);document.extend(Element.listenerMethods);Element.extend(Element.listenerMethods);Element.Events=new Abstract({});var Garbage={elements:[],collect:function(el){if(!el.$){Garbage.elements.push(el);el.$={'opacity':1};}
return el;},trash:function(elements){for(var i=0,j=elements.length,el;i<j;i++){if(!(el=elements[i])||!el.$)return;if(el.$events){el.fireEvent('onTrash');el.removeEvents();}
for(var p in el.$)el.$[p]=null;for(var p in Element.prototype)el[p]=null;el.htmlElement=el.$=null;Garbage.elements.remove(el);}},empty:function(){Garbage.collect(window);Garbage.collect(document);Garbage.trash(Garbage.elements);}};window.addListener('unload',Garbage.empty);var Event=new Class({initialize:function(event){event=event||window.event;this.event=event;this.type=event.type;this.target=event.target||event.srcElement;if(this.target.nodeType==3)this.target=this.target.parentNode;this.shift=event.shiftKey;this.control=event.ctrlKey;this.alt=event.altKey;this.meta=event.metaKey;if(['DOMMouseScroll','mousewheel'].contains(this.type)){this.wheel=event.wheelDelta?(event.wheelDelta/(window.opera?-120:120)):-(event.detail||0)/3;}else if(this.type.contains('key')){this.code=event.which||event.keyCode;for(var name in Event.keys){if(Event.keys[name]==this.code){this.key=name;break;}}
if(this.type=='keydown'){var fKey=this.code-111;if(fKey>0&&fKey<13)this.key='f'+fKey;}
this.key=this.key||String.fromCharCode(this.code).toLowerCase();}else if(this.type.test(/(click|mouse|menu)/)){this.page={'x':event.pageX||event.clientX+document.documentElement.scrollLeft,'y':event.pageY||event.clientY+document.documentElement.scrollTop};this.client={'x':event.pageX?event.pageX-window.pageXOffset:event.clientX,'y':event.pageY?event.pageY-window.pageYOffset:event.clientY};this.rightClick=(event.which==3)||(event.button==2);switch(this.type){case'mouseover':this.relatedTarget=event.relatedTarget||event.fromElement;break;case'mouseout':this.relatedTarget=event.relatedTarget||event.toElement;}
if(this.relatedTarget&&this.relatedTarget.nodeType==3)this.relatedTarget=this.relatedTarget.parentNode;}},stop:function(){return this.stopPropagation().preventDefault();},stopPropagation:function(){if(this.event.stopPropagation)this.event.stopPropagation();else this.event.cancelBubble=true;return this;},preventDefault:function(){if(this.event.preventDefault)this.event.preventDefault();else this.event.returnValue=false;return this;}});Event.keys=new Abstract({'enter':13,'up':38,'down':40,'left':37,'right':39,'esc':27,'space':32,'backspace':8,'tab':9,'delete':46});Element.Events.extend({'mouseenter':{type:'mouseover',map:function(event){event=new Event(event);if(event.relatedTarget==this||this.hasChild(event.relatedTarget))return;this.fireEvent('mouseenter',event);}},'mouseleave':{type:'mouseout',map:function(event){event=new Event(event);if(event.relatedTarget==this||this.hasChild(event.relatedTarget))return;this.fireEvent('mouseleave',event);}}});Function.extend({bindWithEvent:function(bind,args){return this.create({'bind':bind,'arguments':args,'event':Event});}});function $E(selector,filter){return($(filter)||document).getElement(selector);};function $ES(selector,filter){return($(filter)||document).getElementsBySelector(selector);};$$.shared={cache:{},regexp:/^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,getNormalParam:function(selector,items,context,param,i){Filters.selector=param;if(i==0){if(param[2]){var el=context.getElementById(param[2]);if(!el||((param[1]!='*')&&(el.tagName.toLowerCase()!=param[1])))return false;items=[el];}else{items=$A(context.getElementsByTagName(param[1]));}}else{items=$$.shared.getElementsByTagName(items,param[1]);if(param[2])items=items.filter(Filters.id);}
if(param[3])items=items.filter(Filters.className);if(param[4])items=items.filter(Filters.attribute);return items;},getNormalItems:function(items,context,nocash){return(nocash)?items:$$.unique(items);},resolver:function(prefix){return(prefix=='xhtml')?'http://www.w3.org/1999/xhtml':false;},getElementsByTagName:function(context,tagName){var found=[];for(var i=0,j=context.length;i<j;i++)found=found.concat($A(context[i].getElementsByTagName(tagName)));return found;}};$$.shared.getParam=$$.shared.getNormalParam;$$.shared.getItems=$$.shared.getNormalItems;
Element.domMethods={getElements:function(selector,nocash){var items=[];selector=selector.trim().split(' ');for(var i=0,j=selector.length;i<j;i++){var sel=selector[i];var param;if($$.shared.cache[sel]){param=$$.shared.cache[sel].param;}else{param=sel.match($$.shared.regexp);if(!param)break;param[1]=param[1]||'*';$$.shared.cache[sel]={'param':param};}
var temp=$$.shared.getParam(sel,items,this,param,i);if(!temp)break;items=temp;}
return $$.shared.getItems(items,this,nocash);},getElement:function(selector){return $(this.getElements(selector,true)[0]||false);},getElementsBySelector:function(selector,nocash){var elements=[];selector=selector.split(',');for(var i=0,j=selector.length;i<j;i++)elements=elements.concat(this.getElements(selector[i],true));return(nocash)?elements:$$.unique(elements);},getElementsByClassName:function(className){return this.getElements('.'+className);}};Element.extend({getElementById:function(id){var el=document.getElementById(id);if(!el)return false;for(var parent=el.parentNode;parent!=this;parent=parent.parentNode){if(!parent)return false;}
return el;}});document.extend(Element.domMethods);Element.extend(Element.domMethods);var Filters={selector:[],id:function(el){return(el.id==Filters.selector[2]);},className:function(el){return el.className.contains(Filters.selector[3],' ');},attribute:function(el){var current=Element.prototype.getProperty.call(el,Filters.selector[4]);if(!current)return false;var operator=Filters.selector[5];if(!operator)return true;var value=Filters.selector[6];switch(operator){case'=':return(current==value);case'*=':return(current.contains(value));case'^=':return(current.test('^'+value));case'$=':return(current.test(value+'$'));case'!=':return(current!=value);case'~=':return current.contains(value,' ');}
return false;}};Element.extend({getValue:function(){switch(this.getTag()){case'select':var values=[];$each(this.options,function(opt){if(opt.selected)values.push($pick(opt.value,opt.text));});return(this.multiple)?values:values[0];case'input':if(!(this.checked&&['checkbox','radio'].contains(this.type))&&!['hidden','text','password'].contains(this.type))break;case'textarea':return this.value;}
return false;},getFormElements:function(){return $$(this.getElementsByTagName('input'),this.getElementsByTagName('select'),this.getElementsByTagName('textarea'));},toQueryString:function(){var queryString=[];this.getFormElements().each(function(el){var name=el.name;var value=el.getValue();if(value===false||!name||el.disabled)return;var qs=function(val){queryString.push(name+'='+encodeURIComponent(val));};if($type(value)=='array')value.each(qs);else qs(value);});return queryString.join('&');}});Element.extend({scrollTo:function(x,y){this.scrollLeft=x;this.scrollTop=y;},getSize:function(){return{'scroll':{'x':this.scrollLeft,'y':this.scrollTop},'size':{'x':this.offsetWidth,'y':this.offsetHeight},'scrollSize':{'x':this.scrollWidth,'y':this.scrollHeight}};},getPosition:function(overflown){overflown=overflown||[];var el=this,left=0,top=0;do{left+=el.offsetLeft||0;top+=el.offsetTop||0;el=el.offsetParent;}while(el);overflown.each(function(element){left-=element.scrollLeft||0;top-=element.scrollTop||0;});return{'x':left,'y':top};},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;},getCoordinates:function(overflown){var position=this.getPosition(overflown);var obj={'width':this.offsetWidth,'height':this.offsetHeight,'left':position.x,'top':position.y};obj.right=obj.left+obj.width;obj.bottom=obj.top+obj.height;return obj;}});Element.eventMethods={addEvent:function(type,fn){this.$events=this.$events||{};this.$events[type]=this.$events[type]||{'keys':[],'values':[]};if(this.$events[type].keys.contains(fn))return this;this.$events[type].keys.push(fn);var realType=type;var bound=false;if(Element.Events[type]){if(Element.Events[type].add)Element.Events[type].add.call(this,fn);if(Element.Events[type].map)bound=Element.Events[type].map.bindAsEventListener(this);realType=Element.Events[type].type||type;}
if(!this.addEventListener)bound=bound||fn.bindAsEventListener(this);else bound=bound||fn;this.$events[type].values.push(bound);return this.addListener(realType,bound);},removeEvent:function(type,fn){if(!this.$events||!this.$events[type])return this;var pos=this.$events[type].keys.indexOf(fn);if(pos==-1)return this;var key=this.$events[type].keys.splice(pos,1)[0];var value=this.$events[type].values.splice(pos,1)[0];if(Element.Events[type]){if(Element.Events[type].remove)Element.Events[type].remove.call(this,fn);type=Element.Events[type].type||type;}
return this.removeListener(type,value);},addEvents:function(source){return Element.setMany(this,'addEvent',source);},removeEvents:function(type){if(!this.$events)return this;if(type){if(this.$events[type]){$A(this.$events[type].keys).each(function(fn,i){this.removeEvent(type,fn);},this);this.$events[type]=null;}}else{for(var evType in this.$events)this.removeEvents(evType);this.$events=null;}
return this;},fireEvent:function(type,args){if(this.$events&&this.$events[type]){this.$events[type].keys.each(function(fn){fn.bind(this,args)();},this);}}};Element.Events.mousewheel={type:(window.gecko)?'DOMMouseScroll':'mousewheel'};window.extend(Element.eventMethods);document.extend(Element.eventMethods);Element.extend(Element.eventMethods);Element.Events.domready={add:function(fn){if(window.loaded){fn.call(this);return;}
var domReady=function(){if(window.loaded)return;window.loaded=true;window.timer=$clear(window.timer);this.fireEvent('domready');}.bind(this);if(document.readyState&&window.khtml){window.timer=function(){if(['loaded','complete'].contains(document.readyState))domReady();}.periodical(50);}else if(document.readyState&&window.ie){if(!$('ie_ready')){var src=(window.location.protocol=='https:')?'://0':'javascript:void(0)';document.write('<script id="ie_ready" defer src="'+src+'"><\/script>');$('ie_ready').onreadystatechange=function(){if(this.readyState=='complete')domReady();};}}else{window.addListener("load",domReady);document.addListener("DOMContentLoaded",domReady);}}};window.onDomReady=function(fn){return this.addEvent('domready',fn);};window.extend({getWidth:function(){if(this.khtml)return this.innerWidth;if(this.opera)return document.body.clientWidth;return document.documentElement.clientWidth;},getHeight:function(){if(this.khtml)return this.innerHeight;if(this.opera)return document.body.clientHeight;return document.documentElement.clientHeight;},getScrollWidth:function(){if(this.ie)return Math.max(document.documentElement.offsetWidth,document.documentElement.scrollWidth);if(this.khtml)return document.body.scrollWidth;return document.documentElement.scrollWidth;},getScrollHeight:function(){if(this.ie)return Math.max(document.documentElement.offsetHeight,document.documentElement.scrollHeight);if(this.khtml)return document.body.scrollHeight;return document.documentElement.scrollHeight;},getScrollLeft:function(){return this.pageXOffset||document.documentElement.scrollLeft;},getScrollTop:function(){return this.pageYOffset||document.documentElement.scrollTop;},getSize:function(){return{'size':{'x':this.getWidth(),'y':this.getHeight()},'scrollSize':{'x':this.getScrollWidth(),'y':this.getScrollHeight()},'scroll':{'x':this.getScrollLeft(),'y':this.getScrollTop()}};},getPosition:function(){return{'x':0,'y':0}}});var Fx={Shared:{}};Fx.Base=new Class({options:{onStart:Class.empty,onComplete:Class.empty,onCancel:Class.empty,transition:function(t,c,d){return-c/2*(Math.cos(Math.PI*t/d)-1);},duration:500,unit:'px',wait:true,fps:50},initialize:function(options){this.element=this.element||null;this.setOptions(options);if(this.options.initialize)this.options.initialize.call(this);},step:function(){var time=$time();if(time<this.time+this.options.duration){this.cTime=time-this.time;this.setNow();this.increase();}else{this.stop(true);this.now=this.to;this.increase();this.fireEvent('onComplete',this.element,10);this.callChain();}},set:function(to){this.now=to;this.increase();return this;},setNow:function(){this.now=this.compute(this.from,this.to);},compute:function(from,to){return this.options.transition(this.cTime,(to-from),this.options.duration)+from;},start:function(from,to){if(!this.options.wait)this.stop();else if(this.timer)return this;this.from=from;this.to=to;this.time=$time();this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);this.fireEvent('onStart',this.element);return this;},stop:function(end){if(!this.timer)return this;this.timer=$clear(this.timer);if(!end)this.fireEvent('onCancel',this.element);return this;},custom:function(from,to){return this.start(from,to)},clearTimer:function(end){return this.stop(end)}});Fx.Base.implement(new Chain);Fx.Base.implement(new Events);Fx.Base.implement(new Options);Fx.CSS={select:function(property,to){if(property.test(/color/i))return this.Color;if(to.contains&&to.contains(' '))return this.Multi;return this.Single;},parse:function(el,property,fromTo){if(!fromTo.push)fromTo=[fromTo];var from=fromTo[0],to=fromTo[1];if(!to&&to!=0){to=from;from=el.getStyle(property);}
var css=this.select(property,to);return{from:css.parse(from),to:css.parse(to),css:css};}};Fx.CSS.Single={parse:function(value){return parseFloat(value);},getNow:function(from,to,fx){return fx.compute(from,to);},getValue:function(value,unit){return value+unit;}};Fx.CSS.Multi={parse:function(value){return value.push?value:value.split(' ').map(function(v){return parseFloat(v);});},getNow:function(from,to,fx){var now=[];for(var i=0;i<from.length;i++)now[i]=fx.compute(from[i],to[i]);return now;},getValue:function(value,unit){return value.join(unit+' ')+unit;}};Fx.CSS.Color={parse:function(value){return value.push?value:value.hexToRgb(true);},getNow:function(from,to,fx){var now=[];for(var i=0;i<from.length;i++)now[i]=Math.round(fx.compute(from[i],to[i]));return now;},getValue:function(value){return'rgb('+value.join(',')+')';}};Fx.Style=Fx.Base.extend({initialize:function(el,property,options){this.element=$(el);this.property=property;this.parent(options);},hide:function(){return this.set(0);},setNow:function(){this.now=this.css.getNow(this.from,this.to,this);},set:function(to){this.css=Fx.CSS.select(this.property,to);return this.parent(this.css.parse(to));},start:function(from,to){if(this.timer&&this.options.wait)return this;var parsed=Fx.CSS.parse(this.element,this.property,[from,to]);this.css=parsed.css;return this.parent(parsed.from,parsed.to);},increase:function(){this.element.setStyle(this.property,this.css.getValue(this.now,this.options.unit));}});Element.extend({effect:function(property,options){return new Fx.Style(this,property,options);}});Fx.Styles=Fx.Base.extend({initialize:function(el,options){this.element=$(el);this.parent(options);},setNow:function(){for(var p in this.from)this.now[p]=this.css[p].getNow(this.from[p],this.to[p],this);},set:function(to){var parsed={};this.css={};for(var p in to){this.css[p]=Fx.CSS.select(p,to[p]);parsed[p]=this.css[p].parse(to[p]);}
return this.parent(parsed);},start:function(obj){if(this.timer&&this.options.wait)return this;this.now={};this.css={};var from={},to={};for(var p in obj){var parsed=Fx.CSS.parse(this.element,p,obj[p]);from[p]=parsed.from;to[p]=parsed.to;this.css[p]=parsed.css;}
return this.parent(from,to);},increase:function(){for(var p in this.now)this.element.setStyle(p,this.css[p].getValue(this.now[p],this.options.unit));}});Element.extend({effects:function(options){return new Fx.Styles(this,options);}});Fx.Elements=Fx.Base.extend({initialize:function(elements,options){this.elements=$$(elements);this.parent(options);},setNow:function(){for(var i in this.from){var iFrom=this.from[i],iTo=this.to[i],iCss=this.css[i],iNow=this.now[i]={};for(var p in iFrom)iNow[p]=iCss[p].getNow(iFrom[p],iTo[p],this);}},set:function(to){var parsed={};this.css={};for(var i in to){var iTo=to[i],iCss=this.css[i]={},iParsed=parsed[i]={};for(var p in iTo){iCss[p]=Fx.CSS.select(p,iTo[p]);iParsed[p]=iCss[p].parse(iTo[p]);}}
return this.parent(parsed);},start:function(obj){if(this.timer&&this.options.wait)return this;this.now={};this.css={};var from={},to={};for(var i in obj){var iProps=obj[i],iFrom=from[i]={},iTo=to[i]={},iCss=this.css[i]={};for(var p in iProps){var parsed=Fx.CSS.parse(this.elements[i],p,iProps[p]);iFrom[p]=parsed.from;iTo[p]=parsed.to;iCss[p]=parsed.css;}}
return this.parent(from,to);},increase:function(){for(var i in this.now){var iNow=this.now[i],iCss=this.css[i];for(var p in iNow)this.elements[i].setStyle(p,iCss[p].getValue(iNow[p],this.options.unit));}}});Fx.Scroll=Fx.Base.extend({initialize:function(element,options){this.now=[];this.element=$(element);this.addEvent('onStart',function(){this.element.addEvent('mousewheel',this.stop.bind(this,false));}.bind(this));this.removeEvent('onComplete',function(){this.element.removeEvent('mousewheel',this.stop.bind(this,false));}.bind(this));this.parent(options);},setNow:function(){for(var i=0;i<2;i++)this.now[i]=this.compute(this.from[i],this.to[i]);},scrollTo:function(x,y){if(this.timer&&this.options.wait)return this;var el=this.element.getSize();var values={'x':x,'y':y};for(var z in el.size){var max=el.scrollSize[z]-el.size[z];if($chk(values[z]))values[z]=($type(values[z])=='number')?Math.max(Math.min(values[z],max),0):max;else values[z]=el.scroll[z];}
return this.start([el.scroll.x,el.scroll.y],[values.x,values.y]);},toTop:function(){return this.scrollTo(false,0);},toBottom:function(){return this.scrollTo(false,'full');},toLeft:function(){return this.scrollTo(0,false);},toRight:function(){return this.scrollTo('full',false);},toElement:function(el){var parent=this.element.getPosition();var target=$(el).getPosition();return this.scrollTo(target.x-parent.x,target.y-parent.y);},increase:function(){this.element.scrollTo(this.now[0],this.now[1]);}});Fx.Slide=Fx.Base.extend({options:{mode:'vertical'},initialize:function(el,options){this.element=$(el);this.wrapper=new Element('div',{'styles':$extend(this.element.getStyles('margin'),{'overflow':'hidden'})}).injectAfter(this.element).adopt(this.element);this.element.setStyle('margin',0);this.setOptions(options);this.now=[];this.parent(this.options);},setNow:function(){for(var i=0;i<2;i++)this.now[i]=this.compute(this.from[i],this.to[i]);},vertical:function(){this.margin='margin-top';this.layout='height';this.offset=this.element.offsetHeight;},horizontal:function(){this.margin='margin-left';this.layout='width';this.offset=this.element.offsetWidth;},slideIn:function(mode){this[mode||this.options.mode]();return this.start([this.element.getStyle(this.margin).toInt(),this.wrapper.getStyle(this.layout).toInt()],[0,this.offset]);},slideOut:function(mode){this[mode||this.options.mode]();return this.start([this.element.getStyle(this.margin).toInt(),this.wrapper.getStyle(this.layout).toInt()],[-this.offset,0]);},hide:function(mode){this[mode||this.options.mode]();return this.set([-this.offset,0]);},show:function(mode){this[mode||this.options.mode]();return this.set([0,this.offset]);},toggle:function(mode){if(this.wrapper.offsetHeight==0||this.wrapper.offsetWidth==0)return this.slideIn(mode);return this.slideOut(mode);},increase:function(){this.element.setStyle(this.margin,this.now[0]+this.options.unit);this.wrapper.setStyle(this.layout,this.now[1]+this.options.unit);}});Fx.Transitions=new Abstract({linear:function(t,c,d){return c*(t/d);}});Fx.Shared.CreateTransitionEases=function(transition,type){$extend(transition,{easeIn:function(t,c,d,x,y,z){return c-c*transition((d-t)/d,t,c,d,x,y,z);},easeOut:function(t,c,d,x,y,z){return c*transition(t/d,t,c,d,x,y,z);},easeInOut:function(t,c,d,x,y,z){d/=2,c/=2;var p=t/d;return(p<1)?transition.easeIn(t,c,d,x,y,z):c*(transition(p-1,t,c,d,x,y,z)+1);}});['In','Out','InOut'].each(function(mode){transition['ease'+mode].set=Fx.Shared.SetTransitionValues(transition['ease'+mode]);Fx.Transitions[type.toLowerCase()+mode]=transition['ease'+mode];});};Fx.Shared.SetTransitionValues=function(transition){return function(){var args=$A(arguments);return function(){return transition.apply(Fx.Transitions,$A(arguments).concat(args));};}};Fx.Transitions.extend=function(transitions){for(var type in transitions){if(type.test(/^[A-Z]/))Fx.Shared.CreateTransitionEases(transitions[type],type);else transitions[type].set=Fx.Shared.SetTransitionValues(transitions[type]);Fx.Transitions[type]=transitions[type];}};Fx.Transitions.extend({Sine:function(p){return Math.sin(p*(Math.PI/2));},Quad:function(p){return-(Math.pow(p-1,2)-1);},Cubic:function(p){return Math.pow(p-1,3)+1;},Quart:function(p){return-(Math.pow(p-1,4)-1);},Quint:function(p){return Math.pow(p-1,5)+1;},Expo:function(p){return-Math.pow(2,-10*p)+1;},Circ:function(p){return Math.sqrt(1-Math.pow(p-1,2));},Bounce:function(p){var b=7.5625;if(p<(1/2.75))return b*Math.pow(p,2);else if(p<(2/2.75))return b*(p-=(1.5/2.75))*p+0.75;else if(p<(2.5/2.75))return b*(p-=(2.25/2.75))*p+0.9375;else return b*(p-=(2.625/2.75))*p+0.984375;},Back:function(p,t,c,d,x){x=x||1.70158;p-=1;return Math.pow(p,2)*((x+1)*p+x)+1;},Elastic:function(p,t,c,d,x){x=d*0.3/(x||1);return(c*Math.pow(2,-10*p)*Math.sin((p*d-x/4)*(2*Math.PI)/x)+c)/c;}});var Drag={};Drag.Base=new Class({options:{handle:false,unit:'px',onStart:Class.empty,onBeforeStart:Class.empty,onComplete:Class.empty,onSnap:Class.empty,onDrag:Class.empty,limit:false,modifiers:{x:'left',y:'top'},grid:false,snap:6},initialize:function(el,options){this.setOptions(options);this.element=$(el);this.handle=$(this.options.handle)||this.element;this.mouse={'now':{},'pos':{}};this.value={'start':{},'now':{}};this.bound={'start':this.start.bindWithEvent(this),'check':this.check.bindWithEvent(this),'drag':this.drag.bindWithEvent(this),'stop':this.stop.bind(this)};this.attach();if(this.options.initialize)this.options.initialize.call(this);},attach:function(){this.handle.addEvent('mousedown',this.bound.start);return this;},detach:function(){this.handle.removeEvent('mousedown',this.bound.start);return this;},start:function(event){this.fireEvent('onBeforeStart',this.element);this.mouse.start=event.page;var limit=this.options.limit;this.limit={'x':[],'y':[]};for(var z in this.options.modifiers){if(!this.options.modifiers[z])continue;this.value.now[z]=this.element.getStyle(this.options.modifiers[z]).toInt();this.mouse.pos[z]=event.page[z]-this.value.now[z];if(limit&&limit[z]){for(var i=0;i<2;i++){if($chk(limit[z][i]))this.limit[z][i]=limit[z][i].apply?limit[z][i].call(this):limit[z][i];}}}
if($type(this.options.grid)=='number')this.options.grid={'x':this.options.grid,'y':this.options.grid};document.addListener('mousemove',this.bound.check);document.addListener('mouseup',this.bound.stop);this.fireEvent('onStart',this.element);event.stop();},check:function(event){var distance=Math.round(Math.sqrt(Math.pow(event.page.x-this.mouse.start.x,2)+Math.pow(event.page.y-this.mouse.start.y,2)));if(distance>this.options.snap){document.removeListener('mousemove',this.bound.check);document.addListener('mousemove',this.bound.drag);this.drag(event);this.fireEvent('onSnap',this.element);}
event.stop();},drag:function(event){this.out=false;this.mouse.now=event.page;for(var z in this.options.modifiers){if(!this.options.modifiers[z])continue;this.value.now[z]=this.mouse.now[z]-this.mouse.pos[z];if(this.limit[z]){if($chk(this.limit[z][1])&&(this.value.now[z]>this.limit[z][1])){this.value.now[z]=this.limit[z][1];this.out=true;}else if($chk(this.limit[z][0])&&(this.value.now[z]<this.limit[z][0])){this.value.now[z]=this.limit[z][0];this.out=true;}}
if(this.options.grid[z])this.value.now[z]-=(this.value.now[z]%this.options.grid[z]);this.element.setStyle(this.options.modifiers[z],this.value.now[z]+this.options.unit);}
this.fireEvent('onDrag',this.element);event.stop();},stop:function(){document.removeListener('mousemove',this.bound.check);document.removeListener('mousemove',this.bound.drag);document.removeListener('mouseup',this.bound.stop);this.fireEvent('onComplete',this.element);}});Drag.Base.implement(new Events);Drag.Base.implement(new Options);Element.extend({makeResizable:function(options){return new Drag.Base(this,$merge({modifiers:{x:'width',y:'height'}},options));}});Drag.Move=Drag.Base.extend({options:{droppables:[],container:false,overflown:[]},initialize:function(el,options){this.setOptions(options);this.element=$(el);this.position=this.element.getStyle('position');this.droppables=$$(this.options.droppables);if(!['absolute','relative'].contains(this.position))this.position='absolute';var top=this.element.getStyle('top').toInt();var left=this.element.getStyle('left').toInt();if(this.position=='absolute'){top=$chk(top)?top:this.element.getTop();left=$chk(left)?left:this.element.getLeft();}else{top=$chk(top)?top:0;left=$chk(left)?left:0;}
this.element.setStyles({'top':top,'left':left,'position':this.position});this.parent(this.element,this.options);},start:function(event){this.container=$(this.options.container);if(this.container){var cont=this.container.getCoordinates();var el=this.element.getCoordinates();if(this.position=='absolute'){this.options.limit={'x':[cont.left,cont.right-el.width],'y':[cont.top,cont.bottom-el.height]};}else{var diffx=el.left-this.element.getStyle('left').toInt();var diffy=el.top-this.element.getStyle('top').toInt();this.options.limit={'y':[-(diffy)+cont.top,cont.bottom-diffy-el.height],'x':[-(diffx)+cont.left,cont.right-diffx-el.width]};}}
this.parent(event);},drag:function(event){this.parent(event);if(this.out)return this;this.droppables.each(function(drop){if(this.checkAgainst($(drop))){if(!drop.overing)drop.fireEvent('over',[this.element,this]);drop.overing=true;}else{if(drop.overing)drop.fireEvent('leave',[this.element,this]);drop.overing=false;}},this);return this;},checkAgainst:function(el){el=el.getCoordinates(this.options.overflown);return(this.mouse.now.x>el.left&&this.mouse.now.x<el.right&&this.mouse.now.y<el.bottom&&this.mouse.now.y>el.top);},stop:function(){if(!this.out){var dropped=false;this.droppables.each(function(drop){if(this.checkAgainst(drop)){drop.fireEvent('drop',[this.element,this]);dropped=true;}},this);if(!dropped)this.element.fireEvent('emptydrop',this);}
this.parent();return this;}});Element.extend({makeDraggable:function(options){return new Drag.Move(this,options);}});var XHR=new Class({options:{method:'post',async:true,onRequest:Class.empty,onSuccess:Class.empty,onFailure:Class.empty,urlEncoded:true,encoding:'utf-8',autoCancel:false,headers:{}},initialize:function(options){this.transport=(window.XMLHttpRequest)?new XMLHttpRequest():(window.ie?new ActiveXObject('Microsoft.XMLHTTP'):false);if(!this.transport)return;this.setOptions(options);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers={};if(this.options.urlEncoded&&this.options.method=='post'){var encoding=(this.options.encoding)?'; charset='+this.options.encoding:'';this.setHeader('Content-type','application/x-www-form-urlencoded'+encoding);}
if(this.options.initialize)this.options.initialize.call(this);},onStateChange:function(){if(this.transport.readyState!=4||!this.running)return;this.running=false;var status=0;try{status=this.transport.status}catch(e){};if(this.options.isSuccess.call(this,status))this.onSuccess();else this.onFailure();this.transport.onreadystatechange=Class.empty;},isSuccess:function(status){return((status>=200)&&(status<300));},onSuccess:function(){this.response={'text':this.transport.responseText,'xml':this.transport.responseXML};this.fireEvent('onSuccess',[this.response.text,this.response.xml]);this.callChain();},onFailure:function(){this.fireEvent('onFailure',this.transport);},setHeader:function(name,value){this.headers[name]=value;return this;},send:function(url,data){if(this.options.autoCancel)this.cancel();else if(this.running)return this;this.running=true;if(data&&this.options.method=='get')url=url+(url.contains('?')?'&':'?')+data,data=null;(function(){this.transport.open(this.options.method,url,this.options.async);this.transport.onreadystatechange=this.onStateChange.bind(this);if((this.options.method=='post')&&this.transport.overrideMimeType)this.setHeader('Connection','close');$extend(this.headers,this.options.headers);for(var type in this.headers)try{this.transport.setRequestHeader(type,this.headers[type]);}catch(e){};this.fireEvent('onRequest');this.transport.send($pick(data,null));}).delay(this.options.async?1:false,this);return this;},cancel:function(){if(!this.running)return this;this.running=false;this.transport.abort();this.transport.onreadystatechange=Class.empty;this.fireEvent('onCancel');return this;}});XHR.implement(new Chain);XHR.implement(new Events);XHR.implement(new Options);var Ajax=XHR.extend({options:{data:null,update:null,onComplete:Class.empty,evalScripts:false,evalResponse:false},initialize:function(url,options){this.addEvent('onSuccess',this.onComplete);this.setOptions(options);this.options.data=this.options.data||this.options.postBody;if(!['post','get'].contains(this.options.method)){this._method='_method='+this.options.method;this.options.method='post';}
this.parent(this.options);this.setHeader('X-Requested-With','XMLHttpRequest');this.setHeader('Accept','text/javascript, text/html, application/xml, text/xml, */*');this.url=url;},onComplete:function(){if(this.options.update)$(this.options.update).setHTML(this.response.text);if(this.options.evalScripts||this.options.evalResponse)this.evalScripts();this.fireEvent('onComplete',[this.response.text,this.response.xml],20);},request:function(data){data=data||this.options.data;switch($type(data)){case'element':data=$(data).toQueryString();break;case'object':data=Object.toQueryString(data);}
if(this._method)data=(data)?[this._method,data].join('&'):this._method;return this.send(this.url,data);},evalScripts:function(){if(this.options.evalResponse||/(ecma|java)script/.test(this.getHeader('Content-type')))var scripts=this.response.text;else{var script,scripts=[],regexp=/<script[^>]*>([\s\S]*?)<\/script>/gi;while((script=regexp.exec(this.response.text)))scripts.push(script[1]);scripts=scripts.join('\n');}
if(scripts)(window.execScript)?window.execScript(scripts):window.setTimeout(scripts,0);},getHeader:function(name){try{return this.transport.getResponseHeader(name);}catch(e){};return null;}});Object.toQueryString=function(source){var queryString=[];for(var property in source)queryString.push(encodeURIComponent(property)+'='+encodeURIComponent(source[property]));return queryString.join('&');};Element.extend({send:function(options){return new Ajax(this.getProperty('action'),$merge({postBody:this.toQueryString()},options,{method:'post'})).request();}});var Cookie=new Abstract({options:{domain:false,path:false,duration:false,secure:false},set:function(key,value,options){options=$merge(this.options,options);value=encodeURIComponent(value);if(options.domain)value+='; domain='+options.domain;if(options.path)value+='; path='+options.path;if(options.duration){var date=new Date();date.setTime(date.getTime()+options.duration/1000);value+='; expires='+date.toGMTString();}
if(options.secure)value+='; secure';document.cookie=key+'='+value;return $extend(options,{'key':key,'value':value});},get:function(key){var value=document.cookie.match('(?:^|;)\\s*'+key.escapeRegExp()+'=([^;]*)');return value?decodeURIComponent(value[1]):false;},remove:function(cookie,options){if($type(cookie)=='object')this.set(cookie.key,'',$merge(cookie,{duration:-1}));else this.set(cookie,'',$merge(options,{duration:-1}));}});Cookie.Json=new Class({initialize:function(name,options){this.name=name;this.options=options;return;},set:function(key,value){var object=this.get()||{};object[key]=value;this.save(object);return this;},save:function(object){object=Json.toString(object);if(object.length>4096)return false;Cookie.set(this.name,object,this.options);return this;},remove:function(key){var object=this.get();delete object[key];this.save(object);return this;},get:function(key){var object=Json.evaluate(Cookie.get(this.name));return(key)?object[key]:object;},empty:function(){this.save(null);},merge:function(obj){this.save($merge(this.get(),obj));},fill:function(obj){this.save($merge(obj,this.get()));}});var Json={toString:function(obj){switch($type(obj)){case'string':return'"'+obj.replace(/(["\\])/g,'\$1')+'"';case'array':return'['+obj.map(function(ar){return Json.toString(ar);}).join(',')+']';case'object':var string=[];for(var property in obj)string.push(Json.toString(property)+':'+Json.toString(obj[property]));return'{'+string.join(',')+'}';}
return String(obj);},evaluate:function(str){return eval('('+str+')');}};Json.Remote=XHR.extend({initialize:function(url,options){this.url=url;this.addEvent('onSuccess',this.onComplete);this.parent(options);this.setHeader('X-Request','JSON');},send:function(obj){return this.parent(this.url,'json='+Json.toString(obj));},onComplete:function(){this.fireEvent('onComplete',Json.evaluate(this.response.text));}});var Color=new Class({initialize:function(color,type){type=type||(color.push?'rgb':'hex');var rgb,hsb;switch(type){case'rgb':rgb=color;hsb=rgb.rgbToHsb();break;case'hsb':rgb=color.hsbToRgb();hsb=color;break;default:rgb=color.hexToRgb(true);hsb=rgb.rgbToHsb();}
rgb.hsb=hsb;rgb.hex=rgb.rgbToHex();return $extend(rgb,Color.prototype);},mix:function(){var colors=$A(arguments);var alpha=($type(colors[colors.length-1])=='number')?colors.pop():50;var rgb=this.copy();colors.each(function(color){color=new Color(color);for(var i=0;i<3;i++)rgb[i]=Math.round((rgb[i]/100*(100-alpha))+(color[i]/100*alpha));});return new Color(rgb,'rgb');},invert:function(){return new Color(this.map(function(value){return 255-value;}));},setHue:function(value){return new Color([value,this.hsb[1],this.hsb[2]],'hsb');},setSaturation:function(percent){return new Color([this.hsb[0],percent,this.hsb[2]],'hsb');},setBrightness:function(percent){return new Color([this.hsb[0],this.hsb[1],percent],'hsb');}});function $RGB(r,g,b){return new Color([r,g,b],'rgb');};function $HSB(h,s,b){return new Color([h,s,b],'hsb');};Array.extend({rgbToHsb:function(){var red=this[0],green=this[1],blue=this[2];var hue,saturation,brightness;var max=Math.max(red,green,blue),min=Math.min(red,green,blue);var delta=max-min;brightness=max/255;saturation=(max!=0)?delta/max:0;if(saturation==0){hue=0;}else{var rr=(max-red)/delta;var gr=(max-green)/delta;var br=(max-blue)/delta;if(red==max)hue=br-gr;else if(green==max)hue=2+rr-br;else hue=4+gr-rr;hue/=6;if(hue<0)hue++;}
return[Math.round(hue*360),Math.round(saturation*100),Math.round(brightness*100)];},hsbToRgb:function(){var br=Math.round(this[2]/100*255);if(this[1]==0){return[br,br,br];}else{var hue=this[0]%360;var f=hue%60;var p=Math.round((this[2]*(100-this[1]))/10000*255);var q=Math.round((this[2]*(6000-this[1]*f))/600000*255);var t=Math.round((this[2]*(6000-this[1]*(60-f)))/600000*255);switch(Math.floor(hue/60)){case 0:return[br,t,p];case 1:return[q,br,p];case 2:return[p,br,t];case 3:return[p,q,br];case 4:return[t,p,br];case 5:return[br,p,q];}}
return false;}});var Slider=new Class({options:{onChange:Class.empty,onComplete:Class.empty,onTick:function(pos){this.knob.setStyle(this.p,pos);},mode:'horizontal',clickDrags:true,steps:100,wheel:false,offset:0},initialize:function(el,knob,options){this.element=$(el);this.knob=$(knob);this.setOptions(options);this.previousChange=-1;this.previousEnd=-1;this.step=-1;this.element.addEvent('mousedown',this.clickedElement.bindWithEvent(this));if(this.options.wheel)this.element.addEvent('mousewheel',this.scrolledElement.bindWithEvent(this));var mod,offset;if(this.options.mode=='horizontal'){this.z='x';this.p='left';mod={'x':'left','y':false};offset='offsetWidth';}else if(this.options.mode=='vertical'){this.z='y';this.p='top';mod={'x':false,'y':'top'};offset='offsetHeight';}
this.max=this.element[offset]-this.knob[offset]+(this.options.offset*2);this.half=this.knob[offset]/2;this.getPos=this.element['get'+this.p.capitalize()].bind(this.element);this.knob.setStyle('position','relative').setStyle(this.p,-this.options.offset);var lim={};lim[this.z]=[-this.options.offset,this.max-this.options.offset];this.drag=new Drag.Base(this.knob,{limit:lim,modifiers:mod,snap:0,onStart:function(){this.draggedKnob();}.bind(this),onDrag:function(){this.draggedKnob();}.bind(this),onComplete:function(){this.draggedKnob();this.end();}.bind(this)});if(this.options.clickDrags)this.element.addEvent('mousedown',this.drag.start.bindWithEvent(this.drag));if(this.options.initialize)this.options.initialize.call(this);},set:function(step){if(step>this.options.steps)step=this.options.steps;else if(step<0)step=0;this.step=step;this.checkStep();this.end();this.fireEvent('onTick',this.toPosition(this.step));return this;},scrolledElement:function(event){if(event.wheel<0)this.set(this.step+1);else if(event.wheel>0)this.set(this.step-1);event.stop();},clickedElement:function(event){var position=event.page[this.z]-this.getPos()-this.half;if(position>this.max-this.options.offset)position=this.max-this.options.offset;else if(position<-this.options.offset)position=-this.options.offset;this.step=this.toStep(position);this.checkStep();this.end();this.fireEvent('onTick',position);},draggedKnob:function(){this.step=this.toStep(this.drag.value.now[this.z]);this.checkStep();},checkStep:function(){if(this.previousChange!=this.step){this.previousChange=this.step;this.fireEvent('onChange',this.step);}},end:function(){if(this.previousEnd!==this.step){this.previousEnd=this.step;this.fireEvent('onComplete',this.step+'');}},toStep:function(position){return Math.round((position+this.options.offset)/this.max*this.options.steps);},toPosition:function(step){return(this.max)*step/this.options.steps;}});Slider.implement(new Events);Slider.implement(new Options);var SmoothScroll=Fx.Scroll.extend({initialize:function(options){this.parent(window,options);this.links=(this.options.links)?$$(this.options.links):$$(document.links);this.addEvent('onCancel',this.clearChain);var location=window.location.href.match(/^[^#]*/)[0]+'#';this.links.each(function(link){if(link.href.indexOf(location)!=0)return;var anchor=link.href.substr(location.length);if(anchor&&$(anchor))this.useLink(link,anchor);},this);},useLink:function(link,anchor){link.addEvent('click',function(event){if(!window.khtml){this.clearChain();this.chain(function(){window.location.hash=anchor;});}
this.toElement(anchor);event.stop();}.bindWithEvent(this));}});var Tips=new Class({options:{onShow:function(tip){tip.setStyle('visibility','visible');},onHide:function(tip){tip.setStyle('visibility','hidden');},maxTitleChars:30,showDelay:100,hideDelay:100,className:'tool',offsets:{'x':16,'y':16},fixed:false},initialize:function(elements,options){this.setOptions(options);this.toolTip=new Element('div',{'class':this.options.className+'-tip','styles':{'position':'absolute','top':'0','left':'0','visibility':'hidden'}}).inject(document.body);this.wrapper=new Element('div').inject(this.toolTip);$each(elements,function(el){this.build($(el));},this);if(this.options.initialize)this.options.initialize.call(this);},build:function(el){el.$.myTitle=(el.href&&el.getTag()=='a')?el.href.replace('http://',''):(el.rel||false);if(el.title){var dual=el.title.split('::');if(dual.length>1){el.$.myTitle=dual[0].trim();el.$.myText=dual[1].trim();}else{el.$.myText=el.title;}
el.removeAttribute('title');}else{el.$.myText=false;}
if(el.$.myTitle&&el.$.myTitle.length>this.options.maxTitleChars)el.$.myTitle=el.$.myTitle.substr(0,this.options.maxTitleChars-1)+"&hellip;";el.addEvent('mouseenter',function(event){this.start(el);if(!this.options.fixed)this.locate(event);else this.position(el);}.bind(this));if(!this.options.fixed)el.addEvent('mousemove',this.locate.bindWithEvent(this));el.addEvent('mouseleave',this.end.bind(this));},start:function(el){this.wrapper.empty();if(el.$.myTitle){this.title=new Element('span').inject(new Element('div',{'class':this.options.className+'-title'}).inject(this.wrapper)).setHTML(el.$.myTitle);}
if(el.$.myText){this.text=new Element('span').inject(new Element('div',{'class':this.options.className+'-text'}).inject(this.wrapper)).setHTML(el.$.myText);}
$clear(this.timer);this.timer=this.show.delay(this.options.showDelay,this);},end:function(event){$clear(this.timer);this.timer=this.hide.delay(this.options.hideDelay,this);},position:function(element){var pos=element.getPosition();this.toolTip.setStyles({'left':pos.x+this.options.offsets.x,'top':pos.y+this.options.offsets.y});},locate:function(event){var win={'x':window.getWidth(),'y':window.getHeight()};var scroll={'x':window.getScrollLeft(),'y':window.getScrollTop()};var tip={'x':this.toolTip.offsetWidth,'y':this.toolTip.offsetHeight};var prop={'x':'left','y':'top'};for(var z in prop){var pos=event.page[z]+this.options.offsets[z];if((pos+tip[z]-scroll[z])>win[z])pos=event.page[z]-this.options.offsets[z]-tip[z];this.toolTip.setStyle(prop[z],pos);};},show:function(){this.fireEvent('onShow',[this.toolTip]);},hide:function(){this.fireEvent('onHide',[this.toolTip]);}});Tips.implement(new Events);Tips.implement(new Options);

Array.extend({
	append: function(item) {
		this[this.length] = item;
	}
});

Element.extend({
	getParent: function() {
		return this.parentNode;
	},
	
	getContentHeight: function() {
		if ( this.getTag() == 'iframe' ) 
			return this.getFrameDocument().body.scrollHeight;
		
		return this.getVisibleHeight();
	},
	
	getFrameDocument: function() { 
		if ( this.getTag() != 'iframe' ) return false;

		return this.contentDocument || this.document ||
			(this.contentWindow && this.contentWindow.document ? 
			this.contentWindow.document :
			null);
			
	},
	
	getVisibleHeight: function() {
		return this.scrollHeight;
	},
	
	getText: function() {
		return this.textContent || this.innerText;
	},
	
	/**/
	toQueryString: function(){
		var queryString = [];
		$A(this.getElementsByTagName('*')).each(function(el){
			if ( el.nodeType != 8 ) {
				var name = $(el).name;
				var value = el.getValue();
				if (value && name) queryString.push(encodeURIComponent(name)+'='+encodeURIComponent(value));
			}
		});
		return queryString.join('&');
	},
	
	isSelected: function() {
		return this['type'] == 'checkbox' && 
			( this['checked'] == true || 
			this.checked == true ); //on is for IE
	}

});



String.extend({
	startsWith: function(text) {
		return this.test('^' + text);
	},
	
	endsWith: function(text) {
		return this.test(text + '$');
	},
	
	contains: function(text) {
		return this.test(text);
	},
	
	addParameter: function (param, value) { //for a url string
		return this + (( this.contains('?') ? null : '?') || 
			( this.endsWith('&') ? '' : '&' )) + 
			param + '=' + value;
	},
	
	escapeRegEx: function() {
		return this.replace(/([$\.\*\+\?\|\(\)\[\]\{\}\\])/g, '\\$1');
	}
});

var Histogram = new Class({
	initialize: function(hName, path, options) {
		options = options || {};
		this.mName = hName;
		this.mBuckets = {};
		this.mPath = path;
		this.mKeyPrefix = options['keyPrefix'] || '';
	},

	add: function(item) {
		var itemValue = this.evaluate(CommonUtils.getObjectProperty(item, this.mPath));
		var itemValueKey = this.mKeyPrefix + itemValue;
		if ( !this.mBuckets[itemValueKey] ) this.mBuckets[itemValueKey] = [];
		this.mBuckets[itemValueKey].push(item);
	},

	evaluate: function(itemValue) {
		return itemValue;
	}
});

function Counter(options){
	this.mIsActive = false;
	this.mTotalCount = 0;
	this.mCount = 0;
	this.mCycleCount = 0;
	this.mStartAt = CommonUtils.getValue(options,'startCount',0);//the number of counts the first active is delayed by
	this.mStayInactiveCount = CommonUtils.getValue(options,'inactiveCount',1);//the number of counts it remains inactive
	this.mStayActiveCount = CommonUtils.getValue(options,'activeCount',1);//the number of counts it should stay active after going from non-active -> active
	this.mMaxActiveCycles = CommonUtils.getValue(options,'maxActiveCycles',-1);;//number of times it should go from active -> non active
}

Counter.prototype.increment = function(){
	this.mTotalCount++;
	this.mCount++;
	//under start count || over cycle count
	if ( this.mTotalCount <= this.mStartAt || (this.mMaxActiveCycles != -1 && this.mCycleCount >= this.mMaxActiveCycles) ) {
		this.mIsActive = false;
		return;
	}
	
	//going from inactive to active?
	if ( !this.mIsActive && (this.mCount >= this.mStayInactiveCount || this.mTotalCount == this.mStartAt) ){
		this.mIsActive = true;
		this.mCount = 0;
		return; 
	}
	
	//going from active to inactive? This will complete a 'cycle'
	if ( this.mIsActive && this.mCount >= this.mStayActiveCount ){
		this.mIsActive = false;
		this.mCycleCount++;
		this.mCount = 0;
	}
}

Counter.prototype.isActive = function(){
	return this.mIsActive;
}

var Slider = new Class({
	initialize: function(options){
		this.mContainer = $(CommonUtils.getValue(options,'backgroundId',''));
		
		//There are two things to keep track of here:
		//1) The actual position of the slider on the page
		//2) The value in between the minimum and maximum that the position represents
		
		this.mMinValue = CommonUtils.getValue(options,'minValue',2);
		this.mMaxValue = CommonUtils.getValue(options,'maxValue',1139);
		
		this.customSetup(options);
		
		this.mLeftHandleValue = CommonUtils.getValue(options,'leftSliderValue',this.mMinValue);
		this.mRightHandleValue = CommonUtils.getValue(options,'rightSliderValue',this.mMaxValue);
		
		this.mLeftHandle = $(CommonUtils.getValue(options,'leftSliderId',''));
		this.mRightHandle = $(CommonUtils.getValue(options,'rightSliderId',''));
		
		this.mBoundEvents = {
			'dragRight':this.dragHandle.bindWithEvent(this,['right']),
			'dragLeft':this.dragHandle.bindWithEvent(this,['left']),
			'endDragRight':this.endDraggingHandle.bindWithEvent(this,['right']),
			'endDragLeft':this.endDraggingHandle.bindWithEvent(this,['left']),
			'startDragRight':this.startDraggingHandle.bindWithEvent(this,['right']),
			'startDragLeft':this.startDraggingHandle.bindWithEvent(this,['left']),
			'bgClick':this.handleBackgroundClick.bindWithEvent(this)
		};
		
		this.onHandleMove = CommonUtils.getValue(options,'onHandleMove',false);
		this.onHandleMoveComplete = CommonUtils.getValue(options,'onHandleMoveComplete',false);
		
		this.mLeftHandle.addEvent('mousedown',this.mBoundEvents['startDragLeft']);
		this.mRightHandle.addEvent('mousedown',this.mBoundEvents['startDragRight']);
		this.mContainer.addEvent('mouseup',this.mBoundEvents['bgClick']);
		
		this.mIntervalSize = this.mCalculateIntervalSize();
		this.initializeSliderPositions(true);
	},
	
	customSetup: function(options){},
	
	//values related to the internal value of the slider
	
	getLeftHandleValue: function(){
		return this.mLeftHandleValue;
	},
	
	getRightHandleValue: function(){
		return this.mRightHandleValue;
	},

	getSliderRange: function(){
		return this.mMaxValue - this.mMinValue;
	},
	
	getLeftDisplayText: function(){
		return this.getDisplayText(this.mLeftHandleValue);
	},
	
	getRightDisplayText: function(){
		return this.getDisplayText(this.mRightHandleValue);
	},
	
	getDisplayText: function(value){
		return value;
	},
	
	calculateSliderValue: function(mousePosition){
		if ( mousePosition < this.getSliderLeftEdge() )
			return this.mMinValue;
		
		if ( mousePosition > this.getSliderRightEdge() )
			return this.mMaxValue;
		
		var percentSlider = (mousePosition - this.getSliderLeftEdge())/this.getSliderLength();
		
		return Math.round((percentSlider * this.getSliderRange()) + this.mMinValue);
	},
	
	getNumIntervals: function(){
		return 20;
	},

	getIncrements: function(){
		return [1,5,10,20,50,100,200,500,1000];
	},
	
	mCalculateIntervalSize: function(){
		var increments = this.getIncrements();
		var numIntervals = this.getNumIntervals();
		for ( var i = 0; i < increments.length; i++ ){
			if ( this.getSliderRange()/numIntervals < increments[i] ){
				return increments[i];
			}
		}
		return increments[increments.length-1];
	},
	
	//lets you set the slider to a particular value, set findInterval to true
	//if you want it to jump to the closest interval of the slider
	setHandleValue: function(handle,value,findInterval){
		if ( findInterval ) {
			//decide on a best interval for the slider to stick to
			value = this.findClosestInterval(handle,value);
		}
		
		if ( handle == 'left' ){
			this.mLeftHandleValue = value;
		} else if ( handle == 'right' ){
			this.mRightHandleValue = value;
		}
		//this.debug(this.getLeftDisplayText() + ' - ' + this.getRightDisplayText());
		this.updateHandlePosition(handle);
		if ( this.onHandleMove )
			this.onHandleMove(this);
	},
	
	resetHandles: function(){
		this.mLeftHandleValue = this.mMinValue;
		this.mRightHandleValue = this.mMaxValue;
		this.initializeSliderPositions(false);
	},
	
	//returns the nearest internalValue that falls on an interval
	findClosestInterval: function(handle,value){
		if ( handle == 'left' && value > this.mRightHandleValue ){
			value = this.mRightHandleValue;
		} else if ( handle == 'right' && value < this.mLeftHandleValue ) {
			value = this.mLeftHandleValue;
		}
		
		var intervalRight = (Math.round(value/this.mIntervalSize) + 1) * this.mIntervalSize;
		var intervalCenter = (Math.round(value/this.mIntervalSize)) * this.mIntervalSize;
		var intervalLeft = (Math.round(value/this.mIntervalSize) - 1) * this.mIntervalSize;
		var nearestInvertal = -1;
		if(intervalRight - value > Math.abs(value - intervalCenter))
			if(value - intervalLeft > Math.abs(value - intervalCenter))
				nearestInterval = intervalCenter;
			else
				nearestInterval = intervalLeft;
		else
			if(value - intervalLeft > intervalRight - value)
				nearestInterval = intervalRight;
			else
				nearestInterval = intervalLeft;

		if ((value - this.mMinValue)/this.getSliderRange() >= 0.98 || nearestInterval >= this.mMaxValue) nearestInterval = this.mMaxValue;
		if ((value - this.mMinValue)/this.getSliderRange() <= 0.02 || nearestInterval <= this.mMinValue) nearestInterval = this.mMinValue;
		
		if ( handle == 'left' ){
			if ( this.mRightHandleValue <= nearestInterval + this.mIntervalSize ||
					nearestInterval + this.mIntervalSize >= this.mMaxValue ){
				nearestInterval = this.mRightHandleValue - this.mIntervalSize;
			}
		} else if ( handle == 'right' ){
			if ( this.mLeftHandleValue >= nearestInterval - this.mIntervalSize ||
					nearestInterval - this.mIntervalSize <= this.mMinValue ){
				nearestInterval = this.mLeftHandleValue + this.mIntervalSize;
			}
		}
		return nearestInterval;
	},
	
	//values related to the display of the sliders
	
	getSliderLength: function(){
		return this.mContainer.getSize()['size']['x'];
	},
	
	getSliderLeftEdge: function(){
		return this.mContainer.getPosition()['x'];
	},
	
	getSliderRightEdge: function(){
		return this.mContainer.getPosition()['x'] + this.getSliderLength();
	},
	
	initializeSliderPositions: function(skipOnHandleMove){
		//this.mLeftHandleValue = this.mMinValue;
		this.updateHandlePosition('left');
		
		//this.mRightHandleValue = this.mMaxValue;
		this.updateHandlePosition('right');
		
		if ( this.onHandleMove && !skipOnHandleMove )
			this.onHandleMove(this);
	},
	
	calculateLeftOffSet: function(internalHandleValue){
		var percentBar = (internalHandleValue - this.mMinValue)/(this.mMaxValue - this.mMinValue);
		return Math.floor(percentBar * this.getSliderLength())-2;
	},
	
	updateHandlePosition: function(handle){
		var pixelOffSet = this.calculateLeftOffSet(handle == 'right' ? this.mRightHandleValue : this.mLeftHandleValue);
		if ( handle == 'right' ){
			this.mRightHandle.setStyle('left',pixelOffSet + 'px');
		} else if ( handle == 'left' ){
			this.mLeftHandle.setStyle('left',pixelOffSet + 'px');
		}
	},
	
	//functions related to actually moving the sliders
	startDraggingHandle: function(e,slider){
		if ( this.mCurrentlyMoving ) return;
		
		this.mCurrentlyMoving = slider;
		if ( slider == 'left' ){
			document.addEvent('mousemove',this.mBoundEvents['dragLeft']);
			document.addEvent('mouseup',this.mBoundEvents['endDragLeft']);
		} else {
			document.addEvent('mousemove',this.mBoundEvents['dragRight']);
			document.addEvent('mouseup',this.mBoundEvents['endDragRight']);
		}
		this.mContainer.removeEvent('mouseup',this.mBoundEvents['bgClick']);
		e.stop();
	},
	
	dragHandle: function(e,handle){
		if ( !this.mCurrentlyMoving ) return;
		
		//take the x position get the internal value and bounds check it
		var newInternalValue = this.calculateSliderValue(e.page.x);
		
		this.setHandleValue(handle,newInternalValue,true);
		
		e.stop();
	},
	
	endDraggingHandle: function(e,handle){
		if ( !this.mCurrentlyMoving ) return;
		document.removeEvent('mousemove',this.mBoundEvents['dragLeft']);
		document.removeEvent('mousemove',this.mBoundEvents['dragRight']);
		document.removeEvent('mouseup',this.mBoundEvents['endDragLeft']);
		document.removeEvent('mouseup',this.mBoundEvents['endDragRight']);
		this.mContainer.addEvent('mouseup',this.mBoundEvents['bgClick']);
		this.mCurrentlyMoving = null;
		if ( this.onHandleMoveComplete )
			this.onHandleMoveComplete(this);
			
		e.stop();
	},
	
	handleBackgroundClick: function(e){
		if ( this.mCurrentlyMoving ) return;
		
		var newInternalValue = this.calculateSliderValue(e.page.x);
		//is it closer to the left or the right?
		var leftDistance = Math.abs(newInternalValue - this.mLeftHandleValue);
		var rightDistance = Math.abs(newInternalValue - this.mRightHandleValue);

		var handle = 'right';
		if ( leftDistance < rightDistance  ){
			handle = 'left';
		}
		this.setHandleValue(handle,newInternalValue,true);
		
		if ( this.onHandleMoveComplete )
			this.onHandleMoveComplete(this);

		e.stop();
	},
	
	//utility functions
	
	getMousePosition: function(e){
		var posx = 0;
		var posy = 0;
		if (!e) var e = window.event;
		if (e.pageX || e.pageY) 	{
			posx = e.pageX;
			posy = e.pageY;
		}
		else if (e.clientX || e.clientY) 	{
			posx = e.clientX + document.body.scrollLeft
				+ document.documentElement.scrollLeft;
			posy = e.clientY + document.body.scrollTop
				+ document.documentElement.scrollTop;
		}
		return {'x':posx,'y':posy};
	}
});

var PriceSlider = Slider.extend({
	customSetup: function(options){
		this.mCurrencyPrefix = CommonUtils.getValue(options,'currencyPrefix','$');
	},
	
	getDisplayText: function(value){
		return this.mCurrencyPrefix + (Math.round(value));
	}
});


var TimeSlider = Slider.extend({
	getIncrements: function(){
		return [1*60000,5*60000,10*60000,30*60000,60*60000,120*60000,240*60000,360*60000,720*60000];
	},
	
	getDisplayText: function(value){
		return Math.floor(value/3600000) + 'h' + Math.round((value/3600000)%60) + 'm';
	}
});

var DateSlider = Slider.extend({
	customSetup: function(options){
		this.mDaysOfTheWeek = CommonUtils.getValue(options,'daysOfWeek',["Su","Mo","Tu","We","Th","Fr","Sa"]);
		this.mAdjustTimes = CommonUtils.getValue(options,'adjustTimes',true);
		
		var minDate = null;
		var maxDate = null;
		if( this.mAdjustTimes ){
			minDate = getTimeZoneAdjustedDate(this.mMinValue);//new Date(this.mMinValue + (((new Date(this.mMinValue)).getTimezoneOffset() - this.mServerTimeZone)*60000));
			maxDate = getTimeZoneAdjustedDate(this.mMaxValue);//new Date(this.mMaxValue + (((new Date(this.mMaxValue)).getTimezoneOffset() - this.mServerTimeZone)*60000));
		} else {
			minDate= new Date(this.mMinValue);
			maxDate = new Date(this.mMaxValue);
		}
		
		this.mMinValue = Math.round(minDate.getTime());
		this.mMaxValue = Math.round(maxDate.getTime());
	},
	
	getIncrements: function(){
		return [1*60000,5*60000,10*60000,30*60000,60*60000];
	},
	
	getDisplayText: function(value){
		var currDate = new Date(value);
		var extraZero = (currDate.getMinutes() < 10) ? "0" : "";
		var timePostFix = (currDate.getHours() >= 12) ? "p" : "a";
		var hourToDisplay = (currDate.getHours() == 0 || currDate.getHours()%12 == 0) ? 12 : currDate.getHours()%12;

		return this.mDaysOfTheWeek[currDate.getDay()] + " " + hourToDisplay + ":" + 
		extraZero + currDate.getMinutes() + timePostFix;
	}
});


/* 
 * Copyright NexTag 2006, 2007
 */
var ProgressBar = new Class({
	initialize: function(barElement, textElement, callback) {
		
		this.mSpeed = 1200;
		this.mIncrement = 1;
		this.mBarElement = barElement;
		this.mTextElement = textElement;
		
		this.mUpdatable = true;
		
		this.mBarMax = 0;
		this.mBarMaxLast = this.mBarMax;
		this.mBarStartValue = this.mBarMax;
		this.mBarValue = this.mBarStartValue;
		
		this.mHasStarted = false;
		this.mCallback = callback;
	},
	
	start: function(startValue, max) { 
		this.mBarMax = startValue;
		this.updateUI(startValue);
		this.updateTo(max); 
		return this;
	},

	/* */	
	progress: function() {
		this.mHasStarted = true;
		if ( this.mBarValue < this.mBarMax ) {
			this.mBarValue += this.mIncrement;
			this.updateUI(this.mBarValue);
		}
		
		this.progress.delay(this.mSpeed,this);
		
		return this;
	},

	/* */	
	updateTo: function(barMaxNew) {
		if ( !this.mHasStarted ) this.progress();
		
		barMaxNew = parseInt(barMaxNew);
		if ( barMaxNew >= 100 ) {
			this.updateUI(100);
			return this;
		}

		if ( barMaxNew > this.mBarMaxLast &&
				barMaxNew > this.mBarValue &&
				barMaxNew > this.mBarMax) {
			this.mBarMaxLast = this.mBarMax;
			this.mBarMax = barMaxNew;
			this.updateUI(this.mBarMaxLast);		
		}

		return this;
	},
		
	updateUI: function(value) {
		if ( !this.mUpdatable ) return; 
		this.mBarValue = value;
		if ( this.mTextElement ) {
			this.mTextElement.setHTML(this.mBarValue);
			this.mBarElement.setStyle('width', this.mBarValue + '%');
		}	
		if ( this.mCallback ) this.mCallback.call();	
		return this;
	}
});

/**
 *  Keyboard.js
 */
var Keyboard = {
	KEY_BACKSPACE: 8,
	KEY_TAB:       9,
	KEY_RETURN:   13,
	KEY_SHIFT:    16,
	KEY_CTRL :    17,
	KEY_ALT :     18,
	KEY_ESC:      27,
	KEY_LEFT:     37,
	KEY_UP:       38,
	KEY_RIGHT:    39,
	KEY_DOWN:     40,
	KEY_DELETE:   46,
	KEY_HOME:     36,
	KEY_END:      35,
	KEY_PAGEUP:   33,
	KEY_PAGEDOWN: 34
};

/**
 * 
 */

var AutoSuggester = new Class({
	initialize: function(inputNode, url, options) {
		options = options || {};
		this.url = url;
		this.inputNode = inputNode;
		if(!this.inputNode || !this.url) {
			return;
		}
		this.idNode = this.inputNode.form[this.inputNode.id + '_id'];
		
		this.query = this.inputNode.value;
		this.ajaxRequest = null;
		this.suggestions = {};
		this.current = null;
		this.dropDown = null;
		this.dropDownOuter = null;
		this.handledKeyEvent = false;
		this.closed = true;
		this.canHandleKeyUp = !window.opera;
		
		this.container = options.container || document.body;
		this.activityDelay = options.activityDelay || 100;
		this.selectOnBlur = options.selectOnBlur;
		this.minQueryLength = options.minQueryLength || 3;
		this.selectFirst = !options.disableSelectFirst;

		this.inputNode.addEvent("keyup",this.keyup.bind(this));
		this.inputNode.addEvent(window.ie ? "keydown" : "keypress",this.keypress.bind(this));
		this.inputNode.addEvent("click",this.click.bind(this));
		this.inputNode.addEvent("blur",this.blur.bind(this));
		this.inputNode.setAttribute("autocomplete","off");
		
		if(window.ie) {
			this.iframe = new Element("iframe");
			this.iframe.frameBorder = "0";
			this.iframe.marginHeight = "0";
			this.iframe.marginWidth = "0";
			this.iframe.scrolling = "no";
			this.iframe.setStyles({
				"z-index": "999",
				position: "absolute",
				visibility: "hidden"
			});
			this.iframe.injectInside(document.body);
		}
	},
	
	paint: function() {
		var regexp = new RegExp("("+this.query.escapeRegEx()+")","gi");
		var firstTime = true;
		if(this.dropDownOuter) {
			firstTime = false;
			this.dropDown = null;
			this.dropDownOuter.remove();
			this.dropDownOuter = null;
			if(this.iframe) {
				this.iframe.style.visibility="hidden";
			}
		}
		
		var oldCurrent = this.current;
		this.current = null;
		
		var textMatches = {};
		var fuzzyMatches = {};
		for(var key in this.suggestions) {
			if(key.search(regexp) != -1) {
				textMatches[key] = this.suggestions[key];
			} else {
				fuzzyMatches[key] = this.suggestions[key];
			}
		}
		var suggestions = {};
		$extend(suggestions, textMatches);
		$extend(suggestions, fuzzyMatches);
		if(CommonUtils.isEmpty(suggestions)) {
			return;
		}
		var isFirstMatch = CommonUtils.equals(CommonUtils.getFirst(textMatches), CommonUtils.getFirst(suggestions));
		
		this.dropDownOuter = new Element("div");
		this.dropDownOuter.addClass("autosuggest-outer");
		this.dropDownOuter.setStyles({
			position: "absolute", 
			top: this.inputNode.getTop() + this.inputNode.offsetHeight + "px", 
			left: this.inputNode.getLeft() + "px",
			zIndex: 1000
		});
		var dropDownShadow = new Element("div");
		dropDownShadow.addClass("autosuggest-shadow");
		this.dropDown = new Element("div");
		this.dropDown.addClass("autosuggest");
		for(var key in suggestions) {
			var div = new Element("div");
			if(oldCurrent) {
				if(key == oldCurrent.innerHTML) {
					this.setCurrent(div);
				}
			}
			div.addClass("autosuggest-row");
			div.setHTML(key.replace(regexp,"<b>$1</b>"));
			div.addEvent("mousedown",this.selectCurrent.bind(this));
			div.addEvent("mouseover",this.itemMouseOver.bind(this));
			div.injectInside(this.dropDown);
		}

		this.dropDown.injectInside(dropDownShadow);
		dropDownShadow.injectInside(this.dropDownOuter);
		this.dropDownOuter.injectInside(this.container);
		
		if(!this.current && this.dropDown && this.selectFirst && isFirstMatch) {
			this.setCurrent(this.dropDown.getFirst());
		}
		
		if(this.iframe) {
			var pos = this.dropDownOuter.getCoordinates();
			this.iframe.setStyles({
				position: "absolute", 
				top: pos.top + "px",
				left: pos.left + "px",
				width: pos.width + "px",
				height: pos.height + "px"
			});
			this.iframe.style.visibility="visible";
		}
		
	},
	
	close: function() {
		this.closed = true;
		if(this.ajaxRequest) this.ajaxRequest.cancel();
		
		if(this.dropDownOuter) {
			this.dropDown = null;
			this.dropDownOuter.remove();
			this.dropDownOuter = null;
			if(this.iframe) {
				this.iframe.style.visibility="hidden";
			}
		}
		this.setCurrent(null);
	},
	
	selectCurrent: function() {
		if(this.current) {
			var value = this.suggestions[this.current.getText()];
			this.inputNode.value = value.display || value;
			if(this.idNode && value.id) {
				this.idNode.value = value.id;
			}
		}
		this.close();
	},
	
	itemMouseOver: function(event) {
		var target = event.target || event.srcElement;
		this.setCurrent(target);
	},
	
	blur: function(event) {
		this.closed = true;
		if(this.ajaxRequest) this.ajaxRequest.cancel();
		if(this.selectOnBlur) this.selectCurrent();
		this.close.delay(100,this);
	},
	
	keypress: function(event) {
		this.handleKey(event);
	},
	
	keyup: function(event) {
		this.handleKey(event);
		if(this.handledKeyEvent || (!this.closed && this.inputNode.value == this.query) || this.inputNode.value.length < this.minQueryLength) {
			this.handledKeyEvent = false;
			return;
		}
		
		this.closed = false;
		if(this.idNode) this.idNode.value = '';

		this.query = this.inputNode.value;
		$clear(this.requestTimer);
		this.requestTimer = this.makeRequest.delay(this.activityDelay,this);
		this.paint();
	},
	
	handleKey: function(event) {
		switch(event.keyCode) {
			case Keyboard.KEY_RETURN:
				if(!this.handledKeyEvent && this.current) this.stopEvent(event);
			case Keyboard.KEY_TAB:
				if(!this.handledKeyEvent) this.selectCurrent();
			case Keyboard.KEY_ESC:
				if(event.keyCode == Keyboard.KEY_ESC && !this.handledKeyEvent && this.current) this.stopEvent(event);
				if(!this.handledKeyEvent) this.close();
				this.handledKeyEvent = this.canHandleKeyUp;
				return;
			case Keyboard.KEY_UP:
				if(!this.handledKeyEvent) this.handleUpArrow();
				this.handledKeyEvent = this.canHandleKeyUp;
				return;
			case Keyboard.KEY_DOWN:
				if(!this.handledKeyEvent) this.handleDownArrow();
				this.handledKeyEvent = this.canHandleKeyUp;
				return;
			case Keyboard.KEY_CTRL:
			case Keyboard.KEY_ALT:
			case Keyboard.KEY_SHIFT:
			case Keyboard.KEY_LEFT:
			case Keyboard.KEY_RIGHT:
			case Keyboard.KEY_HOME:
			case Keyboard.KEY_END:
			case Keyboard.KEY_PAGEUP:
			case Keyboard.KEY_PAGEDOWN:
				//NO-OP
				this.handledKeyEvent = this.canHandleKeyUp;
				return;
		}
	},
	
	handleUpArrow: function() {
		if(this.current) {
			this.setCurrent(this.current.getPrevious());
		}
		if(!this.current && this.dropDown) {
			this.setCurrent(this.dropDown.getLast());
		}
	},
	
	handleDownArrow: function() {
		if(this.current) {
			this.setCurrent(this.current.getNext());
		}
		if(!this.current && this.dropDown) {
			this.setCurrent(this.dropDown.getFirst());
		}
		if(!this.current && !this.dropDown) {
			this.paint();
		}
	},
	
	click: function(event) {
		this.paint();
	},
	
	makeRequest: function() {
		if(this.ajaxRequest) this.ajaxRequest.cancel();
		this.ajaxRequest = new Ajax(this.url + this.query, {
			method: "get",
		    onComplete: this.handleResponse.bind(this)
		});
		this.ajaxRequest.request();
	},
	
	setCurrent: function(node) {
		if(node && (!node.hasClass || !node.hasClass("autosuggest-row"))) {
			this.setCurrent(node.parentNode);
			return;
		}
		if(this.current && this.current.toggleClass) {
			this.current.toggleClass("selected");
		}
		this.current = node;
		if(this.current && this.current.toggleClass) {
			this.current.toggleClass("selected");
		}
	},
	
	handleResponse: function(responseText, responseXML) {
		this.suggestions = Json.evaluate(responseText || '{}');
		this.ajaxRequest = null;
		if(!this.closed) this.paint();
	},
	
	stopEvent: function(event) {
		if (event.stopPropagation) event.stopPropagation();
		else event.cancelBubble = true;
		
		if (event.preventDefault) event.preventDefault();
		else event.returnValue = false;
	}
	
});


/**/

function MoreBlock(elementId, numToShow, options) {
	this.e = $(elementId);
	if ( !this.e ) return;
	this.text = this.e.innerHTML;
	this.newTag = null;
	this.linkId = CommonUtils.getValue(options, 'linkId', '');
	this.link = CommonUtils.getValue(options, 'link', undefined);
	this.linkEvent = CommonUtils.getValue(options, 'linkEvent', undefined);
	this.numToShow = numToShow;
	this.threshold = CommonUtils.getValue(options, 'threshold', 20);

	this.createContent();
}

/* Modify the content of this MoreBlock's element */
MoreBlock.prototype.createContent = function() {
	if ( this.text.length <= this.numToShow + this.threshold ) 
		return;

	

	//Prepare the subtext to show
	var subtext = this.text.substr(0, this.numToShow);
	
	//Create a span element to hold the subtext
	this.newTag = this.e.clone();
	this.newTag.setAttribute('id', this.e.id + '_new')
	//Fill in the content of the span
	this.newTag.innerHTML = subtext + " ";
	//Clear the current HTML before we insert the subtext
	this.e.setStyle('display', 'none');
	//Insert the span subtext inside the original element
	this.newTag.injectAfter(this.e);

	if ( !this.link ) {
		//create a link to reveal the span
		var moreLink = new Element('a');
		moreLink.setProperty('id', this.linkId ? this.linkId : 
			this.newTag.getAttribute('id') + "more");
		moreLink.setProperty('href', 'javascript:void(0)');
		//bind it so that it shows the item
		if ( !this.linkEvent )
			moreLink.onclick = this.show.bindAsEventListener(this);
		else
			moreLink.onclick = this.linkEvent;
		moreLink.innerHTML = 'more...';
		moreLink.injectInside(this.newTag);
	}
}

MoreBlock.prototype.show = function() {
	this.e.setStyle('display', 
		this.e.tagName == 'span' ? 'inline' : 'block');
	this.newTag.setStyle('display', 'none');
}

/* */
function ScrollBlock(elementId, numToShow, options) {
	options = !options ? {} : options;
	this.e = $(elementId);
	this.elementType = options['elementType'] || 'li';
	this.trigger = null;
	this.triggerText = options['triggerText'] || 'more...';
	this.triggerContainerClass = options['triggerContainerClass'];
	this.items = this.e.getElements(this.elementType);
	this.numToShow = numToShow;
	this.maxHeight = options['maxHeight'];
	this.limitHeight = options['limitHeight'] || false;
	this.collapse();
}

ScrollBlock.prototype.collapse = function(numToShow) {
	var min = numToShow || this.numToShow;
	if ( this.items.length > min ) {
		for ( var i = min; i < this.items.length; i++ ) {
			var item = this.items[i];
			item.style.display='none';
		}
		if ( !this.trigger ) 
			this.triggerContainer = this.createTrigger();
		
		this.maxHeight = this.maxHeight || this.e.offsetHeight;
	}
}

ScrollBlock.prototype.createTrigger = function() {
	var triggerContainer = new Element(this.elementType);
	if ( this.triggerContainerClass )
		triggerContainer.addClass(this.triggerContainerClass);

	var triggerLink = new Element('a');
	triggerLink.setProperty("href", "javascript:void(0)");
	triggerLink.innerHTML = this.triggerText;
	triggerLink.onclick = this.show.bindAsEventListener(this);
	triggerLink.injectInside(triggerContainer);
	this.trigger = triggerLink;
	triggerContainer.injectInside(this.e);

	return triggerContainer;
}

ScrollBlock.prototype.show = function () {
	if ( this.limitHeight == true) {
		this.e.setStyle('height', this.maxHeight);
		this.e.setStyles({'overflow-y': 'scroll'});
	}
	this.triggerContainer.setStyle('display', 'none');
	if ( this.items.length > this.numToShow ) {
		for ( var i = this.numToShow; i < this.items.length; i++ ) {
			var item = this.items[i];
			item.style.display='block';
		}
	}
}

/***/
function MenuTabs(options) {
	this.mOptions = options;
	this.mTabMappings = options['tabMappings'];
	this.mInitialPane = options['initialPane'];
	this.mTabPrefix = options['tabPrefix'] || 'menu_';
	this.mPanePrefix = options['panePrefix'] || 'div_';
	this.mTabs = new Array();
	this.mPanes = new Array();
	this.setupView();
}


MenuTabs.prototype.trigger = function(paneName) {
		var tab = $(this.mTabPrefix + paneName);
		var tabPane = $(this.mPanePrefix + paneName);

		for(var i = 0; i < this.mTabs.length; i++) {
			StyleUtils.removeClass(this.mTabs[i], 'current');
		}
		
		var tabs = this.mTabMappings[tabPane['id']];

		if ( tabs ) {
			for(var i = 0; i < tabs.length; i++) {
				var tab = $(tabs[i]);
				StyleUtils.addClass(tab, 'current');
			}		
		}			

		for(var i = 0; i < this.mPanes.length; i++) {
			if ( tabPane['id'] != this.mPanes[i]['id'] )
				this.mPanes[i].style.display = 'none';
			else
				this.mPanes[i].style.display = 'block';
		}
	};

MenuTabs.prototype.setupView = function() {
	/***/
		for( paneId in this.mTabMappings ) {
			var tabPane = $(paneId);
			if ( !tabPane ) continue;

			var triggerIdArray = this.mTabMappings[paneId];
			for(var i = 0; i < triggerIdArray.length; i++) {
				var tab = $(triggerIdArray[i]);
				
				/***/
				var tabTrigger = tab.getElement('a');
				tabTrigger.addEvent('click',
					this.trigger.pass(tabTrigger.getParent()['id'].replace(this.mTabPrefix, ''), this));
				
				this.mTabs.push(tab); //keep track of tabs
			}

			tabPane.style.display = 'none'; 

			this.mPanes.push(tabPane);
			
		}


		if ( this.mInitialPane && $(this.mInitialPane)) {
			this.trigger(this.mInitialPane.replace(this.mPanePrefix, ''));
		} else {
			if ( !this.mTabs || this.mTabs.length < 1 ) return;
			this.trigger(this.mTabs[0]['id'].replace(this.mTabPrefix, ''));
		}
	};


var StyleUtils = {
	'addClass': function(element, classString) {
		if ( element && element.className.indexOf(classString) == -1 ) {
			element.className = element.className + " " + classString;
		}
	},
	
	'removeClass': function(element, classString) {
		if ( element && element.className ) {
			element.className = element.className.replace(classString, ' ');
		}
	}
};

<!-- 
// helper - calendar pair listener
var BlankCalendarParentSlaveChangeListener = (function(){
	function Listener(cal1, cal2){
		var fromCal = cal1;
		var toCal = cal2;
		
		this.dispatchDateChange = function (cal){
			if (cal==null || fromCal == null || toCal == null)
				return;
			if (cal!=fromCal && cal!=toCal)
				return;
			
			var c_date = cal.getDate();
			if ( cal == fromCal ) {
				toCal.setNewDate(new Date(c_date));
			} else if ( cal == toCal ) {
				fromCal.setNewDate(new Date(c_date));
			}
		}
	};

	return Listener;
})();

var CalendarParentSlaveChangeListener = (function(){
	function Listener(cal1, cal2){
		var fromCal = cal1;
		var toCal = cal2;
		
		this.dispatchDateChange = function (cal){
			if (cal==null || fromCal == null || toCal == null)
				return;
			if (cal!=fromCal && cal!=toCal)
				return;
			
			var c_date = cal.getDate();
			if ( cal == fromCal ) {
				toCal.setNewDate(new Date(c_date));
			} else if ( cal == toCal ) {
				fromCal.setNewDate(new Date(c_date));
			}
		}
	};

	return Listener;
})();

function toggleCheckbox(id){
	if ( $(id) ){
		$(id).checked = !$(id).checked;
	}
}

function createTravelMenuForm(options) {
	var showAdults = options['showAdults'];
	
	if ( !showAdults ) {
		document.getElementById('numAdultsSlave').value = document.getElementById('numRoomsSlave').value;
	}
	
	$('numRoomsSlave').addEvent('change',function() { 
			document.getElementById('numRooms').value = document.getElementById('numRoomsSlave').value;
			if ( !showAdults ) {
				document.getElementById('adult').value = document.getElementById('numRoomsSlave').value;
				document.getElementById('numAdultsSlave').value = document.getElementById('numRoomsSlave').value;
			}
			if ( document.getElementById('numRoomsSlave').value > document.getElementById('numAdultsSlave').value){
				document.getElementById('numAdultsSlave').value = document.getElementById('numRoomsSlave').value;
				document.getElementById('adult').value = document.getElementById('numRoomsSlave').value;
			}
	});
	
	$('numAdultsSlave').addEvent('change',function() { 
			document.getElementById('adult').value = document.getElementById('numAdultsSlave').value;
			if ( document.getElementById('numRoomsSlave').value > document.getElementById('numAdultsSlave').value){
				document.getElementById('numRoomsSlave').value = document.getElementById('numAdultsSlave').value;
				document.getElementById('numRooms').value = document.getElementById('numAdultsSlave').value;
			}
	});
	
	$('numRooms').addEvent('change',function() { 
		document.getElementById('numRoomsSlave').value = document.getElementById('numRooms').value;
			if ( !showAdults ) {
				document.getElementById('adult').value = document.getElementById('numRoomsSlave').value;
				document.getElementById('numAdultsSlave').value = document.getElementById('numRoomsSlave').value;
			}
			if ( document.getElementById('numRoomsSlave').value > document.getElementById('numAdultsSlave').value){
				document.getElementById('numAdultsSlave').value = document.getElementById('numRoomsSlave').value;
				document.getElementById('adult').value = document.getElementById('numRoomsSlave').value;
			}
	});
	
	if ( $('adult') ) {
		$('adult').addEvent('change',function() { 
			document.getElementById('numAdultsSlave').value = document.getElementById('adult').value;
			if ( document.getElementById('numRoomsSlave').value > document.getElementById('numAdultsSlave').value){
				document.getElementById('numRoomsSlave').value = document.getElementById('numAdultsSlave').value;
				document.getElementById('numRooms').value = document.getElementById('numAdultsSlave').value;
			}
		});
	}
	
	var checkboxes = $ES('input.mpc','popup-form-compare-prices-c');
	for( var i=0; i < checkboxes.length; i++ ){
		var merchantClass = checkboxes[i]['id'].replace('-checkbox-popup','');
		if ( $(merchantClass + "-checkbox") ){
			$(merchantClass + "-checkbox").addEvent('click',toggleCheckbox.pass(checkboxes[i]['id']));
			checkboxes[i].checked = $(merchantClass + "-checkbox").checked;
		}
		checkboxes[i].addEvent('click',toggleCheckbox.pass(merchantClass + "-checkbox"));
	}
	
}

function populateTravelMenu(eventName, id, grpId, pnum) {
	var triggerId = id.split("_");

	var contentElementId = "htlDivContent_" + triggerId[1];
	var contentElement = document.getElementById(contentElementId);
	var numStars = document.getElementById('htlStars_' + triggerId[1]).getAttribute('title');
	var starString = parseInt(numStars) > 0 ? 
		'<img src="/images/stars/' + numStars + 'star_black.gif" alt="' + 
			numStars + ' Star hotel"/>' : '';
		
	document.getElementById('hotelNameDisplay').innerHTML = document.getElementById('htlName_' + triggerId[1]).innerHTML;
	document.getElementById('hotelAddressDisplay').innerHTML = document.getElementById('htlLocation_' + triggerId[1]).getAttribute('title');
	if(document.getElementById('h-desc-' + triggerId[1])){
		document.getElementById('hotelDescriptionDisplay').innerHTML = 
			document.getElementById('h-desc-' + triggerId[1]).innerHTML;
	} else {
		document.getElementById('hotelDescriptionDisplay').innerHTML = "";
	}
	document.getElementById('hotelStarsDisplay').innerHTML = starString;
	var submitButton = $('hotelPopupSubmit');
	if(currentPopulate) submitButton.removeEvent('click',currentPopulate);
	currentPopulate = populateFormValues.pass(id);
	submitButton.addEvent('click',currentPopulate);
	contentElement.appendChild(document.getElementById('travelMenuForm'));
}

var currentPopulate = null;

function populateFormValues(id){
	if ( $('hotelDate3').value == "" ){
		alert("Please enter a check-in date");
		return;
	} else if ( $('hotelDate4').value == "" ) {
		alert("Please enter a check-out date");
		return;
	}
	
	var triggerId = id.split("_");

	var contentElementId = "htlDivContent_" + triggerId[1];
	var contentElement = document.getElementById(contentElementId);
	
	var ptitle = document.getElementById('hotelPtitle');
	if( ptitle ) ptitle.value = document.getElementById('htlPtitle_' + triggerId[1]).getAttribute('title');
	
	var hotel_name = document.getElementById('hotelName');
	if( hotel_name ) hotel_name.value = document.getElementById('htlName_' + triggerId[1]).getAttribute('title');
	
	var suggested_cities = document.getElementById('suggested_cities');
	if( suggested_cities ) suggested_cities.value = document.getElementById('htlSuggested_' + triggerId[1]).getAttribute('title');
	
	var location = document.getElementById('hotelLocation1');
	if( location ) location.value = "";
	
	$('numRooms').value = $('numRoomsSlave').value;
	$('adult').value = $('numAdultsSlave').value;
	
	var submitForm = true;

	if ( typeof ( popunderSearch ) != "undefined" ) submitForm = popunderSearch();

	var cityInputs = document.getElementsByName('city');
	for( var i = 0; cityInputs != null && i < cityInputs.length; i++ ){
		cityInputs[i].value = "";
	}
	if ( submitForm ) {
		document.getElementById('hotelSearch').submit();
	}
}


//-->




var SMONTO = 30000;
var TMONTO = 600000;
function cube(params){
	function set_defs(n,d) { if (typeof params[n] == "undefined") { params[n] = d; } };

	set_defs("dg",false);
	set_defs("tmp",false);
	set_defs("det",false);

	var _p = params;
	var dg_ = _p['dg'];
	var _dgw = null;
	var _buf = new Array();
	var _tmp = _p['tmp'];
	var _det = _p['det'];

	var __event = function(e){return e?e:window.event;}

	var __target = function(e){
		return (e.target)?e.target:e.srcElement;
	}

	var __scrollc = function(){
		if( typeof( window.pageYOffset ) == 'number' ) {
			return {x:window.pageXOffset,y:window.pageYOffset};
		} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
			return {x:document.body.scrollLeft,y:document.body.scrollTop};
		} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
			return {x:document.documentElement.scrollLeft,y:document.documentElement.scrollTop};
		}
		return {x:-1,y:-1};
	}
	var __size = function(){
		if( typeof( window.innerWidth ) == 'number' ) {
			return {w:window.innerWidth,h:window.innerHeight};
		} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
			return {w:document.documentElement.clientWidth,h:document.documentElement.clientHeight};
		} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
			return {w:document.body.clientWidth,h:document.body.clientHeight};
		}
		return {w:-1,h:-1};
	}

	var __position = function(e){
		var dim = __size();
		var lmargin = 0;
		if (e.pageX || e.pageY) {
			lmargin = dim.w > 910 ? Math.round((dim.w - 910)/2) - 10 : 5;
			return {x:e.pageX-lmargin,y:e.pageY};
		} else if (e.clientX || e.clientY) {
			lmargin = dim.w > 910 ? Math.round((dim.w - 910)/2) : 10;
			return {x:e.clientX+document.body.scrollLeft+document.documentElement.scrollLeft-lmargin,
					y:e.clientY+document.body.scrollTop+document.documentElement.scrollTop};
		}
		return {x:0,y:0};
	}

	var _debug = function(m){if (_dgw&&_dgw.document)_dgw.document.writeln('> ' + m + '<br/>');}
	var _cap = function(e,v,dd){
		var s="ev"+e+"="+new Date().getTime()+";"+v;
		var p = _buf.length;
		if (dd&&p>0&&_buf[p-1].indexOf("ev"+e)==0)
			p-=1;
		_buf[p]=s;
		_debug(s);
	}
	this.log = function(cmp,s){
		_buf[_buf.length] = cmp + "=" + s;
		_debug(s);
	}
	
	var __last = new Date();
	var __lasti = -1;
	this.tmon = function(){
		var now = new Date();
		_debug("__tmon: " + __last + " | " + __lasti + " | " + now + " | " + _buf.length);
		var diff = now.getTime() - __last.getTime();
		if (diff<TMONTO){
			setTimeout("cube_inst.tmon()",TMONTO-diff);
			return;
		}
		__send();
		setTimeout("cube_inst.tmon()",TMONTO);
	}
	this.smon = function(){
		var now = new Date();
		_debug("__smon: " + __last + " | " + __lasti + " | " + now + " | " + _buf.length);
		var bsz = _buf.length;
		if (__lasti > 0){
			bsz -= __lasti;
		}
		if (bsz >= 20)
			__send();
		setTimeout("cube_inst.smon()",SMONTO);
	}
	var __send = function(){
		_debug("sending: " + __last + " | " + __lasti);
		var top = _buf.length;
		if (__lasti == top-1){
			__last = new Date();
			return;
		}
		var u = _p['id'] + "$";
		var st = __lasti==-1?0:__lasti;
		for (var i=st; i<top; i++){
			u += _buf[i] + "$";
		}
		u += "!!";
		var _cbs = (NextagUtils != "undefined" && NextagUtils.sCubeables) ? NextagUtils.sCubeables : new Array(); 
		for (var i=0; i<_cbs.length; i++){
			if (_cbs[i].getLogs) {u+= _cbs[i].getLogs() + "$"; }
		}
		_debug("send url: " + u);
		if (http)
			http.send(u);
		__lasti = top-1;
		__last = new Date();
	}
	var http = null;
	var _init = function(ev){
		if (dg_){_dgw = window.open("about:blank","cubedgw","width=300,height=800,scrollbars=1");}

		var dim = __size();
		var ilog = document.body.scrollWidth + "x" + document.body.scrollHeight + "-" + dim.w + "x" + dim.h;

		var _events = _p['cap'];
		if (_events){
			ilog += ";[load,unload";
			for (var i=0; i<_events.length; i++){
				var prt = _events[i].split('.');
				var elem = null;;
				var capev = null;
				if (prt.length==1){
					elem = window;
					capev = prt[0];
				} else if (prt.length == 2){
					capev = prt[1];
					if (prt[0]=='window') elem = window;
					else if (prt[0]=='document') elem = document;
					else elem = document.getElementById(prt[0]);
				}
				if (elem && capev){
					ilog += ","+_events[i]
					if (capev=='click') NextagUtils.addEvent(elem,'click',_hc);
					else if (capev=='scroll') elem.onscroll = _hs;
					else if (capev=='resize') elem.onresize = _hr;
					else if (capev=='blur') NextagUtils.addEvent(elem,'blur',_hb);
					else if (capev=='focus') NextagUtils.addEvent(elem,'focus',_hf);
					else if (capev=='dblclick') NextagUtils.addEvent(elem,'dblclick',_hdc);
					else if (capev=='mousemove') NextagUtils.addEvent(elem,'mousemove',_hmm);
					else if (capev=='mouseover') NextagUtils.addEvent(elem,'mouseover',_hmov);
					else if (capev=='mouseout') NextagUtils.addEvent(elem,'mouseout',_hmot);
					else if (capev=='change') NextagUtils.addEvent(elem,'change',_hfc);
					else if (capev=='submit') NextagUtils.addEvent(elem,'submit',_hfs);
					else if (capev=='reset') NextagUtils.addEvent(elem,'reset',_hfr);
					else if (capev=='select') NextagUtils.addEvent(elem,'select',_hfsl);
				}
			}
			ilog += "]";
		}
		setTimeout("cube_inst.tmon()",600000);
		setTimeout("cube_inst.smon()",30000);
		_cap("init",ilog);
		http = new NxtgHttpReq("/tools/cube.jsp");
		http.setPost();
		return true;
	}

	var __css = function(t){
		var s="";
		s += (t&&t.tagName) ? t.tagName.toLowerCase() : "-";
		if(t&&t.id){
			s += "#"+t.id;
		} else if(t&&t.className) {
			s += "."+t.className;
		} else {
			s += ".-";
		}
		return s;
	}

	var __cge = function(ev,v,dd){
		if(!dd||dd == undefined) dd=false;
		var _e = __event(ev);
		var _t = __target(_e);
		var _v = v?v:"-";
		if(_det){
			_v += "~" + __css(_t);
			if (_t)
				_v += __cktmp(_t,ev);
		} else {
			if (_t&&_t.id)
				_v += "."+_t.id;
		}
		_cap(_e.type,_v,dd);
		return true;
	}
	
	var __cktmp = function(t,ev){
		if(typeof(t)=="undefined"||!_tmp||!t.tagName) return "";
		var tagName = t.tagName.toLowerCase();
		if(_tmp[tagName+'#'+t.id]){return _tmp[tagName+'#'+t.id](t,ev);}
		if(_tmp['#'+t.id]){return _tmp['#'+t.id](t,ev);}
		if(_tmp[tagName+'.'+t.className]){return _tmp[tagName+'.'+t.className](t,ev);}
		if(_tmp['.'+t.className]){return _tmp['.'+t.className](t,ev);}
		if(_tmp[tagName]){return _tmp[tagName](t,ev);}
		return "";
	}
	
	var _unload = function(ev){
		__cge(ev);
		if (http){ http.setAsynchronous(false); }
		__send();
	}
	var _hc = function(ev){var p = __position(__event(ev));return __cge(ev,p.x+"."+p.y);}
	var _hs = function(ev){
		var _e = __event(ev);
		var sc = __scrollc();
		return __cge(ev,sc.x+"x"+sc.y,true);
	}
	var _hr = function(ev){
		var dim = __size();
		return __cge(ev,document.body.scrollWidth + "x" + document.body.scrollHeight + "-" + dim.w + "x" + dim.h);
	}
	var _hb = function(ev){return __cge(ev,null,true);}
	var _hf = function(ev){return __cge(ev,null,true);}
	var _hdc = function(ev){var p = __position(__event(ev));return __cge(ev,p.x+"."+p.y);}
	var _hmm = function(ev){return __cge(ev);}
	var _hmov = function(ev){return __cge(ev);}
	var _hmot = function(ev){return __cge(ev);}
	var _hfc = function(ev){return __cge(ev);}
	var _hfsl = function(ev){return __cge(ev);}
	var _hfs = function(ev){return __cge(ev);}
	var _hfr = function(ev){return __cge(ev);}
	this.ace = function(e,v,dd){ _cap(e,v,dd); }
	NextagUtils.addEvent(window,'load',_init);
	NextagUtils.addEvent(window,'unload',_unload);
};

var cube_inst = null;
function initCube(p){
	if (cube_inst == null){ cube_inst = new cube(p); }
	return cube_inst;
}

function NxtgHttpReq (url, options_){
	var options = {
		async: true,
		cb: null,
		handler: null,
		method: 'GET',
		contentType: null
	};

	if (options_){
		if (options_.async) { options.async = options_.async; }
		if (options_.cb) { options.cb = options_.cb; }
		if (options_.handler) { options.handler = options_.handler; }
		if (options_.method) { options.method = options_.method; }
		if (options_.contentType) { options.contentType = options_.contentType; }
	}

	var xhr = null;

	this.getURL = function(){return url;};
	this.setPost = function(){ options.method = 'POST';}
	this.setAsynchronous = function(async){ options.async = async; }
	this.getData = function(){
		if (xhr)
			return xhr.responseText;
		return null;
	};

	this.getStatus = function (){
		if (xhr)
			return xhr.status;
		return 0;
	};

	this.setAsynchronous = function(async){ options.async = async; };

	this.send = function(c){
		if(xhr && xhr.readyState!=0){
			xhr.abort();
		}
		try{
			xhr = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try{
				xhr = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(sc) {
				xhr = null;
			}
		}
		if(!xhr && typeof XMLHttpRequest!="undefined"){
			xhr = new XMLHttpRequest()
		}
		if (options.cb || options.handler){
			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4) {
					if (xhr.status == 200){
						if (options.cb)
							options.cb(xhr.responseText, xhr.responseXML);
						if (options.handler && options.handler.procdata)
							options.handler.procdata(xhr.responseText, xhr.responseXML);
					}
				}
			};
		}
		if(xhr){
			xhr.open(options.method,this.getURL(),options.async);
			var content = null;
			if (options.method == 'POST')
				content = c;
			if (options.contentType)
				xhr.setRequestHeader("Content-Type", options.contentType);
			xhr.send(content);
		}
	};
};


