/* Minification failed. Returning unminified contents.
(7030,5,7072,6): run-time error JS1314: Implicit property name must be identifier: _trackEvent(category, action, label) {
        //Universal Analytics
        if (typeof ga !== 'undefined') {
            ga('send', {
                hitType: 'event',
                eventCategory: category,
                eventAction: action,
                eventLabel: label
            });
        }
        else {
            //in case OneTrust took longer to load, try again after 3 seconds
            setTimeout(function () {
                if (typeof ga !== 'undefined') {
                    ga('send', {
                        hitType: 'event',
                        eventCategory: category,
                        eventAction: action,
                        eventLabel: label
                    });
                }
            }, 3000);
        }

        //GA 4
        if (typeof window.gtag !== 'undefined') {
            window.gtag("event", category, {
                eventAction: action,
                eventLabel: label
            });
        }
        else {
            //in case OneTrust took longer to load, try again after 3 seconds
            setTimeout(function () {
                if (typeof window.gtag !== 'undefined') {
                    window.gtag("event", category, {
                        eventAction: action,
                        eventLabel: label
                    });
                }
            }, 3000);
        }
    }
 */
/* Minification failed. Returning unminified contents.
(6985,5,7027,6): run-time error JS1314: Implicit property name must be identifier: _trackEvent(category, action, label) {
        //Universal Analytics
        if (typeof ga !== 'undefined') {
            ga('send', {
                hitType: 'event',
                eventCategory: category,
                eventAction: action,
                eventLabel: label
            });
        }
        else {
            //in case OneTrust took longer to load, try again after 3 seconds
            setTimeout(function () {
                if (typeof ga !== 'undefined') {
                    ga('send', {
                        hitType: 'event',
                        eventCategory: category,
                        eventAction: action,
                        eventLabel: label
                    });
                }
            }, 3000);
        }

        //GA 4
        if (typeof window.gtag !== 'undefined') {
            window.gtag("event", category, {
                eventAction: action,
                eventLabel: label
            });
        }
        else {
            //in case OneTrust took longer to load, try again after 3 seconds
            setTimeout(function () {
                if (typeof window.gtag !== 'undefined') {
                    window.gtag("event", category, {
                        eventAction: action,
                        eventLabel: label
                    });
                }
            }, 3000);
        }
    }
 */
var ak = ak || {};

ak.constants = (function () {
    return {
        QueryStrings: {
            Page: 'pg',
            SearchTerm: 'term',
            PageSize: 'pgSize',
            Id: 'id',
            Sort: 'sort',
            Category: 'c',
            GroupedOfferId: 'groupedOfferId',
            ContextItemId: 'contextItemId',
            NumberToShow: 'numberToShow',
            SpecialOfferId: 'specialOfferId',
            Region: 'region',
            Subregion: 'subregion',
            Country: 'country',
            Year: 'year',
            Month: 'month',
            YearMonth: 'yearmonth',
            JourneyType: 'journeyType',
            AllDestination: 'All Destination',
            SearchTermForSearchBox: '#?term=',
            DataSourceItemId: 'sc_itemid',
            ActiveSpecialOffers: 'asOffers'
        },
        SearchType: {
            JourneyType: "JourneySiteSearch",
            VideoType: "VideoSiteSearch",
            SpecialOfferType: "SpecialOfferSiteSearch",
            OtherResultsType: "OtherResultsSiteSearch",
            HotelType : "HotelSiteSearch"
        },        
        Keys: {
            Enter: 13
        },
        Paths: {
            LocalImagePath: '/Areas/Ak/Assets/Local/Images/'            
        }                
    };
})();;
// THIS FILE CONTAINS THE MOST COMMON UTILITY FUNCTIONS

var isIE = (navigator.userAgent.indexOf("MSIE") != -1) ? true : false;
var isIE6 = (navigator.userAgent.indexOf("MSIE 6") != -1) ? true : false;

/*
	CLEANTEXT IS A FUNCTION THAT REMOVES HTML ENTITIES AND REPLACES THEM WITH CHARACTERS JAVASCRIPT CAN DISPLAY IN A TEXT NODE.
	THE JAVASCRIPT ESCAPED VERSIONS CAN BE OCTAL (\DDD), HEXIDECIMAL, (\XDD) OR UNICODE (\UDDDD). BELOW WE ARE USING HEX BY
	DEFAULT. IF WE CANNOT FIND A HEX VALUE THAT WORKS, THEN USE UNICODE.
*/
String.prototype.replaceHTMLEntity = function() {
	var cleanString = this;
	cleanString = cleanString.replace(/&amp;/g,'\x26');
	cleanString = cleanString.replace(/&reg;/g,'\xAE');
	cleanString = cleanString.replace(/&trade;/g,'\u2122');
	cleanString = cleanString.replace(/&copy;/g,'\xA9');
	cleanString = cleanString.replace(/&reg;/g,'\xAE');
	cleanString = cleanString.replace(/&aacute;/g,'\xE1');
	cleanString = cleanString.replace(/&eacute;/g,'\xE9');
	cleanString = cleanString.replace(/&ntilde;/g,'\xF1');
	return cleanString;
};

/*
	NUMBERFORMAT IS A FUNCTION THAT WAS FOUND ON THE MOO TOOLS FORUMS. IT ALLOWS US TO FORMAT ANY NUMBER IN JAVASCRIPT
*/

/*
	Property: numberFormat
		Format a number with grouped thousands.

	Arguments:
		decimals, optional - integer, number of decimal percision; default, 2
		dec_point, optional - string, decimal point notation; default, '.'
		thousands_sep, optional - string, grouped thousands notation; default, ','

	Returns:
		a formatted version of number.

	Example:
		>(36432.556).numberFormat()  // returns 36,432.56
		>(36432.556).numberFormat(2, '.', ',')  // returns 36,432.56
	*/

/*
Number.implement({
 
	

	numberFormat : function(decimals, dec_point, thousands_sep) {
		decimals = Math.abs(decimals) + 1 ? decimals : 2;
		dec_point = dec_point || '.';
		thousands_sep = thousands_sep || ',';

		var matches = /(-)?(\d+)(\.\d+)?/.exec((isNaN(this) ? 0 : this) + ''); // returns matches[1] as sign, matches[2] as numbers and matches[2] as decimals
		var remainder = matches[2].length > 3 ? matches[2].length % 3 : 0;
		return (matches[1] ? matches[1] : '') + (remainder ? matches[2].substr(0, remainder) + thousands_sep : '') + matches[2].substr(remainder).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep) + 
				(decimals ? dec_point + (+matches[3] || 0).toFixed(decimals).substr(2) : '');
	}


});
*/
/* THESE HAVE BEEN REPLACED BY MOOTOOLS
function $() {
	return document.getElementById(arguments[0]);
}

function $$() {
	return document.getElementsByTagName(arguments[0]);
}*/

function removeChildNodes() {
	var a = (typeof arguments[0] == "string") ? document.getElementById(arguments[0]) : arguments[0];
	while ( a.hasChildNodes() ) {
		a.removeChild(a.childNodes[0]);
	}
}

function removeElement() {
	var e = (typeof arguments[0] == "string") ? document.getElementById(arguments[0]) : arguments[0];
	var parent = e.parentNode;
	parent.removeChild(e);
}

function getViewportScrollY() {
  var scrollY = 0;
  if( document.documentElement && document.documentElement.scrollTop ) {
    scrollY = document.documentElement.scrollTop;
  }
  else if( document.body && document.body.scrollTop ) {
    scrollY = document.body.scrollTop;
  }
  else if( window.pageYOffset ) {
    scrollY = window.pageYOffset;
  }
  else if( window.scrollY ) {
    scrollY = window.scrollY;
  }
  return scrollY;
}


// ACCEPTS ARRAYS A AND B. ATTEMPTS TO FIND EACH ELEMENT IN ARRAY B IN ARRAY A.
// ONCE A MATCH HAS BEEN FOUND THE POSITION OF THAT ITEM IN ARRAY A IS RETURNED.
// THIS FIND IS CASE SENSITIVE
function arrayFind(arr_a,arr_b) {
	// LOOP THROUGH ARRAY B
	for (var i=0; i<arr_b.length; i++) {
		var e = arr_b[i];
		// USE INDEXOF TO SEARCH ARRAY A FOR VALUE E
		for (var j=0; j<arr_a.length; j++) {
			if (e == arr_a[j]) {
				return j;
			}
		}
	}
	// IF NOTHING IS FOUND RETURN -1
	return -1;
}

// CASE-INSENSITIVE VERSION OF $ARRAYFIND
function arrayFindNoCase(arr_a,arr_b) {
	var a = [];
	var b = [];
	// LOOP THROUGH ARRAY A
	for (var i=0; i<arr_a.length; i++) {
		a.push(arr_a[i].toLowerCase());
	}
	// LOOP THROUGH ARRAY B
	for (var j=0; j<arr_b.length; j++) {
		b.push(arr_b[j].toLowerCase());
	}
	// CALL $ARRAYFIND NOW THAT ALL VALUES ARE IN LOWER CASE
	return arrayFind(a,b);
}

// FIREEVENT IS A WAY TO PROGRAMMATICALLY SIMULATE AN EVENT, LIKE A MOUSECLICK OR AN ONCHANGE
// THIS FUNCTION WAS FOUND AT http://jehiah.cz/archive/firing-javascript-events-properly
function fireEvent(element,event){
	if (event !== undefined) {
		if (document.createEventObject){
			// DISPATCH FOR IE
			var evt = document.createEventObject();
			return element.fireEvent('on'+event,evt);
		}else{
			// DISPATCH FOR FIREFOX + OTHERS
			var evt = document.createEvent("HTMLEvents");
			evt.initEvent(event, true, true ); // EVENT TYPE,BUBBLING,CANCELABLE
			return !element.dispatchEvent(evt);
		}
	}

}

// THE $CHECKALL FUNCTION IS A WAY TO CHECK, OR UNCHECK, A GROUP OF CHECKBOXES, OR TO UNCHECK A GROUP OF RADIO BUTTONS
function checkAll() {
	var e = (typeof arguments[0] == "string") ? document.getElementsByName(arguments[0]) : arguments[0];
	// THIS FUNCTION WILL CHECK ALL BY DEFAULT. PASS IN FALSE TO UNCHECK ALL
	var checkIt = (arguments.length > 1) ? arguments[1] : true;
	var len = e.length;
	
	// RETURN FALSE IF THE TYPE IS NOT CHECKBOX OR RADIO OR IF SOMEONE IS TRYING TO CHECK ALL RADIO BUTTONS
	if( !(e[0].type == "checkbox" || e[0].type == "radio") || (e[0].type == "radio" && checkIt) ) {
		return false;
	} else {
		for(var i=0; i < len; i++) {
			e[i].checked = checkIt;
		}
	}
	return true;
}

// THE $GETSLIDESHOWIMAGES FUNCTION PROVIDES AN AJAX GATEWAY TO RETRIEVE IMAGES FOR THE IMAGE GALLERY
function getSlideShowImages() {
	var method = arguments[0];
	var id = arguments[1];
	var d = new Date();
	// THE CACHESTRING WILL BE UNIQUE PER DAY, SO BROWSERS CAN CACHE A GALLERY REQUEST FOR A DAY. SINCE THE GALLERIES RARELY CHANGE THIS SHOULD BE OK.
	var cacheString = d.getFullYear().toString() + d.getMonth().toString() + d.getDate().toString();
	var gallery_div_id = (arguments[2]) ? arguments[2] : 'image_gallery';
	var myRequest = new Request.JSON({
		url: '/webservices/image_gallery/slide_show.cfc'
		,method: 'get'
		,data: 'method=' + method + '&id=' + id + '&dummy=' + cacheString
		,onSuccess: function(obj,txt) {
			initializeImageGallery(obj,gallery_div_id);
					
		}
		,onFailure: function(e) {
			alert('Error: ' + e.status + '\nPlease try again');
		}
	}).send();
	
	if(gallery_div_id == 'image_gallery'){
		imageGalleryOverlay.show();
	}
			
}

// THE $GETSLIDESHOWIMAGES FUNCTION PROVIDES AN AJAX GATEWAY TO RETRIEVE IMAGES FOR THE IMAGE GALLERY
function getSlideShowImages2() {
	var method = arguments[0];
	var nvp = arguments[1];
	var d = new Date();
	// THE CACHESTRING WILL BE UNIQUE PER DAY, SO BROWSERS CAN CACHE A GALLERY REQUEST FOR A DAY. SINCE THE GALLERIES RARELY CHANGE THIS SHOULD BE OK.
	var cacheString = d.getFullYear().toString() + d.getMonth().toString() + d.getDate().toString();
	var gallery_div_id = (arguments[2]) ? arguments[2] : '';
	
	$.ajax({
	  url: "/webservices/image_gallery/slide_show.cfc?method=" + method + "&" + nvp,
	  dataType: "json",
	  success: function(data){
		  if (gallery_div_id != ""){
			  $("#" + gallery_div_id).akImageRotator({imageWidth: 386, imageHeight: 258, data : data.images, numericControlPaging: true, clickableImage: false});
		  }
		  else{
			  var rotator = $("<div style='width: 490px;'></div>").akImageRotator({imageWidth: 490, data : data.images, numericControlPaging: true, showCaption: true, clickableImage: false, title:data.title});
			  $("<a href=''></a>").akOverlay({width: 490, content: $(rotator), background: "#f4f4f4"}).click();
			  if (typeof pageTracker !== "undefined") pageTracker._trackEvent('Overlay', 'Gallery', data.title);

		  }
	  }
	});
	
			
}

// THE $GETTRAVELINTERESTOVERLAY FUNCTION PROVIDES AN AJAX GATEWAY TO RETRIEVE DETAILS FOR A TRAVEL INTEREST TO BE DISPLAYED IN AN OVERLAY
function getTravelInterestOverlay() {
	var id = arguments[0];
	$.ajax({
	  url: "/webservices/trip/auxiliary_data.cfc?method=getTravelInterestOverlay&id=" + id,
	  dataType: "json",
	  success: function(data){
		  $("<a href=''></a>").akOverlay({title: data.h2_content, content: data.description, background: "#f4f4f4"}).click();
		  if (typeof pageTracker !== "undefined") pageTracker._trackEvent('Overlay', 'Travel Series', data.h2_content);
	  }
	});
}

function getSeriesOverlay() {
	var id = arguments[0];
	$.ajax({
	  url: "/webservices/trip/auxiliary_data.cfc?method=getSeriesOverlay&id=" + id,
	  dataType: "json",
	  success: function(data){
		  $("<a href=''></a>").akOverlay({title: data.h2_content, content: data.description}).click();
		  if (typeof pageTracker !== "undefined") pageTracker._trackEvent('Overlay', 'Travel Series', data.h2_content);
	  }
	});
}

function updateTravelInterestOverlay(obj){
	var overlay_div = document.getElementById('travel_interest_overlay');
	/*var h2 = overlay_div.getElement('h2');*/
	var h2 = $('#travel_interest_overlay .hl2')[0];
	h2.set('html',obj.h2_content);
	h2.set('class',obj.class_name + ' hl2');
	
	var div = h2.getNext('div');
	div.set('html',obj.description);
	div.set('class','description ' + obj.class_name);
	travel_interest_overlay.show();
};
function checkDropNav() {
    $(".destinations").show(); /* show element to calculate heights*/

    /* sets width of whole area */
    var listWidth = $("#header").width() - (parseInt($("#header").find("div.columns").css("padding-left")) * 2);

    $("div.destinations").css("width", listWidth + "px");
    $("div.journeys").css("width", listWidth + 15 + "px");

    /*total heights of each column*/
    var navHeight1 = 0;
    var navHeight2 = 0;
    var navHeight3 = 0;
    var navHeight4 = 0;
    var navHeight5 = 0;

    /* number of items in each column*/
    var totNav1 = 0;
    var totNav2 = 0;
    var totNav3 = 0;
    var totNav4 = 0;
    var totNav5 = 0;

    $(".destinations > ul > li").each(function () {
        var thisClass = $(this).attr("class");
        var thisHeight = $(this).height();

        if ((thisClass.indexOf("nav1") + 1) > 0) {
            navHeight1 += thisHeight;
            totNav1++;
        }
        else if ((thisClass.indexOf("nav2") + 1) > 0) {
            navHeight2 += thisHeight;
            totNav2++;
        }
        else if ((thisClass.indexOf("nav3") + 1) > 0) {
            navHeight3 += thisHeight;
            totNav3++;
        }
        else if ((thisClass.indexOf("nav4") + 1) > 0) {
            navHeight4 += thisHeight;
            totNav4++;
        }
        else if ((thisClass.indexOf("nav5") + 1) > 0) {
            navHeight5 += thisHeight;
            totNav5++;
        }

        /* offsets (with extra to compensate margins*/
        var navOffset2 = navHeight1 + (totNav1 * 20);
        var navOffset3 = navHeight2 + (totNav2 * 20);
        var navOffset4 = navHeight3 + (totNav3 * 20);
        var navOffset5 = navHeight4 + (totNav4 * 20);

        $(".nav2.top").css("margin-top", "-" + navOffset2 + "px");
        $(".nav3.top").css("margin-top", "-" + navOffset3 + "px");
        $(".nav4.top").css("margin-top", "-" + navOffset4 + "px");
        $(".nav5.top").css("margin-top", "-" + navOffset5 + "px");

        /* sets height of whole area */
        var biggestOffset = Math.max(navOffset2, navOffset3, navOffset4, navOffset5);
        $(".destinations").css('min-height', biggestOffset + 20 + "px");
    });

    $(".destinations").css('display', ''); // reset display (cant hide as then drop down will never show)
}


function readMoreBlock(element, minHeight) {
    if (minHeight === undefined) {
        if (element.hasClass("offers")) minHeight = 200;
        else if (element.parents(".read-more-block").hasClass("count_info")) minHeight = 0;
        else minHeight = 290;
    }

    var contentHeight = element.parents(".read-more-block").children(".read-more-content").height();
    var btnHeight = element.parents(".read-more-block-btns").height();
    var totalHeight = (contentHeight + btnHeight + 50);

    if (element.parents(".read-more-block").height() > minHeight) {
        if (element.parents(".read-more-block").hasClass("count_info")) {
            if (element.hasClass("button")) element.html("Country Information <span class=\"icon more\"></span>");
            else element.removeClass("active");
        } else {
            if (element.hasClass("button")) element.html("Show More <span class=\"icon more\"></span>");
            else element.removeClass("active");
        }

        element.parents(".read-more-block").animate({ height: minHeight + "px" }, 1000, function () {
            $(document).foundation("equalizer", "reflow");
        });
    } else {
        if (element.parents(".read-more-block").hasClass("count_info")) {
            if (element.hasClass("button")) element.html("Hide Country Information <span class=\"icon less\"></span>");
            else element.removeClass("active");
        } else {
            if (element.hasClass("button")) element.html("Show Less <span class=\"icon less\"></span>");
            else element.removeClass("active");
        }

        element.parents(".read-more-block").animate({ height: totalHeight + "px" }, 1000, function () {
            $(document).foundation("equalizer", "reflow");
        });
    }

    element.parents(".read-more-block").toggleClass("open");
}

function vert_center(element) {
    var this_height = element.height();
    var par_height = element.parent().height();
    var new_marg = (par_height - this_height) / 2;

    element.css("margin-top", new_marg + "px");
}

function v_align(element) {
    var maxHeight = 0;
    var columns = element.children(".columns.advert");

    columns.each(function () {
        // loop through and get biggest height
        if ($(this).height() > maxHeight) maxHeight = $(this).height();
    });

    columns.each(function () {
        // loop through and set padding for each column
        if ($(this).height() < maxHeight) {
            var heightDiff = maxHeight - $(this).height();
            var columnPad = (heightDiff / 2);

            $(this).css("margin-top", columnPad + "px");
        }
    });
}

function checkButtons() {
    // Buttons with too much text in
    $(".button").each(function () {
        if ($(this).height() > (parseInt($(this).css("line-height")) + 10)) {
            // text runs on to two lines
            var totalHeight = $(this).height();
            var heightDiff = $(this).height() - $(this).children(".icon").height();

            $(this).children(".icon").css("margin-top", heightDiff / 2 + "px");
        }
        else {
            if ($(this).hasClass("small")) $(this).children(".icon").css("margin-top", "-1px");
            else $(this).children(".icon").css("margin-top", "-6px");
        }
    });
}

// Pinterest Embedded Board
function resizePinterest() {
    setTimeout(function () {
        $("span[class$='embed_grid']:visible").each(function () {
            boardWidth = $(this).parent().width();
            innerBoardWidth = boardWidth - (parseInt($(this).children("span:first-child").css("margin-left")) + parseInt($(this).children("span:first-child").css("margin-right")));

            pinSpacing = 2;
            pinsPerRow = 4;
            if (boardWidth <= 400) pinsPerRow = 2;
            else if (boardWidth <= 640) pinsPerRow = 3;
            pinWidth = (innerBoardWidth - (4 * pinSpacing)) / pinsPerRow;

            boardURL = $(this).children("a[class$='embed_grid_ft']").attr("data-pin-href");

            console.log("add new board size: " + boardWidth);
            $(this).after('<a data-pin-do="embedUser" href="' + boardURL + '" data-pin-scale-width="' + pinWidth + '" data-pin-board-width="' + boardWidth + '" data-pin-scale-height="500">Follow A&amp;K\'s board on Pinterest.</a>');
            $(this).remove();
            doBuild($(this).parent());
        });
    }, 50);
}

$.fn.positionOn = function (element, align) {
    return this.each(function () {
        var target = $(this);
        var position = element.position();

        var x = position.left;
        var y = position.top;

        if (align == 'right') {
            x -= (target.outerWidth() - element.outerWidth());
        } else if (align == 'center') {
            x -= target.outerWidth() / 2 - element.outerWidth() / 2;
        }

        target.css({
            position: 'absolute',
            zIndex: 5000,
            top: y,
            left: x
        });
    });
};


$(document).ready(function () {
    $("a.close-reveal-modal").click(function () {
        // Makes button close overlays on iPhone
        $(this).parent(".reveal-modal").foundation("reveal", "close");
    });

    $("a#call-link").click(function () {
        // get updated phone number and set as link
        var phoneNum = $("#mob-call-area a").text().replace(/\s+/g, '');
        $("#mob-call-area a").attr("href", "tel:" + phoneNum);
        // hide/show
        $(this).toggleClass("active");
        $("#mob-call-area").slideToggle({
            start: function () {
                if ($("#mob-call-area").is(":visible")) {
                    $(".tab-bar").addClass("active");
                } else {
                    $(".tab-bar").removeClass("active");
                }
            },
            complete: function () {
                if ($("#mob-call-area").is(":visible")) {
                    $(".tab-bar").addClass("active");
                } else {
                    $(".tab-bar").removeClass("active");
                }
            }
        });
    });

    $(document).on("click", "a.show-more", (function () {
        $(this).toggleClass("active");
        $(this).parent().prev(".show-more-area").slideToggle();
        $(this).blur();
    }));

    $("a.show-more-bar").click(function () {
        $(this).toggleClass("active");
        $(this).next(".show-more-area").slideToggle();
    });

    $(".read-more-block").each(function () {
        if ($(this).outerHeight(false) > $(this).find("div.read-more-content").outerHeight(false)) {
            $(this).height("auto");
            $(this).find("a.read-more-block-btn").hide();
        }
        else if ($(this).hasClass("balanced")) {
            if ($(this).outerHeight() < $(this).parents(".row").height()) {
                var newHeight = $(this).parents(".row").height() - parseInt($(this).css("padding-bottom"));
                // round to nearest 20px
                var newHeight = Math.floor(newHeight / 10) * 10;
                $(this).height(newHeight);
            }
            // save height
            $(this).attr("data-original-height", $(this).outerHeight());
        }
    });

    $("a.read-more-block-btn").click(function () {
        if ($(this).parents(".read-more-block").attr("data-original-height")) {
            var blockHeight = $(this).parents(".read-more-block").attr("data-original-height");
            readMoreBlock($(this), blockHeight);
        }
        else {
            readMoreBlock($(this));
        }
    });

    $(".vert_center").each(function () {
        vert_center($(this));
    });

    var p = $('#kwf').offset();
    if (p) $('.ui-autocomplete').css({ top: p.top + 45, left: p.left });

    checkDropNav();

    if ($(window).width() > 640) {
        $(".row.v_align").each(function () {
            v_align($(this));
        });
    }

    $(window).resize(function () {
        if ($(window).width() > 640) {
            checkDropNav();
            // hide mobile things
            $(".off-canvas-wrap").foundation("offcanvas", "hide", "move-right");
            $("#mob-call-area").hide();
            $(".tab-bar").removeClass("active");
            $("a#call-link").removeClass("active");
            $(".show-more-area").css("display", "");
            $(".row.v_align").each(function () { v_align($(this)); });
        }

        var p = $('#kwf').offset();
        if (p) $('.ui-autocomplete').css({ top: p.top + 45, left: p.left });
        checkButtons();
        resizePinterest();
    });

    $(".navFlyoutDetails").mouseenter(function () {
        var el = $(this);
        var t = "#" + el.attr('name');
        var target = t + "_preview ";
        var txt = el.attr('desc');
        $(target + t + "_desc").html(txt);
        txt = el.attr('allhref').split('|');
        if (txt.length >= 2) { // allhref must be a list of two elements, delimited by | 
            $(target + t + "_allhref").attr('href', txt[1]);
            $(target + t + "_allhref").html('<span>' + txt[0] + '<span class="button small">Learn more</span></span>');
        }

        if (txt.length == 3) { // if a 3 element exists, its for changing the A target 
            $(target + t + "_allhref").attr('target', txt[2]);
        }

        $(target + t + "_img img").hide();
        if ($(window).width() > 640) {
            txt = target + t + "_img img#" + el.attr('img');
            $(txt).show();
        }

        txt = el.attr('title');
        $(target + t + "_title").html(txt);
    });

    $("div#nav > ul > li:not(.separator)").mouseenter(function () {
        if ($(this).children(".drop_nav").hasClass("destinations") || $(this).children(".drop_nav").hasClass("journeys")) {
            var thisWidth = $(this).width();
            var thisPos = $(this).position();

            // Position whole drop-down box
            var dropPosition = -(thisPos.left - parseInt($("#nav").css("padding-left")));
            $(this).children(".drop_nav").css("left", dropPosition + "px");

            // Background positon (arrow)
            var bgPosition = -(dropPosition) + ((thisWidth / 2) + parseInt($(this).css("padding-left"))) - 10;
            $(this).children(".drop_nav").css("background-position", bgPosition + "px 0");

        } else {

            var bgPosition = ((thisWidth / 2) + parseInt($(this).css("padding-left"))) - 10;
            $(this).children(".drop_nav").css("left", thisPos + "px");
            $(this).children(".drop_nav").css("background-position", bgPosition + "px 0");
        }
    });

    $(".trigger").hover(function () {
        $(this).parent().find(".btn_con a, a.button.carrot").toggleClass("hover");
    });

    $(".search_result .trigger").hover(function () {
        $(this).parents(".search_result").find(".btn_con a, a.button.carrot, h3 a").toggleClass("hover");
    });

    $('#search_filter select').on('change', function () {
        window.location.href = this.value;
    });

    var isChrome = !!window.chrome && !!window.chrome.webstore;

    $(".CS_Element_CustomCF table tr").each(function () {
        // Each column
        $(this).children("td:not(:empty)").each(function () {
            // Remove inline styles and add classes
            $(this).removeAttr("style");

            // Make image full width
            $(this).find("img").filter(function () { return $(this).width() > 50; }).addClass("fill");

            // Remove empty paragraphs, and tidy others
            $(this).find("p").each(function (index, element) {
                $(this).html($(this).html().replace(/(<br>\s*)+$/, ''));
                if ($(this).is(":empty")) $(this).remove();
            });
        });
    });

    // MORE TIDY UP FUNCTIONS

    $("table[align='center'], table *[align='center']").each(function () {
        $(this).css("text-align", "center");
    });

    $("div[style*=border-radius]").each(function () {
        // Cleans up styles
        $(this).addClass("responsive_box");

        // Make image full width
        $(this).find("img").filter(function () { return $(this).width() > 50; }).addClass("fill");
    });

    $("div[id$=contentsupplemental] div").each(function (index, element) {
        // Make image full width
        $(this).find("img").filter(function () { return $(this).width() > 50; }).addClass("fill");

        // Remove h3 inline styles
        $(this).find("h3").removeAttr("style");

        // Change span tags to p tags
        var spanHTML = $(this).find("span").parent().html();
        if (spanHTML != null) {
            spanHTML = spanHTML.replace(/<span/g, '<p').replace(/<\/span>/g, '</p>');
        }
    });

    /*$("img").filter(function() {
		return $(this).css("float") == "left";
	}).addClass("float_left");*/

    // Tidy icon links in paragraphs
    $("p:has(a.icon.swirl_arrow)").each(function () {
        $(this).append("<span class=\"dummy_div\"></span>");
        var trimmedPara = $.trim($(this).html().replace(/(<br ?\/?>)*/g, ""));
        $(".dummy_div").html(trimmedPara);

        if ($(".dummy_div").length === 1 && $(".dummy_div").contents().length === 1) {
            // if link is only item in paragraph, add class to parent
            $(".dummy_div").remove();
            $(this).find("a.icon.swirl_arrow").removeClass().prepend("&gt; ").parent().addClass("right");
        }
        else {
            // if not, move out of paragraph into a new parent
            $(".dummy_div").remove();
            $(this).find("a.icon.swirl_arrow").removeClass().prepend("&gt; ").insertAfter($(this)).wrap("<p class=\"right\"></p>");
        }

        // add clear after floated paragraph (no matter whether it's the original one, or moved)
        $(this).parent().children("p.right").after("<br class=\"clear\" />");

        // remove trailing br tags in source paragraph
        var paraHTML = $(this).html().replace(/(<br>\s*)+$/, "");
        $(this).html(paraHTML);
    });

    // Tidy icon links outside of paragraphs
    $("a.icon.swirl_arrow").not("p a.icon.swirl_arrow").each(function () {
        $(this).removeClass().prepend("&gt; ").wrap("<p class=\"right\"></p>");
    });

    // pre-set first link preview for Small Group Journey dropdown
    $('div.journeys a.navFlyoutDetails:first').triggerHandler("mouseenter");
    $('div.cruises a.navFlyoutDetails:first').triggerHandler("mouseenter");
    $('div.tailor a.navFlyoutDetails:first').triggerHandler("mouseenter");

    // Automated hide/show functionality
    token = "[[[BREAK]]]";
    $(".min-height p:contains(" + token + ")").each(function () {
        var parentElement = $(this).closest(":not(p)");

        if ($(this).html() == token && $(this).get(0).outerHTML == "<p>" + token + "</p>") {
            replaceText = "<p>" + token + "</p>";
        }
        else {
            replaceText = token;
        }

        var splitString = parentElement.html().split(replaceText);
        parentElement.html('<div class="clear">' + splitString[0] + '</div><div class="clear split-area">' + splitString[1] + '</div><p class="no_marg_top no_marg_bot"><a class="clear show-more show-split" title="show more" href="javascript:void(0);">show more</a></p>');

        $(".split-area").hide();

        $("a.show-split").off().click(function () {
            console.log("show-split clicked");
            $(this).toggleClass("active");
            $(this).parent().prev(".split-area").slideToggle();
            $(this).blur();
        });
    });

    checkButtons();
});

$(window).load(function () {
    if ($(window).width() < 1024) {
        resizePinterest();
    }
});;
(function($){	
	$.fn.akOverlay = function(settings){
        var config = {
            "width" : 400,
            "height" : 300,
            "background" : "#fff",
            "className" : "",
            "content" : "",
            "title" : "",
            "link" : "",
            "linktext" : "",
            "timeout" : 0,
			"escape" : false
        };

        if (settings){
            $.extend(config, settings);
        }

        return this.each(function(){
   			var $this = $(this);
			var overlayHeightPadding = 50;
			var overlayDetailsWidthPadding = 50;
			//var maxcontentheight = 530;
			var maxcontentheight = 1200;
			var contentType = "";
            
            $this.on("click", function(e){
                var inlineSettings = $.parseJSON(this.rel);
                $.extend(config, inlineSettings);
                var ocode = '<div id="ak-overlay"><a class="close"></a><div class="overlay-details"><div class="overlay-padding"><img style="position: relative; margin:-20px auto 0; top:50%;" src="/assets/images/graphics/ajax-loader.gif"/></div></div></div>';
                
                $('body').append(ocode);
                // apply custom variables to details div

				//'width': config.width + "px"
/*
    margin: 0 25px;
    max-height: 530px;
    overflow-x: hidden;
    overflow-y: auto;
    padding: 0;
    position: relative;*/


                $('#ak-overlay .overlay-details').css({
                    'background': config.background
                });
					
				//'margin-left':"-" + ((config.width + overlayDetailsWidthPadding) /2) + "px"
				//                	'width':(config.width + overlayDetailsWidthPadding) + "px"

                $('#ak-overlay').css({
                	'height':"50%",
                	'margin':"5% 25%",
                	'top':"10%",
                	'width':"50%",
                	'left':"0"
				});
                
                // add class
                if (config.className != '') {
                    $('#ak-overlay .overlay-details').addClass(config.className);
                }
				
				// remove padding when container bg matches content bg	
				if (config.background == "#f4f4f4"){
					$('#ak-overlay .overlay-padding').css({
						'padding':0
					});
				}
				
                // load content, check if content is set inline 
                if ((typeof config.content == "string") && ($.trim(config.content) != '') || 
                        ($.trim(config.title) != '')) {

                    var title = "";
                    var content = "";
                    var link = "";
                    var linktext = "";
					
					contentType = "string";
                    
                    if ($.trim(config.title) != '') {
                        title = '<h3 class="clear_margins">' + config.title + '</h3>';                        
                    }
					if ($.trim(config.link) != '' && $.trim(config.linktext) != '') {
						link = '<p class="base_font_size"><a class="icon swirl_arrow" href="' + config.link + '">';
                        linktext = config.linktext + '</a></p>';
					}
                    if ($.trim(config.content) != '') {
						content = config.content;
						if (config.escape){
							content = unescape(content);
						}
                        content = '<p>' + content + '</p>';
                    }
                    
					
                    $('#ak-overlay .overlay-padding').html(title + content + link + linktext);
					
			
                } else if (typeof config.content == "object"){

					contentType = "object";
					$('#ak-overlay .overlay-padding').html("");
					$('#ak-overlay .overlay-padding').append(config.content);
				} else {					

					$.ajax({
					  url: this.href,
					  async: false,
					  success: function(data){
						  $('#ak-overlay .overlay-padding').html(data);
					  }
					});
                }
				
				if (config.background != "#f4f4f4") {
					$('#ak-overlay .overlay-padding p:last-child').css({
						'margin-bottom':0
					});	
				}
                
                // call overlay mask
                $('body').append('<div id="ak-overlay-mask" style="width:' + $(window).width() + 'px; height:' + $(window).height() + 'px;"/>');
	
				// call overlay
                $('#ak-overlay').fadeIn('fast');

				// call overlay form plugin if ajax looks in forms folder
				//if ((this.href).indexOf("/forms/")) {
				//	$('#ak-overlay .overlay-padding').akoverlayform();
				//}
				 
				// call adjust height and margin-height, setting max-height
				var h = parseInt($('#ak-overlay .overlay-details').height());
				if (h <= maxcontentheight) {
					h_details = h;
				} else {
					h_details = maxcontentheight
				};
				
				var total_height = (h_details + overlayHeightPadding); 
				
				if (config.background != "#f4f4f4"){
					total_height = total_height + 10;
				}
				
				//'margin-top':"-" + ((total_height) /2) + "px"
				$('#ak-overlay').css({
					'height':total_height + "px"
				});
				
			
                // close the overlay
                $('#ak-overlay-mask, #ak-overlay .close').bind('click', function(){
                    ooverlay_close()     
                });
                
                if (config.timeout > 0) {
                    setTimeout(function() {
                        ooverlay_close();
                    }, config.timeout * 1000);
                }
	
                function ooverlay_close() {
                    $('#ak-overlay').remove();
                    $('#ak-overlay-mask').remove();
                }
                
                e.preventDefault();
            });
        });

    };
	
	$.fn.akImageRotator = function(settings){
        var config = {
			"imageWidth" : 0,
			"imageHeight" : 0,
            "data" : [{}],
            "rotateSpeed" : 5000,
            "transitionSpeed" : 2000,
            "showNumericControl" : true,
            "numericControlPaging" : false,
            "numberPerPage": 8,
			"showCaption": false,
			"clickableImage": true,
			"resetNumericControlWidth": false
        };
        if (settings){
			$.extend(config, settings);
        }

        return this.each(function(){
            var $this = $(this);
            var $images = null;
            var $pages = null;
            var timeInterval = null;
            var selectedIndex = 1;
            var previousIndex = 0;
            var paginationWidth = 0;
            var minimumNumberPerPage = 5;
			var width = $this.width();
			var height = $this.height();
			var paginationAnimationIsActive = false;
			
			$this.html("");
			$this.addClass("ak-image-rotator");
			
			//Add images
			var imageTag = "<img id='gallery-image-rotator-loader' src='/assets/images/graphics/ajax-loader.gif' alt=''/>";//
            for (var i = 0; i < config.data.length; i++){
				if (config.clickableImage){
					imageTag += "<a href='" + config.data[i].href + "'>";
				}
                
                imageTag += "<img src='" + config.data[i].source + "' alt='" + config.data[i].alt + "' ";
				if (config.imageWidth > 0){
					imageTag += " width='" + config.imageWidth + "' ";
				}
				if (config.imageHeight > 0){
					imageTag += " height='" + config.imageHeight + "' ";
				}
				imageTag += "/>";
				
				if (config.clickableImage){
               		imageTag += "</a>";
				}
            }
			
			$this.append(imageTag);
			
			$images = $("img", $this);
            for (var y = 1; y < $images.length; y++){
                $($images[y]).css({"display" : "none"});
            }
			
			var imageCounter = 0;            
			$images.load(function(){
				imageCounter++;
				
				if (imageCounter == $images.length){
					//Add numeric control
					if (config.showNumericControl){
						buildNumericControl();
					}
					
					buildCaption();
					
					buildTitle();
					
					timeInterval = window.setInterval(rotate, config.rotateSpeed);
				}
				
			});
            
			
			function buildNumericControl(){
				$("#gallery-image-rotator-loader", $this).remove();
				$($images[1]).fadeIn();
			
				$images = $("img", $this);
			
				var controlTag = "<div class='ak-image-rotator-control'>";
				controlTag += "<ul class='ak-image-rotator-control-numbers clear_list_styles'>";            
				for (var x = 0; x < config.data.length; x++){
					controlTag += "<li><a href='javascript:void(0);' rel='" + x + "' class='ak-image-rotator-control-number" + ((x == 0) ? " ak-image-rotator-control-select" : "") + "'>" + (x+1) + "</a></li>";
				}            
				controlTag += "</u></div>";            
				$this.prepend(controlTag);            

				$pages = $(".ak-image-rotator-control-numbers a.ak-image-rotator-control-number", $this);
				$($pages).on("click", function(event){
					select($(this).attr("rel"));
					event.preventDefault();
				});
				
				if (config.numericControlPaging && config.numberPerPage >= minimumNumberPerPage){
					//Hide numbers
					for (var z = 0; z < $(".ak-image-rotator-control-numbers li", $this).length; z++){
						if (z > config.numberPerPage - 1){
							$($(".ak-image-rotator-control-numbers li", $this)[z]).hide();
						}
					}
				}
				
				// Reset pagination container       
				if (config.resetNumericControlWidth){
					$(".ak-image-rotator-control", $this).css("width", ($images.length * 25) + "px");
				} else if ($images.length >= config.numberPerPage){
					$(".ak-image-rotator-control", $this).css("width", (config.numberPerPage * 26) + "px");
				} else {
					$(".ak-image-rotator-control", $this).css("width", ($images.length * 26) + "px");
				}
							
				
			}
			
			function buildCaption(){
				//Add image caption
				if (config.showCaption){
					var caption = "<div class='ak-image-rotator-caption'>";
					if (config.data[0].caption != undefined){
						caption += config.data[0].caption;
					}
					caption += "</div>";
					$this.append(caption);
				}
			}
			
			function buildTitle(){
				//Add gallery title
				if (config.showCaption){
					if (config.data[0].caption != undefined){
						var gal_title = "<strong class='title'>" + config.title + "</strong>";
						$this.prepend(gal_title);
					}
				}
			}
			
			function rotate(){
                $($images[previousIndex]).fadeOut(config.transitionSpeed);                
                $($images[selectedIndex]).fadeIn(config.transitionSpeed);
				
				if (config.showCaption){
					if (config.data[selectedIndex].caption != undefined){
						$(".ak-image-rotator-caption", $this).html(config.data[selectedIndex].caption);
					}							
				}
                
                if (config.showNumericControl){
                    $($pages[previousIndex]).attr("class", "ak-image-rotator-control-number");                
                    $($pages[selectedIndex]).attr("class", "ak-image-rotator-control-number ak-image-rotator-control-select");
                    
                    if (config.numericControlPaging && config.numberPerPage >= minimumNumberPerPage){
                        numericControlPage(selectedIndex, false);
                    }                    
                }                

                previousIndex = selectedIndex++;
                
                if(selectedIndex > $images.length-1)
                {
                    selectedIndex = 0;
                    previousIndex= $images.length-1;
                }
            }
            
            function select(index){
				
				if (!paginationAnimationIsActive){
					
					window.clearInterval(timeInterval);
					timeInterval = null;
					
					//Only highlight image/control number if not currently selected
					if ($($pages[index]).attr("class").toString().search("ak-image-rotator-control-select") == -1){
						selectedIndex = index;
	
						$($images[selectedIndex]).fadeIn(config.transitionSpeed);
						$($images[previousIndex]).fadeOut(config.transitionSpeed);                
	
						$($pages[selectedIndex]).attr("class", "ak-image-rotator-control-number ak-image-rotator-control-select");
						$($pages[previousIndex]).attr("class", "ak-image-rotator-control-number");
						
						if (config.showCaption){
							if (config.data[index].caption != undefined){
								$(".ak-image-rotator-caption", $this).html(config.data[index].caption);	
							}							
						}
						
						if (config.numericControlPaging && config.numberPerPage >= minimumNumberPerPage){
							numericControlPage(selectedIndex, true);
						}
	
						previousIndex = selectedIndex;
						selectedIndex++;
	
						if (previousIndex < 0){
							previousIndex = 0;
							previousIndex= $images.length-1;
						}
	
						if (selectedIndex >= $images.length){
							selectedIndex = 0;
						}
					}
					
					timeInterval = window.setInterval(rotate, config.rotateSpeed);
				}
            }
            
            function numericControlPage(index, selected){
                var $visiblePages = $(".ak-image-rotator-control-numbers li a", $this).filter(":visible");
                var relStart = $visiblePages.length - config.numberPerPage;
                var relEnd = $visiblePages.length - 1;
                var lastIndex = $pages.length - 1;
                                
                if (index == 0){
                    previousPage(lastIndex - config.numberPerPage + 1, lastIndex);
                }
				
                //Move to the next page
                if (index == relEnd && lastIndex > index){
                    if ((parseInt(index) + parseInt(config.numberPerPage)) >= lastIndex){
                        //Move up to the last item
                        nextPage(lastIndex - index, relEnd);
                    }
                    else{
                        nextPage(config.numberPerPage - 1, relEnd);
                    }
                }

                //Move one item to the next page
                if (index == (relEnd - 1) && lastIndex - 1 > index){
                    nextPage(1, relEnd);
                }

                //Move to the previous page
                if (index == relStart && index != 0 ){
                    if ((parseInt(index) - parseInt(config.numberPerPage)) < 0){
                        //Move until the first item
                        if (index == config.numberPerPage - 1){
                            previousPage(Math.round(index/2), relEnd);
                        }
                        else{
                            previousPage(index, relEnd);
                        }
                    }
                    else{
                        previousPage(config.numberPerPage - Math.round(config.numberPerPage/2), relEnd);
                    }
                }

                //Move one item to the left
                if (index == (relStart + 1)  && index != 1 && selected){
                    previousPage(1, relEnd);
                }

            }
            
            function nextPage(count, endIndex){
                var lastItemIndex = endIndex;
				
				paginationAnimationIsActive = true;
                
                for (var i = 0; i < count; i++){
                    lastItemIndex++;
                    $($(".ak-image-rotator-control-numbers li", $this)[lastItemIndex]).fadeIn();
                }
                
                paginationWidth += $(".ak-image-rotator-control-numbers li:first", $this).outerWidth(true)*count;
                
                $(".ak-image-rotator-control-numbers", $this).animate({
                    marginLeft: "-" + paginationWidth + "px"
                }, 1000, function(){paginationAnimationIsActive = false;});  
            }
            
            function previousPage(count, endIndex){
                var lastItemIndex = endIndex;
				
				paginationAnimationIsActive = true;
                
                paginationWidth -= $(".ak-image-rotator-control-numbers li:first", $this).outerWidth(true)*count;
                
                $(".ak-image-rotator-control-numbers", $this).animate({
                    marginLeft: "-" + paginationWidth + "px"
                }, 1000, function(){
                    for (var i = count; i > 0; i--){                    
                        $($(".ak-image-rotator-control-numbers li", $this)[lastItemIndex]).fadeOut();
                        lastItemIndex--;
						paginationAnimationIsActive = false;
                    }   
                });    
            }
            
        });
    };
	
	$.fn.akoverlayform = function(settings) {
    	var config = {
			"width" : 750,
			"validate_url" : "/assets/overlays/forms/json.cfm"
        };
		if (settings){$.extend(config, settings);}
		
		var first_slide = $("fieldset:first-child", this);
		var slides = $("fieldset", this);
		var current_slide = 0;
		//var slide_index = 0;
		var slide_count = $("fieldset", this).length - 1;
		var loader = $("#loader", this);
		var validate = $(".validate", this);
		
		return this.each(function(){
			$(this).height(first_slide.height());
			$(this).addClass("bg-loader");
			equalize(first_slide, slides);
			
			$(this).on("click", ".next", function(event){		
				//show_loader();
				
				var form_data = slides.eq(current_slide).serializeArray();
    			var required = [];
				slides.eq(current_slide).find(".required").each(function(i){
					required.push($(this).attr("name"));
				});
				form_data.push({ name: "required", value: required});

				$.ajax({
					url: config.validate_url,
					type: "POST",
					data: form_data,
					dataType: 'json',
					success: function(data) {
						if (form_data[4].value.indexOf("@") != -1){
							slidemove("next");
						} else {
							slides.eq(current_slide).find(":[name=" + form_data[4].name + "]").parent("label").addClass("error");
						}
					},
					error: function(data){ 
						alert("error");
					}	
				});
        		return false;
			});
		});
		
		function equalize(constant, change) {
			change.height(constant.height()).width(config.width -30);
		}
		function show_loader(){
			slides.addClass("hide");
		}
		function slidemove (direction){
			if (direction == "next"){
				current_slide++;
				slides.addClass("hide").eq(current_slide).removeClass("hide");
			} else if (direction == "prev"){
			
			}
			akform_loader("hide");
		}
	};

})(jQuery);;
/*
 * overrides.js   Copyright PaperThin, Inc.
 */
hasRTE = false;
checkDlg = function()
{
	ResizeWindow();
}

CloseWindow = function()
{
	top.commonspot.lightbox.closeCurrent();
}

cs_OpenURLinOpener = function(workUrl)
{
	OpenURLInOpener(workUrl);
}

doCPOpenInOpener = function(workUrl)
{
	OpenURLInOpener(workUrl);
}

DoFocus = function(){};

handleLoad = function()
{
	ResizeWindow();
}

if (typeof handleLoad != 'function')
{
	handleLoad = function()
	{
		ResizeWindow();
	}
}

csExtendedWindow = function(name, url, windowProps)
{
	var wnd = window.open(url, name, windowProps);
}

newWindow = function(name, url, customOverlayMsg, openInWindow, windowProps)
{
	var customOverlayMsg = customOverlayMsg ? customOverlayMsg : null;
	var openInWindow = openInWindow ? openInWindow : false;
	var windowProps = windowProps ? windowProps : null;
	var wnd = top;
	var opr;
	var url = typeof url != 'undefined' ? url : '';
	if (openInWindow == true)
	{
		var wnd = window.open(url, name, windowProps);
		return wnd;
	}
	if (url.indexOf('/commonspot/dashboard/') == 0 || url.indexOf('controls/imagecommon/add-image') > 0)
	{
		if (!top.commonspot.util.browser.valid)
		{
			alert('This functionality requires Internet Explorer versions 9 (or later) or Firefox Extended Support Release (ESR) versions or Safari 6 or 7 (only on Mac OS) or Chrome 31 (or later).');
			return;
		}
		var setupComplete = checkDashboardSetup();
		if (!setupComplete)
		{
			setTimeout(function(){
				newWindow(name, url, customOverlayMsg);
			},1);
			return;
		}
	}

	if (top.commonspot && top.commonspot.lightbox)
	{
		if (top.commonspot.lightbox.stack.length > 0)
			opr = top.commonspot.lightbox.stack.last().getWindow();
		top.commonspot.lightbox.openDialog(url, null, name, customOverlayMsg, null, opr);
		wnd = top.commonspot.lightbox.stack.last().getWindow();
	}
	return wnd;
}

OpenURLandClose = function(workUrl)
{
	var openerWin = top.commonspot.lightbox.getOpenerWindow();
	openerWin.location.href = workUrl;
	if (document.getElementById("leavewindowopen").checked == false)
	{
		setTimeout('window.close()', 250);
	}
}

OpenURLInOpener = function(workUrl)
{
	var openWin = top.commonspot.lightbox.getOpenerWindow();
	if (openWin)
	{
		openWin.location.href = workUrl;
	}
}

RefreshAndCloseWindow = function(clearQueryParams)
{
	clearQueryParams = clearQueryParams ? clearQueryParams : 0;
	var openWin, openFrame;
	if (clearQueryParams)
	{
		ResetParentWindow();
		return;
	}
	try // without this try-catch IE throws Access Denied for dialogs called from site-admin
	{
		if (top.commonspot.util.browser.chrome || top.commonspot.util.browser.safari) //
		{
			openFrame = top.commonspot.lightbox.getOpenerLightboxFrame();
			// next line are exceptions to this special case, re accurev 17450 and 17894
			var doSpecialCase = openFrame
					&& (openFrame.src.indexOf('/dashboard/dialogs/siteadmin/metadata-form-addedit.html') === -1)
					&& (openFrame.src.indexOf('/commonspot/dashboard/null') === -1);
			if (doSpecialCase)
				openFrame.src = openFrame.contentWindow.location.href;
			else
			{
				openWin = top.commonspot.lightbox.getOpenerWindow();
				if (openWin)
					openWin.location.reload();
			}
		}
		else
		{
			openWin = top.commonspot.lightbox.getOpenerWindow();
			if (openWin)
				openWin.location.reload();
		}
	}
	catch(e) {}
	CloseWindow();
}

ResetParentWindow = function()
{
	var pWin = top.commonspot.lightbox.getOpenerWindow();
	try // without this try-catch IE throws Access Denied for dialogs called from site-admin
	{
		if (pWin)
		{
			var addPageInLView = 0;
			var pSearch = pWin.location.search;
			if (pSearch.indexOf('cs_pgIsInLView=1') >= 0)
				addPageInLView = 1;
			var pHref = pWin.location.href;
			if (pHref.length && pSearch.length)
				pHref = pHref.replace(pSearch, '');
			if (addPageInLView)
				pHref = pHref + '?cs_pgIsInLView=1';
			if (pHref != pWin.location.href)
				pWin.location.href = pHref;
			else
				pWin.location.reload();
		}
	}
	catch(e) {}
	CloseWindow();
}

ReloadAndFocus = function(tabID)
{
	var win = top.commonspot.lightbox.stack.last().getWindow();
	if (typeof win['tabDialog'] == 'function')
	{
		top.commonspot.util.event.addEvent(win, "load", tabDialog(tabID));
		win.location.reload();
	}
}

RefreshParentWindow = function()
{
	var openerWin = top.commonspot.lightbox.getOpenerWindow();
	pageid = openerWin.js_gvPageID;
	if (pageid > 0)
	{
		openerWin.document.cookie = "scrollPage=" + pageid;
		openerWin.document.cookie = "scrollX=" + cd_scrollLeft;
		openerWin.document.cookie = "scrollY=" + cd_scrollTop;
	}
	openerWin.location.reload();
	DoFocus(self);
	DoFocusDone=1;	// not done, but we don't want the focus
}

ResizeWindow = function(doRecalc, curTab)
{
	if (!curTab && typeof window['delayReload'] != 'undefined')
	{
		hasRTE = 1;
		if (window['delayReload'] == 1 && window['hasActiveRTE'] != 1)
			return;
		else
		{
			if (typeof adjustEditorSize == 'function')
				adjustEditorSize();
		}	
	}	
	if (typeof ResizeWindowSafe != 'undefined')		// this variable is set in dlgcommon-head for legacy dialogs (initially set to 0, then to 1 upon calling dlgcommon-foot)
	{
		if (ResizeWindowSafe == 1)
			ResizeWindow_Meat(doRecalc, curTab);  // this function is defined in over-rides.js
		else
			ResizeWindowCalledCount = ResizeWindowCalledCount + 1;
	}
	else
		ResizeWindow_Meat(doRecalc, curTab);  // this function is defined in over-rides.js
}


ResizeWindow_Meat = function(doRecalc, currentTab)
{
	var maintable = document.getElementById('MainTable');
	if (maintable)
	{
		if (doRecalc)
		{
			if (top.commonspot)
			{
				top.commonspot.lightbox.initCurrentServerDialog(currentTab);
				ResizeWindow_Meat();
			}
		}
		else
		{
			var pendingRTEs = checkRTELoadingState(top.commonspot.lightbox);
			if (pendingRTEs)
			{
				setTimeout(function(){
					ResizeWindow_Meat(doRecalc, currentTab);
				},1);
				return;
			}
			fixMinHeightAndWidth(maintable);
			if (top.commonspot)
			{
				top.commonspot.lightbox.initCurrent(maintable.offsetWidth+5, maintable.offsetHeight + 42);
				fixFooterWidth(maintable.offsetWidth,maintable.offsetHeight + 40);
			}
		}
		// to fix IE7 insanity! without this, in ie7 the maintable is not getting its gray background set.
		var mClass = maintable.className;
		if (mClass.indexOf('csMainTable') < 0)
			mClass += ' csMainTable';
		maintable.className = mClass;
	}
}

fixMinHeightAndWidth = function(maintable)
{
	var curScript;
	var minWidth = 350;
	var minHeight = 130;
	// first check if there are tabs rendered in the dialog
	try
	{
		var ele = maintable.getElementsByClassName('cs_tab_active');
		if (ele.length > 2) 
			minWidth = 550;	
	}
	catch(e){};
	var jsScripts = document.getElementsByTagName('SCRIPT');
	for (var i=0; i<jsScripts.length; i++)
	{
		curScript = jsScripts[i];
		try
		{
			if (curScript.src && (curScript.src).indexOf('calendar.js') >0)
				minHeight = 180;
		}
		catch(e){};

	}
	if (maintable.offsetHeight < minHeight)
		maintable.style.height = minHeight+'px';
	else
		maintable.style.height = '';
	if (maintable.offsetWidth < minWidth)
		maintable.style.width = minWidth+'px';
};

fixFooterWidth = function()
{
	var proxyBtnTable = document.getElementById('clsProxyButtonTable');
	var maintable = document.getElementById('MainTable');
	//debugger;
	if (proxyBtnTable && maintable && proxyBtnTable.offsetWidth > (maintable.offsetWidth+10))
	{
		maintable.style.width = proxyBtnTable.offsetWidth + 'px';
		top.commonspot.lightbox.initCurrent(proxyBtnTable.offsetWidth, maintable.offsetHeight + 40);
	}
};

setthefocus = function(){};


checkDashboardSetup = function()
{
	if (top.commonspot.clientUI && top.commonspot.dialog && top.commonspot.dialog.server)
		return true;


	doDashboardSetup();
}

doDashboardSetup = function()
{
	if (parent.window.document.getElementById("hiddenframeDiv"))
		return true;
	if (document.parentWindow)
		var curWin = document.parentWindow;
	else
		var curWin = window;
	var iframeDiv = curWin.parent.parent.document.createElement('div');
	iframeDiv.id = 'hiddenframeDiv';
	iframeDiv.style.left = '-1000px';
	iframeDiv.style.top = '-1000px';

	var iframeHTML = '<iframe src="/commonspot/dashboard/hidden_iframe.html" name="hidden_frame" id="hidden_frame" width="1" height="1" scrolling="no" frameborder="0"></iframe>';
	iframeDiv.innerHTML = iframeHTML;
	var hiddenFrame = iframeDiv.childNodes[0];
	parent.window.document.body.appendChild(iframeDiv);
	return true;
}


convertHrefToOnclick = function(doc, elemID)
{
	var newOC,existingOC,href,shown,style,isJS,itms;
	var elemID = elemID ? elemID : null;
	var doc = doc ? doc : document;
	if (elemID)
		itms = document.getElementById(elemID).getElementsByTagName('a');
	else
		itms = document.getElementsByTagName('a');
	for (var i=0; i<itms.length; i++)
	{
		elem = itms[i];
		href = elem.getAttribute('href');
		isJS = /javascript/.test(href);
		style = elem.style;
		shown = style ? style.display : '';
		// walk the links only if they have a href attrib and it is displayed
		if (href && shown!='none' && href != '#' && isJS)
		{
			newOC = href.replace(/javascript:/gi, '');
			if (newOC == ';') // handle situation where we have just javascript:; in href attribute
				newOC = '';
			existingOC = elem.getAttribute('onclick');
			// replace when newOC is not empty and not already in existingOC OR when there is no existingOC
			if ((existingOC && newOC != '' && existingOC.indexOf(newOC) == -1) || !existingOC )
				existingOC = (existingOC ? (existingOC + ';') : '') + newOC;
			elem.setAttribute('onclick', existingOC);
			elem.setAttribute('href', 'javascript:;');
			//elem.removeAttribute('href');
		}
	}
}

if (typeof(onLightboxLoad) == "undefined")
{
	/**
	* Hook that gets called by lightbox whenever the dialog gets loaded
	*/
	onLightboxLoad = function()
	{
		try{
			var rootDiv = document.getElementById('cs_commondlg')
		}catch(e){
			// $ function is not defined when there is an error.
			// in that case, just return so we can show the error msg.
			return;
		}
		convertHrefToOnclick(document);
		if (rootDiv)
		{
			// Check if we have buttons

			var outerDiv = document.getElementById('clsPushButtonsDiv');
			var tableEle = document.getElementById('clsPushButtonsTable');
			var otherBtns = top.commonspot.util.dom.getElementsByClassName('clsDialogButton', document);
			if (tableEle || otherBtns.length)
			{
				// Remove existing "proxy" buttons first
				var btnHolder = document.getElementById('clsProxyButtonHolder');
				if (btnHolder)
				{
					btnHolder.parentNode.removeChild(btnHolder);
				}

				// check if cf debug is on
				var arr = top.commonspot.util.dom.getElementsByClassName('cfdebug', document);
				// Append a new <div> that will contain the "proxy" buttons
				var dom = document.createElement('div');
				dom.id = "clsProxyButtonHolder";
				dom.innerHTML = '<table id="clsProxyButtonTable" border="0" cellspacing="2" cellpadding="0"><tr><td id="clsProxySpellCheckCell" nowrap="nowrap"></td><td id="clsProxyButtonCell" nowrap="nowrap"></td></tr></table>';
				if (arr.length > 0) 	// stick in after root div and before CF debug table
				{
					/*
						IE ver < 10 has problem with appending node before a script node. to get around it we add a div
						node around	the script tags we have after rootDiv (dlgcommon-foot.cfm) and manipulate its innerHTML
						however, non-ie browsers has problem with manipulating innerHTML so doing it ol'way
					*/
					if (top.commonspot.util.browser.ie && top.commonspot.util.browser.version < 10)
					{
						var inHTML = dom.outerHTML + rootDiv.nextSibling.innerHTML;
						rootDiv.nextSibling.innerHTML = inHTML;
					}
					else
						rootDiv.parentNode.insertBefore(dom, rootDiv.nextElementSibling);
				}
				else
					rootDiv.parentNode.appendChild(dom);

				proxySpellChecker($('clsProxySpellCheckCell'));
				proxyPushButtons($('clsProxyButtonCell'));
				// Hide the "real" buttons
				if (outerDiv)
					outerDiv.style.display='none';
				if (tableEle)
					tableEle.style.display='none';
			}
		}
	}
}

proxyPushButtons = function(targetNode)
{
	if (typeof $ == 'undefined')
		return;
	var cellNode = $('clsProxyButtonCell');
	var buttons = $$('#clsPushButtonsTable input[type="submit"]', '#clsPushButtonsTable input[type="button"]');
	var moreButtons = top.commonspot.util.dom.getElementsByClassName('clsDialogButton', document, 'INPUT');
	var addClose = 0;
	for (var i=0; i<moreButtons.length; i++)
	{
		// lame! but FF is not happy with concat arrays feature;
		buttons.push(moreButtons[i]);
	}
	if ((buttons.length == 1 && buttons[0].value == 'Help') || buttons.length == 0)
		addClose = 1;
	cleanRadioAndCheckBoxes($$('#MainTable input[type="checkbox"]', '#MainTable input[type="radio"]'));
	var doneButtons = [];
	var buttonString = [];
	for(var i=0; i<buttons.length; i++)
	{
		buttons[i].style.display = 'none';
		var buttonText = buttons[i].value.replace(/^\s+|\s+$/g, '');
		buttonString[i] = buttonText.toLowerCase();
	}
	// show prev button
	var indexButton = arrayIndexOf(buttonString,'prev');
	var proxyIndex = 1;
	if (indexButton != -1 && arrayIndexOf(doneButtons,'prev') == -1)
	{
	cellNode.appendChild(createProxyButton(buttons[indexButton],proxyIndex++));
	doneButtons.push('prev');
	}

	// show next button
	indexButton = arrayIndexOf(buttonString,'next');
	if (indexButton != -1 && arrayIndexOf(doneButtons,'next') == -1)
	{
	cellNode.appendChild(createProxyButton(buttons[indexButton],proxyIndex++));
	doneButtons.push('next');
	}
	// show all misc. buttons that are not submit and not cancel or close
	for(var i=0; i<buttons.length; i++)
	{
		buttonText = buttons[i].value.replace(/^\s+|\s+$/g, '');
		if (buttonText != 'Help' &&
				buttonText != 'Close' &&
				buttonText != 'No' &&
				buttonText != 'Cancel' &&
				buttons[i].type == 'button' &&
				arrayIndexOf(doneButtons,buttonText) == -1)
		{
			cellNode.appendChild(createProxyButton(buttons[i],proxyIndex++));
			doneButtons.push(buttonText);
		}
	}


	// show all submit buttons that are not cancel or close
	for(var i=0; i<buttons.length; i++)
	{
		buttonText = buttons[i].value.replace(/^\s+|\s+$/g, '');
		if (buttonText != 'Help' &&
					buttonText != 'Close' &&
					buttonText != 'No' &&
					buttonText != 'Cancel' &&
					buttons[i].type == 'submit' &&
					arrayIndexOf(doneButtons,buttonText) == -1)
		{
			cellNode.appendChild(createProxyButton(buttons[i],proxyIndex++));
			doneButtons.push(buttonText);
		}
	}

	// show cancel and close buttons
	for(var i=0; i<buttons.length; i++)
	{
		buttonText = buttons[i].value.replace(/^\s+|\s+$/g, '');
		if (buttonText != 'Help' && arrayIndexOf(doneButtons,buttonText) == -1)
		{
			cellNode.appendChild(createProxyButton(buttons[i],proxyIndex++));
			doneButtons.push(buttonText);
		}
	}

	if (arrayIndexOf(doneButtons, 'cancel') != -1 || arrayIndexOf(doneButtons, 'close') != -1)
		addClose = 0;

	// show close button if there are no buttons in the lighbox
	if (addClose && cellNode)
	{
		var closeNode = {
			value: 'Close',
			className: 'clsCloseButton',
			type: 'button',
			name: 'Close'
		};
		cellNode.appendChild(createProxyButton(closeNode,proxyIndex++));
	}
}

cleanRadioAndCheckBoxes = function(buttons)
{
	var cName = "";
	for (var i=0; i<buttons.length; i++)
	{
		cName = buttons[i].className;
		if (cName.indexOf('clsNoBorderInput')==-1)
		{
			buttons[i].className = cName+' clsNoBorderInput';
		}
	}
}

checkRTELoadingState = function(frame)
{
	var wn = frame.getCurrentWindow();
	var rteObjs = {};
	var key;
	var done = false;
	if (wn && typeof wn['RTEInstances'] != 'undefined')
	{
		rteObjs = wn['RTEInstances'];
		for (key in rteObjs)
		{
			// do what?
			if (rteObjs[key] == false)
				return true;
		}
	}
	else
		return false;
}
proxySpellChecker = function(targetNode)
{
	if (typeof $ == 'undefined')
		return;
	var boxNode = $('OldSpellCheckOn');
	// Proxy the node only if it's visible (it could be hidden)
	if (boxNode && (boxNode.type == 'checkbox'))
	{
		var proxyLabel = document.createElement('label');
		var proxyBox = document.createElement('input');
		proxyBox.setAttribute('id', 'SpellCheckOn');
		proxyBox.setAttribute('name', 'SpellCheckOn');
		proxyBox.setAttribute('type', 'checkbox');
		proxyBox.setAttribute('value', 1);
		proxyBox.className = 'clsNoBorderInput';
		proxyBox.onclick = function(){
			var o = $('OldSpellCheckOn');
			if (o)
				o.checked = this.checked;
		};
		proxyLabel.appendChild(proxyBox);
		proxyLabel.appendChild(document.createTextNode('Check Spelling'));
		targetNode.appendChild(proxyLabel);
		// Reflect original's status
		proxyBox.checked = boxNode.checked;
	}
}

/**
 * Helper method. Generate a proxy DOM node out of an original button
 * @param buttonNode   (node). Required. The original button DOM node
 * @return node
 */
createProxyButton = function(buttonNode,index)
{

	/*
	Buttons must be styled to look as links.
	Since this can be tricky accross browsers, we wrap a <span> around the buttons
	*/

	// Use trimmed value for text
	var buttonText = buttonNode.value.replace(/^\s+|\s+$/g, '');
	var newButtonText = buttonText;
	if (buttonText == 'OK' || buttonText == 'Finish')
		newButtonText = 'Save';

	var proxyContainer = document.createElement('span');
	proxyContainer.id = 'proxyButton' + index;
	if (buttonNode.title)
		proxyContainer.title = buttonNode.title;
	proxyContainer.className = buttonNode.className;
	if ((buttonText == 'Cancel' || buttonText == 'Close') &&
				(buttonNode.className.indexOf('clsPushButton') >= 0 || buttonNode.className.indexOf('clsCancelButton') >= 0 || buttonNode.className.indexOf('clsCloseButton') >= 0)){
	proxyContainer.className = 'cls'+buttonText+'Button';
	}

	var proxyBox = document.createElement('input');
	if (buttonNode.type == 'submit' && typeof buttonNode.click == 'function'){
	proxyBox.setAttribute('type', 'button');
	}
	else{
		proxyBox.setAttribute('type', buttonNode.type);
	}
	proxyBox.setAttribute('name', buttonNode.name);
	proxyBox.setAttribute('value', newButtonText);
	proxyBox.setAttribute('id', buttonText);

	if (newButtonText=='Cancel' || newButtonText=='Close')
	{
	proxyContainer.onclick = function()
	{
		if (typeof buttonNode.click == 'function' || typeof buttonNode.click == 'object')
		{
			buttonNode.click();
		}
		else
			top.commonspot.lightbox.closeCurrent();
	}
	}
	else
	{
		proxyContainer.onclick = function()
		{
			if (typeof buttonNode.click == 'function' || typeof buttonNode.click == 'object')
			{
				buttonNode.click();
			}
			return false;
		}
	}
	proxyBox.onmouseover = function()
	{
		this.style.textDecoration = 'underline';
		return false;
	}
	proxyBox.onmouseout = function()
	{
		this.style.textDecoration = 'none';
		return false;
	}
	proxyContainer.appendChild(proxyBox);
	return proxyContainer;
}
/**
* Helper method.    Return index of an element in an array NOT case-sensitive.
* @param _this      Required. Array
 * @param x          Required. key
* @return index
*/
arrayIndexOf = function(_this,x)
{
	for(var i=0;i<_this.length;i++)
	{
		if (_this[i].toLowerCase()==x.toLowerCase())
			return i;
	}
	return-1;
}

if (typeof(onLightboxResize) == "undefined")
{

	/**
	 * Hook that gets called by lightbox whenever the dialog gets resized
	 * @param w         (int). Required. Width
	 * @param h         (int). Required. Height
	 */
	onLightboxResize = function(w, h)
	{
		// Remove margins from the dialog's body
		document.body.style.margin = 0;
		document.body.style.padding = 0;
		var rootDiv = document.getElementById('cs_commondlg');
		if (rootDiv)
		{
			main_table = document.getElementById('MainTable');
			if (main_table && main_table.style)
			{
				if (w >= 300)
				{
					main_table.style.width = (w-35)+'px';
					rootDiv.style.width = (w-10)+'px';
				}
				main_table.style.height = (h -45) + 'px';
				main_table.style.marginTop = 0;
				rootDiv.style.marginTop = '10px';
				rootDiv.style.height = (h -37) + 'px';
			}

			// Add scrollbars to the main box
			rootDiv.style.overflow = 'auto';
		}
	}
}
;
/*
 * bring browser up to speed somewhat
 * NOTE: THESE PROTOTYPE METHODS ARE DUPLICATED IN util.js AND nondashboard-utils.js
 * 		KEEP THEM IDENTICAL
 */
if(!String.prototype.trim)
{
	String.prototype.trim = function()
	{
		var start = -1;
		var end = this.length;
		while(this.charCodeAt(--end) < 33);
		while(this.charCodeAt(++start) < 33);
		return this.slice(start, end + 1);
	};
}
if(!String.prototype.toBoolean)
{
	String.prototype.toBoolean = function()
	{
		switch(this.valueOf())
		{
			case "1":
				return true;
				break;
			case "0": case "": case "no": case "false":
			case "No": case "False": case "NO": case "FALSE":
				return false;
				break;
			default:
				return true;
		}
	};
}
if(!Array.prototype.indexOf)
{
	Array.prototype.indexOf = function(value, fromIndex)
	{
		var len = this.length;
		if(fromIndex == null)
			fromIndex = 0;
		else if(fromIndex < 0)
			fromIndex = Math.max(0, len + fromIndex);
		for(var i = fromIndex; i < len; i++)
		{
			if(this[i] === value)
				return i;
		}
		return -1;
	};
}
var EventCache=function() 
{
	var listEvents=[];
	return{
		listEvents: listEvents,
		add: function(node,sEventName,fHandler,bCapture)
		{
			listEvents.push(arguments);
		},
		
		flush: function()
		{
			var i, item;
			for(i=listEvents.length-1;i>=0;i=i-1) 
			{	
				item=listEvents[i];
				if(!item) 
					continue;
				if(item[0].removeEventListener) 
					item[0].removeEventListener(item[1],item[2],item[3]);
				var logical_type='';
				if(item[1].substring(0,2)!="on") 
				{
					logical_type=item[1];
					item[1]="on"+item[1];
				}
				else 
					logical_type=item[1].substring(2,event_name_without_on.length);
				if(typeof item[0].__eventHandlers!='undefined'&&typeof item[0].__eventHandlers[logical_type]!='undefined') 
					item[0].__eventHandlers[logical_type]=null;
				if(item[0].detachEvent) 
					item[0].detachEvent(item[1],item[2]);
				item[0][item[1]]=null;
			};
			listEvents=null;
		}
	}
}();

function flashMsg(msg, width, timeToKeep)
{
	var FLASH_MSG_ID = 'cs_flashMsg'; // id of html object that shows the msg
	var timeToKeep = typeof timeToKeep != 'undefined' ? timeToKeep : 2000;
	if(!width)
		var width = 200;
	var div = document.createElement('div');
	div.id = FLASH_MSG_ID;
	div.style.width = width + 'px';
	div.style.marginLeft = (-width / 2) + 'px'; // minus half the width, to center on pg
	div.className = 'cs_flashMsg';
	div.innerHTML = msg;
	div.onclick = close; // let user close it; probably not needed, but safe
	document.body.appendChild(div);
	setTimeout(close, timeToKeep); // kill msg after a while in case page isn't going to reload
	
	function close()
	{
		var div = document.getElementById(FLASH_MSG_ID);
		if(div)
			div.parentNode.removeChild(div);
	}
}

/* start functions used by lightbox */
function OnMouseDown(e)
{
	// IE is retarded and doesn't pass the event object
	if (e == null) 
		e = window.event; 
   if(typeof e.stopPropagation!='undefined')
      e.stopPropagation();
   else
      e.cancelBubble=true;		
	// IE uses srcElement, others use target
	var target = e.target != null ? e.target : e.srcElement;
	if (_debug)
		_debug.innerHTML = target.className == 'drag' 
		? 'draggable element clicked' 
		: 'NON-draggable element clicked';
	target = getDraggableTarget(target);
	// for IE, left click == 1
	// for Firefox, left click == 0
	if ((e.button == 1 && window.event != null || 
		e.button == 0) && target)
	{
		// grab the mouse position
		_startX = e.clientX;
		_startY = e.clientY;
		
		// grab the clicked element's position
		_offsetX = ExtractNumber(target.style.left);
		_offsetY = ExtractNumber(target.style.top);
		
		// bring the clicked element to the front while it is being dragged
		_oldZIndex = target.style.zIndex;
		target.style.zIndex = 10000;
		
		// we need to access the element in OnMouseMove
		_dragElement = target;

		// tell our code to start moving the element with the mouse
		document.onmousemove = OnMouseMove;
		
		// cancel out any text selections
		document.body.focus();
		
		// prevent text selection in IE
		document.onselectstart = function () { return false; };
		// prevent IE from trying to drag an image
		target.ondragstart = function() { return false; };
		
		// prevent text selection (except IE)
		return false;
	}
}

function OnMouseUp(e)
{
	if (_dragElement != null)
	{
		_dragElement.style.zIndex = _oldZIndex;

		// we're done with these events until the next OnMouseDown
		document.onmousemove = null;
		document.onselectstart = null;
		_dragElement.ondragstart = null;

		// this is how we know we're not dragging
		_dragElement = null;
		if (_debug)
			_debug.innerHTML = 'mouse up';
	}
}

function OnMouseMove(e)
{
	if (e == null) 
		var e = window.event; 
   if(typeof e.stopPropagation!='undefined')
      e.stopPropagation();
   else
      e.cancelBubble=true;				

	// this is the actual "drag code"
	_dragElement.style.left = (_offsetX + e.clientX - _startX) + 'px';
	_dragElement.style.top = (_offsetY + e.clientY - _startY) + 'px';
	if (_debug)
		_debug.innerHTML = '(' + _dragElement.style.left + ', ' + _dragElement.style.top + ')';	
}

function ExtractNumber(value)
{
	var n = parseInt(value);
	
	return n == null || isNaN(n) ? 0 : n;
}

function getDraggableTarget(obj)
{
	if (obj.className.indexOf('drag') >= 0)
		return obj;
	if (obj.offsetParent)
	{	
		while(obj=obj.offsetParent)
		{
			if (obj.className.indexOf('drag') >= 0)
				return obj;			
		}
	}
	return null;
}
/* END functions used by lightbox */

// this function is duplicated in browser-all.js and util.js; if you change one, change the other!
function BrowserCheck()
{
	var b = navigator.appName.toString();
	var b_ver;
	var up = navigator.platform.toString();
	var ua = navigator.userAgent.toString().toLowerCase();
	var re_opera = /Opera.([0-9\.]*)/i;
	var re_msie = /MSIE.([0-9\.]*)/i;
	var re_gecko = /gecko/i;
	// IE11 user-agent string ------ mozilla/5.0 (windows nt 6.1; wow64; trident/7.0; slcc2; .net clr 2.0.50727; rv:11.0) like gecko
	var re_msie_11 = /rv:([0-9\.]*)/i;
	// mozilla/5.0 (macintosh; u; intel mac os x 10_6_7; en-us) applewebkit/533.20.25 (khtml, like gecko) version/5.0.4 safari/533.20.27
	var re_safari = /safari\/([\d\.]*)/i;
	var re_mozilla = /firefox\/([\d\.]*)/i;
	var re_chrome = /chrome\/([\d\.]*)/i;
	var ie_documentMode = 0;
	var browserType = {};
	var ie11 = !!ua.match(/trident.*rv[ :]*11\./);
	browserType.mozilla = browserType.ie = browserType.opera = r = false;
	browserType.version = (ua.match(/.+(?:rv|it|ra|ie|me)[\/: ]([\d.]+)/) || [])[1];
	browserType.chrome = /chrome/.test(ua);
	browserType.safari = /webkit/.test(ua) && !/chrome/.test(ua);
	browserType.opera = /opera/.test(ua);
	browserType.ie = /msie/.test(ua) && !/opera/.test(ua);
	browserType.mozilla = /mozilla/.test(ua) && !/(compatible|webkit)/.test(ua) && !/trident/.test(ua);
	browserType.ie_documentMode = 0;
	if (ua.match(re_opera))
	{
	    r = ua.match(re_opera);
	    browserType.version = parseFloat(r[1]);
	}
	else if (ua.match(re_msie))
	{
	    r = ua.match(re_msie);
	    browserType.version = parseFloat(r[1]);
	    ie_documentMode = browserType.version;
	    if (browserType.version <= 7)
	    {
	        re_ver = /trident\/([\d\.]*)/i;
	        r = ua.match(re_ver);
	        // in IE compat mode, trident=4.0 (IE8), =5.0 (IE9), =6.0 (IE10) etc, i.e, version=trident+4.
	        if (r && parseFloat(r[1]) >= 4)
	        {
	            browserType.version = parseFloat(r[1]) + 4;
	            ie_documentMode = document.documentMode;
	        }
	    }
	}
	else if ((ua.match(re_msie_11) && /trident/.test(ua)) || ie11) // IE browser, version higher than 10
	{
		r = ua.match(re_msie_11);
		browserType.ie = true;
		browserType.mozilla = false;
		browserType.version = parseFloat(r[1]);
		ie_documentMode = browserType.version;
		re_ver = /trident\/([\d\.]*)/i;
		r = ua.match(re_ver);
		// in IE compat mode, trident=4.0 (IE8), =5.0 (IE9), =6.0 (IE10) etc, i.e, version=trident+4.
		if (r && parseFloat(r[1]) >= 4)
		{
		    browserType.version = parseFloat(r[1]) + 4;
		    ie_documentMode = document.documentMode;
		}
	}
	else if (browserType.safari && !browserType.chrome)
	{
	    re_ver = /version\/([\d\.]*)/i;
	    if (ua.match(re_ver))
	    {
	        r = ua.match(re_ver);
	        browserType.version = parseFloat(r[1]);
	    }
	}
	else if (browserType.chrome)
	{
	    b_ver = ua.match(re_chrome);
	    r = b_ver[1].split('.');
	    browserType.version = parseFloat(r[0]);
	}
	else if (ua.match(re_gecko))
	{
	    var re_gecko_version = /rv:\s*([0-9\.]+)/i;
	    r = ua.match(re_gecko_version);
	    browserType.version = parseFloat(r[1]);
	    if (ua.match(re_mozilla))
	    {
	        r = ua.match(re_mozilla);
	        browserType.version = parseFloat(r[1]);
	    }
	}
	else if (ua.match(re_mozilla))
	{
	    r = ua.match(re_mozilla);
	    browserType.version = parseFloat(r[1]);
	}
	browserType.windows = browserType.mac = browserType.linux = false;
	browserType.Platform = ua.match(/windows/i) ? "windows" : (ua.match(/linux/i) ? "linux" : (ua.match(/mac/i) ? "mac" : ua.match(/unix/i) ? "unix" : "unknown"));
	this[browserType.Platform] = true;
	browserType.v = browserType.version;
	browserType.valid = browserType.ie && browserType.v >= 6 || browserType.mozilla && browserType.v >= 1.4 || browserType.safari && browserType.v >= 5 || browserType.chrome && browserType.v >= 12;
	browserType.okToAuthor = (browserType.ie && browserType.v >= 8 && ie_documentMode >= 7) || browserType.mozilla && browserType.v >= 3.6 || browserType.safari && browserType.v >= 5 || browserType.chrome && browserType.v >= 12;
	browserType.ie_documentMode = ie_documentMode;
	if (browserType.safari && browserType.mac && browserType.mozilla) 
		browserType.mozilla=false;	
	return browserType;
};

function removeDuplicateParams(qParams)
{
	var nParams = '';
	var qParams = qParams.replace('&amp;', '&');
	var fLtr = qParams.substr(0,1);
	if (fLtr == '&')
		nParams = fLtr;
	else if (fLtr == '?')
	{
		nParams = fLtr;
		qParams = qParams.replace('?', '');
	}	
	var qArr = qParams.split('&');
	var cArr = '';
	for (var i=0; i<qArr.length; i++)
	{
		cArr = qArr[i].split('=');
		if (cArr[0] == '')
			continue;
		if (nParams.toLowerCase().indexOf(cArr[0].toLowerCase()) == -1)
		{
			if (cArr.length == 2)
				nParams = nParams + cArr[0] + '=' + cArr[1] + '&';
			else if (cArr.length == 1)
				nParams = nParams + cArr[0] + '=&';	
		}	
		else
			alert('Multiple instances of ' + cArr[0] + ' argument found in the URL query parameter.');
	}
	return nParams;
}
// make sure we have our namespace
// must be called AFTER code to relocate if not in dashboard, if that's used
var commonspot = window.commonspot || parent.commonspot || {};

/**
 * commonspot.util: utility package
 */
if(typeof commonspot.util == 'undefined')
{
	commonspot.util = {};
	
	commonspot.util.browser = BrowserCheck();	
	commonspot.util.removeDuplicateParams = removeDuplicateParams;
	commonspot.util.checkDashboard = function()
	{
		return (typeof(commonspot.lview) != 'undefined');
	}
	
	/**
	 * Encode string properly for html charactor
	 * @return string
	 */
	commonspot.util.encodeString = function(str)
	{	
		var regExp = /&amp;#39;|&amp;amp;|&amp;nbsp;|&lt;br \/&gt;&lt;br \/&gt;/;
		  	
		if (str && str.search(regExp) != -1)		
		{ 
			str = str.replace(/&amp;amp;/, '&amp;');
			str = str.replace(/&amp;#39;/, '&#39;');  
			str = str.replace(/&amp;nbsp;/, '&nbsp;'); 
			str = str.replace(/&lt;br \/&gt;&lt;br \/&gt;/, ' '); 		
		}  	
			 
		return str;
	};
		
	/**
	 * Escape special XML characters with the equivalent entities
	 * @return string
	 */
	commonspot.util.encodeXmlEntities = function(str)
	{
		if(str && str.search(/[&<>"]/) != -1)
		{
			str = str.replace(/&/g, '&amp;');
			str = str.replace(/</g, '&lt;');
			str = str.replace(/>/g, '&gt;');
			str = str.replace(/"/g, '&quot;');
		}
		// dmerrill 3/12/09: don't know why we do this, not xml spec
		return encodeURIComponent(str);
	};
		
	/**
	 * format a std commonspot date (yyyy-mm-dd hh:mm:ss) for display as a date only
	 * default format is yyyy-mm-dd
	 * if USFormat is true, returns it as mm/dd/yyyy
	 */
	commonspot.util.formatCSDate = function(csDateStr, USFormat)
	{
	   if(!csDateStr)
	      return;
		if(USFormat)
		{
			var aDateParts = csDateStr.split(/[- :]/);
			if(aDateParts.length < 3)
				throw("[formatCSDate(USFormat)] invalid date: " + csDateStr);
			return aDateParts[1] + "/" + aDateParts[2] + "/" + aDateParts[0];
		}
		return csDateStr.substr(0, 10);
	};
	
	/**
	 * for ea passed field in passed object, creates a new field w orig fld value converted to std date format
	 * @param row (object): object to process
	 * 		it's assumed to contain each of the fields in dateFieldsList, ea w date data
	 * @param dateFieldsList (string): comma-delimited list of fields to process
	 * @param fieldNameSuffix (string): appended to end of processed fld name to create name of formated fld
	 * 	if not passed, '_display' is used
	 * 	to overwrite orig fld w formatted version, pass ''
	 */
	commonspot.util.formatCSDateFields = function(obj, dateFieldsList, fieldNameSuffix)
	{
		if(!fieldNameSuffix)
			fieldNameSuffix = '_display';
		var aDateFlds = dateFieldsList.split(',');
		for(var i = 0; i < aDateFlds.length; i++)
			obj[aDateFlds[i] + fieldNameSuffix] = commonspot.util.formatCSDate(obj[aDateFlds[i]]);
	};
	
	
	/*
	 * @return object: returns an object with values from url hash, interpreted as query string format
	 */
	commonspot.util.getHashArgs = function()
	{
		var argStr = document.location.hash.replace(/^#+/, ''); // strip all leading #
		if (!argStr.toQueryParams)
			return null;
		var qstring = window.location.search;
		var qmPos = argStr.indexOf('?');
		var args;
		if (qmPos >= 0)
		{
			qstring = argStr.substr(qmPos);
			argStr = argStr.substr(0, qmPos);
			args = argStr.toQueryParams();
		}
		else
			args = argStr.toQueryParams();
		args.qstring = qstring;
		if (args.mode)
			args.mode = args.mode.toLowerCase();
		return args;
	};
	
	commonspot.util.getObjFieldLCase = function(obj, name)
	{
		if (name)
			return obj[name.toLowerCase()];
		else
			return null;
	};

	// return true if any item in permissionNeededList is in permissionList
	commonspot.util.hasAnyPermission = function(permissionNeededList, permissionList)
	{
		if( (!permissionNeededList) || (!permissionList) )
			return false;			
			
		aPermsNeeded = permissionNeededList.toLowerCase().split(',');
		aPermsYouHave = permissionList.toLowerCase().split(',');
		
		for(var i = 0; i < aPermsNeeded.length; i++)
		{
			if(aPermsYouHave.indexOf(aPermsNeeded[i]) != -1) 
				return true;
		}
		return false;
	};
		
	
	/*
	 * returns true if passed array or object has members
	 */
	commonspot.util.hasMembers = function(obj)
	{
		for(var f in obj)
		{
			try
			{
				if(obj.hasOwnProperty(f))
					return true;
			}
			catch(e)
			{
				return false;	
			}
		}
		return false;
	};
	
	/**
	 * Return boolean (true/false) as per the permission.
	 */	
	commonspot.util.hasPermission = function(permission, permissionList)
	{
		if( ! permissionList )
			return false;			
			
		permissionList = ',' + permissionList.toLowerCase() + ',';
		return (permissionList.indexOf(',' + permission.toLowerCase() + ',') != -1)
	};

	/*
	 * adds members of src to dest, returning dest
	 * overwrites existing members if overwrite is true
	 * ignores prototype members of either src or dest
	 * 	means it won't copy from src prototype, and it will overwrite dest prototype members
	 */
	commonspot.util.merge = function(dest, src, overwrite, lcaseDestField)
	{
		var destFld;
		for(var fld in src)
		{
			destFld = lcaseDestField ? fld.toLowerCase() : fld;
		   if(src.hasOwnProperty(fld) && (overwrite || (!dest.hasOwnProperty(destFld)) || dest[destFld] === null))
		      dest[destFld] = src[fld];
		}
		return dest;
	};
	
	/*
	 * pads passed value to a minimum of len chars; no effect if it's already that long or more
	 */
	commonspot.util.pad = function (val, len)
	{
		val = String(val);
		len = len || 2;
		while (val.length < len) val = "0" + val;
		return val;
	};
		
	/**
	 * commonspot.util.plural
	 * returns a string with passed count, a space, and count-appropriate form of noun
	 * @see \cs\devdocs\javascript-function-docs.js
	 */
	commonspot.util.plural = function(count, noun, specialPlural, specialZero)
	{
		switch(count)
		{
			case 0:
				return count + " " + (specialZero || specialPlural || (noun + "s"));
				break;
			case 1:
				return count + " " + noun;
				break;
			default:
				return count + " " + (specialPlural || (noun + "s"));
		}
	};
		
	commonspot.util.setOptions = function(dest, src)
	{
		for(var fld in src)
			dest[fld] = src[fld];
	};
							
	
	/*
	 * converts a date, or a string parsable as one, to commonspot's std yyyy-mm-dd hh:mm:ss format
	 * rtns commonspot.err.INVALID_DATE_TOKEN if not a valid date
	 */
	commonspot.util.toCSDateFormat = function(date)
	{
		date = new Date(date); // applies Date.parse if necessary
		if(isNaN(date))
			return commonspot.err.INVALID_DATE_TOKEN;
		return	date.getFullYear() + "-" +
					commonspot.util.pad((date.getMonth() + 1)) + "-" +
					commonspot.util.pad(date.getDay()) + " " +
					commonspot.util.pad(date.getHours()) + ":" +
					commonspot.util.pad(date.getMinutes()) + ":" +
					commonspot.util.pad(date.getSeconds());
	};

	/**
	 * Return true if a given object is an array
	 * @return boolean
	 * technique used in the next few functions is known as the Miller Device; see here:
	 * 	http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?p=916
	 * obj.constructor === Array and similar fails in multi-window/multi-frame environment
	 */
	commonspot.util.isArray = function(obj)
	{
		return obj && Object.prototype.toString.apply(obj) === "[object Array]";
	};
	commonspot.util.isDate = function(obj)
	{
		return obj && (Object.prototype.toString.apply(obj) === "[object Date]");
	}
	commonspot.util.isValidDate = function(obj)
	{
		return obj && commonspot.util.isDate(obj) && !(isNaN(obj));
	}
	commonspot.util.getObjectClass = function(obj)
	{
		var classStr = Object.prototype.toString.apply(obj); // "[object Array]", "[object String]", etc
		return classStr.substring(8, classStr.length - 1); // "Array", "String", etc
	};
	commonspot.util.arrayTest = function(_this, item, from)
	{
	   //return cs_utility.array.arrayIndexOf(_this,item,from)!=-1;
	   return _this.indexOf(item, from)!=-1;
	};
	
	/**
	 * given an array of objects and the name of a keyFld, returns an object...
	 * ...whose keys are the values in keyFld and whose values are the corresponding objects
	 * @param objArr (array): array of objects to examine
	 * @param keyFld (string): name of fld to look for in each object; values become keys in result object
	 */
	commonspot.util.objectArrayToObject = function(objArr, keyFld)
	{
		var i, keyValue;
		var obj = {};
		for(var i = 0; i < objArr.length; i++)
		{
			keyValue = objArr[i][keyFld];
			if(typeof keyValue != 'undefined')
				obj[keyValue] = objArr[i];
		}
		return obj;
	};
	
	/**
	 * returns a new object that's a by-value copy of passed one
	 * USAGE: foo = new commonspot.util.cloneObject(someObject);
	 */
	commonspot.util.cloneObject = function (obj)
	{
		for (i in obj)
			this[i] = obj[i];
	};
	
	/**
	 * Return a random integrer
	 * @return integer
	 */
	commonspot.util.generateRandomInt = function()
	{
		return Math.floor(Math.random() * 100000);
	};

	commonspot.util.getFileSizeHtml = function(fileSize, precision)
	{
		precision = (typeof precision === 'undefined') ? 0 : precision;
		var pos = 0;
		if (fileSize == 0)
			return '';
		while ( fileSize >= 1024 )
		{
			pos++;
			fileSize = fileSize / 1024;
		}
		return fileSize.toFixed(precision) + ' ' + commonspot.util.getFileSizeHtml.sizes[pos];
	};
	commonspot.util.getFileSizeHtml.sizes = ['bytes', 'KB', 'MB', 'GB', 'TB'];
	
	commonspot.util.calcPreviewImgProp = function(origWidth, origHeight, maxWidth, maxHeight)
	{
		var isScaled = false;
		var newW = origWidth;
		var newH = origHeight;
				
		if ((origWidth >= maxWidth) || (origHeight >= maxHeight))
		{
			var ratioW = maxWidth / origWidth;
			var ratioH = maxHeight / origHeight;
			var ratio = Math.min(ratioW,ratioH);
	
			newW = Math.max(Math.round(origWidth * ratio), 1);		 
			newH = Math.max(Math.round(origHeight * ratio), 1);				
	
			isScaled = true;
		}		
	
		var imgProp = {width: newW,
							height: newH,
							isScaled: isScaled}
								
		return imgProp;
	};
	
	/*
	 * rtns html dump of passed obj
	 */
	commonspot.util.getDumpHTML = function(obj, caption)
	{
		var html = "";
		if(obj == undefined)
			html = "Object is undefined."
		else if(obj == null)
			html = "Object is null."
		else if(typeof obj == "function")
			html = "[function]";
		else if(typeof obj !== "object" || commonspot.util.isDate(obj))
			html = obj.toString().escapeHTML();
		else if(commonspot.util.isArray(obj))
		{
			var getDumpHTML = commonspot.util.getDumpHTML;
			var len = obj.length;
			html = '<table class="dumpTable">';
			if(caption)
				html += "<caption>" + caption +"</caption>";
			for(var i = 0; i < len; i++)
				html += "<tr><td>" + i + "</td><td>" + getDumpHTML(obj[i]) + "</td></tr>";
			html += "</table>";
		}
		else // object
		{
			var getDumpHTML = commonspot.util.getDumpHTML;
			html = '<table class="dumpTable">';
			if(caption)
				html += "<caption>" + caption +"</caption>";
			for(var key in obj)
				html += "<tr><td>" + key + "</td><td>" + getDumpHTML(obj[key]) + "</td></tr>";
			html += "</table>";
		}
		return html;
	};
	
	commonspot.util.repeatString = function(str, count)
	{
		var t = "";
		for(var i = 1; i <= count; i++)
			t += str;
		return t;
	};
	
	commonspot.util.jsSafe = function(str) // escape same chars as cf's JSStringFormat function
	{
		return str.replace(/(['"\\\b\t\n\f\r])/g, function(chr){return "\\" + commonspot.util.jsSafe.chars[chr.charCodeAt(0)];})
	};
	commonspot.util.jsSafe.chars = 
	{
	     8: "b",	// backspace
	     9: "t",	// tab
	    10: "n",	// newline
	    12: "f",	// formfeed
	    13: "r",	// carriage return
	    34: '"',	// dbl quote
	    39: "'",	// single quote
	    92: "\\"	// backslash
	};
	
	// returns str with tokens in the form {key} replaced by the value of data[key]
	// if key isn't found in data, returns original token
	// key can contain only alphanumeric characters and underscores
	commonspot.util.replaceTokens = function(str, data)
	{
		return str.replace
		(
			/{(\w+)}/g,
			function(fullMatch, key) // key is portion of match inside (), ie inside {} within str
			{
				return (typeof data[key] === "undefined") ? fullMatch : data[key];
			}
		);
	};
	
	
	commonspot.util.hasContributorUI = function()
	{
		if (typeof commonspot.clientUI != 'undefined' && 
						typeof commonspot.dialog != 'undefined'  && 
						typeof commonspot.dialog.server != 'undefined' && 
						typeof commonspot.admin != 'undefined')
			return true;
		else
			return false;	
	};
	/**
	 * commonspot.util.cookie: package for cookie-related utilities
	 */
	commonspot.util.cookie = {};
		
	commonspot.util.cookie.createCookie = function(name,value,days,hours)
	{
		if (days)
		{
			var date = new Date();
			date.setTime(date.getTime() + (days*24*60*60*1000));
			var expires = "; expires=" + date.toGMTString();
		}
		else if (hours)
		{
			var date = new Date();
			date.setHours(date.getHours() + hours);
			var expires = "; expires=" + date.toGMTString();		
		}
		else 
			var expires = "";
		document.cookie = name + "=" + value + expires + "; path=/";			
	};
	
	commonspot.util.cookie.readCookie = function(name)
	{
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for (var i=0; i < ca.length; i++)
		{
			var c = ca[i];
			while (c.charAt(0) == ' ')
			{
				c = c.substring(1,c.length);
			}
			if (c.indexOf(nameEQ) == 0)
			{
				return c.substring(nameEQ.length,c.length);
			}	
		}
		return null;
	};
	
	commonspot.util.cookie.eraseCookie = function(name)
	{
		commonspot.util.cookie.createCookie(name,"",-1);
	};
	
	/**
	 * commonspot.util.dom: package for dom-related utilities
	 */
	commonspot.util.dom = {};
	
	/*
	encapsulation of dom createElement
	objType, objID, objClass, objTitle, objHTML, objParent, objOnClick, objRefBefore, objRefAfter
	*/	
	commonspot.util.dom.addToDom = function(args)
	{
		var dom = document.createElement(args.objType);
		if (args.objID)
			dom.id = args.objID;
		if (args.objTitle)
			dom.title = args.objTitle;
		if (args.objClass)
			dom.className = args.objClass;
		if (args.objHTML)
			dom.innerHTML = args.objHTML;	
		if (args.objRefBefore)
			args.objParent.insertBefore(dom, args.objRefBefore);
		else if (args.objRefAfter){} // not implemented
		else		
			args.objParent.appendChild(dom);
		if (args.objOnClick)
			commonspot.util.event.addEvent(dom, "click", args.objOnClick);
		return dom;	
	}
	/**
	 * commonspot.util.dom.getWinScrollSize: returns actual content size of given window; 
	 * @param win (object): window object. if not supplied returns value for current window
	 * @return {width, height}
	 */	
	commonspot.util.dom.getWinScrollSize = function()
	{
		var sWidth=0, sHeight=0;
		var winSize = commonspot.util.dom.getWinSize();
		var win = self;
		if (win.document.body.clientHeight)
		{
			sHeight = win.document.body.clientHeight;
			sWidth = win.document.body.clientWidth;
		}	
		else if (win.document.height)
		{
			sHeight = win.document.height;
			sWidth = win.document.width;
		}
		return {width: Math.max(sWidth,winSize.width), height: Math.max(sHeight,winSize.height)};
	};
	
	/**
	 * commonspot.util.dom.getWinSize: returns inner size of current window; from PPK
	 * @return {width, height}
	 */
	commonspot.util.dom.getWinSize = function()
	{
		var width, height;
		if (self.innerHeight) // all except Explorer
		{
			width = self.innerWidth;
			height = self.innerHeight;
		}
		else if (document.documentElement && document.documentElement.clientHeight) // Explorer 6 Strict Mode
		{
			width = document.documentElement.clientWidth;
			height = document.documentElement.clientHeight;
		}
		else if (document.body) // other Explorers
		{
			width = document.body.clientWidth;
			height = document.body.clientHeight;
		}
		return {width: width, height: height};
	};
	
	/**
	 * removes all child nodes from passed obj
	 * needed because IE won't directly set innerHTML of some tags
	 * 
	 * @param obj (object): object to remove all children from
	 */
	commonspot.util.dom.removeAllChildren = function(obj)
	{
		while(obj.firstChild)
			obj.removeChild(obj.firstChild);
	};
	
	/**
	 * finds tag w requested name further up in dom hierarchy from passed obj
	 * 
	 * @param obj (dom node): object to find an ancestor of
	 * @param tagName (string): tag name to find
	 * 	not case sensitive
	 * 	won't find body or anything above there; those are singletons w simpler ways to find them
	 * @param level (int, optional): if passed, return level'th matching ancestor, not just first one
	 */
	commonspot.util.dom.getAncestorTag = function(obj, tagName, level)
	{
		if(!obj || !obj.parentNode)
			return null;
			
		tagName = tagName.toUpperCase();
		if(typeof level == 'undefined')
			level = 1;
		
		var tag = obj.parentNode;
		var curLevel = 0;
		
		while((tag.nodeName != tagName || curLevel < level) && tag.parentNode && tag.parentNode.nodeName != 'BODY')
		{
			tag = tag.parentNode;
			if(tag.nodeName == tagName)
				curLevel++;
		}
		
		if(tag.nodeName != tagName || curLevel < level)
			tag = null;
		return tag;
	};
	
	/**
	 * returns elements w passed className inside element w passed id.
	 * homegrown because Prototype 1.5's getElementsBySelector seems broken in IE7.
	 * @param id (string): id of element to look inside
	 * @param className (string): className to look for
	 * @param tagName (string, optional): if passed, looks only at tags w this name 
	 * @param getAll (boolean, optional): if true, return array of all found elements, otherwise, return first one
	 */
	commonspot.util.dom.getChildrenByClassName = function(id, className, tagName, getAll)
	{
		var results = [];
		var classMatchRegex = new RegExp("(^|\\s)" + className + "(\\s|$)");
		var tags = document.getElementById(id).getElementsByTagName(tagName || '*');
		for(var i = 0; i < tags.length; i++)
		{
			if(tags[i].className == className || tags[i].className.match(classMatchRegex))
			{
				if(getAll)
					results.push(tags[i]);
				else
					return tags[i];
			}
		}
		// if looking for single element and found none, rtn null; w/o this, rtns an empty array
		// when geAll=true we always rtn an array
		// when it's not, rtn a dom object, or something analogous to "no dom object", and tests false if you do if(domObj)
		if((!getAll) && (results.length === 0))
			return null;
		return results;
	};
	
	
	commonspot.util.dom.getElementsByClassName = function(searchClass,node,tag) 
	{
		if ( node == null )
			node = document;
		if ( tag == null )
			tag = '*';
		var classElements = new Array();
		try
		{
			classElements = node.getElementsByClassName(searchClass);
		}
		catch (e)
		{
			var els = node.getElementsByTagName(tag);
			var elsLen = els.length;
			var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
			classElements = new Array();
			for (i = 0, j = 0; i < elsLen; i++) 
			{
				if ( pattern.test(els[i].className) ) 
				{
				        classElements[j] = els[i];
				        j++;
				}
			}
		}
		return classElements;
	};
	
	/*
	* get all editable fields of the form
	*/
	commonspot.util.dom.findAllFields = function(iform,includeHidden) {	
		var arr = [];
		var elements = iform.elements;	
		var element;
		var omitList = 'button,submit,reset';
		var includeHidden = (typeof includeHidden != 'undefined') ? includeHidden : 1;
		if (includeHidden != 1)
			omitList += ',hidden';
		for (var i=0; i<elements.length; i++)
		{
			element = elements[i];
			// get rid of bad apples first
			if((omitList).indexOf(element.type)>=0)
				continue;
			if (element.disabled || element.readOnly)
				continue;
			arr.push(element);		
		}

		return arr;
	};

	/*
	* activate all editable fields of the form
	*/	
	commonspot.util.dom.activateAllFields = function(iform) {	
		var elements = commonspot.util.dom.findAllFields(iform);
		var curFld;

		for (var i=0; i< elements.length; i++)
		{
			try
			{
				curFld = eval(iform + '.' + elements[i]);
				if (curFld)
				{
					if (curFld.activate)
						curFld.activate();
					else
						curFld.focus();	
				}
			}
			catch (ex) {}	
		}
	};
	
	/*
	* Finds the first editable, non-disabled, non-hidden form field excluding buttons to set focus.
	* Takes a form as single argument. 
	* This is an enhanced version of prototype's "findFirstElement" function
	*/
	commonspot.util.dom.findFirstEditableField = function(iform) {
		var firstByIndex = null;

		var elements = commonspot.util.dom.findAllFields(iform);
		try
		{
			if (elements.findAll)
			{
				firstByIndex = elements.findAll(function(element) 
				{
				  return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
				}).sortBy(function(element) { return element.tabIndex }).first();
			}
		}
		catch(e){}
		return firstByIndex ? firstByIndex : arr[0];
  	};
		
	/**
	 * commonspot.util.css: package for event-related utilities 
	 * we only need this addEvent function so adding it here instead of importing event package of prototype
	 */	

	
	commonspot.util.event = {};
	
	/**
	*	Irons out the IE and FF differences. Ideally we should use W3C model addEventListener,
	*	ie, when IE agrees with it
	*/
	commonspot.util.event.addEvent = function( dObj, type, fn ) 
	{
		if (dObj.addEventListener) 
		{
			dObj.addEventListener( type, fn, false );
			//EventCache.add(dObj, type, fn, 1);
		}
		else if (dObj.attachEvent) 
		{
			dObj["e"+type+fn] = fn;
			dObj[type+fn] = function() 
			{ 
				dObj["e"+type+fn]( window.event ); 
			}
			dObj.attachEvent( "on"+type, dObj[type+fn] );
			EventCache.add(dObj, type, fn, 1);
		}
		else 
		{
			dObj["on"+type] = dObj["e"+type+fn];
		}
	};
	
	/**
	 * commonspot.util.css: package for css-related utilities
	 */
	commonspot.util.css = {};

	commonspot.util.css.addRemoveClassNameByIDs = function(objIDsList, className, add, contextWindow)
	{
		contextWindow = contextWindow || top.commonspot.lightbox.getCurrentWindow();
		var objIDs = objIDsList.split(",");
		var objs = contextWindow.$.apply(contextWindow, objIDs);
		if(objs)
		{
			if(objs.nodeName) // single element
				objs = [objs];
			objs.each(function(elem, index)
			{
				if(!elem)
					throw new Error("[addRemoveClassNameByIDs] Element with ID '" + objIDs[index] + "' can't be found.");
				else if(add)
					elem.addClassName(className);
				else
					elem.removeClassName(className);
			});
		}
		else // oops, bad objIDsList
			throw new Error("[addRemoveClassNameByIDs] Unable to find objects with the following IDs: " + objIDsList);
	};
		
		
	/**
	 * commonspot.util.css.showHideCSSClass: shows or hides a css class
	 */
	commonspot.util.css.showHideCSSClass = function(show, stylesheetID, targetClass)
	{
		var display = show ? '' : 'none';
		commonspot.util.css.setStyleRuleProperty(stylesheetID, targetClass, 'display', display);
	};
	
	/**
	*
	*/
	commonspot.util.css.setHideForMenusForAllFrames = function(stylesheetID, targetClass, propertyName, value, win)
	{
		var cWin;
		var win = win ? win : window;
		var arrayWindows = [];
		var iFrames = win.document.getElementsByTagName('iframe');
		for (var i =0; i<iFrames.length; i++)
		{
			cWin = iFrames[i].contentWindow;
			try
			{
				if (cWin && cWin.document)
					arrayWindows[i] = cWin;
			}
			catch(e){};		
		}
		
		if (win.document)
			arrayWindows[iFrames.length] = win;
		for (i=0; i<arrayWindows.length; i++)
		{	
			commonspot.util.css.setStyleRuleProperty(stylesheetID, targetClass, propertyName, value, arrayWindows[i]);
		}	
	};	
	
	

	
	/**
	 * commonspot.util.css.setStyleRuleProperty: sets a requested property of a stylesheet class
	 */
	commonspot.util.css.setStyleRuleProperty = function(stylesheetID, targetClass, propertyName, value, win)
	{	
	 	// note that propertyNames need to use their js-style names, ie, 'whiteSpace', not 'white-space'
		var cssRules, ruleIndex;
		var doc = win ? win.document : document;
		var ss = doc.getElementById(stylesheetID);
		if(!ss)
			return;
		if(!ss.sheet) // IE
		{
			ss = doc.styleSheets[stylesheetID];
			cssRules = doc.styleSheets[stylesheetID].rules;
		}
		else // Firefox
		{
			cssRules = ss.sheet.cssRules;
		}
		ruleIndex = getCSSRuleIndex(cssRules, '.' + targetClass);
		if(ruleIndex != null)
		{
			cssRules[ruleIndex].style[propertyName] = value;
		}
		return;
	
		function getCSSRuleIndex(cssRules, selectorText)
		{
			for(var i = 0; i < cssRules.length; i++)
			{
				if(cssRules[i].selectorText == selectorText)
				{
					return i;
				}
			}
			return null;
		}
	};
	
	commonspot.util.css.hideForMenus = function(hide) 
	{
		var prop=hide ? 'hidden' : 'visible';
		commonspot.util.css.setStyleRuleProperty('cs_maincss','cpHideForMenus','visibility',prop);
		commonspot.util.css.setStyleRuleProperty('cs_maincss','cpMenuSafe','visibility',prop);
	};
	
	/*
	 * shows or hides any number of passed elements, passed as objects or as IDs
	 * elements argument can be:
	 * 	- an elementID string, comma delimited for multiple
	 * 	- an object containing html elements or strings
	 *		- an array containing html elements or string elementIDs
	 * note:
	 * 	showHideElements works by modifying inline style
	 * 	showHideElementsUsingCSSClass does the same thing by adding or removing a css class; 
	 * 		it's a better choice for table rows
	 * 	copies of these functions in util.js work on objects in the top frame, regardless of where they're called from
	 * 	copies of them in nondashboard-util.js work on local window
	 */
	commonspot.util.css.showHideElements = function(show, elements, dspType)
	{
   	if (!dspType) 
   		dspType = 'block';
   	var display = show ? dspType : 'none';
   	var targets;
   	if (typeof elements == 'string') 
   		targets = elements.split(',');
   	else 
   		targets = elements;
	   targets.each(function(elem)
		{
			$(elem).style.display = display;
		});
	};
	
	// see comments above for showHideElements
	commonspot.util.css.showHideElementsUsingCSSClass = function(show, elements)
	{
		var targets = (typeof elements == 'string') ? elements.split(',') : elements;
		if(typeof targets !== "array")
		{
			targets.each(function(elem)
			{
				if(show)
					$(elem).removeClassName('showHideElements_hide');
				else
					$(elem).addClassName('showHideElements_hide');
			});
		}
	};

	
	/*
	 * disables any number of passed elements, passed as objects or as IDs
	 * 	does visual change w css class 'disabled'; set that up to look right for the look of each kind of item 
	 *		does actual disabling by stashing item's onclick in onclickDisabled custom property, nulling onclick
	 *		also sets item's disabled property
	 *			if neither of those to methods applies (disabled parent item etc), code will need to check some other way
	 */
	commonspot.util.css.enableDisableElements = function(enable, elements)
	{
		if(enable)
			elements.each(function(elem)
				{
					elem.removeClassName('disabled');
					elem.onclick = elem.onclickDisabled ? elem.onclickDisabled : elem.onclick;
	            elem.onmouseover = elem.onmouseoverDisabled ? elem.onmouseoverDisabled : elem.onmouseover;
					elem.disabled = false;
				});
		else
			elements.each(function(elem)
				{
					elem.addClassName('disabled');
					elem.onclickDisabled = elem.onclick ? elem.onclick : elem.onclickDisabled;
	            elem.onmouseoverDisabled = elem.onmouseover ? elem.onmouseover : elem.onmouseoverDisabled;
					elem.onclick = null;
	            elem.onmouseover = null;
					elem.disabled = true;
				});
	};
	
	
	commonspot.util.css.showFromMenuFields = function(visibleMenuClassList, fieldsList, dspType)
	{
	   if(!dspType)
	      dspType = 'block';
		var fld, show, selector;
		var aFields = fieldsList.split(',');
	   var aData = visibleMenuClassList.split(',');
	
		for(var i = 0; i < aFields.length; i++)
		{
			fld = aFields[i];
	      
	      show = commonspot.util.arrayTest(aData,fld,0) ? 1 : 0;
			
			selector = '.cs_' + fld + '_hide';
			commonspot.util.css.showHideElements(show, $$(selector), dspType)
		} 
	};
	
	commonspot.util.css.enableFromMenuFields = function(enabledMenuClassList, fieldsList, dspType)
	{
	   if(!dspType)
	      dspType = 'block';
		var fld, enable, selector;
		var aFields = fieldsList.split(',');
	   var aData = enabledMenuClassList.split(',');
		for(var i = 0; i < aFields.length; i++)
		{
			fld = aFields[i];
	      
	      enable = commonspot.util.arrayTest(aData,fld,0) ? 1 : 0;
			
			selector = '.cs_' + fld + '_disable';
			commonspot.util.css.enableDisableElements(enable, $$(selector))
		} 
		

	};
	
	commonspot.util.css.removeClass = function(el, className) 
	{
		if (!(el && el.className)) 
		{
			return;
		}
		var cls = el.className.split(" ");
		var ar = new Array();
		for (var i = cls.length; i > 0;) 
		{
			if (cls[--i] != className) 
			{
				ar[ar.length] = cls[i];
			}
		}
		el.className = ar.join(" ");
	};
	
	commonspot.util.css.addClass = function(el, className) 
	{
		commonspot.util.css.removeClass(el, className);
		el.className += " " + className;
	};	
	
	/**
	 * display effects package
	 */
	commonspot.util.effects = {};
	
	/**
	 * commonspot.util.effects.blindLeft: like scriptaculous BlindUp, but to left
	 */
	commonspot.util.effects.blindLeft = function(element) {
	  element = $(element);
	  element.makeClipping();
	  return new Effect.Scale(element, 0,
	    Object.extend({ scaleContent: false, 
	      scaleX: true,
	      scaleY: false,
	      restoreAfterFinish: true,
	      afterFinishInternal: function(effect) {
	        effect.element.hide().undoClipping();
	      } 
	    }, arguments[1] || {})
	  );
	};
	
	/**
	 * commonspot.util.effects.blindRight: like scriptaculous BlindDown, but from left
	 */
	commonspot.util.effects.blindRight = function(element) {
	  element = $(element);
	  var elementDimensions = element.getDimensions();
	  return new Effect.Scale(element, 100, Object.extend({ 
	    scaleContent: false, 
	    scaleX: true,
	    scaleY: false,
	    scaleFrom: 0,
	    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
	    restoreAfterFinish: true,
	    afterSetup: function(effect) {
	      effect.element.makeClipping().setStyle({width: '0px'}).show(); 
	    },  
	    afterFinishInternal: function(effect) {
	      effect.element.undoClipping();
	    }
	  }, arguments[1] || {}));
	};
	
	
	/**
	 * commonspot.util.menus: package for operating menus
	 */
	commonspot.util.menus = {};
	
	/*
	 * checks or unchecks passed menu item
	 * requires css class 'checked', with check image as background
	 * item should have class 'checkableMenuItem' applied always, for correct spacing
	 */
	commonspot.util.menus.checkItem = function(checked, item)
	{
		var element = $(item);
		if(!element)
			{}
		else if(checked)
			element.addClassName('checkedMenuItem');
		else
			element.removeClassName('checkedMenuItem');
	};
	

	
	/**
	 * change StyleRule.
	 * Currently the property is hardcoded for display:block.
	 * We have to make it dynamic . so that it can set any property.
	 */ 
	commonspot.util.css.changeStyleRule = function(document, sheetTitle, className, propertyName, value)
	{
		var rules = commonspot.util.css.getStyleSheetByTitle(document, sheetTitle).rules; 
		
		for (i=0; i< rules.length; i++)
		{      
			if (rules[i].selectorText.toLowerCase() == className.toLowerCase())
			{ 	
				rules[i].style.display = value; 
				break; 
			} 
		}  
	};
	 
	/**
	 * Get Stylesheet By Title.
	 */ 
	commonspot.util.css.getStyleSheetByTitle = function(doc, sheetTitle)
	{ 	
		var sheet = null;
		var rules = null;
		var thisTitle = null;
		
		if (doc.styleSheets.length > 0)
		{
			for (i = 0; i< doc.styleSheets.length; i++)
			{
				thisTitle = doc.styleSheets[i].title ? doc.styleSheets[i].title : null;
				if ( thisTitle && thisTitle.toLowerCase()  == sheetTitle)
				{
					sheet = doc.styleSheets[i];
					rules = sheet.cssRules? sheet.cssRules: sheet.rules;
					break; 
				}			 
			}  	
		}
		
		return {sheet: sheet, rules: rules};
	};

	
	/*
	 * xml utilities
	 */
	commonspot.util.xml = {};
	
	/**
	 * Serialize object's properties into XML tags
	 * @param obj (any type ex function I think) required
	 * @param nodeName (string) optional
	 * 	if not passed, defaults to 'struct' for structs, and 'array' for arrays
	 * 	for other types, no root node is rendered unless nodeName is passed, in which case it's used
	 * array containers have a 'class="array"' attribute to tell the server side that it's an array
	 * empty structs have a 'class="struct"' attribute for the same reason
	 * array item nodes are always <item> tags
	 * array example:
	 * 	<foo class="array"><item>hello</item><item>world</item></foo>
	 * @return an XML string
	 */
	 /*
		test code:
var UNDEFINED;
tests =
[
	"asdf & <qwer>",
	new Date(),
	new Date("not a valid date"),
	{a:1,b:2},
	{a:1,b:2,c:{aa:11,bb:22,cc:{aaa:111,bbb:222}}},
	[1,2],
	[1,2,"asdf & <qwer>",{aa:11,bb:22}],
	[1,2,[33,44,[555,666]]],
	{a:1,b:2,c:[33,44,[555,666,{aa:77,bb:88,cc:[1,2]}]]},
	{a:1,b:'foo',c:'',d:[],e:{}},
	["one element array"],
	{a:1,b:2,c:["one element array"]},
	function(){},
	{a:1,b:2,c:function(){}},
	UNDEFINED,
	null,
	{lastName: UNDEFINED, firstName: null, birthday: new Date('not a valid date')}
];
for(var i = 0; i < tests.length; i++)
{
	console.log(i, "TEST OBJ:", tests[i]);
	console.log(i, commonspot.util.xml.objectToXml(tests[i]));
	console.log(i, commonspot.util.xml.objectToXml(tests[i], "data"));
}
commonspot.util.xml.objectToXml(x);
	 */
	
	commonspot.util.xml.objectToXml = function(obj, nodeName)
	{
		var xml = '';
		var _nodeName = nodeName;
		
		var type = typeof obj;
		if(obj === undefined)
			type = 'undefined';
		else if(obj == null)
			type = 'null';
		else if(type !== 'object')
			{}
		else if(commonspot.util.isArray(obj))
			type = 'array';
		else if(commonspot.util.isDate(obj))
			type = 'date';

		switch (type)
		{
			case 'number':
			case 'boolean':
				xml = obj;
				break;
				
			case 'string':
				xml = commonspot.util.xml.encodeEntities(obj);
				break;
			
			case 'date':
				if(isNaN(obj))
				{
					xml = commonspot.err.INVALID_DATE_TOKEN;
					nodeClass = 'exception';
				}
				else
				{
					xml = commonspot.util.toCSDateFormat(obj);
					if(xml === commonspot.err.INVALID_DATE_TOKEN)
						nodeClass = 'exception';
				}
				break;
			
			case 'array':
				_nodeName = _nodeName ? _nodeName : 'array';
				var nodeClass = 'array';
				var objectToXml = commonspot.util.xml.objectToXml; // local, will bang on it
				var len = obj.length;
				for(var i = 0; i < len; i++)
					xml += objectToXml(obj[i], 'item');
				break;
				
			case 'object':
				_nodeName = _nodeName ? _nodeName : 'struct';
				nodeClass = 'struct';
				var objectToXml = commonspot.util.xml.objectToXml; // local, will bang on it
				for(var key in obj)
				{
					xml += objectToXml(obj[key], key);
					nodeClass = ''; // dont' need to put a class on it if it has children
				}
				break;
			
			case 'null':
				xml = commonspot.err.NULL_VALUE_TOKEN;
				nodeClass = 'exception';
				break;
			
			case 'undefined':
				xml = commonspot.err.UNDEFINED_VALUE_TOKEN;
				nodeClass = 'exception';
				break;
				
			default:
				xml = commonspot.err.UNSUPPORTED_TYPE_TOKEN.replace('</', ': ' + typeof obj + '</');
				nodeClass = 'exception';
		}

		if(_nodeName)
			xml = '<' + _nodeName + (nodeClass ? ' class="' + nodeClass + '"' : '') + '>' + xml + '</' + _nodeName + '>';
		return xml;
	};
	
	/**
	 * returns a javascript object analguous to a passed xml node
	 * @param node (xml node): node to process
	 * @param skip (string || object):
	 * 	can be a comma delimited list of dot-path items to omit, ie, "item.data,item.status.data.cmd"
	 * 		no extra whitespace!!!
	 * 	can also be a struct w those dot-path items as keys and any value that evals as true in a boolean test
	 * 	NOT xpath etc, ie, no wildcards, just simple exact match to passed skip paths
	 * 	this is recursive, and passed string gets converted to a more efficient struct, which then gets passed on
	 * @param path (string || null):
	 * 	DO NOT PASS THIS. calls itself recursively, passing this internally to support @param skip
	 * @return (object): js object representing pass xml node
	 * 
	 * somewhat specialized for commonspot use
	 * 	doesn't create or examine attributes, with one exception:
	 * 	attribute 'class' is used to know if a container is an array, but not applied to result
	 */
	/* test code
xml = '<s><a>1</a><b>2</b><c class="array"><item>11</item><item>22 &quot; &apos; &lt; &gt; &amp; &amp;amp; &amp;amp;amp;</item><item></item><item class="array"></item><item class="struct"></item></c></s>';
xmlDoc = tmt.xml.stringToDOM(xml);
commonspot.util.xml.nodeToObject(xmlDoc);
*/
	
	commonspot.util.xml.nodeToObject = function(node, skip, path)
	{
		if(!node)
			return null;
			
		if(!skip)
			skip = {};
		else if(typeof skip === "string")
		{	// passed value is a string, convert to struct for efficient existance testing
			var aSkip = skip.split(",");
			skip = {};
			for(var i = 0; i < aSkip.length; i++)
			   skip[aSkip[i]] = true;
		}
		
		// if no path, make it "", and if it's not "", put a "." on end
		path = path || "";
		path = (path === "") ? path : (path + ".");
	
		var obj = {};
		var child, typeClass, isArray, isStruct, hasChildNodes, tagName, childObj, childPath, nodeAtrs, dataType, csItemKey;
	
		nodeAtrs = commonspot.util.xml.getNodeAttributes(node);
		if(commonspot.util.xml.nodeHasValue(node)) // node has a value, use it
		{
			dataType = (nodeAtrs && nodeAtrs["type"]) ? nodeAtrs["type"].toLowerCase() : null; // we honor 'type' attribute
			try
			{
				child = node.firstChild;
				switch(child.nodeType)
				{
					case 3: // TEXT_NODE
					case 4: // CDATA_SECTION_NODE
						obj = child.data;
						if(dataType === "bool")
							obj = obj.toBoolean();
						else if(dataType === "int")
						{
							obj = parseInt(obj);
							obj = isNaN(obj) ? 0 : obj;
						}
						/* dmerrill 9/4/09: works, not used, yet, maybe never
						else if(dataType === "float")
						{
							obj = parseFloat(obj);
							obj = isNaN(obj) ? 0 : obj;
						}*/
						else if(child.nodeType == 3) // TEXT_NODE
							obj = commonspot.util.xml.encodeEntities(obj);
						break;
				}
			} catch (e) { alert("commonspot.util.xml.nodeToObject() exception caught: " + e); }
		}
		else // no value
		{
			hasChildNodes = (node.childNodes && node.childNodes.length > 0);
			isArray = isStruct = false;
			if(nodeAtrs)
			{
				isArray = (nodeAtrs["class"] === "array");
				isStruct = (nodeAtrs["class"] === "struct");
			}
			if(!(isArray || isStruct))
				isStruct = hasChildNodes; // it's a struct if it isn't an array and has child nodes
			obj = isArray ? [] : isStruct ? {} : "";
			
			if(!hasChildNodes) // no value, no children
				return obj;
			
			child = node.firstChild;
			while(child)
			{
				tagName = child.nodeName;
				if(tagName === 'cs_item')
				{
					csItemKey = commonspot.util.xml.getNodeAttribute(child, 'key');
					tagName = csItemKey || tagName;
				}
				childPath = path + tagName;
				if(child.nodeType == 1 && !skip[childPath]) // Node.ELEMENT_NODE and not skipped path
				{
					childObj = commonspot.util.xml.nodeToObject(child, skip, childPath);
					if(isArray)
						obj.push(childObj);
					else
						obj[tagName] = childObj;
				}
				child = child.nextSibling;
			}
		}
		return obj;
	};
	
	commonspot.util.xml.getNodeAttribute = function(node, attributeName)
	{
		if((!node.attributes) || node.attributes.length === 0)
			return null;
		attributeName = attributeName ? attributeName.toLowerCase() : null;
		for(var i = 0; i < node.attributes.length; i++)
		{
			if(node.attributes[i].name && (node.attributes[i].name.toLowerCase() == attributeName))
				return node.attributes[i].value;
		}
		return null;
	};
	
	commonspot.util.xml.getNodeAttributes = function(node)
	{
		if((!node.attributes) || node.attributes.length === 0)
			return null;
		var atrs = node.attributes;
		var result = {};
		for(var i = 0; i < atrs.length; i++)
		{
			if (atrs[i].name)
				result[atrs[i].name.toLowerCase()] = atrs[i].value;
		}	
		return result;
	};
		
	commonspot.util.xml.nodeHasValue = function(node)
	{
		if (node)
		{
			var child = node.firstChild;
			// 3 = Node.TEXT_NODE, 4 = CDATA_SECTION_NODE
			if (child && child.nextSibling == null && (child.nodeType == 3 || child.nodeType == 4))
				return true;
		}
		return false;
	};
	
	/**
	 * Unescapes special chars that the commonspot serializer escapes
	 * @return string
	 */
	commonspot.util.xml.decodeEntities = function(str)
	{
		if(str && (str.length >= 4) && str.search(/&lt;|&gt;|&quot;|&amp;/) != -1)
		{
			str = str.replace(/&lt;/gi, '<');
			str = str.replace(/&gt;/gi, '>');
			str = str.replace(/&quot;/gi, '"');
			str = str.replace(/&amp;/gi, '&');
		}
		return str;
	};
	
	commonspot.util.xml.encodeEntities = function(str)
	{
		if (str && str.search(/[&<>"]/) != -1)
		{
			str = str.replace(/&/g, '&amp;');
			str = str.replace(/</g, '&lt;');
			str = str.replace(/>/g, '&gt;');
			str = str.replace(/"/g, '&quot;');
		}
		return str;
	};
	
} // End: commonspot.util



/*
 * Error managment tools
 */
if(!commonspot.err) // commonspot.err not built yet
{
	// NAMESPACE
	commonspot.err = {};
	
	// CONSTANTS
	commonspot.err.COMMAND_REFUSAL_ERROR_CODE = 409;
	commonspot.err.AUTHORING_DISABLED_ERROR_CODE = 503;
	commonspot.err.INTERNAL_ERROR_CODE = 560;
	
	commonspot.err.INCOMPLETE_RETURN_VALUE_EXCEPTION = 'CSIncompleteReturnValueException';
	
	commonspot.err.HTTP_ERROR_MSG = 'Failed to get command response, server reported a communication error.';
	commonspot.err.FATAL_COMMAND_COLLECTION_ERROR_MSG = 'We\'re sorry, an error has occurred.';
	commonspot.err.EMPTY_COLLECTION_MSG = 'The command collection is empty and cannot be sent.';
	commonspot.err.EMPTY_RESPONSE_MSG = 'The server response is empty and cannot be processed.';
	commonspot.err.COMMAND_HANDLER_ERROR_MSG_START = 'JavaScript error in command response handler.';
	commonspot.err.UNMAPPED_FIELD_ERROR_MSG_START = '';
	commonspot.err.MISSING_DATASET_ERROR_MSG = 'Unable to locate dataset';
	commonspot.err.REQUIRED_MSG = "This field is required.";
	
	commonspot.err.MAPPED_FIELD_ERROR_MSGS_HEADER = 'Please correct the following:';
	commonspot.err.INTERNAL_ERROR_MSGS_HEADER = 'We\'re sorry, an internal error has occurred.';
	
	commonspot.err.FIELD_ERROR_CSS_CLASS = 'CommonSpotFieldError';
	commonspot.err.INVALID_VALUE_PREFIX = "{!INVALID_VALUE_PREFIX!}";
	
	commonspot.err.NULL_VALUE_TOKEN = '<message>Attempt to pass a null value.</message>';
	commonspot.err.UNDEFINED_VALUE_TOKEN = '<message>Attempt to pass an undefined value.</message>';
	commonspot.err.UNSUPPORTED_TYPE_TOKEN = '<message>Attempt to pass an unsupported type.</message>';
	commonspot.err.INVALID_DATE_TOKEN = '<message>Attempt to pass an invalid date.</message>';
	
	// STATIC METHODS
	
	/*
	 * rtns passed msg w INVALID_VALUE_PREFIX prepended
	 * point is that it's recognized by ErrorCollection.checkFieldValue as an invalid value
	 * for an example, see /dashboard/dialogs/tools/js/advanced-search.js:
	 * 	getOwner() rtns a msg built w commonspot.err.invalidMsg() if it's invalid
	 * 	collectFormArgs() creates a new commonspot.err.ErrorCollection
	 * 		then checks each collected value with the collection's checkFieldValue() method
	 * 		it then calls the collection's displayErrors() method to show them, and bails if that rtns true (were rrs)
	 */
	commonspot.err.invalidMsg = function(msg)
	{
		return commonspot.err.INVALID_VALUE_PREFIX + msg;
	};
		
	/*
	 * clears field error styling off all fields that might get it if they fail
	 * relevant fields are ones whose highlightIDs are in passed fieldErrorMap or are values in errorCodeMap
	 * always operates on topmost lightbox window, regardless of where it's called from
	 */
	commonspot.err.clearFieldErrorDisplay = function(fieldErrorMap, errorCodeMap, fieldErrorContext)
	{
		var contextWindow = commonspot.err.getFieldErrorContextWindow(fieldErrorContext);
		var highlightIDs;
		for(var fld in fieldErrorMap)
		{
			highlightIDs = fieldErrorMap[fld].highlightIDs;
			if(highlightIDs)
				commonspot.util.css.addRemoveClassNameByIDs(highlightIDs, commonspot.err.FIELD_ERROR_CSS_CLASS, false, contextWindow);
		}
		for(var code in errorCodeMap)
		{
			highlightIDs = errorCodeMap[code].highlightIDs;
			if(highlightIDs) // should exist, friendlyName and highlightIDs are reason for map to exist
				commonspot.util.css.addRemoveClassNameByIDs(highlightIDs, commonspot.err.FIELD_ERROR_CSS_CLASS, false, contextWindow);
		}
	};
	
	commonspot.err.getFieldErrorContextWindow = function(fieldErrorContext)
	{
		var contextWindow;
		switch(fieldErrorContext) // may need more cases in here some day
		{
			case 'admin':
				contextWindow = commonspot.lightbox.getAdminWindow();
				break;
			default:
				contextWindow = top.commonspot.lightbox.getCurrentWindow();
		}
				
		return contextWindow;
	};
	
	// CLASSES
	
	/*
	 * ErrorCollection class, holds and displays error objects
	 */
	commonspot.err.ErrorCollection = function ()
	{
		this.errors = [];
		return this;
	};
	
	/*
	 * adds passed errorObject to this collection
	 * object must support render() method
	 * 	TODO: explain that more
	 */
	commonspot.err.ErrorCollection.prototype.addError = function(errorObject)
	{
		this.errors.push(errorObject);
	};
	
	/**
	 * checks passed value, if it starts w INVALID_PREFIX, it's an error, and rest of it is error msg
	 * 	so, add corresponding FieldError object to this ErrorCollection, and rtn true
	 * otherwise, it's not an error, clear its error appearance, and rtn false
	 * can also validate the value here, but mostly we validate on the server side, so in general, don't
	 * 
	 * @param value (any) required: value to check
	 * @param friendlyName (string) optional: name to call it in user alerts
	 * @param highlightID (string) optional: id of dom element to hilight if invalid
	 * @param validator (string or function) optional:
	 * 	if passed, it's used to process the value first
	 * 	can be the name of a std validator, in commonspot.err.validators namespace...
	 * 		...or a reference to (not the name of) a custom function 
	 * 	validator functions should return passed value if it's valid, else commonspot.err.invalidMsg("Some message")
	 */
	commonspot.err.ErrorCollection.prototype.checkFieldValue = function(value, friendlyName, highlightID, validator)
	{
		if(typeof validator === "string")
			validator = commonspot.err.validators[validator];
		if(typeof validator === "function")
			value = validator(value);
			
		var lightboxWindow = top.commonspot.lightbox.getCurrentWindow();
		if((typeof value === "string") && (value.substr(0, commonspot.err.INVALID_VALUE_PREFIX.length) == commonspot.err.INVALID_VALUE_PREFIX))
		{
			if(highlightID && highlightID != "")
				lightboxWindow.$(highlightID).addClassName(commonspot.err.FIELD_ERROR_CSS_CLASS);
			var msg = value.substr(commonspot.err.INVALID_VALUE_PREFIX.length);
			var fieldError = new commonspot.err.FieldError(msg, friendlyName, highlightID);
			this.addError(fieldError);
			return true;
		}
		else if(highlightID && highlightID != "")
		{
			lightboxWindow.$(highlightID).removeClassName(commonspot.err.FIELD_ERROR_CSS_CLASS);
			return false;
		}
	};
	
	/*
	 * if collection contains errors, displays them and rtns true, else rtns false
	 * TODO: explain more about responsibilities of objects in its error collection, and how instances of them get created
	 */
	commonspot.err.ErrorCollection.prototype.displayErrors = function(fieldErrorContext)
	{
		if(this.errors.length > 0)
		{
			var contextWindow = fieldErrorContext
					? commonspot.err.getFieldErrorContextWindow(fieldErrorContext)
					: top.commonspot.lightbox.getCurrentWindow();
			var fieldMsgs = "";
			var userMsgs = "";
			var internalMsgs = "";
			var msgs;
			for(var i = 0; i < this.errors.length; i++)
			{
				msgs = this.errors[i].render(contextWindow);
				if(msgs.field && msgs.field !== "")
					fieldMsgs += msgs.field;
				if(msgs.user && msgs.user !== "")
					userMsgs += msgs.user;
				if(msgs.internal && msgs.internal !== "")
					internalMsgs += msgs.internal;
			}
			var msg = "";
			if(userMsgs !== "")
				msg += userMsgs;
			if(fieldMsgs !== "")
				msg += "<h2>" + commonspot.err.MAPPED_FIELD_ERROR_MSGS_HEADER + "</h2><dl>" + fieldMsgs + "</dl>";
			if(internalMsgs !== "")
				msg += "<h2>" + commonspot.err.INTERNAL_ERROR_MSGS_HEADER + "</h2><dl>" + internalMsgs + "</dl>";
			commonspot.dialog.client.alert(msg);
		}
		return (this.errors.length > 0); // boolean == hasErrors
	};
	
	
	/*
	 * Helper function.  Checks if the passed value is empty. If so sets an invalidMsg and checks the field Value
	 */
	commonspot.err.ErrorCollection.prototype.setErrorIfEmpty = function(value, friendlyName, highlightID, msg)
	{
		if(value == "")
		{
			if(typeof(msg) == "undefined")
				msg = commonspot.err.REQUIRED_MSG;
			value = commonspot.err.invalidMsg(msg);
			this.checkFieldValue(value, friendlyName, highlightID);		
		}	
	};
	
	/*
	 * CmdError class, represents a server-side error running a cmd
	 * TODO: write this, document fieldErrors and fieldErrorMap members better
	 * fieldErrors
	 * 	errortype:
	 * 	message:
	 * 	fieldtype:
	 * 	passedtype:
	 * fieldErrorMap
	 * 	struct, keyed by the lcase argument name on the server side.
	 * 	for each field, value is a struct containing...
	 * 		friendlyName:
	 * 		highlightIDs:
	 * 		position:
	 */
	commonspot.err.CmdError = function(responseStatus, fieldErrorMap, errorCodeMap)
	{
		this.cmd = responseStatus.cmd;
		this.code = responseStatus.code;
		this.reasonCode = responseStatus.reasoncode;
		this.text = responseStatus.text;
		this.hasFieldErrors = responseStatus.hasFieldErrors;
		if(responseStatus.data)
		{
			this.exceptionType = responseStatus.data.exceptiontype;
			this.fieldErrors = responseStatus.data.fielderrors;
		}
		this.fieldErrorMap = fieldErrorMap;
		this.errorCodeMap = errorCodeMap;
					//console.log("CmdError.this", this);
		return this;
	};
	
	/*
	 * visually indicate field errors when applicable, and rtn struct w error msgs:
	 * 	.field: user-fixable data problems
	 * 	.user: other expected exception alerts
	 * 	.internal: unexpected internal error (cf crash, unmapped field errors, etc)
	 */
	commonspot.err.CmdError.prototype.render = function(contextWindow)
	{
		var map, fieldName, highlightIDs, position;
		var msgs = {field: "", user: "", internal: ""};
		var orderedFieldMsgs = [];
		var unorderedFieldMsgs = [];
		if (this.hasFieldErrors)
		{	// cmd refusal with field errors user can fix (if we have a mapping for the fld), typically validation
			if (this.fieldErrorMap)
			{
				// fieldErrorMap entries have position only if added to cmd collection via a Command obj; want to fill in the rest using order added to the map
				// find highest position spec'd in map
				position = -1;
				for (fieldName in this.fieldErrorMap)
				{
					if (typeof this.fieldErrorMap[fieldName].position !== 'undefined')
						position = this.fieldErrorMap[fieldName].position;
				}
				// starting one higher than highest existing position, number all unnumbered ones, in order defined in map
				position++;
				for (fieldName in this.fieldErrorMap)
				{
					if (typeof this.fieldErrorMap[fieldName].position === 'undefined')
						this.fieldErrorMap[fieldName].position = position++;
				}
			}
			for (var fld in this.fieldErrors)
			{
				if (!this.fieldErrors.hasOwnProperty(fld)) // skip prototype extended methods
					continue;
				// if error is a string, not an object, it's an internal exception; so far, that's only INCOMPLETE_RETURN_VALUE_EXCEPTION
				if (typeof this.fieldErrors[fld] === 'string')
				{
					msgs.internal += '<dt>' + this.errorSource(this.cmd, fld) + '</dt><dd>' + this.fieldErrors[fld].escapeHTML() + '</dd>';
				}
				else if (this.fieldErrorMap && this.fieldErrorMap[fld]) // have a mapping for this fld -- user-entered data they can change
				{
					map = this.fieldErrorMap[fld];
					fieldName = map.friendlyName || fld;
					highlightIDs = map.highlightIDs;
					position = map.position;
					if(highlightIDs)
						commonspot.util.css.addRemoveClassNameByIDs(highlightIDs, commonspot.err.FIELD_ERROR_CSS_CLASS, true, contextWindow);
					msg = (this.fieldErrors[fld].errortype == "empty") ? commonspot.err.REQUIRED_MSG : this.fieldErrors[fld].message;
					msg = '<dt title="Data type: ' + this.fieldErrors[fld].fieldtype + '">' + fieldName + '</dt><dd>' + msg.escapeHTML() + '</dd>';
					if (typeof position !== 'undefined' && typeof orderedFieldMsgs[position] === 'undefined')
						orderedFieldMsgs[position] = msg;
					else // shouldn't happen I think, but don't want to die if there's a way it can
						unorderedFieldMsgs.push(msg);
				}
				else // no mapping for this fld, not something user can fix -- internal error or missing or incorrect map
					msgs.internal += '<dt title="Data type: ' + this.fieldErrors[fld].fieldtype + '">' + this.errorSource(this.cmd, fld) + '</dt><dd>' + commonspot.err.UNMAPPED_FIELD_ERROR_MSG_START + this.fieldErrors[fld].message.escapeHTML() + '</dd>';
			}
		}
		else if (this.code === commonspot.err.COMMAND_REFUSAL_ERROR_CODE) // non-field cmd refusal
		{
			map = this.errorCodeMap ? this.errorCodeMap.getForCode(this.reasonCode) : null;
			if(map) // have specs for this reasonCode, alert like a field error and highlight requested flds
			{
				commonspot.util.css.addRemoveClassNameByIDs(map.highlightIDs, commonspot.err.FIELD_ERROR_CSS_CLASS, true, contextWindow);
				msg = '<dt>' + map.itemTitle + '</dt><dd>' + this.text.escapeHTML() + '</dd>';
				unorderedFieldMsgs.push(msg);
			}
			else
				msgs.user += '<p>' + this.text.escapeHTML() + '</p>';
		}
		else if (this.code === commonspot.err.AUTHORING_DISABLED_ERROR_CODE) // authoring is disabled, just say it
			msgs.user += '<p>' + this.text.escapeHTML() + '</p>';
		else // non-field internal error
			msgs.internal += '<dt>' + this.errorSource(this.cmd) + '</dt><dd>' + this.text + '</dd>';
			
		msgs.field = orderedFieldMsgs.join("") + unorderedFieldMsgs.join(""); // concat ordered msgs, ones w no position at end
		return msgs;
	};
	
	commonspot.err.CmdError.prototype.errorSource = function(cmd, fld)
	{
		switch(this.exceptionType)
		{
			case "CSIncompleteReturnValueException":
				return cmd + ", " + "field '" + fld + "' in return value:";
			default:
				return (fld ? cmd + "." + fld : cmd);
		}
	};
	
	
	/*
	 * CmdHandlerError class, represents a client-side js error in a cmd response handler
	 * TODO: write this
	 */
	commonspot.err.CmdHandlerError = function(cmd, error)
	{
		this.cmd = cmd;
		this.text = error.toString().escapeHTML();
		return this;
	};
	
	/*
	 * visually indicate field errors when applicable, which won't happen, and...
	 * rtn struct w error msgs:
	 * 	.field: user-fixable data problems; null
	 * 	.user: other expected exception; null
	 * 	.internal: unexpected internal error; error text
	 */
	commonspot.err.CmdHandlerError.prototype.render = function(lightboxWindow)
	{
		var msgs =
		{
			field: "",
			user: "",
			internal: "<dt>" + this.cmd + "</dt><dd>" + commonspot.err.COMMAND_HANDLER_ERROR_MSG_START + "<br />" + this.text.escapeHTML() + "</dd>"
		};
		return msgs;
	};
	
	/*
	 * FieldError class, represents a client-side validation error specific to some field
	 * TODO: write this
	 */
	commonspot.err.FieldError = function(msg, friendlyName, highlightIDs)
	{
		this.msg = msg;
		this.friendlyName = friendlyName;
		this.highlightIDs = highlightIDs;
		return this;
	};
	
	/*
	 * visually indicate field errors when applicable, which won't happen, and...
	 * rtn struct w error msgs:
	 * 	.field: user-fixable data problems; null
	 * 	.user: other expected exception; null
	 * 	.internal: unexpected internal error; error text
	 */
	commonspot.err.FieldError.prototype.render = function(lightboxWindow)
	{
		if(this.highlightIDs && this.highlightIDs != "")
			lightboxWindow.$
				.apply(lightboxWindow, this.highlightIDs.split(","))
				.addClassName(commonspot.err.FIELD_ERROR_CSS_CLASS);
		var msgs =
		{
			field: "<dt>" + this.friendlyName + "</dt><dd>" + this.msg.escapeHTML() + "</dd>",
			user: "",
			internal: ""
		};
		return msgs;
	};

	/*
	* ErrorCodeMap class, represents a mapping of error codes to error item titles and highlightIDs
	* use to handle non-validation errors (cmd refusal) as a field error when it's a known code
	* constructor args let you create first mapping immediately; call addCode to add more if needed
	*/
	commonspot.err.ErrorCodeMap = function(code, itemTitle, highlightIDs)
	{
		this.map = {};
		if(code)
			this.addCode(code, itemTitle, highlightIDs);
		return this;
	};

	commonspot.err.ErrorCodeMap.prototype.addCode = function(code, itemTitle, highlightIDs)
	{
		this.map[code] = {itemTitle: itemTitle, highlightIDs: highlightIDs};
	};

	commonspot.err.ErrorCodeMap.prototype.getForCode = function(code)
	{
		return this.map[code];
	};
	
	/*
	 * namspace for client-side value validators
	 * shouldn't be many of these, most validation is server-side
	 * validators should return passed value if it's valid, else commonspot.err.invalidMsg("Some message")
	 * validators are used by ErrorCollection.checkFieldValue, so far
	 * you can pass checkFieldValue the name of a std validator, or a reference to (not the name of) a custom function 
	 */
	commonspot.err.validators = {};
	
	commonspot.err.validators.required = function(value)
	{
		if(value == "") // assumes value has been trimmed, as by commonspotLocal.util.getValue
			value = commonspot.err.invalidMsg(commonspot.err.REQUIRED_MSG);
		return value;
	};

} // commonspot.err not built yet
;
// VALIDATION FUNCTIONS
var _emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i;
function isInt() {
    var v = arguments[0];
    var re = /^[+-]?\d+$/;
    return re.test(v);
}

function isFloat() {
    var v = arguments[0];
    var re = /^[-+]?\d*\.?\d*$/;
    return re.test(v) && !isBlank(v);
}

function isBlank() {
    var v = arguments[0];
    var re = /\S+/;
    return !re.test(v);
}

function isNotBlank() {
    var v = arguments[0];
    var re = /\S+/;
    return re.test(v);
}

function isEmail() {
    var v = arguments[0];
    var re = new RegExp(_emailRegex);
    return re.test(v);
}

function isPassword() {
    var v = arguments[0];
    // THE FOLLOWING REGULAR EXPRESSION VALIDATES A PASSWORD THAT IS 6-20 CHARACTERS IN LENGTH SINCE IT IS
    // CASE INSENSITIVE, IT DOESN'T MATTER IF THE LETTER IS LOWER CASE OR UPPER CASE AND WE ALSO DON'T CARE
    // IF THEY USE SPECIAL CHARACTERS
    var re = /.{6,20}/i;
    return re.test(v);
}

function isUSDate() {
    var v = arguments[0];
    // THE FOLLOWING REGULAR EXPRESSION WAS WRITTEN BY MICHAEL ASH. IT WAS FOUND AT http://regexlib.com/REDetails.aspx?regexp_id=113
    // IT VALIDATES LEAP YEARS AND IT HAS BEEN MODIFIED TO ONLY ALLOW THE THE M/D/Y FORMAT
    // (THE ORIGINAL SCRIPT ALLOWED . AND - IN ADDITION TO / AS SEPERATORS) LEADING ZEROS ARE OPTIONAL.
    var re = /^(?:(?:(?:0?[13578]|1[02])(\/)31)\1|(?:(?:0?[13-9]|1[0-2])(\/)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/;
    return re.test(v);

    // ORIGINAL REGEX AS LISTED ON regexlib.com /^(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[13-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/
}

function isEuroDate() {
    var v = arguments[0];
    // THE FOLLOWING REGULAR EXPRESSION WAS WRITTEN BY MICHAEL ASH. IT WAS FOUND AT http://regexlib.com/REDetails.aspx?regexp_id=610
    // IT ALLOWS D/M/Y FORMATS (LEADING ZEROS OPTIONAL) AND IT VALIDATES LEAP YEARS TOO. THE TIME PORTION OF THIS SCRIPT HAS BEEN REMOVED.
    var re = /^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])\1(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))?$/;
    return re.test(v);

    //	ORIGINAL REGEX AS LISTED ON regexlib.com /^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])\1(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$/;
}

/*
	THIS FUNCTION IS SPECIFICALLY FOR VALIDATING THE FAKE IATA NUMBERS THAT WE SOMETIMES GIVE TO AGENTS
	THESE NUMBERS ARE ALWAYS 8 CHARACTERS STARTING WITH DNAGO (THAT'S THE LETTER O, NOT THE NUMBER ZERO)
	FOLLOWED BY 3 DIGITS OR DNAG FOLLOWED BY 4 DIGITS.
*/
function isDNAG() {
    var v = arguments[0];
    var re1 = /^DNAGO\d{3}$/i;
    var re2 = /^DNAG\d{4}$/i;
    return re1.test(v) || re2.test(v);
}

function isCreditCardNumber() {
    var v = arguments[0];
    var object_value;

    // THIS FUNCTION WAS TAKEN FROM THE CFFORM VALIDATION JAVASCRIPT
    // TRIM WHITESPACE BEFORE WE VALIDATE
    object_value = v.replace(/^\s+/, '').replace(/\s+$/, '');

    if (object_value.length == 0) return false;

    var white_space = " -";
    var creditcard_string = "";
    var check_char;

    for (var i = 0; i < object_value.length; i++) {
        check_char = white_space.indexOf(object_value.charAt(i));
        if (check_char < 0)
            creditcard_string += object_value.substring(i, (i + 1));
    }

    if (creditcard_string.length < 13 || creditcard_string.length > 19) {
        return false;
    }

    if (creditcard_string.charAt(0) == "+") {
        return false;
    }

    if (!isInt(creditcard_string)) {
        return false;
    }

    var doubledigit = creditcard_string.length % 2 == 1 ? false : true;
    var checkdigit = 0;
    var tempdigit;

    for (i = 0; i < creditcard_string.length; i++) {
        tempdigit = eval(creditcard_string.charAt(i));

        if (doubledigit) {
            tempdigit *= 2;
            checkdigit += (tempdigit % 10);

            if ((tempdigit / 10) >= 1.0)
                checkdigit++;

            doubledigit = false;
        }
        else {
            checkdigit += tempdigit;
            doubledigit = true;
        }
    }

    return (checkdigit % 10) == 0 ? true : false;
}

function preventSpace(e) {
    var event = e || window.event;  // get event object
    var key = event.keyCode || event.which; // get key cross-browser
    if (key == 32) { //Space bar key code
        if (event.preventDefault) event.preventDefault(); //normal browsers
        event.returnValue = false; //IE
    }
}

function getMsg(selector) {
    return $(selector).attr('data-msg');
}

(function () {
    window.ak = window.ak || {};
    $.validator.addMethod("customEmail", function (value, element) {
        return this.optional(element) || _emailRegex.test(value);
    }, "Enter a valid Email Address");

    var formValidator = window.ak.formValidator = {
        init: function (formSelector) {
            var validator = $(formSelector).validate({
                errorClass: "valmsg",
                errorElement: "em",
                ignore: ":hidden:not(#address1)",
                highlight: function (element) {
                    $(element).addClass("newFormValidation");
                    if ($(element).is("select")) {
                        $(element).parent().addClass("newFormValidation");
                    }
                    if ($(element).attr("id") === "address1" && $(element).is(":hidden")) {
                        $(formSelector).find("#address_search").addClass("newFormValidation");
                    }
                },
                unhighlight: function (element) {
                    $(element).removeClass("newFormValidation");
                    if ($(element).is("select")) {
                        $(element).parent().removeClass("newFormValidation");
                    }
                    if ($(element).attr("id") === "address1" && $(element).is(":hidden")) {
                        $(formSelector).find("#address_search").removeClass("newFormValidation");
                    }
                },
                errorPlacement: function (error, element) {
                    if ($(element).attr("id") === "address1" && $(element).is(":hidden")) {
                        var selector = formSelector + " #address_search";
                        error.insertAfter($(selector).first());
                    }
                    else if ($(element).attr("id") === "address1" && $(element).is(":visible")) {
                        error.insertAfter(element);
                    }
                    else if ($(element).hasClass("telephone")) {
                        var intlTelInput = $(element).closest(".intl-tel-input");
                        error.insertAfter(intlTelInput);
                    }
                    else {
                        error.insertAfter(element);
                    }
                }
            });
            $(".email-validate").rules("add", {
                customEmail: true
            });
            $("#address1").change(function () {
                validator.element(this);
            });
        }
    };
})();;
var ak = window.ak || {};

ak.gif = (function () {
    var pub = {};
    var $form;
    var loginStep = "LoginStep";
    var journeyStep = "JourneyStep";
    var contactStep = "ContactStep";
    var passportStep = "PassportStep";
    var healthStep = "HealthStep";
    var specialRequestStep = "SpecialRequestStep";
    var reviewStep = "ReviewStep";
    var submitStep = "SubmitStep";

    var qasInProcess = [];

    function getCurrentStep() {
        return $form.find("#FormStepId").val();
    }

    function setActiveStep() {
        var stepId = getCurrentStep();
        $("li[data-step='" + stepId + "']").addClass("active-step");
    }

    function getPreviousStep() {
        var currentStep = getCurrentStep();

        if (currentStep === journeyStep) {
            return loginStep;
        } else if (currentStep === contactStep) {
            return journeyStep;
        } else if (currentStep === passportStep) {
            return contactStep;
        } else if (currentStep === healthStep && $(".disabled-step").length === 0) {
            return passportStep;
        } else if (currentStep === healthStep) {
            return contactStep;
        } else if (currentStep === specialRequestStep) {
            return healthStep;
        } else if (currentStep === reviewStep) {
            return specialRequestStep;
        } else if (currentStep === submitStep) {
            return reviewStep;
        } else {
            return loginStep;
        }
    }

    function isInViewport($element) {
        if (($element.offset().top - $(window).scrollTop()) < window.innerHeight) {
            return true;
        } else {
            return false;
        }
    }

    function showDependentFields(fieldName) {
        $form.find("[data-dependsOn='" + fieldName + "']").show();
    }

    function hideDependentFields(fieldName) {
        $form.find("[data-dependsOn='" + fieldName + "']").hide();
    }

    function toggleDependentFields(htmlElement) {
        var fieldName = $(htmlElement).attr("name");
        if (htmlElement.value === "True") {
            showDependentFields(fieldName);
        } else {
            hideDependentFields(fieldName);
        }
    }

    function populateStateDropdown(countrySelector, stateSelector, selectedState) {

        if ($(countrySelector).val().length < 1) return;

        var $placeholder = $(stateSelector).children().first();
        $(stateSelector).empty();
        $placeholder.appendTo(stateSelector);
        $.ajax({
            type: "GET",
            url: "/akapi/Gif/GetStates?countryId=" + $(countrySelector).val(),
            success: function (states) {
                if (states.length > 0) {

                    $.each(states,
                        function (i, state) {
                            var stateText = state.Code;
                            if (state.Name !== "") {
                                stateText = state.Name;
                            }
                            var selected = "";
                            if (state.Code === selectedState) {
                                selected = "selected";
                            }

                            $(stateSelector)
                                .append("<option " + selected +" value='" + state.Code + "'>" + stateText + "</option>");
                        });
                    if ($(countrySelector).is(":visible")) {
                        $(stateSelector).parent().show();
                    }
                } else {
                    $(stateSelector).parent().hide();
                }
            }
        });
    }

    function searchAddress(address, country) {
        return $.ajax({
            type: "POST",
            url: "/akapi/Gif/SearchAddress",
            data: {
                address: address,
                country: country
            }
        });
    }

    function getFinalAddress(id) {
        return $.ajax({
            type: "POST",
            url: "/akapi/Gif/FinalAddress",
            data: {
                id: id
            }
        });
    }

    function validatePassportExpiration() {
        var expirationDate = $form.find("#PassportValidUntil").val();
        var issuedDate = $form.find("#PassportDateOfIssue").val();

        //Business Rule: Passport Expiration cannot be before Passport Issued
        if (new Date(expirationDate) < new Date(issuedDate)) {
            $form.find("#PassportValidUntil").addClass("error input-validation-error");
            $("#PassportValidUntilExpired-error").show();
            //$("#PassportValidUntil-error").show();

            return;
        } else {
            $form.find("#PassportValidUntil").removeClass("error input-validation-error");
            $("#PassportValidUntilExpired-error").hide();
            //$("#PassportValidUntil-error").hide();
        }

        //Business Rule: Passport Expiration must be at least 6 months after the departure date
        var $departureDate = $form.find("#DateOfFirstService");
        var departureDate = new Date($departureDate.val());
        var departureDateYear = departureDate.getFullYear();
        var departureDateMonth = departureDate.getMonth();
        var departureDateDay = departureDate.getDate();
        if (new Date(expirationDate) < new Date(departureDateYear, departureDateMonth + 6, departureDateDay)) {
            $form.find("#PassportValidUntil").addClass("error input-validation-error");
            //$("#PassportValidUntil-error").show();
            $("#PassportValidUntilExpired-error").show();
        } else {
            $form.find("#PassportValidUntil").removeClass("error input-validation-error");
            //$("#PassportValidUntil-error").hide();
            $("#PassportValidUntilExpired-error").hide();
        }
    }

    function validatePhoneNumber($element, telephoneInput) {

        var id = $element.attr("id");
        var errorMessage = $("span[id=" + id + "-error]");
        var countryErrorMessage = $("span[id=" + id + "-countryerror]");

        if ($element.val().length === 0) {
            $element.removeClass("error input-validation-error qas-validate");
            errorMessage.hide();
            countryErrorMessage.hide();
            return;
        }

        if (!$element.hasClass("qas-validate")) return;

        var dialCode = "1";
        var countryData = telephoneInput.GetSelectedCountryData();
        if (countryData) {
            dialCode = countryData.dialCode;
        }

        if (!dialCode) {
            $("#" + id).addClass("error input-validation-error");
            countryErrorMessage.show();
            return;
        } else {
            countryErrorMessage.hide();
        }


        qasInProcess.push($.ajax({
            type: "POST",
            url: "/akapi/Gif/ValidatePhone",
            data: {
                phone: $element.val(),
                dialCode: dialCode
            },
            success: function (data) {
                var response = JSON.parse(data);
                if (!response.IsValid) {
                    $("#" + id).data("qasvalidate", response.ValidationMessageKey);
                    $("#" + id).addClass("error input-validation-error");
                    errorMessage.show();
                } else {
                    telephoneInput.SetValue(response.Number);
                    $("input[name='" + id + "'][type='hidden']").val();
                    $("#" + id).data("qasvalidate", "");
                    $("#" + id).removeClass("error input-validation-error qas-validate");
                    errorMessage.hide();
                }
            }
        }));
    }

    function validatePhoneNumbers() {
        $form.find(".qas-phonenumber").each(function () {
            var input = new TelephoneInput($(this).attr("id"));
            validatePhoneNumber($(this), input);
        });
    }

    function validateEmail($element) {
        if ($element.val().length === 0) {
            $element.removeClass("error input-validation-error qas-validate");
            $("span[id=" + $element.attr("id") + "-error]").hide();
            return;
        };
        if (!$element.hasClass("qas-validate")) return;
        var id = $element.attr("id");
        qasInProcess.push($.ajax({
            type: "POST",
            url: "/akapi/Gif/ValidateEmail",
            data: {
                email: $element.val()
            },
            success: function (data) {
                var response = JSON.parse(data);
                if (!response.IsValid) {
                    $("#" + id).data("qasvalidate", response.ValidationMessageKey);
                    $("#" + id).addClass("error input-validation-error");
                    $("span[id=" + id + "-error]").show();
                } else {
                    $("#" + id).data("qasvalidate", "");
                    $("#" + id).removeClass("error input-validation-error qas-validate");
                    $("span[id=" + id + "-error]").hide();
                }
            }
        }));
    }

    function validateEmails() {
        $form.find(".qas-email").each(function () {
            validateEmail($(this));
        });
    }

    function bindDatePickers() {
        $form.find(".ui-datepicker").each(function () {
            $(this).datepicker({
                changeMonth: true,
                changeYear: true,
                onSelect: function () {
                    $(this).valid();
                },
                yearRange: "-125Y:+15Y"
            });
        });

       //Business Rule: Passport Expiration cannot be before Passport Issued
       //Business Rule: Passport Expiration should default to Passport Issued + 10 years
        $form.find("#PassportDateOfIssue").datepicker("destroy");
        $form.find("#PassportDateOfIssue").datepicker({
            changeMonth: true,
            changeYear: true,
            yearRange: "-25Y:+15Y",
            onSelect: function (date) {
                var selectedDate = new Date(date);
                var year = selectedDate.getFullYear();
                var month = selectedDate.getMonth();
                var day = selectedDate.getDate();
                var defaultDate = new Date(year + 10, month, day);

                $form.find("#PassportValidUntil").datepicker("option", "minDate", selectedDate);
                $form.find("#PassportValidUntil").datepicker("option", "defaultDate", defaultDate);
                $(this).valid();
            }
        });

        $form.find("#PassportValidUntil").change(function () {
            validatePassportExpiration();
        });

        $form.find(".ak-date-icon").each(function() {
            $(this).on("click", function () {
                $(this).siblings("input").datepicker("show");
            });
        });
    }

    function bindPhoneInputs() {
        $form.find(".qas-phonenumber").each(function () {
            //Add Country Dropdown
            var input = new TelephoneInput($(this).attr("id"));

        //    //Validate
        //    $(this).blur(function () {
        //        $(this).addClass("qas-validate");
        //        validatePhoneNumber($(this), input);
        //    });
        });
    }

    function bindEmailInputs() {
        //$form.find(".qas-email").each(function () {
        //    $(this).blur(function () {
        //        $(this).addClass("qas-validate");
        //        validateEmail($(this));
        //    });
        //});
    }

    function bindAddressInputs() {
        var searchTimeout = null; 
        $form.find(".qas-address").each(function () {
            $(this).on("keyup input", null, $(this).val(), function () {
                var $addressInput = $(this);
                var $addressGroup = $addressInput.closest(".qas-address-group");
                var $country = $addressGroup.find('.qas-country');
                var usaCountryId = "6224";
                if ($country.val() !== usaCountryId) return; //Only Process USA Addresses
                
                var id = $addressInput.attr("id");
                var pickListSelector = "#" + id + "Picklist";
                var address = $(this).val();

                if (searchTimeout != null) {
                    clearTimeout(searchTimeout);
                }
                searchTimeout = setTimeout(function () {
                    searchTimeout = null;

                    var addressResult = searchAddress(address, "USA");
                    addressResult.success(function(data) {
                        if (data) {
                            $(pickListSelector).empty();
                            var response = JSON.parse(data);
                            for (var i = 0; i < response.results.length; i++) {
                                var result = response.results[i];
                                $(pickListSelector).append("<div data-id='"+ result.id +"' class='address-item'>" + result.text + "</div>");
                            }
                            $(pickListSelector).show();
                            $(pickListSelector).find(".address-item").click(function () {
                                var finalAddressResult = getFinalAddress($(this).data("id"));
                                finalAddressResult.success(function (data) {
                                    if (data) {
                                        var addressParts = JSON.parse(data);
                                        //0: Address Line 1
                                        //1: Address Line 2
                                        //2: Address Line 3
                                        //3: City
                                        //4: State
                                        //5: ZIP
                                        //6: Country
                                        $addressGroup.find(".qas-address").val($.trim(addressParts.fields[0].content));
                                        $addressGroup.find(".qas-city").val($.trim(addressParts.fields[3].content));
                                        $addressGroup.find(".qas-state").val($.trim(addressParts.fields[4].content));
                                        $addressGroup.find(".qas-postalcode").val($.trim(addressParts.fields[5].content));
                                        $(pickListSelector).hide();
                                    }
                                });
                            });
                        }
                    });
                }, 300);  
            });
        });
    }

    function toggleHiddenFields() {
        $(".ak-clarification-copy").each(function() {
            if ($(this).html().length < 1) {
                $(this).hide();
            }
        });
    }

    function bindFocusPostion() {
        $("input").focus(function () {
            var height = $(".sticky-buttons").height() * 2;
            if (($(this).offset().top - $(window).scrollTop()) > (window.innerHeight - height)) {
                $(window).scrollTop($(window).scrollTop() + height);
            } else if (($(this).offset().top - $(window).scrollTop()) < (120)) {
                $(window).scrollTop($(window).scrollTop() - 120);
            }
        });
    }

    function bindModalNotifications() {
        var previousValue;
        $form.find("#ContactGender").on("focus", function () {
            previousValue = this.value;
        }).change(function() {
            if (previousValue === "M" && $(this).val() === "F" && $(".completed-step").length > 2) {
                var modal = "#" + $(this).data("modal");
                $(modal).foundation("reveal", "open");
            }
        });

        $form.find("#IsUsCitizenTravelingWithinUsNo").change(function () {
            if ($(".disabled-step").length > 0) {
                var modal = "#" + $(this).data("modal");
                $(modal).foundation("reveal", "open");
            }
        });
    }

    function bindRadioButtons() {
        $("input[type='radio']").not(":checked").each(function() {
            toggleDependentFields(this);
        });

        $("input[type='radio']:checked").each(function () {
            toggleDependentFields(this);
        });

        $("input[type='radio']").change(function () {
            toggleDependentFields(this);

        });
    }

    function bindCovidStatusDropdown() {
        $("#COVID19VaccinationStatus").change(function () {
            var selectedVal = $('option:selected', this).val();
            var fieldName = $(this).attr("name");
            if (selectedVal != undefined && selectedVal != '') {
                if (selectedVal === "Not Vaccinated") {
                    hideDependentFields(fieldName);
                    $('#DateOfVaccination').val('');
                    $('#TypeOfVaccination').val('');
                }
                else
                    showDependentFields(fieldName);
            }
        });
    }

    function bindSubmitButtons() {
        $form.find("#btnPrevious").click(function () {
            pub.previousButtonClicked = true;
            pub.isFormSubmitting = true;
            $form.find("#FormSkipToStepId").val(getPreviousStep());

            $form[0].submit();
        });

        $form.find("#btnSubmit").click(function () {
            pub.isFormSubmitting = true;
        });

        $form.find("#btnSkipToReview").click(function () {
            $("#FormSkipToStepId").val(reviewStep);
            $form.find("#btnSubmit").click();
        });

        $form.find("#Submit").click(function () {
            $form.find("#btnSubmit").click();
        });

        $form.submit(function (e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            validatePassportExpiration();
            validateEmails();
            validatePhoneNumbers();

            var hasErrors = $form.find("input.error:visible").length > 0;
            var $firstErroredElement = $form.find("input.error:visible").first();

            if ($form.valid() && !hasErrors) {
                $.when.apply(null, qasInProcess).done(function() {
                    if ($form.find("input.error:visible").length > 0) {
                        $form.find("input.error:visible").first().focus();
                    } else {
                        document.getElementById($form.attr("id")).submit();
                    }
                });
            }
            else if (hasErrors) {
                $firstErroredElement.focus();
            }
        });

        $(window).scroll(function () {
            var $stickyButtons = $form.find(".sticky-buttons");
            var $stickyButtonsPosition = $form.find(".sticky-buttons-original-position");

            if ($stickyButtonsPosition.length > 0 && $stickyButtons.length > 0) {
                if (isInViewport($stickyButtonsPosition)) {
                    $stickyButtons.removeClass("is-fixed");
                } else {
                    $stickyButtons.addClass("is-fixed");
                }
            }
        });
    }

    function bindUnloadNotifications() {
        window.onload = function () {
            window.addEventListener("beforeunload", function (e) {
                if (pub.isFormSubmitting && !pub.previousButtonClicked) {
                    return undefined;
                }

                if (pub.isFormSubmitting) {
                    return undefined;
                }

                var confirmationMessage = "Changes you made may not be saved.";

                (e || window.event).returnValue = confirmationMessage; //Gecko + IE

                return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
            });
        };
    }

    pub.isFormSubmitting = false;
    pub.previousButtonClicked = false;

    pub.init = function(formSelector) {
        $form = $(formSelector);
        setActiveStep();
        bindDatePickers();
        bindPhoneInputs();
        bindEmailInputs();
        bindAddressInputs();
        bindRadioButtons();
        bindSubmitButtons();
        bindModalNotifications();
        toggleHiddenFields();
        bindFocusPostion();
        bindCovidStatusDropdown();
        if (getCurrentStep() !== loginStep) {
            bindUnloadNotifications();
        }

        $form.validate({
            groups: {
                phone_group_error:"ContactPrimaryPhone ContactSecondaryPhone"
            },
            rules: {
                ContactPrimaryPhone: {
                    require_from_group :[1,".phone_group"]
                },
                ContactSecondaryPhone: {
                    require_from_group: [1, ".phone_group"]
                }
            },
            invalidHandler: function (form, validator) {
                var errors = validator.numberOfInvalids();
                if (errors) {
                    var firstInvalidElement = $(validator.errorList[0].element);
                    firstInvalidElement.focus();
                }
            },
            onfocusout: function (element) {
                this.element(element);
            }
        });

        return pub;
    }

    pub.bindStateDropdown = function (countrySelector, stateSelector, selectedState) {
        populateStateDropdown(countrySelector, stateSelector, selectedState);
        $(countrySelector).change(function () {
            populateStateDropdown(countrySelector, stateSelector, selectedState);
        });
    }

    pub.toggleReadOnlyField = function (fieldSelector, isEnabled) {
        if (isEnabled) {
            $form.find(fieldSelector).removeAttr('readonly');
        } else {
            $form.find(fieldSelector).attr('readonly', 'readonly');
        }

    }

    pub.bindEditButtons = function (skipToStepSelector) {
        $form.find(".ak-edit").click(function () {
            var step = $(this).data("step");
            $(skipToStepSelector).val(step);
            $form.find("button[type='submit']").click();
        });
    }

    return pub;
}());;
$(document).ready(function () {
    var urlParamsGlobal = new URLSearchParams(window.location.search);
    var scrollToDiv1 = $('#' + urlParamsGlobal.get('scrollto'));
    if (scrollToDiv1.length == 0 && window.location.hash.length == 0) {
        $('.generic-modal').foundation('reveal', 'open');
    }
});;
function positionTitle() {
    $(".grid-item .title").each(function () {
        var thisHeight = $(this).outerHeight();
        var parHeight = $(this).parents(".grid-item").outerHeight();
        var topVal = parHeight - (thisHeight + 15);
        $(this).parent().css({ "top": topVal + "px" });
    });
}
function positionQuote() {
    $(".grid-item .quote p").each(function() {
        var thisHeight = $(this).outerHeight();
        var parHeight = $(this).parent().outerHeight();
        var topVal = ((parHeight - thisHeight) / 2) - 15;
        $(this).css({ "margin-top": topVal + "px" });
    });
}
function positionText() {
    $(".grid-item .text").each(function() {
        var thisHeight = $(this).outerHeight();
        var parHeight = $(this).parents(".grid-item").outerHeight();
        var topVal = ((parHeight - thisHeight) / 2);
        $(this).css({ "top": topVal + "px" });
    });
}

$(document).ready(function() {
    positionTitle();
    positionQuote();
    positionText();
    $(window).resize(function() {
        positionTitle();
        positionQuote();
        positionText();
    });
});
$(window).load(function () {
    $('.grid').masonry({
        // options
        itemSelector: '.grid-item',
        columnWidth: '.grid-sizer',
        percentPosition: true
    });
});
function PagedForm(page1Id, page2Id, waypointId, nextButtonId, previousButtonId, submitButtonId) {
    this.Page1 = document.getElementById(page1Id);
    this.Page2 = document.getElementById(page2Id);
    this.WaypointControl = document.getElementById(waypointId);
    this.NextButton = document.getElementById(nextButtonId);
    this.SubmitButton = document.getElementById(submitButtonId);
    this.PreviousButton = document.getElementById(previousButtonId);
    this.FirstWaypoint = this.WaypointControl.getElementsByClassName("form-waypoint first")[0];
    this.SecondWaypoint = this.WaypointControl.getElementsByClassName("form-waypoint second")[0];
    this.ThirdWaypoint = this.WaypointControl.getElementsByClassName("form-waypoint third")[0];
    this._SetupEvents();
}

PagedForm.prototype._SetupEvents = function () {
    var _this = this;

    this.NextButton.addEventListener("click", function (e) {
        e.preventDefault();
        _this.NextButtonOnClick(e);
    });

    this.PreviousButton.addEventListener("click", function (e) {
        e.preventDefault();
        _this.PreviousButtonOnClick(e);
    });

    this.SubmitButton.addEventListener("click", function (e) {
        e.preventDefault();
        _this.SubmitButtonOnClick(e);
    });
}

PagedForm.prototype.NextButtonOnClick = function (e) {
    this.ClearErrors();
    if (this.IsValid()) {
        this.Page1.style.display = "none";
        this.Page2.style.display = "block";
        //this.FirstWaypoint.classList.remove("active");
        this.SecondWaypoint.classList.add("active");
        this.SecondWaypoint.scrollIntoView({ behavior: "smooth" });
    }
}

PagedForm.prototype.PreviousButtonOnClick = function (e) {
    this.Page1.style.display = "block";
    this.Page2.style.display = "none";
    this.FirstWaypoint.classList.add("active");
    this.SecondWaypoint.classList.remove("active");
    this.FirstWaypoint.scrollIntoView({ behavior: "smooth" });
}

PagedForm.prototype.SubmitButtonOnClick = function (e) {
    this.Page1.style.display = "none";
    this.Page2.style.display = "none";
    this.Page3.style.display = "block";
    this.FirstWaypoint.classList.add("active");
    this.SecondWaypoint.classList.add("active");
    this.ThirdWaypoint.classList.add("active");
    this.ThirdWaypoint.scrollIntoView({ behavior: "smooth" });
}

PagedForm.prototype.IsValid = function () {
    let isValid = true;
    let requiredFields = this.Page1.getElementsByClassName("required");
    for (var i = 0; i < requiredFields.length; i++) {
        if (requiredFields[i].value == "") {
            let errorLabel = document.createElement("em");
            requiredFields[i].parentElement.parentElement.append(errorLabel);
            errorLabel.setAttribute("id", requiredFields[i].getAttribute("name") + "-error");
            errorLabel.classList.add("valmsg");
            errorLabel.style.display = "block";
            errorLabel.innerHTML = requiredFields[i].dataset.msgRequired;
            isValid = false;
        }
    }
    return isValid;
}

PagedForm.prototype.ClearErrors = function () {
    let requiredFieldLabels = this.Page1.getElementsByClassName("valmsg");
    for (var i = 0; i < requiredFieldLabels.length; i++) {
        requiredFieldLabels[i].remove();
    }
};
function JourneyInterestControl(journeyInterestId, fieldId) {
    this.JourneyInterestContainer = document.getElementById(journeyInterestId);
    this.JourneyInterestTextContainer = this.JourneyInterestContainer.querySelector("#form-journey-interest-text-container");
    this.JourneyInterestItemContainer = this.JourneyInterestContainer.querySelector("#form-journey-interest-item-container");
    this.JourneyInterestItems = this.JourneyInterestItemContainer.getElementsByClassName("form-journey-interest-item");
    this.FormField = document.getElementById(fieldId);
    this._SetupEvents();
}

JourneyInterestControl.prototype._SetupEvents = function () {
    var _this = this;

    for (var i = 0; i < this.JourneyInterestItems.length; i++) {
        this.JourneyInterestItems[i].addEventListener("click", function (e) {
            _this.JourneyInterestItemOnClick(e);
        });
    }
}

JourneyInterestControl.prototype.JourneyInterestItemOnClick = function (e) {
    this.FormField.value = e.currentTarget.dataset.interest;

    console.log("What is it? " + e.currentTarget.dataset.isnonjourneyrelated);

    var h4 = $("#search-results-heading-tag");

    //e.currentTarget.dataset.isNonJourneyRelated
    if (e.currentTarget.dataset.isnonjourneyrelated == "true" && h4.length) {        
        var text = h4.text();
        console.log("Journey-related... Text: " + text);

        if (text.indexOf("*") > 0) {
            h4.text(h4.text().replace("*", ""));
            if ($("#WhereDoYouWantToGo").hasClass("required")) {
                $("#WhereDoYouWantToGo").removeClass("required");
                $("#WhereDoYouWantToGo-error").hide();
            }
        }       
    }
    else {
        var text = h4.text();
        console.log("Non-Journey-related... Text: " + text);

        if (h4.text().indexOf("*") < 0) {
            h4.append("<span style='position: absolute; top: 14px; font-size: 16px;'>*</span>");
        }
       
        if ($("#WhereDoYouWantToGo").hasClass("required") == false) {
            $("#WhereDoYouWantToGo").addClass("required");
        }
    }

    for (var i = 0; i < this.JourneyInterestItems.length; i++) {
        this.JourneyInterestItems[i].classList.remove("selected");
        this.JourneyInterestItems[i].classList.add("notselected");
    }

    e.currentTarget.classList.remove("notselected");
    e.currentTarget.classList.add("selected");
    document.getElementById("form_journey_interests-error").style.display = 'none';
};
var CookieNames = {
    FadeIn: "AK_signup_fadeIn",
    DelayFadeInCounter: "AK_delayFadeInCounter",
    FadeCountdown: "AK_signup_fadeCountdown",
    SignupNoMore: "AK_signup_noMore"
};
var journeyEmailCaptchaLoaded = false;
$(document).ready(function () {
    var recaptchaWidgetSignUpFlyRecaptchaJS = false;
    var recaptchaWidgetSignUpMiddleRecaptchaJS = false;

    $.cookie(CookieNames.DelayFadeInCounter, 4, { expire: 1, path: '/', secure: true });
    if (!$.cookie(CookieNames.FadeIn)) { // first visit to site (since last cookie clear out or after a year)
        $.cookie(CookieNames.FadeCountdown, 1, { expires: 60, path: '/', secure: true });
        $.cookie(CookieNames.FadeIn, 1, { expires: 365, path: '/', secure: true }); // so the process doesn't just start again after 60days
    }

    if ($.cookie(CookieNames.FadeCountdown) && $.cookie(CookieNames.FadeIn) && (!$.cookie(CookieNames.SignupNoMore))) {

        $("#fadeInsignUpClose").click(function () {
            $('#signUp_overlay-shade').css("display", "none");
        });
        if ($('#signUp_overlay-shade').length === 0) {

            // open the background shading            
            setTimeout(function () {
                var value = $("#fadeInSignUp");
                if (value.length > 0) {
                    if (typeof pageTracker !== "undefined")pageTracker._trackEvent('Forms', 'Email Middle Pop', 'Loading');
                    $('body').prepend('<div id="signUp_overlay-shade" onClick="closeOverlay();"></div>');
                }

            }, 14000);
        }

        setTimeout(function () {
            $('#signUp_overlay-shade').fadeTo(300, 0.3, function () {
                if ($(window).width() > 640) {

                    var script = document.createElement('script');
                    script.src = $("#recaptchaWidgetSignUpMiddleRecaptchaJS").val();
                    script.id = "emailSignupfadeJS";
                    document.head.appendChild(script);                   

                    $("#fadeInSignUp").css({ 'display': 'block', 'opacity': '0' }).animate({ 'z-index': '10001', 'opacity': '1' }, 600);
                }
                if (typeof pageTracker !== "undefined") pageTracker._trackEvent('Forms', 'Email Middle Pop', 'Open');
            });

        }, 15000);

        $("#fadeInsignUpClose").click(function (e) {
            $.cookie(CookieNames.SignupNoMore, 1, { expires: 30, path: "/", secure: true });
            $("#fadeInSignUp").fadeOut(500);
            $("#recaptchaWidgetSignUpMiddle").remove();
            $(".val-errors").hide();
            if (typeof pageTracker !== "undefined") pageTracker._trackEvent('Forms', 'Email Middle Pop', 'Close');
            if ($(this).attr("href") == "#") e.preventDefault();
        });
    }

  
   
    $("#journey-email-btn").click(function (e) {

        e.preventDefault();
       
        journeyEmailCaptchaLoaded = false;
        $("#contactUsFormContainer").empty();
        $("#callToActionBarFormContainer").empty();
        $("#tailorMadeFormContainer").empty();
        $("#journey-booking").empty();

        $("#recaptchaWidgetSignUpFly").remove();
        $("#recaptchaWidgetSignUpMiddle").remove();
        $("#recaptchaWidgetSignUpJourneyEmail").remove();

        $("#emailSignupfadeJS").remove();
        $("#emailSignupPopJS").remove();
        $("#journeyEmailJS").remove();

        if ($("#recaptchaWidgetSignUpJourneyEmail").length) {
            console.log("recaptcha div (Journey Email) already added");
        }
        else {
            console.log("adding recaptcha div (Journey Email)");
            $("<div id='recaptchaWidgetSignUpJourneyEmail' class='captcha-badge journey-email'></div>").insertBefore("#journey-email-wrap");
        }

      
        var script = document.createElement('script');
        script.src = $("#recaptchaWidgetJourneyEmailRecaptchaJS").val();
        script.id = "journeyEmailJS";
        document.head.appendChild(script);
    });

    // header Signup Popup
    $("#signUpFly").click(function (e) {
        e.preventDefault();

        destroyOverlayHTMLFromDOM();

        if ($("#recaptchaWidgetSignUpFly").length) {
            console.log("recaptcha div already added");
        }
        else {
            console.log("adding recaptcha div");
            $("<div id='recaptchaWidgetSignUpFly' class='captcha-badge email-fly'></div>").insertBefore("#signUpFlyDown");
        }

        if ($('#signUp_overlay-shade').length === 0) {
            $('body').prepend('<div id="signUp_overlay-shade" onClick="closeOverlay();"></div>');         
        }

        $('#signUp_overlay-shade').fadeTo(300, 0.3, function () {        });

        var script = document.createElement('script');
        script.src = $("#recaptchaWidgetSignUpFlyRecaptchaJS").val();
        script.id = "emailSignupPopJS";
        document.head.appendChild(script);         

        openOverlay("div#signUpFlyDown");
        if (typeof pageTracker !== "undefined") pageTracker._trackEvent("Website", "SignUp-Top Header", "Open");
        FloodlightTags.EmailSignup();
    });
    // header mobile Signup Popup
    $("#signUpFly-mobile").click(function (e) {
        e.preventDefault();

        destroyOverlayHTMLFromDOM();

        if ($("#recaptchaWidgetSignUpFly").length) {
            console.log("recaptcha div already added");
        }
        else {
            console.log("adding recaptcha div");
            $("<div id='recaptchaWidgetSignUpFly' class='captcha-badge email-fly'></div>").insertBefore("#signUpFlyDown");
        }

        //inject the recaptcha script on-demand so it's no loaded on EVERY page request
        var script = document.createElement('script');
        script.src = $("#recaptchaWidgetSignUpFlyRecaptchaJS").val();
        script.id = "emailSignupPopJS";
        document.head.appendChild(script);
        
        openOverlay("div#signUpFlyDown");
        if (typeof pageTracker !== "undefined") pageTracker._trackEvent("Website", "SignUp-Top Header", "Open");
    });

    // signup flydown events 3
    $("#signUpClose").click(function (e) {
        closeOverlay();
    });

    //show validation on click of submit button only if form fields validations are correct
    $(function () {
        var $checkForAll = "false";
        var keys = [];
        $('.contact_us_form .form-inline  .btn').click(function (e) {

            var $formInline = $(this);
            var $scfFormGroup = $formInline.parents('.form-inline').find('.form-group.required-field');
            var $fieldSet = $formInline.parents('.form-inline').find("fieldset");
            if ($scfFormGroup.length > 0) {
                $scfFormGroup.each(function () {
                    var $this = $(this);
                    var $input = $this.find('input[type="text"]');
                    var $inputMail = $this.find('input[type="email"]');
                    var $dropdownvalue = $this.find('select');
                    var $inputPlaceholderText = $input.attr("placeholder");
                    var singleLine = $this.find(".single-line");
                    if (singleLine.length > 0) {
                        var $className = $this.find(".single-line").attr("class");
                        if ($className != null && $className != '' && $className.includes("single-line")) {
                            if ($input.length > 0) {
                                var $checkForValidation = validateAlphaNumericTextBox($input);
                                if ($checkForValidation == true) {
                                    $input.css({ "border": "1px solid #ff0004", "margin-bottom": "4px" });
                                    $fieldSet.css("margin-top", "0");
                                    $checkForAll = "true";
                                    keys.push($checkForAll);
                                    $input.parent().parent().find("label").find(".required-error-msg").remove();
                                    $input.parent().find(".scValidator").remove();
                                    $input.parent().append('<span class="scValidator">' + 'Enter ' + $inputPlaceholderText + '</span>');
                                }

                                else {
                                    $input.css("border", "1px solid #CCCCCC");
                                    $input.parent().parent().find('label').find('.required-error-msg').remove();
                                    $fieldSet.css("margin-top", "15px");
                                    $input.parent().find('.scValidator').remove();
                                    $checkForAll = "false";
                                    keys.push($checkForAll);
                                }
                            }
                            else if ($inputMail.length > 0) {
                                var $checkForValidation = validateEmail($inputMail.val());
                                var $inputPlaceholderText = $inputMail.attr("placeholder");
                                if ($checkForValidation == true) {
                                    $(".contact_us_form .address_search_container").css("top", "24%");
                                    $inputMail.css({ "border": "1px solid #ff0004", "margin-bottom": "4px" });
                                    $fieldSet.css("margin-top", "0");
                                    $checkForAll = "true";
                                    keys.push($checkForAll);
                                    $inputMail.parent().parent().find("label").find(".required-error-msg").remove();
                                    $inputMail.parent().find(".scValidator").remove();
                                    $inputMail.parent().append('<span class="scValidator">' + 'Enter ' + $inputPlaceholderText + '</span>');
                                }

                                else {
                                    $(".contact_us_form .address_search_container").css("top", "23%");
                                    $inputMail.css("border", "1px solid #CCCCCC");
                                    $inputMail.parent().parent().find('label').find('.required-error-msg').remove();
                                    $fieldSet.css("margin-top", "15px");
                                    $inputMail.parent().find('.scValidator').remove();
                                    $checkForAll = "false";
                                    keys.push($checkForAll);
                                }
                            }
                        }
                    }

                    if ($dropdownvalue.length > 0) {
                        var $dropDownClassName = $dropdownvalue.parent(".form-group").attr("class");
                        if ($dropDownClassName != null && $dropDownClassName != '' && $dropDownClassName.includes("scfDropList")) {
                            var $ddlDefaullValue = $dropdownvalue.find('option:eq(0)').val().trim();
                            var $selectedValue = $dropdownvalue.val();
                            if ($ddlDefaullValue == $selectedValue) {
                                $dropdownvalue.css({ "border": "1px solid #ff0004", "margin-bottom": "4px" });
                                $fieldSet.css("margin-top", "0");
                                $checkForAll = "true";
                                keys.push($checkForAll);
                                $dropdownvalue.parent().find(".scValidator").remove();
                                $dropdownvalue.parent().append('<span class="scValidator">' + $ddlDefaullValue + '</span>');
                            }
                            else {
                                $dropdownvalue.css("border", "1px solid #CCCCCC");
                                $fieldSet.css("margin-top", "15px");
                                $dropdownvalue.parent().find('.scValidator').remove();
                                $checkForAll = "false";
                                keys.push($checkForAll);
                            }
                        }
                    }
                });
            }
            for (var i = 0, l = keys.length; i < l; i++) {
                if (keys[i] == "true") {
                    e.preventDefault();
                }
            }
            keys.length = 0;
        });
    });

    // validate email and confirm email
    $(function () {
        $('.overlayBackground .form-inline .btn').click(function (e) {

            var $scfFormGroup = $(this).parent('.form-inline');
            if ($scfFormGroup.length > 0) {
                var $emailInput = $scfFormGroup.find('.email input[type="email"]');
                var $confirmEmailInput = $scfFormGroup.find('.confirm-email input[type="email"]');

                if (typeof ($emailInput.val()) !== 'undefined' && $emailInput.val() != null && $emailInput.val().trim() !== '' && typeof ($confirmEmailInput.val()) !== 'undefined' && $confirmEmailInput.val() != null && $confirmEmailInput.val().trim() !== '') {
                    var $checkForEmailValidation = validateEmail($emailInput.val());

                    if (($checkForEmailValidation === false || $checkForEmailValidation === 'false') && ($emailInput.val().trim() !== $confirmEmailInput.val().trim())) {
                        $emailInput.focus();
                        $emailInput.val("");
                        e.preventDefault();
                        $('.form-bottom-message').css("display", "none");
                        $('.email-validate-message').css("display", "block");
                    } else {
                        $('.form-bottom-message').css("display", "block");
                        $('.email-validate-message').css("display", "none");
                    }
                }
            }
        });
    });

    // check for email validation
    function validateEmail(sEmail) {
        var filter = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
        if (filter.test(sEmail)) {
            return false;
        }
        else {
            return true;
        }
    }

    // function for validating single line textbox values
    function validateAlphaNumericTextBox($obj) {
        var pattern = /^[a-zA-Z0-9]{1}/;
        if (!pattern.test($obj.val())) {
            return true;
        }
        else {
            return false;
        }
    }
});

function openOverlay(olEl) {
    $oLay = $(olEl);
    var props = {
        oLayWidth: $oLay.width(),
        scrTop: $(window).scrollTop(),
        viewPortWidth: $("body.ak_body").width()
    };
    var rightPos = 5;
    $oLay.css({ display: 'block', opacity: 0, top: '-=300', right: rightPos + '%' }).animate({ top: props.scrTop + 40, opacity: 1 }, 600);
}
function closeOverlay() {
    $('.signUp_overlay').animate({ top: '-=300', opacity: 0 }, 400, function () {
        if ($('#signUp_overlay-shade')) $('#signUp_overlay-shade').fadeOut(300);
        $(this).css('display', 'none');
        $(".val-errors").hide();
        destroyOverlayHTMLFromDOM();
    });
}

function getStateIndex(id, hiddenName) {
    if ($("#" + id).length > 0) {
        var selectedIndex = $("#" + id)[0].selectedIndex;
        var selector = "input:hidden[name='" + hiddenName + "']";
        $(selector).val(selectedIndex);
    }
}
function destroyOverlayHTMLFromDOM() {
    journeyEmailCaptchaLoaded = false;
    $("#contactUsFormContainer").empty();
    $("#callToActionBarFormContainer").empty();
    $("#tailorMadeFormContainer").empty();
    $("#journey-booking").empty();

    $("#recaptchaWidgetSignUpFly").remove();
    $("#recaptchaWidgetSignUpMiddle").remove();
    $("#recaptchaWidgetSignUpJourneyEmail").remove();

    $("#emailSignupfadeJS").remove();
    $("#emailSignupPopJS").remove();
    $("#journeyEmailJS").remove();
   
};
function initializeHotelSlider($modal) {
    $(".ak-hotel-slider").css("display", "block");
    if (!$modal.find("ul").hasClass("slick-initialized")) {
        $modal.find("ul.slider-for").slick({
            //lazyLoad: 'ondemand',
            slidesToShow: 1,
            slidesToScroll: 1,
            arrows: true,
            fade: true,
            asNavFor: $modal.find("ul.slider-nav")
        });
        $modal.find("ul.slider-nav").slick({
            //lazyLoad: 'ondemand',
            slidesToShow: 4,
            slidesToScroll: 1,
            responsive: [
                {
                    breakpoint: 992,
                    settings: {
                        slidesToShow: 3,
                        slidesToScroll: 1
                    }
                },
                {
                    breakpoint: 650,
                    settings: {
                        slidesToShow: 2,
                        slidesToScroll: 1
                    }
                }
            ],
            arrows: false,
            asNavFor: $modal.find("ul.slider-for"),
            dots: false,
            centerMode: false,
            focusOnSelect: true
        });
    }
}

function fedScripts() {
    // Header Search bar
    $('#hu-search').on('click', function (e) {
        e.stopPropagation();
        $('.hu-search').fadeIn().find('input[type="text"]').focus();
    });
    $(document).on("click", function () {
        var husearchfield = document.getElementById("hu_search_field");
        if (husearchfield !== null)
            if (husearchfield.value.length === 0) {
                $('.hu-search').fadeOut();
            }
    });

    // Fade Main Nav Dropdown
    $('.main-nav-item').hover(function () {
        $(this).find('.main-nav-dropdown').stop().fadeIn(150);
    }, function () {
        $(this).find('.main-nav-dropdown').stop().fadeOut(150);
    });

    // Everything to do with mobile nav
    $('.mobile-nav-toggle').click(function () {
        $(this).stop().toggleClass('open');
        $('#ak-mobile-nav, .blackout, .inner-wrap').stop().toggleClass('open');
    });

    // l1
    $('#ak-mobile-nav .level1-link').on('click', function () {
        if ($(this).parent().hasClass('has-dd')) {
            $(this).parent().find('.level2').fadeIn().animate({
                left: '0'
            }, { duration: 0, queue: false }, function () { });
            var container = $('#ak-mobile-nav'),
                scrollTo = $('.nav-scrollto');
            container.animate({
                scrollTop: scrollTo.offset().top - container.offset().top + container.scrollTop()
            }, { duration: 500, queue: false }, function () { });
        }
    });

    // L2
    $('#ak-mobile-nav .level2-link').on('click', function () {
        if ($(this).parent().hasClass('has-dd')) {
            $(this).parent().find('.level3').fadeIn().animate({
                left: '0'
            }, { duration: 0, queue: false }, function () { });
            var container = $('#ak-mobile-nav'),
                scrollTo = $('.nav-scrollto');
            container.animate({
                scrollTop: scrollTo.offset().top - container.offset().top + container.scrollTop()
            }, { duration: 500, queue: false }, function () { });
        }
    });
    $('#ak-mobile-nav .back-link').on('click', function () {
        $(this).parent().fadeOut().animate({
            left: '0'
        }, { duration: 0, queue: false }, function () {
        });
    });

    // Load video background
    var homepageHero = $(".ak-main-hero");
    var homepageVideo = homepageHero.find(".background-video");
    var motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
    var allowAutoplay = false;
    if (homepageVideo.length && $(".ak-main-hero").find(".hdnPlayInMobile").first().val() == 'true') {
        allowAutoplay = !motionQuery.matches;
        // alert('autoplay true');
    }
    else {
        allowAutoplay = window.screen.width > 1023 && !motionQuery.matches;
        //  alert('autoplay false');
    }

    if (allowAutoplay && homepageVideo && homepageVideo.length) {
        homepageVideo.find('source').each(function () {
            var source = $(this).data('src');
            $(this).attr('src', source);
        });
        if (homepageVideo[0].readyState === 0) {
            // alert('loading video');
            homepageVideo[0].load();
            homepageVideo[0].play()
                .then(() => {
                })
                .catch((error) => {
                    //homepageVideo.remove();
                    var homepageVideoImage = homepageHero.find(".background-video-image");
                    homepageVideoImage.show();
                });
        }
    }

    var blogHeroBgVideo = $(".blog-hero .background-video");
    if (allowAutoplay && blogHeroBgVideo && blogHeroBgVideo.length) {
        blogHeroBgVideo.find('source').each(function () {
            var source = $(this).data('src');
            $(this).attr('src', source);
        });
        if (blogHeroBgVideo[0].readyState === 0) {
            blogHeroBgVideo[0].load();
        }
    }

    // Load image into hero carousel
    var carousel = $('.ak-main-hero.carousel');
    $(carousel).each(function (index, item) {
        var image = $(item).data('image');
        var alt = $(item).data('alt');

        $(item).backstretch(image);
        $(item).find('.backstretch img').prop('alt', alt);
    });



    // Chat Bubble
    //on the pifer, we needed to remove the header and footer.  By doing this, it caused an issue.  
    try {
        var rightDistance = $("#header").offset().left;
        $(".chat-now-bubble").css("right", rightDistance + 25);
    } catch (ex) {
        console.log("Error loading chat bubble.");
    }


    // Chat Bubble stop
    $(document).scroll(function () {
        // var mainFooterHeight = $("#main_footer").height();
        // var regFooterHeight = $("#footer").height();
        // var ccFooterHeight = $("#footer-cc").height();
        // console.log(mainFooterHeigh + " " + regFooterHeight + " " + ccFooterHeight);

        if ($("#main_footer").length) {
            var topDistance = $("#main_footer").offset().top - 537;
            var pxFromTop = $(document).scrollTop();
            // console.log(topDistance + " . " + pxFromTop);
            if (pxFromTop > topDistance) {
                $('.chat-now-bubble').addClass('stuck');
                $('.chat-now-bubble').css("top", topDistance + 537);
            } else {
                $('.chat-now-bubble').removeClass('stuck');
            }
        }
    });



    // Load image into video hero
    var videoHero = $(".ak-video-hero");
    var videoHeroImg = videoHero.data('image');
    var videoHeroAltTxt = videoHero.data('alt');
    videoHero.backstretch(videoHeroImg);
    videoHero.find('.backstretch img').prop("alt", videoHeroAltTxt);


    // 3up Carousel
    $(window).on("load", function () {
        $('.carousel-container ul').each(function () {
            $(this).slick(slickSettingsCarousel());
        });

        $('.journey-scroller-caoursel ul').each(function () {
            if ($("li.slick-slide").length < 4) {
                $('.slick-prev').hide();
                $('.slick-next').hide();
            }
            $(this).slick(slickSettingsCarousel());
        });
    });


    // Hero Carousel
    $('.carousel-container-hero ul').slick({
        slidesToShow: 1,
        centerPadding: '0',
        infinite: false,
        dots: true,
        responsive: [{
            breakpoint: 1024,
            settings: {
                arrows: false
            }
        }]
    });


    // Foundation stuff
    $(window).on("load", function () {
        $(document).foundation({
            tab: {
                callback: function (tab) {
                    $(".content.active").find(".carousel-container").each(function () {
                        if ($(this).find(".slick-initialized")) {
                            $(this).find(".slick-initialized").slick("unslick");
                            $(this).find("ul").slick(slickSettingsCarousel());
                        }
                    });
                }
            },
            reveal: {
                callback: function (reveal) {

                },
                animation: "fade",
                animation_speed: 250
            }
        });
    });


    // Journey Tabs Tickery
    $(".tabs-container ul.tabs").addClass("closed");

    window.bindAccordions = function () {
        if ($(".ak-accordion li .ak-accordion-head").hasClass("open")) {
            $(".ak-accordion li .ak-accordion-head.open").parent().find(".ak-accordion-table").slideToggle(150);
        }
        $(".ak-accordion li .ak-accordion-head").on("click", function () {
            $(this).parent().find(".ak-accordion-table").slideToggle(150);
            $(this).toggleClass("open");
        });
    };

    window.bindAccordions();

    window.imageGalleryBindCallback = function () {
        var slidesToShow = $(this).closest('.photo-gallery-component__modal').length > 0 ? 6 : 4;
        $(".ak-modal-gallery").css("display", "block");
        $(".ak-modal-gallery").find("img").each(function () {
            var src = $(this).attr("data-src");
            if ($(this).attr("src") != src)
                $(this).attr("src", src);
        });
        if (!$(this).find("ul").hasClass("slick-initialized")) {
            $(this).find("ul.slider-for").slick({
                slidesToShow: 1,
                slidesToScroll: 1,
                arrows: true,
                fade: true,
                asNavFor: $(this).find("ul.slider-nav")
            });
            $(this).find("ul.slider-nav").slick({
                slidesToShow: slidesToShow,
                slidesToScroll: 1,
                responsive: [
                    {
                        breakpoint: 992,
                        settings: {
                            slidesToShow: 3,
                            slidesToScroll: 1
                        }
                    },
                    {
                        breakpoint: 650,
                        settings: {
                            slidesToShow: 2,
                            slidesToScroll: 1
                        }
                    }
                ],
                arrows: false,
                asNavFor: $(this).find("ul.slider-for"),
                dots: false,
                centerMode: false,
                focusOnSelect: true
            });
        }
    };

    window.bindGalleries = function () {
        $('.gallery-modal').bind('opened', window.imageGalleryBindCallback);

        // Reinit Hotel slider once modal opens
        $(document).on('opened.fndtn.reveal', '[data-reveal]', function () {
            var _model = $(this);
            $(".blogvideoinit").map(function () {
                if ($(this).attr("data-reveal-id") === _model.attr("id")) {
                    if ($(_model).find(".ak-modal-content .h2-large").length === 0) {
                        $(_model).find(".ak-modal-content").css("padding", "35px");
                    }
                    $(_model).addClass("blog-video-modal");
                    return false;
                }
            });


            if ($(this).hasClass("ak-hotel-modal")) {
                initializeHotelSlider($(this));
            }
        });
    };

    window.bindGalleries();

    window.modalCloseBindCallback = function () {
        $(this).closest('.reveal-modal').remove();
        $('.reveal-modal-bg').hide();
    };

    window.blogGalleryBindcallBack = function () {
        $('.ak-blog-gallery-modal').bind('opened', function () {
            $('.slidewrap').slick('slickRemove', 0);
            if ($(this).hasClass("ak-blog-gallery-modal")) {
                if (!$(this).find("ul").hasClass("slick-initialized")) {
                    $(this).find("ul.ak-blog-slider").slick({
                        slidesToShow: 1,
                        adaptiveHeight: true,
                        initialSlide: 0,
                        responsive: [{
                            breakpoint: 1024,
                            settings: {
                                arrows: true
                            }
                        }]
                    });
                    setTimeout(function () {
                        $('.ak-blog-gallery-modal').addClass("blog-gallery-visible");
                    }, 10);
                }
            }
        });
    };

    // Improbe Tables radio buttons
    $(".radio-btn").on("click", function () {
        if ($(this).find("input[type='radio']").is(':enabled')) {
            $(this).find("input[type='radio']").prop("checked", true);
            $("tr").removeClass("radio-selected");
            $(this).parent().addClass("radio-selected");
        }
    });

    $(".replace-with-yt-embed").on("click", function () {
        var ytId = $(this).data("youtube-id");
        if (!ytId) return;

        var qstringVideoId = getUrlParams("video");
        var mute = "";
        if (qstringVideoId == ytId) {
            mute = "&mute=1";
        }

        $(this).parent().addClass("size-for-embed");
        var $embedIframe = $('<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen autoplay></iframe>');
        $embedIframe.attr("src", "https://www.youtube.com/embed/" + ytId + "?autoplay=1&modestbranding=1" + mute);
        $(this).after($embedIframe);
        $(this).hide();
    });

    // Mobile Journey Tabs
    $(".tabs-mobile-trigger").on("click", function () {
        $(this).toggleClass("open");
        $(".tabs-container ul.tabs").toggleClass("open");
    });
    $("ul.tabs li").on("click", function () {
        $(".tabs-mobile-trigger").toggleClass("open");
        $(".tabs-container ul.tabs").removeClass("open");
        var tabTxt = $(this).find(".tab-title-txt").html();
        $(".tabs-mobile-trigger").html(tabTxt);
        console.log(tabTxt);
    });


    // 3up Carousel Slider Settings
    function slickSettingsCarousel() {
        return {
            slidesToShow: 3,
            centerPadding: '0',
            infinite: false,
            responsive: [
                {
                    breakpoint: 641,
                    settings: {
                        arrows: true,
                        centerMode: true,
                        slidesToShow: 1,
                        dots: false
                    }
                }
            ]
        };
    }



    // Open Up ak footer flags Dropdown
    $(".ak-flags-dd-container").on("click", function () {
        if ($(this).hasClass("open")) {
            $(this).removeClass("open");
        } else {
            $(this).addClass("open");
        }
    });
    $('body').click(function (event) {
        if (!$(event.target).closest('.ak-flags-dd-container').length) {
            $('.ak-flags-dd-container').removeClass("open");
        };
    });



    //// populate section with images
    $('.two-box-block-img .img-container').each(function () {
        $(this).backstretch($(this).data('img'));
    });


    // image puzzle
    var $grid = $('.ak-img-puzzle').masonry({
        itemSelector: '.ak-img-puzzle-item',
        columnWidth: '.ak-img-puzzle-sizer',
        percentPosition: true
    });
    $grid.imagesLoaded().progress(function () {
        $grid.masonry('layout');
    });

    function _hoverListGetLinkText(hoverLink, hoverLinkText, gatext) {
        var linkText = "";
        if (hoverLink !== undefined && hoverLinkText !== undefined) {
            var onclick = "if (typeof pageTracker !== 'undefined')pageTracker._trackEvent('Navigation', 'Journey type - see journeys', jQuery(this).attr('linkgatext'));";
            var _gatext = "linkgatext='" + gatext + "'";
            linkText = '<a ' + _gatext + ' onclick="' + onclick + '" href="' + hoverLink + '" class="nav-hover-link ak-btn basic right-arrow">' + hoverLinkText + '</a>';
        }
        return linkText;
    }

    // Populate hover list
    $('.hover-list-item').hover(function () {
        var hoverImg = $(this).data('img'),
            hoverTitle = $(this).data('title'),
            hoverBody = $(this).data('body'),
            hoverLink = $(this).data('link'),
            hoverLinkText = $(this).data('linktext'),
            hoverLinkGatext = $('.nav-hover-list ul li:first-child a').data('linkgatext'),
            linkText = _hoverListGetLinkText(hoverLink, hoverLinkText, hoverTitle);

        var $row = $(this).closest('.row.dd-row');
        if ($row && $row.length) {
            $row.find('.nav-hover-block').html('<div class="nav-hover-img"><img src="'
                + hoverImg + '"></div><div class="nav-hover-content"><h6>'
                + hoverTitle + '</h6><div class="nav-hover-body">'
                + hoverBody + '</div>' + linkText + '</div>');
        }
    });

    // Populate hover list
    $('.ak-nav-item.has-dd').each(function (e, i) {
        var $firstChild = $(this).find('.nav-hover-list ul li:first-child a');
        var $hoverBlock = $(this).find('.nav-hover-block');

        if ($firstChild && $firstChild.length && $hoverBlock && $hoverBlock.length) {
            var hoverImg = $firstChild.data('img'),
                hoverTitle = $firstChild.data('title'),
                hoverBody = $firstChild.data('body'),
                hoverLink = $firstChild.data('link'),
                hoverLinkText = $firstChild.data('linktext'),
                hoverLinkGatext = $firstChild.data('linkgatext'),
                linkText = _hoverListGetLinkText(hoverLink, hoverLinkText, hoverTitle);

            $hoverBlock.html('<div class="nav-hover-img"><img src="'
                + hoverImg + '"></div><div class="nav-hover-content"><h6>'
                + hoverTitle + '</h6><div class="nav-hover-body">'
                + hoverBody + '</div>' + linkText + '</div>');
        }
    });

    // Mobile Phone toggle
    $('.mobile-phone-toggle').on('click', function () {
        $(this).toggleClass('open');
        $('.mobile-phone-block').slideToggle(350);
        if (typeof pageTracker !== "undefined") pageTracker._trackEvent('Website', 'Content', 'Mobile Phone Icon');
    });

    // Journey Finder
    function journeyFinder() {
        // if ($(window).width() > 1024) {
        //     var destinationsH = $(".jf-destinations").height();
        //     var countriesH = $(".jf-countries").height();
        //     var dateH = $(".jf-date").height();
        //     var typeH = $(".jf-type").height();
        //
        //     var jfHeights = [destinationsH, countriesH, dateH, typeH];
        //
        //     var largest= 0;
        //
        //     for (i = 0; i <= largest; i++){
        //         if (jfHeights[i] > largest) {
        //             var largest = jfHeights[i];
        //         }
        //     }
        //
        //     $(".jf-destinations, .jf-countries, .jf-date, .jf-type").height(largest);
        // }

        $(".jf-destination-title").on("click", function () {
            var mapLocation = $(this).data("map");

            if (mapLocation === "africa") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/Africa.png");
            } else if (mapLocation === "antarctica") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/Antarctica.png");
            } else if (mapLocation === "arctic") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/Arctic.png");
            } else if (mapLocation === "australianz") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/AustraliaNZ.png");
            } else if (mapLocation === "egyptmorocco") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/EgyptMorocco.png");
            } else if (mapLocation === "europe") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/Europe.png");
            } else if (mapLocation === "asia") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/Asia.png");
            } else if (mapLocation === "india") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/India.png");
            } else if (mapLocation === "latinamerica") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/LatinAmerica.png");
            } else if (mapLocation === "northamerica") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/NorthAmerica.png");
            } else if (mapLocation === "fullmap") {
                $(".jf-map img").attr("src", "Assets/Local/Images/map/FullMap.png");
            }
        });

        //$(".journey-finder").on("click", ".jf-month", function () {
        //    $(this).toggleClass("active");
        //});

        //$(".journey-finder").on("click", ".jf-year", function () {

        //    var jfYear = $(this).data("year");
        //    console.log("in");
        //    $(".jf-date-months").slideUp();

        //    $(".jf-date-months").each(function () {
        //        var jfMYear = $(this).data("year");
        //        if ($(this).data("year") == jfYear) {
        //            console.log("main.js" + $(this).data("year"));
        //            $(this).slideDown();
        //        }
        //    });
        //    $(".jf-year").removeClass("active");
        //    $(this).addClass("active");
        //});
    }
    journeyFinder();

    // Journy Finder Date Picker
    if ($('.jf-date-picker').length) {
        $('.jf-date-picker').MonthPicker({
            yearRange: '2017:2220',
            ShowIcon: false
        });
    }


    $(".jf-link").on("click", function (e) {
        if ($(".journey-finder").length) {
            e.preventDefault();

            $('html, body').animate({
                scrollTop: $('.journey-finder').position().top - 122
            }, 'fast');

        } else {
            $(".journey-finder-floating").stop().fadeToggle();
        }
    });

    $(".jf-modal-close").on("click", function () {
        $(".journey-finder-floating").stop().fadeOut();
    });

    $(".ak-nav-item").on({
        mouseenter: function () {
            if ($(this).hasClass("has-dd")) {
                $(this).find(".ak-nav-dropdown").delay(500).fadeIn();
                $('#ak-nav').addClass('slow-opaque');
            }
        },
        mouseleave: function () {
            $(".ak-nav-dropdown").stop().css("display", "none");
            $('#ak-nav').removeClass('slow-opaque');
        }
    });

    $(document).on('closed.fndtn.reveal', '[data-reveal]', function () {
        var frame = $(this).find("iframe");
        var url = frame.attr("src");
        frame.attr('src', '');
        frame.attr('src', url);
    });
    $(".close-alert-box").on("click", function () {
        $(this).parent().parent().fadeOut();
    });

    // hotel Finder
    function hotelFinder() {
        $(".hf-destination-title").on("click", function () {
            var mapLocation = $(this).data("map");

            if (mapLocation === "africa") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/Africa.png");
            } else if (mapLocation === "antarctica") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/Antarctica.png");
            } else if (mapLocation === "arctic") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/Arctic.png");
            } else if (mapLocation === "australianz") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/AustraliaNZ.png");
            } else if (mapLocation === "egyptmorocco") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/EgyptMorocco.png");
            } else if (mapLocation === "europe") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/Europe.png");
            } else if (mapLocation === "asia") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/Asia.png");
            } else if (mapLocation === "india") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/India.png");
            } else if (mapLocation === "latinamerica") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/LatinAmerica.png");
            } else if (mapLocation === "northamerica") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/NorthAmerica.png");
            } else if (mapLocation === "fullmap") {
                $(".hf-map img").attr("src", "/Areas/Ak/Assets/Local/Images/map/FullMap.png");
            }
        });

        // Multi Select stuff
        $(".hf-destination-title, .hf-countries-title").on("click", function () {
            if ($(this).hasClass("hf-destination-title")) {
                $(".hf-destination-title").removeClass("open");
            }
            $(this).toggleClass("open");
        });
    }
    hotelFinder();

    if ($('#back-to-top').length) {
        var scrollTrigger = 500,
            backToTop = function () {
                var scrollTop = $(window).scrollTop();
                if (scrollTop > scrollTrigger) {
                    $('#back-to-top').addClass('show');
                } else {
                    $('#back-to-top').removeClass('show');
                }
            };
        backToTop();
        $(window).on('scroll', function () {
            backToTop();
        });
        $('#back-to-top').on('click', function (e) {
            e.preventDefault();
            $('html,body').animate({
                scrollTop: 0
            }, 700);
        });
    }

    if ($('.brochurerequest-footer-sticky').length) {
        var footerStickyScrollTrigger = 100,
            showHideStickyFooter = function () {
                var scrollTop = $(window).scrollTop();
                if (scrollTop >= footerStickyScrollTrigger) {
                    $('.brochurerequest-footer-sticky').addClass('show').fadeIn(150);
                } else {
                    $('.brochurerequest-footer-sticky').removeClass('show').fadeOut(150);
                }
            };
        showHideStickyFooter();
        $(window).on('scroll', function () {
            showHideStickyFooter();
        });
    }

    if ($('.call-to-action-bar').length) {
        var cTABarScrollTrigger = 100,
            showHideCTABar = function () {
                var scrollTop = $(window).scrollTop();
                if (scrollTop >= cTABarScrollTrigger) {
                    $('.call-to-action-bar').addClass('show').fadeIn(150);
                } else {
                    $('.call-to-action-bar').removeClass('show').fadeOut(150);
                }
            };
        showHideCTABar();
        $(window).on('scroll', function () {
            showHideCTABar();
        });
    }

    if ($('#ak-nav').length) {
        var navScrollTrigger = 0,
            opaqueNav = function () {
                var scrollTop = $(window).scrollTop();
                if (scrollTop > navScrollTrigger) {
                    $('#ak-nav').addClass('opaque');
                } else {
                    $('#ak-nav').removeClass('opaque');
                }
            };
        opaqueNav();
        $(window).on('scroll', function () {
            opaqueNav();
        });
    }

    // turn journey finder to orange when hovering over journey finder
    $(document).on("scroll", function () {
        if ($(".journey-finder").length > 0) {
            var jfHeight = $(".journey-finder").height(),
                jfOffsetTop = $(".journey-finder").offset().top,
                pxFromTop = $(document).scrollTop(),
                jfOffsetTotal = jfOffsetTop + jfHeight;

            if (pxFromTop >= (jfOffsetTop - 175) && (jfOffsetTotal - 100) > pxFromTop) {
                $(".jf-link").addClass("active");
            } else {
                $(".jf-link").removeClass("active");
            }
        }
    });

    var videoId = getUrlParams("video");
    if (videoId.length > 0) {

        setTimeout(function () {
            if ($("#video-" + videoId).length) {

                if ($("#video-" + videoId).closest(".ak-video-hero-container").length > 0) {
                    var focusParentId = $("#video-" + videoId).closest(".ak-video-hero-container");
                    var childId = focusParentId.find(".ak-video-hero-content").first();
                    childId.click();                   
                }
                else if ($("#video-" + videoId).closest(".blog-hero").length > 0) {
                    var focusParentId = $("#video-" + videoId).closest(".blog-hero");
                    var childId = focusParentId.find(".view_overlay").first();
                    childId.click();
                }
                else if ($("#video-" + videoId).closest(".video-list-callout").length > 0) {
                    var focusParentId = $("#video-" + videoId).closest(".video-list-callout");
                    var childId = focusParentId.find(".view_overlay").first();
                    $('html,body').animate({
                        scrollTop: childId.offset().top + 1500
                    }, 1500, function () {
                        childId.click();
                    });                   
                }
                else if ($("#video-" + videoId).closest(".blog-content-panel").length > 0) {
                    var focusParentId = $("#video-" + videoId).closest(".blog-content-panel");
                    var childId = focusParentId.find(".video-blog").first();
                    $('html,body').animate({
                        scrollTop: childId.offset().top - 400
                    }, 1500, function () {
                        childId.click();
                    });
                }
            }
        }, 2000);       
    }
}

function fedScriptsResize() {
    // Load video background
    var homepageHero = $(".ak-main-hero");
    var homepageVideo = homepageHero.find(".background-video");
    var motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
    var allowAutoplay = false;
    if (homepageVideo.length && $(".ak-main-hero").find(".hdnPlayInMobile").first().val() == 'true') {
        allowAutoplay = !motionQuery.matches;
    }
    else {
        allowAutoplay = window.screen.width > 1023 && !motionQuery.matches;
    }

    if (allowAutoplay && homepageVideo && homepageVideo.length) {
        homepageVideo.find('source').each(function () {
            var source = $(this).data('src');
            $(this).attr('src', source);
        });
        if (homepageVideo[0].readyState === 0) {
            homepageVideo[0].load();
        }
    }

    var blogHeroBgVideo = $(".blog-hero .background-video");
    if (allowAutoplay && blogHeroBgVideo && blogHeroBgVideo.length) {
        blogHeroBgVideo.find('source').each(function () {
            var source = $(this).data('src');
            $(this).attr('src', source);
        });
        if (blogHeroBgVideo[0].readyState === 0) {
            blogHeroBgVideo[0].load();
        }
    }

    // Load image into hero carousel
    var carousel = $('.ak-main-hero.carousel');
    $(carousel).each(function (index, item) {
        var image = $(item).data('image');
        var alt = $(item).data('alt');

        $(item).backstretch(image);
        $(item).find('.backstretch img').prop('alt', alt);
    });

    // Load image into video hero
    var videoHero = $(".ak-video-hero");
    var videoHeroImg = videoHero.data('image');
    var videoHeroAltTxt = videoHero.data('alt');
    videoHero.backstretch(videoHeroImg);
    videoHero.find('.backstretch img').prop("alt", videoHeroAltTxt);


    // populate section with images
    $('.two-box-block-img .img-container').each(function () {
        $(this).removeAttr('style');
        $(this).backstretch($(this).data('img'));
    });

    // Populate image puzzle masonry with images
    $('.ak-img-puzzle-img').each(function () {
        $(this).parent().backstretch('../' + $(this).attr('src'));
    });
}





$(document).ready(function () {

    fedScripts();

});

$(window).on("load", function () {
    $(".journey-finder-floating").fadeOut(1);
    $(".journey-finder-floating").css("right", 0);
});

$(window).on('resize', function () {
    fedScriptsResize();
});

//declare custom onbeforeprint method
const customOnBeforePrint = () => {
    const smoothScroll = (h) => {
        let i = h || 0;
        if (i < 200) {
            setTimeout(() => {
                window.scrollTo(window.scrollY, window.scrollY + i);
                smoothScroll(i + 10);
            }, 10);
        }
    };

    let height = document.body.scrollHeight;
    let newHeight;
    while (true) {
        smoothScroll(100);

        if (newHeight === height) break;
        height = newHeight;
    }
};

//override the onbeforeprint method
window.onbeforeprint = customOnBeforePrint;

$(document).ready(function () {
    var isPrinting = window.matchMedia('print');
    isPrinting.addListener((media) => {
        if (media.matches) {
            console.log("p2");
        }
    })

    if ($(".header-outer .row").length) {
        var offsetDistance = $(".header-outer .row").offset().left;

        $(".ak-chat-bubble").css({
            right: offsetDistance + 25
        });
    }
    //$(".ak-chat-bubble").on("click", function() {
    //    $(".ak-chatbox").fadeToggle();
    //});
    //$(".ak-chatbox .decline-chat").on("click", function() {
    //    $(".ak-chatbox").fadeOut();
    //});

    $(document).scroll(function () {
        if ($("#main_footer").length) {
            var pxFromTop = $(document).scrollTop(),
                docHeight = $(window).height(),
                pxToFooter = pxFromTop + docHeight,
                footerOffsetDistance = $("#main_footer").offset().top;

            if (pxToFooter > footerOffsetDistance) {
                $(".ak-chat-bubble").css({
                    position: "absolute",
                    bottom: "auto",
                    top: (footerOffsetDistance - 65)
                });
                $(".brochurerequest-footer-sticky").css({
                    position: "absolute",
                    bottom: "auto",
                    top: (footerOffsetDistance - parseInt($('.brochurerequest-footer-sticky').css("height")))
                });
                $(".call-to-action-bar").css({
                    position: "absolute",
                    bottom: "auto",
                    top: (footerOffsetDistance - parseInt($('.call-to-action-bar').css("height")))
                });
            } else {
                $(".ak-chat-bubble,.brochurerequest-footer-sticky,.call-to-action-bar").css({
                    position: "fixed",
                    bottom: 0,
                    top: "auto"
                });
            }
        }
    });

    $(window).on('resize', function () {
        if ($(".header-outer .row").length) {
            var offsetDistance = $(".header-outer .row").offset().left;

            $(".ak-chat-bubble").css({
                right: offsetDistance + 25
            });
        }
    });
});

//Brochure Request CTA - Footer
$(".brochurerequest-footer-sticky").find(".close-button").on("click", function (e) {
    e.preventDefault();
    if (!$(".brochurerequest-footer-sticky").hasClass("brochuredismissed")) {
        $(".brochurerequest-footer-sticky").addClass("brochuredismissed");
    }
    $.cookie('brochuredismissed', true);
});

$(".call-to-action-bar").find(".close-button").on("click", function (e) {
    e.preventDefault();
    if (!$(".call-to-action-bar").hasClass("ctabardismissed")) {
        $(".call-to-action-bar").addClass("ctabardismissed");
    }

    $.cookie('ctabardismissed', true, { path: '/' });
});

//Lazy loading images in modal dialogs.
$(document).ready(function () {
    $(document).on('open.fndtn.reveal', '[data-reveal]', function () {
        var modal = $(this);
        modal.find("img").each(function () {
            var src = $(this).attr("data-src");
            $(this).attr("src", src);
        });

    });

    //Brochure Request CTA - Footer
    if ($.cookie('brochuredismissed')) {
        if (!$(".brochurerequest-footer-sticky").hasClass("brochuredismissed")) {
            $(".brochurerequest-footer-sticky").addClass("brochuredismissed");
        }
    }

    //ol-Numbered-List
    var _numberedList = $(".rich-text ol,ul").each(function () {
        var _parentElement = $(this);
        if ($(_parentElement).find(".numbered-list").length > 0) {
            $(_parentElement).addClass("numbered-list-display");
            return false;
        }
    });

    $('.richtext-gallery-modal-link').on('click', function (e) {
        e.preventDefault();

        let _this = $(this);
        const href = _this.attr('id');
        const targetType = _this.attr('href');

        let blogModalId = "#blogGalleryModal_";
        let hotelModalId = "#hotelModal_";

        if ($(".loader").length) {
            $(".loader").show();
        } else {
            $("<div class='loader' style='display:none;'></div>").appendTo("body")
            $(".loader").show();
        }

        $.ajax({
            type: 'GET',
            url: '/akapi/RichTextSearch/GetGalleryModal',
            data: { searchId: href },
            success: function (response) {
                $('#onetrust-consent-sdk').after(response);
                let modalId = "#photoGridModal_" + href.substring(1, href.length - 1);
                if (targetType === "blog-gallery") {
                    modalId = blogModalId + href.substring(1, href.length - 1);
                }
                else if (targetType === "hotel-gallery") {
                    modalId = hotelModalId + href.substring(1, href.length - 1);
                }

                $(".loader").hide();
                setTimeout(function () {
                    $(modalId).foundation('reveal', 'open');
                    if (targetType === "blog-gallery") {
                        //window.blogGalleryBindcallBack();
                        $(modalId).bind('opened', window.blogGalleryBindcallBack());
                    }
                    else if (targetType === "hotel-gallery") {
                        const hotelModal = $(document).find(modalId);
                        initializeHotelSlider(hotelModal);
                        $(modalId).bind('opened', window.imageGalleryBindCallback);
                        $('.slick-next').click();
                        $('.slick-prev').click();
                        hotelModal.find('.ak-modal-gallery').show();
                    } else {
                        $(modalId).bind('opened', window.imageGalleryBindCallback);
                    }

                    $('.close-reveal-modal').bind('click', window.modalCloseBindCallback);
                }, 500);
            },
            error: function (error) {
                console.log('error response:', error);
            }
        });
    });

});

function getUrlParams(prop) {
    var params = {};
    var search = decodeURIComponent(window.location.href.slice(window.location.href.indexOf('?') + 1));
    var definitions = search.split('&');

    definitions.forEach(function (val, key) {
        var parts = val.split('=', 2);
        params[parts[0]] = parts[1];
    });

    return (prop && prop in params) ? params[prop] : params;
}

// Object Fit Images (Polyfill)
objectFitImages();

// Blog Gallery Carousel
var _initialSlickSlide = 0;
$('.ak-blog-gallery-modal').bind('opened', function () {
    $('.slidewrap').slick('slickRemove', 0);
    if ($(this).hasClass("ak-blog-gallery-modal")) {
        if (!$(this).find("ul").hasClass("slick-initialized")) {
            $(this).find("ul.ak-blog-slider").slick({
                slidesToShow: 1,
                adaptiveHeight: true,
                initialSlide: _initialSlickSlide,
                responsive: [{
                    breakpoint: 1024,
                    settings: {
                        arrows: true
                    }
                }]
            });
            setTimeout(function () { $('.ak-blog-gallery-modal').addClass("blog-gallery-visible"); }, 10);
        }
    }
});


$('.blog-image-card-anchor').click(function (e) {
    var _index = $(this).closest('.gallery-block').find('.blog-image-card-anchor').index($(this));
    e.preventDefault();
    var _model = $(this).attr("data-reveal-id");
    if ((_model != 'undefined' && _model != null) && (_index != 'undefined' && _index != null)) {
        _initialSlickSlide = _index;
        $("#" + _model).find('.ak-blog-slider.slick-initialized').slick('unslick');
        $("#" + _model).removeClass("blog-gallery-visible");
    }
});


// Trip Log (Expand)
let expandBtn = document.getElementsByClassName('trip-log__top');
let expandContent = document.getElementsByClassName('trip-log__bottom');

for (let i = 0; i < expandBtn.length; i++) {
    setContentHeight(expandBtn[i]);
    expandBtn[i].onclick = function () {
        let setClasses = !this.classList.contains('trip-log__top--active');
        setClass(expandBtn, 'trip-log__top--active', 'remove');
        setClass(expandContent, 'trip-log__bottom--expanded', 'remove');
        setTripLogCardHeight(expandBtn);
        if (setClasses) {
            this.getElementsByClassName("text__content")[0].style.height = "auto";
            this.classList.toggle('trip-log__top--active');
            this.nextElementSibling.classList.toggle('trip-log__bottom--expanded');
            if (typeof pageTracker !== "undefined") pageTracker._trackEvent(jQuery(this).attr('gacategory'), jQuery(this).attr('gaaction'), jQuery(this).attr('gatext'));
        }

    };
}

function setContentHeight(__expendBtn) {
    let _defaultHeight = 200;
    let _setClasses = __expendBtn.classList.contains('trip-log__top--active');
    let contentDiv = __expendBtn.getElementsByClassName("text__content");
    let _img = __expendBtn.getElementsByClassName("trip-log__img");
    if (contentDiv.length > 0 && _img.length > 0 && !_setClasses) {
        contentDiv[0].style.height = _img[0].height > _defaultHeight ? _img[0].height + "px" : _defaultHeight + "px";
    }
    else if (contentDiv.length > 0 && _img.length === 0 && !_setClasses) {
        contentDiv[0].style.height = _defaultHeight + "px";
    }
    else if (_setClasses) {
        contentDiv[0].style.height = "auto";
    }

}


function setTripLogCardHeight(_ele) {
    for (let i = 0; i < _ele.length; i++) {
        setContentHeight(_ele[i]);
    }
}

function setClass(els, className, fnName) {
    for (let i = 0; i < els.length; i++) {
        els[i].classList[fnName](className);
    }
}

$(window).on("load", function () {
    setJourneyExpertSection();
});

function setJourneyExpertSection() {
    var _journeyExpertid = "#journey-experts-h3";
    if ($('html,body').find(_journeyExpertid).length > 0) {
        if (window.location.hash !== "" && window.location.hash.toLowerCase() === _journeyExpertid) {
            animateExpertSection(_journeyExpertid);
        }
        $('html,body').find('a').on('click', function (e) {
            if ($(this).attr("href") != undefined && $(this).attr("href") == _journeyExpertid) {
                e.preventDefault();
                animateExpertSection(_journeyExpertid);
            }
        });
    }
}

function animateExpertSection(_ele) {
    $('html,body').animate({
        scrollTop: $(_ele).offset().top - 200
    }, 800, function () { });
}

if (navigator.userAgent.match(/Trident\/7\./)) { // if IE
    $('body').on("mousewheel", function (event) {
        // remove default behavior
        event.preventDefault();

        //scroll without smoothing
        var wheelDelta = event.originalEvent.wheelDelta;
        var currentScrollPosition = window.pageYOffset;
        window.scrollTo(0, currentScrollPosition - wheelDelta);
    });
}

function removeElementsByClass(className) {
    const elements = document.getElementsByClassName(className);
    while (elements.length > 0) {
        elements[0].parentNode.removeChild(elements[0]);
    }
}

$(function () {

    //Digital-Reward
    $(".digital-reward").find(".drlink").each(function (obj) {
        var drObject = $(this).closest(".digital-reward").find("#drlinkurl");
        if (drObject) {
            $(this).attr({ "href": drObject.val(), "target": "_blank" });
        }
    });


    window.loadHighCharts = function (climateChartPopupGuid, googleAnalyticsCallback) {
        removeElementsByClass("weather_chart");
        var jclimateChartPopup = $("#" + climateChartPopupGuid);

        if (window.highChartsIsLoaded) {
            window.climateChartOpened(jclimateChartPopup);
            googleAnalyticsCallback();
            return;
        }

        $.ajax({
            url: 'https://code.highcharts.com/highcharts.js',
            dataType: "script",
            async: true,
            success: function () {
                $.ajax({
                    url: 'https://code.highcharts.com/modules/exporting.js',
                    dataType: "script",
                    async: true,
                    success: function () {
                        window.climateChartOpened(jclimateChartPopup);
                        googleAnalyticsCallback();
                        window.highChartsIsLoaded = true;
                    }.bind(this)
                });
            }.bind(this)
        });
    }

    window.climateChartOpened = function (jclimateChartPopup) {
        $.ajax({
            url: "/akapi/ClimateChart/" + $("#climateChartParentId").val(),
            type: "GET",
            dataType: "html",
            success: function (data) {
                $(jclimateChartPopup).find(".climate-chart-popup__content").html(data);
                $(jclimateChartPopup).find('.weather_chart').each(function () {
                    if ($(this).highcharts() != undefined) {
                        $(this).highcharts().reflow();
                        console.log("reflow");
                    }
                });
                $(jclimateChartPopup).find('.loading_spinner').fadeOut(500);
                $(jclimateChartPopup).find('.weather_chart').css('visibility', 'visible').delay(500);
            }
        });
    }

    //Agency-Name issue - Journey Pages - Email and PDF
    $('#journey-email,#journey-pdf').bind('opened', function () {
        if ($(this).find("input[name='prefContactInfo'][data-counter='1']").prop("checked")) {
            $(this).find(".agent-info-wrapper-container").find("#showAgentName").val("1");
        }
        $(this).find(".prefRadio").on("click",
            function () {
                $(this).closest(".agent-info-wrapper-container").find("#showAgentName").val("0");
                if ($(this).is(":checked") && $(this).attr("data-counter") === "1") {
                    $(this).closest(".agent-info-wrapper-container").find("#showAgentName").val("1");
                }
            });
    });


    if (typeof journeyTabberInView === "undefined") {
        var urlParams = new URLSearchParams(window.location.search);
        var scrollToDiv = $('#' + urlParams.get('scrollto'));
        if (scrollToDiv !== null) {
            setTimeout(function () {
                if (scrollToDiv.length) {
                    $('html, body').animate({ scrollTop: scrollToDiv.offset().top - 130 }, 1000);
                }
            }, 500);

        }
    }
});;
const pageTracker = {
    _trackEvent(category, action, label) {
        //Universal Analytics
        if (typeof ga !== 'undefined') {
            ga('send', {
                hitType: 'event',
                eventCategory: category,
                eventAction: action,
                eventLabel: label
            });
        }
        else {
            //in case OneTrust took longer to load, try again after 3 seconds
            setTimeout(function () {
                if (typeof ga !== 'undefined') {
                    ga('send', {
                        hitType: 'event',
                        eventCategory: category,
                        eventAction: action,
                        eventLabel: label
                    });
                }
            }, 3000);
        }

        //GA 4
        if (typeof window.gtag !== 'undefined') {
            window.gtag("event", category, {
                eventAction: action,
                eventLabel: label
            });
        }
        else {
            //in case OneTrust took longer to load, try again after 3 seconds
            setTimeout(function () {
                if (typeof window.gtag !== 'undefined') {
                    window.gtag("event", category, {
                        eventAction: action,
                        eventLabel: label
                    });
                }
            }, 3000);
        }
    }
};


function GoogleAnalytics() {

}

GoogleAnalytics.TrackEvent = function (gaCategory, gaAction, gaLabel) {
    if (typeof pageTracker !== "undefined") {
        pageTracker._trackEvent(gaCategory, gaAction, gaLabel);
    }
};

GoogleAnalytics.ClientId = '';

;
(function () {
    window.ak = window.ak || {};

    var brochureslist = window.ak.brochureslist = {        

        init: function (id, hdnUrl, message, brochureLimit) {
            
            this._$brochurecontainer = $('#' + id);

            // check count of checkboxes
            this._checkboxCount(hdnUrl, message, brochureLimit);
        },

        _checkboxCount: function (hdnUrl, message, brochureLimit) {
            var checkdCheckbox = this._$brochurecontainer.find("input[type='checkbox']:checked");
            
            if (checkdCheckbox.length > brochureLimit) {
                alert(message);
            } else {
                var checkedBrochureList = "";
                checkdCheckbox.each(function () {
                    checkedBrochureList += $(this).val() + ",";
                });
                checkedBrochureList = checkedBrochureList.replace(/,\s*$/, "");
                if (checkedBrochureList !== "") {
                   
                    window.location.href = encodeURI(hdnUrl + "?brochures=" + checkedBrochureList);
                }
            }
        }        
    };
})();;
(function () {
    window.ak = window.ak || {};

    var emergencyMessages = window.ak.emergencyMessages = {

        close: function () {
            $.post("/akapi/EmergencyMessage/CloseEmergencyMessage");
        }
    };
})();;
(function () {
	window.ak = window.ak || {};

    var aksearch = window.ak.search = {
        init: function (inputSelector, searchButtonSelector, searchPageUrlSelector, enableRedirect) {
            var search = this;
			this._$searchPageUrl = $(searchPageUrlSelector).val();
            this._$searchInput = $(inputSelector);

			this._$searchInput.keyup(function (e) {
                if (e.keyCode === 13) {
                    search._directSearch($(this), enableRedirect);
                    $(this).val("");
                }
            });

			$(searchButtonSelector).click(function (clevt) {
				clevt.preventDefault();
				search._directSearch(search._$searchInput, enableRedirect);
			});
		},

        _directSearch: function (ele, enableRedirect) {

			if (ele.length > 0) {
				var val = ele.val();
				if (val !== "") {
					if (this._$searchPageUrl !== undefined) {
						var $searchPage = $('.search-page');
						var $primarySearch = $searchPage && $searchPage.length ? $searchPage.find('input.search-box') : null;

						if ($primarySearch && $primarySearch.length) {
							// already on search page, run the search via angular component
							var $searchBox = $($primarySearch[0]);

							var scope = angular.element($primarySearch[0]).scope();
							scope.searchbox = val;
							scope.$apply();

							var enter = $.Event('keydown');
							enter.which = 13;
							$searchBox.focus();
							$searchBox.trigger(enter);
                        }
                        if (enableRedirect) {
                            window.location = this._$searchPageUrl + encodeURIComponent(val);
                        }
					}
					else {
						ele.preventDefault();
					}
				}
			}
        }
	};
})();;
function TelephoneInput(inputId) {
    this.InputId = inputId;

    this.InputElement = $('#' + inputId);

    this.InputElement.intlTelInput({
        utilsScript: "/Areas/Ak/Assets/Vendor/Packages/intl-tel-input-12.0.0/build/js/utils.js",
        autoPlaceholder: "polite",
        formatOnDisplay: true,
        hiddenInput: inputId,
        preferredCountries: ["us", "ca"]
    });
}

TelephoneInput.prototype.SetValue = function (phone) {
    this.InputElement.intlTelInput("setNumber", phone);
}

TelephoneInput.prototype.GetValue = function () {
    var number = this.InputElement.intlTelInput("getNumber");
    return number;
}

TelephoneInput.prototype.GetSelectedCountryData = function() {
    var countryData = this.InputElement.intlTelInput("getSelectedCountryData");
    return countryData;
}

$(function () {
    $.validator.addMethod("validatePhone", function (value, element) {
        if ($(element).val().length === 0) return true;  //only evaluate if there is content in the input.
        if ($(element).intlTelInput('isPossibleNumber')) return true;  //only evaluate if there is content in the input 
        else return false;
    }, " Invalid Phone Number");

    $.validator.addClassRules({
        telephone: {
            validatePhone: true
        }
    });
});;
function EmailPreferenceForm(containerClass) {
    this.Form = $("#emailPreferences");
    this.Container = $('.' + containerClass);
    this.ErrorMessage = this.Container.find(".text-error");
    this.SuccessMessage = this.Container.find(".text-success");
    this.txtEmail = this.Container.find("#EmailAddress");
    this.EmailOptions = this.Container.find(".email-options");
    this.SearchInputs = this.Container.find(".search-inputs");
    this.AgentOnly = this.EmailOptions.find(".agent-only");
    this.ConsumerOnly = this.EmailOptions.find(".consumer-only");
    this.chkANews = this.EmailOptions.find("#anews");
    this.chkENews = this.EmailOptions.find("#enews");
    this.chkEvillas = this.EmailOptions.find("#evillas");
    this.chkAvillas = this.EmailOptions.find("#avillas");
    this.btnSearch = this.Container.find("#btnSearch");
    this.btnUpdate = this.Container.find("#btnUpdate");
    this.encryptedRenderingIds = this.EmailOptions.find("#encryptedRenderingIds");
    this.RIID = "0";
    this.Response = "";   
    
}

EmailPreferenceForm.prototype.Init = function () {
    var _this = this;

    this.EmailOptions.hide();

    this.btnSearch.click(
        function (e) {
            _this.RetrievePreferences();
        });

    this.btnUpdate.click(
        function (e) {
            _this.UpdatePreferences();
        });

    var pairs = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    var hasParameters = pairs.length > 0;
    var firstParamDoesNotContainEquals = pairs[0].indexOf('=') === -1;
    var firstParamDoesNotContainHostName = pairs[0].indexOf(window.location.host) === -1;
    if (hasParameters && firstParamDoesNotContainEquals && firstParamDoesNotContainHostName) {
        this.RIID = pairs[0];
        this.GetPreferences(this.RIID);
    }
};

EmailPreferenceForm.prototype.GetPreferences = function(riid) {
    var _this = this;
    this.Clear();

    if (riid) {
        $.ajax({
            url: "/akapi/emailpreferences/preferences?id=" + riid,
            type: "GET",
            success: function (response) {

                if (response.Found) {
                    _this.SetData(response);
                } 
            },
            error: function (xhr) {
                _this.ShowError("An error occurred while attempting to retrieve your email preferences.  Please try again.");
            }
        });
    }
};

EmailPreferenceForm.prototype.RetrievePreferences = function () {
    var _this = this;
    this.Clear();
    var email = this.txtEmail.val();
    var isValidEmail = isEmail(email);

    if (!isValidEmail) {
        _this.ShowError("Please enter a valid email address.");
        event.preventDefault();
        return false;
    }

    if (typeof grecaptcha !== 'undefined') {
        var gResponse = grecaptcha.getResponse();
        if (!gResponse) {
            event.preventDefault();
            setTimeout(function () { grecaptcha.execute(); }, 2000);
            return false;
        }
    }


    if (isValidEmail) {

        $.ajaxSetup({ cache: false }); // IE automatically caches GET requests

        $.ajax({
            url: "/akapi/emailpreferences/retrievepreferences",
            type: "POST",
            data: this.Form.serializeArray(),
            success: function (response) {

                if (response.Found) {
                    _this.SetData(response);
                } else {
                    _this.ShowError("The email address you entered was not found.  Please try again.");
                }
            },
            error: function (xhr) {

                _this.ShowError("An error occurred while attempting to retrieve your email preferences.  Please try again.");
            }
        });
    }
    else {
        _this.ShowError("Please enter a valid email address.");

    }

};

EmailPreferenceForm.prototype.UpdatePreferences = function () {
    var _this = this;
    this.GetData();

    if (this.Response !== "") {
        $.ajax({
            url: "/akapi/emailpreferences/savepreferences",
            type: "post", //send it through get method
            data: {
                preferenceResult: this.Response,
                form: this.Form.serializeArray()
            },
            success: function (response) {


                //clear any previous messages
                _this.HideError();
                _this.HideSuccess();

                if (!response.Found) {
                    _this.ShowError("The email address you entered was not found.  Please try again.");
                }
                else if (response.Found && !response.Updated) {
                    _this.ShowError("Unfortunately there was an issue updating your data.  Please try again later or contact technical support.");
                }
                else if (!response.Found && !response.Updated) {
                    _this.ShowError("Unfortunately there was an issue updating your data.  Please try again later or contact technical support.");
                }
                else if (response.Found && response.Updated) {
                    _this.ShowSuccess();
                }

            },
            error: function (xhr) {
                _this.ShowError("An error occurred while attempting to retrieve your email preferences.  Please try again.");
            }
        });
    }
};

EmailPreferenceForm.prototype.Clear = function () {
    this.HideError();
    this.HideSuccess();
    this.EmailOptions.hide();
};

EmailPreferenceForm.prototype.SetData = function (response) {
    this.Response = response;
    this.SearchInputs.hide();
    this.EmailOptions.show();
    this.txtEmail.val(response.Email);

    if (response.IsAgent) {
        this.AgentOnly.show();
        this.ConsumerOnly.hide();
        this.chkANews.prop("checked", response.ANews);
        this.chkAvillas.prop("checked", response.Avillas);
        this.chkENews.prop("checked", false);
        this.chkEvillas.prop("checked", false);
    } else {
        this.AgentOnly.hide();
        this.ConsumerOnly.show();
        this.chkANews.prop("checked", false);
        this.chkAvillas.prop("checked", false);
        this.chkENews.prop("checked", response.ENews);
        this.chkEvillas.prop("checked", response.Evillas);
    }
};

EmailPreferenceForm.prototype.GetData = function () {
    this.Response.ANews = this.chkANews.prop("checked");
    this.Response.ENews = this.chkENews.prop("checked");
    this.Response.Evillas = this.chkEvillas.prop("checked");
    this.Response.Avillas = this.chkAvillas.prop("checked");
    this.Response.encryptedRenderingIds = this.encryptedRenderingIds.val();
};

EmailPreferenceForm.prototype.ShowError = function (error) {
    this.ErrorMessage.text(error);
    this.ErrorMessage.parent().show();
};

EmailPreferenceForm.prototype.ShowSuccess = function () {
    this.SuccessMessage.parent().show();
    this.HideError();
};

EmailPreferenceForm.prototype.HideError = function () {
    this.ErrorMessage.text("");
};

EmailPreferenceForm.prototype.HideSuccess = function () {
    this.SuccessMessage.parent().hide();
};
;
function FloodlightTags() {

}

FloodlightTags.GetRandomNumber = function () {
    var axel = Math.random() + "";
    var a = axel * 10000000000000;
    return a;
}

//Start of DoubleClick Floodlight Tag: Please do not remove
//Activity name of this tag: A&K | Brochure Request | Order Confirmation
//URL of the webpage where the tag is expected to be placed: http://www.abercrombiekent.com/travel_brochures/order_confirmation.cfm?orderid=D7E40423-B02F-45FB-20ECE5E1F77F28D0&brid_list=313,302,299
//This tag must be placed between the <body> and </body> tags, as close as possible to the opening tag.
//Creation Date: 02/21/2017
FloodlightTags.BrochureRequestOrderConfirmation = function () {
    var a = FloodlightTags.GetRandomNumber();
    $("body").append('<iframe src="https://6488200.fls.doubleclick.net/activityi;src=6488200;type=leads0;cat=akbro0;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
}

//Tailor Made Request
//Start of DoubleClick Floodlight Tag: Please do not remove
//Activity name of this tag: A&K | Custom Trip Request
//URL of the webpage where the tag is expected to be placed: https://www.abercrombiekent.com/travel/index.cfm?fuseaction=dsp_dates&tid=6588&enquire=1
//This tag must be placed between the <body> and </body> tags, as close as possible to the opening tag.
//Creation Date: 02/21/2017
FloodlightTags.CustomTripRequest = function () {
    var a = FloodlightTags.GetRandomNumber();
    $("body").append('<iframe src="https://6488200.fls.doubleclick.net/activityi;src=6488200;type=leads0;cat=akcus0;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
}

//Start of DoubleClick Floodlight Tag: Please do not remove
//Activity name of this tag: A&K | Direct Brochure Download
//URL of the webpage where the tag is expected to be placed: http://www.abercrombiekent.com/downloads/brochures/placeholder
//This tag must be placed between the <body> and </body> tags, as close as possible to the opening tag.
//Creation Date: 02/21/2017
FloodlightTags.DirectBrochureDownload = function () {
    var a = FloodlightTags.GetRandomNumber();
    $("body").append('<iframe src="https://6488200.fls.doubleclick.net/activityi;src=6488200;type=leads0;cat=akdir0;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;ord=1;num=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
}

//Start of DoubleClick Floodlight Tag: Please do not remove
//Activity name of this tag: A&K | E-mail Sign Up | Fire On Click
//URL of the webpage where the tag is expected to be placed: http://www.abercrombiekent.com/travel_brochures/
//This tag must be placed between the <body> and </body> tags, as close as possible to the opening tag.
//Creation Date: 02/21/2017
FloodlightTags.EmailSignup = function () {
    var a = FloodlightTags.GetRandomNumber();
    $("body").append('<iframe src="https://6488200.fls.doubleclick.net/activityi;src=6488200;type=fireo0;cat=ake-m0;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;ord=1;num=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
}

//Start of DoubleClick Floodlight Tag: Please do not remove
//Activity name of this tag: A&K | Form Brochure Download
//URL of the webpage where the tag is expected to be placed: http://www.abercrombiekent.com/downloads/brochures/placeholder
//This tag must be placed between the <body> and </body> tags, as close as possible to the opening tag.
//Creation Date: 02/21/2017
FloodlightTags.FormBrochureDownload = function () {
    var a = FloodlightTags.GetRandomNumber();
    $("body").append('<iframe src="https://6488200.fls.doubleclick.net/activityi;src=6488200;type=leads0;cat=akfor0;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
}

//Start of DoubleClick Floodlight Tag: Please do not remove
//Activity name of this tag: A&K | Online Booking Request (w/ revenue)
//URL of the webpage where the tag is expected to be placed: http://www.abercrombiekent.com/travel/index.cfm?fuseaction=dsp_request_booking_confirmation&tid=6588&order=28620&order_enc=%25%29%3E%2F%5BCM%3C%20
//This tag must be placed between the <body> and </body> tags, as close as possible to the opening tag.
//Creation Date: 02/21/2017
FloodlightTags.BookingRequestWithRevenue = function (revenue, orderid) {
    $("body").append('<iframe src="https://6488200.fls.doubleclick.net/activityi;src=6488200;type=sales0;cat=akonl0;qty=1;cost=' + revenue + ';dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;ord=' + orderid + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
}

//Start of DoubleClick Floodlight Tag: Please do not remove
//Activity name of this tag: A&K | Travel Question
//URL of the webpage where the tag is expected to be placed: https://www.abercrombiekent.com/travel_questions/index.cfm?fuseaction=dsp_confirmation
//This tag must be placed between the <body> and </body> tags, as close as possible to the opening tag.
//Creation Date: 02/21/2017
FloodlightTags.TravelQuestion = function () {
    var a = FloodlightTags.GetRandomNumber();
    $("body").append('<iframe src="https://6488200.fls.doubleclick.net/activityi;src=6488200;type=leads0;cat=aktra0;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
}

//Attach event for each brochure download if exists on page.
$(document).ready(function () {
    $(".ak-btn.basic.download").each(function () {
        $(this).on("click", function () {
            FloodlightTags.DirectBrochureDownload();
        });
    });
});;
function LivePerson() {
    
}

LivePerson.AvailabilityFlag = true;

LivePerson.RetrieveAvailability = function (callback) {

    $.ajax({
        dataType: "json",
        url: "/akapi/liveperson/RetrieveAvailability",
        data: { t: new Date().getTime() },
        success: function (data) {
            callback(data.availability);
        },
        error: function(data) {  //default to true if there is an error
            callback(true);
        }
    });

}
;
var SearchComponent = function (containerId, redirect) {
    this.Redirect = true;
    if (redirect == false)
        this.Redirect = false;

    this.Container = document.getElementById(containerId);
    this.SearchButton = this.Container.getElementsByClassName("autocomplete-btn-search")[0];
    this.AdvancedSearchButton = this.Container.getElementsByClassName("autocomplete-btn-advanced")[0];
    this.InputBox = this.Container.getElementsByTagName("input")[0];
    this.SuggestDiv;
    this.CurrentFocus = 0;
};

SearchComponent.SearchItemData = [];

SearchComponent.prototype.Init = function() {
    var _this = this;

    if (this.InputBox) {
        this.InputBox.addEventListener('input',
            function (eventArgs) {
                _this.InputBoxOnChange(eventArgs);
            });

        this.InputBox.addEventListener('keydown',
            function (eventArgs) {
                _this.InputBoxOnKeydown(eventArgs);
            });
    }

    if (this.SearchButton) {
        this.SearchButton.addEventListener('click',
            function (eventArgs) {
                _this.SearchButtonOnClick(eventArgs);
            });
    }

    if (this.AdvancedSearchButton) {
        this.AdvancedSearchButton.addEventListener('click',
            function (eventArgs) {
                _this.AdvancedSearchButtonOnClick(eventArgs);
            });
    }

    document.addEventListener("click",
        function(e) {
            _this.CloseAllLists(e.target);
        });
};

SearchComponent.prototype.SearchButtonOnClick = function (eventArgs) {
    var _val = this.InputBox.value;
    var _enableTracking = $(this.SearchButton).data("gaTracking");
    var _topHeaderSearchTracking = $(this.SearchButton).data("topheaderGaTracking");
    var _searchResultTracking = $(this.SearchButton).data("searchresultGaTracking");
    if (_enableTracking === true && GoogleAnalytics) {
        GoogleAnalytics.TrackEvent('Search', 'Search-Homepage Orange Button', _val);
    }
    if (_topHeaderSearchTracking === true && GoogleAnalytics) {
        GoogleAnalytics.TrackEvent('Search', 'Search-Top Header', _val);
    }

    if (_searchResultTracking === true && GoogleAnalytics) {
        GoogleAnalytics.TrackEvent('Search', 'Search- Keyword Search Results Page', _val);
    }

    this.CloseAllLists();
    this.RedirectBasedOnString(_val);
};

SearchComponent.prototype.AdvancedSearchButtonOnClick = function (eventArgs) {
    var _val = this.InputBox.value;

    this.CloseAllLists();
    this.RedirectBasedOnString(_val, true);
};

SearchComponent.prototype.InputBoxOnChange = function(eventArgs) {
    var _this = this;
    var _val = this.InputBox.value;
    var _suggestedItemDiv;

    this.CloseAllLists();

    if (!_val) {
        return false;
    }

    this.CurrentFocus = -1;

    //Create a DIV element that will contain the items (values)
    this.SuggestDiv = document.createElement("DIV");
    this.SuggestDiv.setAttribute("class", "autocomplete-items");

    //Append the DIV element as a child of the autocomplete container
    this.InputBox.parentNode.appendChild(this.SuggestDiv);

    var _arr = SearchComponent.SearchItemData;

    for (var i = 0; i < _arr.length; i++) {

        //Check if the item starts with the same letters as the text field value
        if (_arr[i].text.substr(0, _val.length).toUpperCase() === _val.toUpperCase()) {

            //create a DIV element for each matching element
            _suggestedItemDiv = document.createElement("DIV");

            //make the matching letters bold
            _suggestedItemDiv.innerHTML = "<strong>" + _arr[i].text.substr(0, _val.length) + "</strong>";
            _suggestedItemDiv.innerHTML += _arr[i].text.substr(_val.length);

            //insert a input field that will hold the current array item's value
            _suggestedItemDiv.innerHTML += "<input type='hidden' value='" + _arr[i].id + "'>";

            //execute a function when someone clicks on the item value (DIV element)
            _suggestedItemDiv.addEventListener("click",
                function(e) {
                    _this.SuggestedItemOnClick(e);
                });

            this.SuggestDiv.appendChild(_suggestedItemDiv);
        }
    }
};

SearchComponent.prototype.SuggestedItemOnClick = function (e) {
    var _id = e.currentTarget.getElementsByTagName('input')[0].value;
    var _label = e.currentTarget.innerText;
    var _searchLocation = $(this.InputBox).data("searchLocation");

    this.InputBox.value = _label;
    if ($(this.InputBox).data("scid") !== undefined) {
        console.log('has id');
        console.log(_id);
        $(this.InputBox).data("scid", _id);
    }

    if ($(this.InputBox).data("label") !== undefined) {
        console.log('has label');
        console.log(_label);
        $(this.InputBox).data("label", _label);
    }
    
    this.CloseAllLists();
    if (GoogleAnalytics) {
        GoogleAnalytics.TrackEvent('Search', 'Type Ahead Search-' + _searchLocation, _label);
    }
    this.RedirectBasedOnId(_id);
};

SearchComponent.prototype.RedirectBasedOnId = function (id) {
    if (this.Redirect == false) {
        return;
    }

    var _arr = SearchComponent.SearchItemData;

    for (var i = 0; i < _arr.length; i++) {
        if (_arr[i].id === id) {
            window.location.href = _arr[i].url;
        }
    }
};

SearchComponent.prototype.RedirectBasedOnString = function (text, forceAdvanced) {
    if (this.Redirect == false) {
        return;
    }

    var _arr = SearchComponent.SearchItemData;
    var searchPageBase = "/search-page";
    var searchPage = searchPageBase + "#?term=" + encodeURIComponent(text);
    for (var i = 0; i < _arr.length; i++) {
        if (_arr[i].text.toLowerCase() === text.toLowerCase()) {
            window.location.href = _arr[i].url;
            return;
        }
    }

    // No match was found so just send the text to the search page if we're not already there.
    // Option to redirect to journey finder
    if (forceAdvanced === true) {
        searchPage = "/journey-search";
        window.location.href = searchPage;
        return;
    }

    var _enableTracking = $(this.SearchButton).data("gaTracking");
    if (_enableTracking === true && GoogleAnalytics) {
        GoogleAnalytics.TrackEvent('Search', 'Search-Homepage Orange Button', text);
    }


    if (window.location.href.indexOf(searchPageBase) < 0) {
        window.location.href = searchPage;
        return;
    }
};

SearchComponent.prototype.InputBoxOnKeydown = function(e) {
    var _listItems;

    if (this.SuggestDiv) {
        _listItems = this.SuggestDiv.getElementsByTagName("div");
    }

    if (e.keyCode === 40 || e.keyCode === 9) { //down or tab
        // if tab reaches the end of list, use default behavior
        if (e.keyCode === 9 && this.CurrentFocus >= _listItems.length - 1) {
            this.CloseAllLists();
            return;
        }
        e.preventDefault();
        this.CurrentFocus++;
        this.AddActive(_listItems);
        this.MatchInputToActiveItem(_listItems);
    } else if (e.keyCode === 38) { //up
        e.preventDefault();
        this.CurrentFocus--;
        this.AddActive(_listItems);
        this.MatchInputToActiveItem(_listItems);
    } else if (e.keyCode === 13) {

        //If the ENTER key is pressed, prevent the form from being submitted
        e.preventDefault();

        if (this.CurrentFocus > -1) {

            //Simulate a click on the "active" item
            if (_listItems) {
                _listItems[this.CurrentFocus].click();
            }
        } else {
            //No specific item was clicked or had focus when the enter button is hit, so we try to find a match via string rather than id.
            this.CloseAllLists();
            this.RedirectBasedOnString(this.InputBox.value);
        }
    }
};

SearchComponent.prototype.AddActive = function(listItems) {
    if (!listItems) {
        return false;
    }

    this.RemoveActive(listItems);

    if (this.CurrentFocus >= listItems.length) {
        this.CurrentFocus = 0;
    }

    if (this.CurrentFocus < 0) {
        this.CurrentFocus = (listItems.length - 1);
    }

    listItems[this.CurrentFocus].classList.add("autocomplete-active");
};

SearchComponent.prototype.RemoveActive = function(listItems) {
    for (var i = 0; i < listItems.length; i++) {
        listItems[i].classList.remove("autocomplete-active");
    }
};

SearchComponent.prototype.MatchInputToActiveItem = function(listItems) {
    if (this.CurrentFocus > -1) {
        this.InputBox.value = listItems[this.CurrentFocus].innerText;
    }
};

SearchComponent.prototype.CloseAllLists = function(element) {
    /*close all autocomplete lists in the document,
      except the one passed as an argument:*/
    var _acItems = document.getElementsByClassName("autocomplete-items");

    for (var i = 0; i < _acItems.length; i++) {
        if (element !== _acItems[i] && element !== this.InputBox) {
            _acItems[i].parentNode.removeChild(_acItems[i]);
        }
    }
};

$(document).ready(function () {
    $.getJSON("/akapi/SiteSearch/TypeAheadSearchInitialize", function (data) {
        SearchComponent.SearchItemData = data;
    });
});;
