{"version":3,"file":"script.js","sources":["../../../dev/components/video-wistia/_script.js","../../../dev/assets/js/utilities.js","../../../dev/components/breadcrumbs/_script.js","../../../dev/components/ctas/trip/_script.js","../../../dev/components/trip/dates-pricing/_script.js","../../../dev/components/olark/_script.js","../../../dev/components/enso/_script.js","../../../dev/components/modal/_script.js","../../../dev/components/hero/_video.js","../../../dev/components/modal/generic-dialog/_script.js","../../../dev/components/trip/dates-pricing/accordion-dates/_script.js","../../../dev/components/trip/dates-pricing/accordion-pricing/_script.js","../../../dev/components/subpage-layout/_script.js","../../../dev/components/back-to-trip/_script-trip.js","../../../dev/components/lists/country-list/_country-list.js","../../../dev/assets/js/smartypants.js","../../../dev/assets/js/global-form-functions.js","../../../dev/components/modal/itinerary/_script.js","../../../dev/components/modal/custom/_script.js","../../../dev/components/modal/private/_script.js","../../../dev/components/modal/pdf/_script.js","../../../dev/components/modal/ask/_script.js","../../../dev/components/slideshow-old/_script.js","../../../dev/components/slideshow/_script.js","../../../dev/components/modal/slideshow-accommodation/_script.js","../../../dev/components/nav/_script.js","../../../dev/components/masthead/_script.js","../../../dev/components/masthead/nav/_script.js","../../../dev/components/modal/catalog/_script.js","../../../dev/components/modal/enews/_script.js","../../../dev/components/modal/message/_script.js","../../../dev/components/modal/refer/_script.js","../../../dev/components/modal/digital/_script.js","../../../dev/components/modal/youtube/_script.js","../../../dev/components/modal/eBook/_script.js","../../../dev/components/ctas/magic/_script.js","../../../dev/components/masthead/favorites/_script.js","../../../dev/templates/trip-dates-fees/script.js"],"sourcesContent":["export function isWistiaVideoPlaying() {\n\tlet isVideoPlaying = false;\n\n\tfunction wistiaVideo() {\n\t\tconst videoID = document.querySelector(\".js-wistia-video-id\").textContent;\n\t\tconst wistiaSrc = `https://fast.wistia.net/embed/iframe/${videoID}?videoFoam=true`;\n\n\t\tif (wistiaSrc === \"https://fast.wistia.net/embed/iframe/?videoFoam=true\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst wistiaIframe = document.querySelector(\".js-wistia-video\");\n\t\twistiaIframe.setAttribute(\"src\", wistiaSrc);\n\n\t\twindow._wq = window._wq || [];\n\t\tconst videoTitles = document.querySelector(\".js-video\");\n\t\tvideoTitles.addEventListener(\"click\", function (ev) {\n\t\t\tvideoTitles.classList.add(\"hide\");\n\t\t\tplayVideo();\n\t\t});\n\t\tfunction playVideo() {\n\t\t\tlet playStatus;\n\t\t\t_wq.push({\n\t\t\t\tid: \"_all\",\n\t\t\t\tonReady: function (video) {\n\t\t\t\t\tvideo.play();\n\t\t\t\t\tvideo.bind(\"play\", function () {\n\t\t\t\t\t\tplayStatus = true;\n\t\t\t\t\t\tvideoPlayStatus(playStatus);\n\t\t\t\t\t});\n\t\t\t\t\tvideo.bind(\"pause\", function () {\n\t\t\t\t\t\tplayStatus = false;\n\t\t\t\t\t\tvideoPlayStatus(playStatus);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\twistiaVideo();\n\n\tfunction videoPlayStatus(status) {\n\t\tisVideoPlaying = status;\n\t}\n\treturn isVideoPlaying;\n}\n","import { isWistiaVideoPlaying } from \"../../components/video-wistia/_script.js\";\n\nexport function isAdmin() {\n\tconst ensoElement = document.querySelector(\"[enso]\");\n\tconst ensoElementAttribute = ensoElement.getAttribute(\"enso\");\n\treturn Boolean(ensoElementAttribute);\n}\n\nexport function showForAdmin() {\n\tif (!isAdmin()) return;\n\n\tif (window.matchMedia(\"(max-width : 768px)\").matches) return;\n\n\tconst elements = document.querySelectorAll(\"[js-show-for-admin]\");\n\tfor (const element of elements) {\n\t\tconst getDisplayType = element.getAttribute(\"js-show-for-admin\");\n\t\telement.classList.remove(\"hide\");\n\t\telement.style.display = `${getDisplayType}`; // to pick up edge cases during migration\n\t}\n}\n\nexport function cleanupAnchorTags() {\n\t// Remove a tag if href is missing or undefined\n\t$(\"a\").each(function () {\n\t\tif ($(this).attr(\"href\") == \"\" || $(this).attr(\"href\") == \"undefined\") {\n\t\t\t$(this).remove();\n\t\t}\n\t});\n}\n\n// Check all a links to find target = _blank see above\nexport function cleanupAnchorTagsBlankTarget() {\n\tdocument.querySelectorAll(\"a\").forEach(function (link) {\n\t\tif (!link.hasAttribute(\"href\")) link.remove();\n\n\t\tconst linkHref = link.getAttribute(\"href\");\n\n\t\t// Add _blank to all links that go to Monster Campaigns so they open on top of our pages instead of being redirected to Monsty\n\t\tif (linkHref && linkHref.includes(\"https://app.monstercampaigns.com/\")) {\n\t\t\tlink.setAttribute(\"target\", \"_blank\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove all _blank from a tags on mobile and tablet\n\t\tif (document.documentElement.clientWidth < 1025) {\n\t\t\tlink.setAttribute(\"target\", \"_self\");\n\t\t}\n\t});\n}\n\nexport function pushEvent(item, action, label) {\n\ttry {\n\t\tdataLayer.push({\n\t\t\tevent: item,\n\t\t\taction: action,\n\t\t\tlabel: label\n\t\t});\n\t\tconsole.log(\"Success: Pushed Event via data layer:\", item, action, label);\n\t} catch (error) {\n\t\tconsole.log(\"Failed: Pushed Event:\", item, action, label, \"-\", error);\n\t}\n}\n\nexport function pushEventFacebook() {\n\ttry {\n\t\tfbq(\"track\", \"Lead\");\n\t} catch (error) {\n\t\tconsole.log(\"Failed : pushEventFacebook\");\n\t}\n}\n\nexport function pushEventBing() {\n\ttry {\n\t\twindow.uetq = window.uetq || [];\n\t\twindow.uetq.push({\n\t\t\tec: \"Lead\",\n\t\t\tea: \"Catalog_Request\"\n\t\t});\n\t} catch (error) {\n\t\t// console.log(\"Failed : pushEventBing\");\n\t}\n}\n\n// Function: get user's device size. This function is intentionally duplicated here to be available for global use. Second instance lives in resize-img.js\nexport function getBrowserDevice() {\n\tif (window.matchMedia(\"(max-width : 767px)\").matches) return \"mobile\";\n\tif (window.matchMedia(\"(min-width : 768px) AND (max-width : 1023px)\").matches) return \"tablet\";\n\tif (window.matchMedia(\"(min-width : 1024px)\").matches) return \"desktop\";\n\treturn \"unsure\";\n}\n\n// EVENT - Check for country local storage, set if not already set\nexport async function saveUserCountryToLocalStorage() {\n\tlet userCountry = localStorage.getItem(\"country\");\n\tif (userCountry === null) {\n\t\tuserCountry = await setUserCountry();\n\t}\n}\n\n// set user country in local storage\nasync function setUserCountry() {\n\ttry {\n\t\tlet response = await fetch(\"https://ipinfo.io/json?token=5ddc6962f801d5\");\n\t\tlet data = await response.json();\n\t\tlet userCountry = data.country || \"unknown\";\n\t\tlocalStorage.setItem(\"country\", userCountry);\n\t\treturn userCountry;\n\t} catch (err) {\n\t\tconsole.error(\"Failed to fetch user country.\", err);\n\t\treturn \"unknown\"; // Return a default value in case of an error\n\t}\n}\n\n// Function: check if any modal is open\nexport function checkForOpenModals() {\n\tconst isOpen = sessionStorage.getItem(\"modalOpen\") === \"true\";\n\treturn isOpen;\n}\n\n// Function: check if a wistia video is playing\nexport function checkIfWistiaVideoPlaying() {\n\tconst wistiaVideo = document.querySelector(\".js-video\");\n\tif (wistiaVideo && isWistiaVideoPlaying() !== undefined) {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n// vanilla wrapper to get cookie value\nexport function getCookie(name) {\n\tlet value = `; ${document.cookie}`;\n\tlet parts = value.split(`; ${name}=`);\n\tif (parts.length === 2) return parts.pop().split(\";\").shift();\n}\n\n// Utility to copy text to clipboard\nexport async function copyToClipboard(val) {\n\ttry {\n\t\tawait navigator.clipboard.writeText(val);\n\t} catch (err) {\n\t\tconsole.error(\"Failed to copy: \", err);\n\t}\n}\n\n// Utility to track browser size for Google Analytics -- are we using this?\nexport function browserSize() {\n\tlet width = window.innerWidth || document.body.clientWidth;\n\tlet height = window.innerHeight || document.body.clientHeight;\n\tlet size = width + \"x\" + height;\n\n\tlet browserSizeCookie = Cookies.get(\"browserSize\");\n\tif (browserSizeCookie === \"blocked\" || browserSizeCookie == null || browserSizeCookie != size) {\n\t\tbrowserSizeCookie = size;\n\t\tCookies.set(\"browserSize\", size, {\n\t\t\texpires: 365\n\t\t});\n\t\tpushEvent(\"Browser Size\", \"Range\", size);\n\t}\n}\n\n// Function: show hero photo credit if name has been entered in CMS\nexport function showHeroPhotoCredit() {\n\tconst photoCredit = document.querySelector(\"[js-hero-photo-credit]\");\n\tif (photoCredit) {\n\t\tconst creditText = photoCredit.textContent.trim();\n\t\tif (creditText.length > 2) {\n\t\t\tphotoCredit.classList.remove(\"hide\");\n\t\t} else {\n\t\t\tphotoCredit.classList.add(\"hide\");\n\t\t}\n\t}\n}\n\n// Need to run on page load but not a huge priority\nexport function setFavIcon() {\n\tconst favicon = document.querySelector(\"[js-set-favicon]\");\n\tconst mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\tif (!favicon) return;\n\tfunction updateFavicon() {\n\t\tfavicon.setAttribute(\"href\", mediaQuery.matches ? \"/assets/images/icons/favicon-dark-mode.png\" : \"/assets/images/icons/favicon-light-mode.png\");\n\t}\n\tupdateFavicon();\n\tmediaQuery.addEventListener(\"change\", updateFavicon);\n}\n\n// Track social icon clicks for GA\nexport function trackSocialClicks(links, area) {\n\tlet socialLinks = document.querySelectorAll(`[${links}]`);\n\tsocialLinks.forEach(function (link) {\n\t\tlink.addEventListener(\"click\", function () {\n\t\t\tlet platform = link.getAttribute(`${links}`);\n\t\t\tpushEvent(\"Clicks\", `Social ${area}`, `${platform}`);\n\t\t});\n\t});\n}\n\n// Functions: check if elements exist\nconst ensureElementExists = (elementSelector, limit) =>\n\tnew Promise((resolve, reject) => {\n\t\tlet count = 0;\n\t\tfunction waitForElement() {\n\t\t\tconst element = document.querySelector(elementSelector);\n\t\t\tif (element) return resolve(element);\n\t\t\tif (limit && count > limit) return false;\n\t\t\tcount += 1;\n\t\t\tsetTimeout(waitForElement, 100);\n\t\t}\n\t\twaitForElement();\n\t});\n\nexport const waitUntilElementExists = async (elementSelector, limit) => {\n\tconst response = await ensureElementExists(elementSelector, limit);\n\treturn response;\n};\n\nexport function addEnsoExample(selector) {\n\tconst element = document.querySelector(selector);\n\tconst elementText = element.innerText;\n\n\tif (element && elementText === \"\") element.classList.add(\"js-enso-example\");\n}\n\nexport function removeMissingImage() {\n\tconst images = document.querySelectorAll(\"[js-remove-missing-image]\");\n\timages.forEach((img) => {\n\t\tif (img.naturalWidth === 0) {\n\t\t\timg.remove();\n\t\t}\n\t});\n}\n","import { getBrowserDevice } from \"../../assets/js/utilities.js\";\n\n// check for breadcrumbs up to 4 levels deep and animate sticky hero elements\nexport function manageBreadcrumbs() {\n\tconst breadcrumbsBar = document.querySelector(\"[js-breadcrumbs-bar]\"); // desktop\n\tconst breadcrumbsListItems = document.querySelectorAll(\"[js-breadcrumbs-item]\"); // desktop and mobile\n\n\tbreadcrumbsListItems.forEach((item) => {\n\t\tif (item.textContent === \"\") item.remove();\n\t});\n\n\t// hide home link if no breadcrumbs (ie. 404 page)\n\tif (document.querySelector(\"[js-breadcrumbs-mobile-list]\") && document.querySelector(\"[js-breadcrumbs-mobile-list]\").innerText === \"\") {\n\t\tdocument.querySelector(\"[js-breadcrumbs-mobile-home-link]\").classList.add(\"hide\");\n\t}\n\n\tif (getBrowserDevice() === \"desktop\" && breadcrumbsBar) {\n\t\tScrollTrigger.create({\n\t\t\ttrigger: breadcrumbsBar,\n\t\t\tonUpdate: (self) => scale_breadcrumbs_pagename(self.direction, breadcrumbsBar)\n\t\t});\n\t}\n}\n\nwindow.addEventListener(\"resize\", manageBreadcrumbs);\n\nfunction scale_breadcrumbs_pagename(direction, breadcrumbsBar) {\n\tconst pageName = document.querySelector(\"[js-sticky-pagename]\");\n\tconst distanceToTop = 0.08;\n\tlet position = ScrollTrigger.positionInViewport(breadcrumbsBar, \"top\");\n\n\t// scrolling down\n\tif (direction === 1 && position < distanceToTop) scaleDown(pageName, breadcrumbsBar);\n\n\t// scrolling up\n\tif (direction === -1 && position > distanceToTop) scaleUp(pageName, breadcrumbsBar);\n}\n\nfunction scaleDown(pageName, breadcrumbsBar) {\n\tpageName.classList.add(\"js-transform-pagename\");\n\tbreadcrumbsBar.classList.add(\"js-transform-breadcrumbs\");\n}\n\nfunction scaleUp(pageName, breadcrumbsBar) {\n\tpageName.classList.remove(\"js-transform-pagename\");\n\tbreadcrumbsBar.classList.remove(\"js-transform-breadcrumbs\");\n}\n","import { pushEvent } from \"../../../assets/js/utilities.js\";\n\n// Book NOW Button - Set URL\nexport function bookNowButton() {\n\tlet finalSegment = window.location.pathname.split(\"/\");\n\tfinalSegment.pop();\n\tfinalSegment.shift();\n\tfinalSegment.shift();\n\tfinalSegment = `https://book.nathab.com/book-now/adventure/${finalSegment[0]}/`;\n\n\tconst bookButtons = document.querySelectorAll(\".js-book-init\");\n\tfor (const button of bookButtons) {\n\t\tbutton.setAttribute(\"href\", finalSegment);\n\t\tbutton.addEventListener(\"click\", function () {\n\t\t\tpushEvent(\"Misc\", \"Book Now\", \"Open\");\n\t\t});\n\t}\n}\n","// Hide header if text is empty\nexport function hideEmptyHeaders() {\n\t$(\"[dates~='text']\").each(function () {\n\t\tif (!$.trim($(this).html())) {\n\t\t\t$(this).hide();\n\t\t\t$(this).prev(\"h5\").hide();\n\t\t}\n\t});\n}\n\nexport function hideShowPricingAccordionsForAdmin() {\n\tconst pricingAccordions = document.querySelectorAll(\"[js-pricing-accordion]\");\n\tconst currentMonth = new Date().getMonth() + 1; // +1 for months 1-12 instead of 0-11\n\tconst currentYear = new Date().getFullYear();\n\n\tpricingAccordions.forEach((accordion) => {\n\t\tlet pricingYear = accordion.classList[1]; // pricing year;\n\t\tpricingYear = parseInt(pricingYear.replace(\"pricing-\", \"\")); // separate out year & make an int\n\n\t\tlet showForAdmin = false;\n\t\tconst yearsToShow = [currentYear, currentYear + 1, currentYear + 2, currentYear + 3]; // this year and the next 3 years\n\n\t\t// show last year for admin until march and any years in the yearsToShow array\n\t\tif ((pricingYear + 1 === currentYear && currentMonth < 3) || yearsToShow.includes(pricingYear)) showForAdmin = true;\n\n\t\tif (showForAdmin) accordion.setAttribute(\"js-show-for-admin\", \"block\");\n\t});\n}\n\nexport function hide_max_travelers_if_empty() {\n\tconst limitedToElement = document.querySelector(\"[js-hide-if-no-travelers]\");\n\tconst maxTravelers = document.querySelector(\"[js-get-max-travelers]\");\n\n\tif (!limitedToElement || !maxTravelers) return;\n\n\tif (!maxTravelers.textContent.trim()) limitedToElement.classList.add(\"hide\");\n}\n\nexport async function add_pricing_to_overview_pages() {\n\tconst pricingElement = document.querySelector(\"[js-override-tigress-price]\");\n\tif (!pricingElement) return;\n\n\tconst pricingSuffix = document.querySelector(\"[js-get-pricing-suffix]\");\n\n\tif (pricingElement.getAttribute(\"js-override-tigress-price\") === \"yes\") {\n\t\tnormalize_database_pricing(pricingElement);\n\t\treturn;\n\t}\n\n\tconst pricingData = await fetch_pricing_data();\n\tconst fromPrice = get_lowest_trip_price(pricingData, window.location.pathname, false);\n\n\tset_lowest_tigress_trip_price(pricingElement, fromPrice, pricingSuffix);\n}\n\nexport async function add_pricing_to_repeaters() {\n\tconst repeaterPricingElements = document.querySelectorAll(\"[js-get-repeater-trip-pricing].show\");\n\tconst pricingData = await fetch_pricing_data();\n\n\tfor (const repeater of repeaterPricingElements) {\n\t\tconst pricingElement = repeater.querySelector(\"[js-override-tigress-price]\");\n\t\tconst hrefElement = repeater.closest(\"[js-get-trip-href]\");\n\t\tif (!pricingElement || !hrefElement) continue;\n\n\t\tconst tripUrl = hrefElement.getAttribute(\"js-get-trip-href\");\n\t\tconst pricingSuffix = repeater.querySelector(\"[js-get-pricing-suffix]\");\n\n\t\tif (pricingElement.getAttribute(\"js-override-tigress-price\") === \"yes\") {\n\t\t\tnormalize_database_pricing(pricingElement);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst wiwTrip = hrefElement.hasAttribute(\"js-wiw-trip\") ? true : false;\n\t\tconst fromPrice = get_lowest_trip_price(pricingData, tripUrl, wiwTrip);\n\t\tset_lowest_tigress_trip_price(pricingElement, fromPrice, pricingSuffix);\n\t}\n}\n\nasync function fetch_pricing_data() {\n\ttry {\n\t\tconst response = await fetch(\"/_data/new-prices.json\");\n\t\tconst data = await response.json();\n\t\treturn data.tripData;\n\t} catch (error) {\n\t\tconsole.error(\"Error fetching prices:\", error);\n\t\treturn [];\n\t}\n}\n\nfunction get_lowest_trip_price(pricingData, url, wiwTrip) {\n\tconst currentDate = new Date();\n\tconst currentYear = currentDate.getFullYear();\n\tconst allYears = currentYear + 2; // look 2 years out per Maya\n\tconst prices = [];\n\n\tpricingData.forEach((trip) => {\n\t\tconst tripUrl = trip.repeaterURL;\n\t\tconst departureDate = new Date(trip.departure);\n\t\tconst departureYear = departureDate.getFullYear();\n\t\tconst notes = trip.notes;\n\n\t\tconst isMatchingUrl = tripUrl === url;\n\t\tconst isFutureDeparture = departureDate >= currentDate;\n\t\tconst isWithinAllowedYears = departureYear <= allYears;\n\t\tconst isWomenOnlyTrip = !wiwTrip || (notes && notes.includes(\"Women\"));\n\n\t\tif (isMatchingUrl && isFutureDeparture && isWithinAllowedYears && isWomenOnlyTrip) {\n\t\t\tconst priceMatch = trip.pricing.match(/\\$(\\d{1,3},\\d{3}|\\d+)/gm);\n\t\t\tif (priceMatch) priceMatch.forEach((price) => prices.push(Number(price.replace(\"$\", \"\").replace(\",\", \"\"))));\n\t\t}\n\t});\n\n\treturn prices.length ? Math.min(...prices) : null; // Return the lowest price or null if no valid prices found\n}\n\nfunction set_lowest_tigress_trip_price(pricingElement, fromPrice, pricingSuffix) {\n\tconst suffixText = pricingSuffix ? pricingSuffix.textContent : \"\";\n\n\tfromPrice ? (pricingElement.textContent = `From $${fromPrice} ${suffixText}`) : normalize_database_pricing(pricingElement);\n}\n\nfunction normalize_database_pricing(pricingElement) {\n\tconst pricingTextContent = pricingElement.textContent;\n\tpricingElement.textContent = pricingTextContent.replace(\"From\", \"\");\n\n\tif (pricingTextContent.includes(\"$\")) pricingElement.textContent = `From ${pricingTextContent}`;\n}\n","import { pushEvent, getCookie, getBrowserDevice, checkForOpenModals, checkIfWistiaVideoPlaying, waitUntilElementExists } from \"../../assets/js/utilities.js\";\n\nexport function olarkLoader() {\n\tlet isChatBoxOpen = false;\n\tlet modalAndVideoCheck = true;\n\tlet isOperatorAvailable = \"blocked\"; // default state\n\tlet chatCookieCheck;\n\tconst browserDevice = getBrowserDevice();\n\tconst chatCookieMaxAge = \"43200\"; // 43200 seconds = 12 hours\n\tconst userActionAutopopDelay = 15000; // 15 seconds\n\n\tdocument.addEventListener(\"readystatechange\", (event) => {\n\t\tif (event.target.readyState === \"complete\") {\n\t\t\tconst chatButtonDesktop = document.querySelector(\".js-chat-button-desktop\");\n\t\t\tconst chatButtonMobileBanner = document.querySelector(\".js-chat-banner-mobile\");\n\t\t\tconst chatButtonMobile = document.querySelector(\".js-chat-button-mobile\");\n\t\t\tconst chatMobileDrawerLabel = document.querySelector(\"[js-click-toggle~='contact']\");\n\t\t\tconst chatMobileDrawerToggle = document.querySelector(\"[js-close-chat]\");\n\n\t\t\tolark(\"api.chat.onReady\", function () {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tisOperatorAvailable = checkChatStatus();\n\t\t\t\t\tautoPopChatAfterXSeconds(isOperatorAvailable); // function call for 90 second auto popup\n\t\t\t\t\tif (isOperatorAvailable !== \"blocked\" && browserDevice !== \"mobile\") {\n\t\t\t\t\t\tchatButtonDesktop.classList.remove(\"hide\");\n\t\t\t\t\t} else if (isOperatorAvailable !== \"blocked\" && browserDevice == \"mobile\") {\n\t\t\t\t\t\tchatButtonMobileBanner.classList.remove(\"hide\");\n\t\t\t\t\t\tchatButtonMobile.classList.remove(\"hide\");\n\t\t\t\t\t}\n\t\t\t\t}, 2000);\n\t\t\t\tolark(\"api.box.shrink\");\n\t\t\t});\n\n\t\t\t// For when the box is expanded either from a button click or operator initiated\n\t\t\tolark(\"api.box.onExpand\", function () {\n\t\t\t\tisChatBoxOpen = true;\n\t\t\t\tif (browserDevice !== \"mobile\") {\n\t\t\t\t\tchatButtonDesktop.classList.add(\"hide\");\n\t\t\t\t}\n\t\t\t\tif (browserDevice === \"mobile\") {\n\t\t\t\t\tchatMobileDrawerLabel.click();\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tolark(\"api.box.expand\");\n\t\t\t\t\t}, 100);\n\t\t\t\t}\n\n\t\t\t\t// check if session has been set to remove consent message\n\t\t\t\tlet showConsent = sessionStorage.getItem(\"showConsent\");\n\t\t\t\tif (showConsent === \"false\") {\n\t\t\t\t\tconst consentMessageDiv = document.querySelector(\".olark-gdpr-consent-message\");\n\t\t\t\t\tif (consentMessageDiv) {\n\t\t\t\t\t\tconsentMessageDiv.remove();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// When chat is opened, call function to decide if enews consent box is displayed and gets pre-checked\n\t\t\t\tshouldEmailConsentBeDisplayed();\n\t\t\t});\n\n\t\t\tolark(\"api.box.onShow\", function () {\n\t\t\t\tisChatBoxOpen = true;\n\t\t\t\tchatButtonDesktop.classList.add(\"hide\");\n\t\t\t});\n\n\t\t\t// For when the box is shrunk either from a button click\n\t\t\tolark(\"api.box.onShrink\", function () {\n\t\t\t\tisChatBoxOpen = false;\n\t\t\t\tchatButtonDesktop.classList.remove(\"hide\");\n\t\t\t\tchatButtonDesktop.classList.remove(\"animate__animated\");\n\n\t\t\t\tif (browserDevice == \"mobile\") {\n\t\t\t\t\tchatMobileDrawerToggle.click();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tolark(\"api.box.onHide\", function () {\n\t\t\t\tisChatBoxOpen = false;\n\t\t\t\tchatButtonDesktop.classList.remove(\"hide\");\n\t\t\t\tchatButtonDesktop.classList.remove(\"animate__animated\");\n\n\t\t\t\tif (browserDevice == \"mobile\") {\n\t\t\t\t\tchatMobileDrawerToggle.click();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// For when the operator sends a message on mobile only\n\t\t\tolark(\"api.chat.onMessageToVisitor\", function (event) {\n\t\t\t\tisOperatorAvailable = checkChatStatus();\n\t\t\t\tif (browserDevice === \"mobile\" && isOperatorAvailable) {\n\t\t\t\t\tolark(\"api.box.expand\");\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Callback if operator is available\n\t\t\tolark(\"api.chat.onOperatorsAvailable\", function () {\n\t\t\t\tisOperatorAvailable = checkChatStatus();\n\t\t\t\tautoPopChatAfterXSeconds(isOperatorAvailable);\n\t\t\t});\n\n\t\t\t// Disappear consent button on first message to operator when chat is online\n\t\t\tolark(\"api.chat.onMessageToOperator\", function (e) {\n\t\t\t\tconst consentMessageDiv = document.querySelector(\".olark-gdpr-consent-message\");\n\t\t\t\tconsentMessageDiv.remove();\n\t\t\t\t// set session so div is removed when user goes to a new page\n\t\t\t\tsessionStorage.setItem(\"showConsent\", \"false\");\n\t\t\t});\n\n\t\t\t// CLICK LISTENERS\n\t\t\t// Add click listener to mobile button on contact drawer\n\t\t\tchatButtonMobile.addEventListener(\"click\", function (e) {\n\t\t\t\tolark(\"api.box.expand\");\n\t\t\t});\n\n\t\t\t// Add click listener to mobile banner\n\t\t\tchatButtonMobileBanner.addEventListener(\"click\", function (e) {\n\t\t\t\tchatMobileDrawerLabel.click();\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tolark(\"api.box.expand\");\n\t\t\t\t}, 100);\n\t\t\t\tpushEvent(\"Olark_Chat\", \"Button Click\", \"Mobile\");\n\t\t\t});\n\n\t\t\t// Add click listener to desktop button\n\t\t\tchatButtonDesktop.addEventListener(\"click\", function (e) {\n\t\t\t\tolark(\"api.box.expand\");\n\t\t\t\tpushEvent(\"Olark_Chat\", \"Button Click\", \"Desktop\");\n\t\t\t});\n\n\t\t\t// check for session value in case user went to different page before the 15 second timeout allowed chat to autopop after user action\n\t\t\tchatCookieCheck = cookieValueCheck(\"chatAutoPopupSession\");\n\t\t\tif (chatCookieCheck > userActionAutopopDelay) {\n\t\t\t\topenChat(isOperatorAvailable);\n\t\t\t\t// set auto popup cookies to prevent more auto popups\n\t\t\t\tsetAutoPopupCookie(\"chatAutoPopup\", chatCookieMaxAge);\n\t\t\t}\n\t\t}\n\t});\n\n\t// MAIN FUNCTIONS FOR EMAIL CONSENT BOX\n\tfunction shouldEmailConsentBeDisplayed() {\n\t\tconst consentMessageDiv = document.querySelector(\".olark-gdpr-consent-message\");\n\t\tconst consentButton = document.querySelector(\".olark-gdpr-consent-checkbox\");\n\n\t\tif (consentButton && consentButton.classList.contains(\"olark-gdpr-consent-checked\")) {\n\t\t\tconsentMessageDiv.remove();\n\t\t}\n\t\tconst onlineStartChatButton = document.querySelector(\".olark-button.olark-survey-form-submit\"); // when chat is online, this exists and email consent is displayed\n\t\tconst offlineNextButton = document.querySelector(\".olark-button.olark-survey-form-nav\"); // when chat is offline, this exists and email consent is not displayed\n\n\t\t// when chat is online, listen for chat start button and call function to decide if enews consent gets checked and set cookies so no autopop happens\n\t\tif (onlineStartChatButton) {\n\t\t\tonlineStartChatButton.addEventListener(\"click\", function () {\n\t\t\t\tpreCheckConsent(\"online\");\n\t\t\t\tsetAutoPopupCookie(\"chatAutoPopup\", chatCookieMaxAge);\n\t\t\t\tsetAutoPopupCookie(\"chatAutoPopupBlock\", chatCookieMaxAge);\n\t\t\t});\n\t\t}\n\n\t\t// when chat is offline, add click listener, call function to decide if enews consent gets checked and call next function\n\t\tif (offlineNextButton) {\n\t\t\tofflineNextButton.addEventListener(\"click\", offlinePageTwo);\n\t\t\tpreCheckConsent(\"offline\");\n\t\t}\n\t}\n\n\t// Precheck email consent box for users in US, India, and Australia when chat is online and add privacy policy\n\tfunction preCheckConsent(chatStatus) {\n\t\tlet consentButtonClass;\n\t\tlet consentMessageDivClass;\n\t\tconst privacyPolicy = 'Privacy Policy';\n\n\t\tif (chatStatus === \"online\") {\n\t\t\tconsentButtonClass = \".olark-gdpr-consent-checkbox\";\n\t\t\tconsentMessageDivClass = \".olark-gdpr-consent-message\";\n\t\t}\n\t\tif (chatStatus === \"offline\") {\n\t\t\tconsentButtonClass = \".olark-survey-form-input.olark-survey-form-checkbox\";\n\t\t\tconsentMessageDivClass = \".olark-survey-form-input-wrap\";\n\t\t}\n\n\t\twaitUntilElementExists(consentButtonClass).then(countryCheck);\n\t\twaitUntilElementExists(consentMessageDivClass).then(insertPrivacyPolicy);\n\n\t\tfunction countryCheck() {\n\t\t\tlet userCountry = localStorage.getItem(\"country\") || \"unknown\";\n\t\t\tconst consentButton = document.querySelector(consentButtonClass);\n\t\t\tif (userCountry === \"US\" || userCountry === \"IN\" || userCountry === \"AU\") {\n\t\t\t\tif (consentButton.checked === false) {\n\t\t\t\t\tconsentButton.click();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction insertPrivacyPolicy() {\n\t\t\tconst consentMessageDiv = document.querySelector(consentMessageDivClass);\n\t\t\tconst privacyPolicyElement = document.querySelector(\".js-chat-button-privacy\");\n\t\t\tif (!privacyPolicyElement) {\n\t\t\t\tconsentMessageDiv.insertAdjacentHTML(\"beforeend\", privacyPolicy);\n\t\t\t}\n\t\t}\n\t}\n\n\t// When chat is offline, switch mailbox icon to eNews icon on page 2\n\tfunction offlinePageTwo() {\n\t\tdocument.querySelector(\".olark-button\").removeEventListener(\"click\", offlinePageTwo);\n\t\tconst mailboxIconClass = \".olark-survey-form-emoji-wrap svg\";\n\t\twaitUntilElementExists(mailboxIconClass).then(iconSwitch);\n\n\t\tfunction iconSwitch() {\n\t\t\tconst mailboxIcon = document.querySelector(mailboxIconClass);\n\t\t\tconst enewsIcon = '';\n\t\t\tconst enewsIconElement = document.querySelector(\".js-chat-enews-icon\");\n\t\t\tif (!enewsIconElement) {\n\t\t\t\tmailboxIcon.insertAdjacentHTML(\"beforebegin\", enewsIcon);\n\t\t\t}\n\t\t}\n\t}\n\n\t// MAIN FUNCTIONS TO AUTO POPUP CHAT\n\t// Initial 90 second chat auto popup\n\tfunction autoPopChatAfterXSeconds(isOperatorAvailable) {\n\t\tconst autopopDelay = 90000; // 90 seconds\n\t\t// const autopopDelay = 15000; // 15 seconds for testing\n\n\t\t// auto popup chat only on desktop && if operator is online\n\t\tif (browserDevice !== \"desktop\" || isOperatorAvailable !== true) {\n\t\t\treturn;\n\t\t}\n\n\t\t// autopop only if chat is online, autopop blocking cookie is not set, and at least 90 seconds have passed\n\t\tlet chatCookieCheck = cookieValueCheck(\"chatAutoPopup\");\n\t\tif (getCookie(\"chatAutoPopupBlock\") === \"true\" || chatCookieCheck < autopopDelay) {\n\t\t\treturn;\n\t\t}\n\n\t\t// set cookie if not already set\n\t\tif (chatCookieCheck === \"none\") {\n\t\t\tsetAutoPopupCookie(\"chatAutoPopup\", chatCookieMaxAge);\n\t\t\treturn;\n\t\t}\n\n\t\t// if no modal is open and no video is playing, auto pop chat and set cookies\n\t\tmodalAndVideoCheck = callOpenModalAndVideoFunctions();\n\t\tif (modalAndVideoCheck === false) {\n\t\t\topenChat(isOperatorAvailable);\n\t\t\tsetAutoPopupCookie(\"chatAutoPopup\", \"0\"); //remove (expire) cookie so other auto popup works\n\t\t\tsetAutoPopupCookie(\"chatAutoPopupBlock\", chatCookieMaxAge);\n\t\t}\n\t}\n}\n\n// User-action-initiated chat auto popup occurs after user submits Ask a Question, Send Us a Message, or downloads PDF forms or opens a date or pricing accordion\nexport function autoPopChatUserAction(inputID) {\n\tconst inputDiv = document.querySelector(inputID);\n\tconst bodyDiv = document.querySelector(\"body\");\n\tconst userActionAutopopDelay = 15000; // 15 seconds\n\tlet modalInputDiv;\n\tlet accordionInputDiv;\n\n\t// auto popup chat only on desktop && if operator is online\n\tlet isOperatorAvailable = checkChatStatus();\n\tif (getBrowserDevice() !== \"desktop\" || isOperatorAvailable !== true) {\n\t\treturn;\n\t}\n\n\t// assign variable whether modal or accordion to determine how chat auto popup is executed\n\tif (inputDiv.hasAttribute(\"accordion\")) {\n\t\taccordionInputDiv = inputDiv;\n\t} else {\n\t\tmodalInputDiv = inputDiv;\n\t}\n\n\t// if input that triggered function is an open modal, add click listener to know when it's closed\n\tif (modalInputDiv && modalInputDiv.checked) {\n\t\tbodyDiv.addEventListener(\"click\", shouldChatAutoPop);\n\t}\n\n\t// if input that triggered function is an open accordion, call chat auto popup to open on top of accordion\n\tif (accordionInputDiv) {\n\t\tshouldChatAutoPop();\n\t}\n\n\tfunction shouldChatAutoPop() {\n\t\tconst chatCookieMaxAge = \"43200\"; // 43200 seconds = 12 hours\n\n\t\t// don't auto popup chat if the form is still open\n\t\tif (modalInputDiv && modalInputDiv.checked) {\n\t\t\treturn;\n\t\t}\n\t\t// don't auto popup chat if user action autopop has happened within 12 hours (both cookies have a value)\n\t\tlet chatCookieCheck = cookieValueCheck(\"chatAutoPopup\");\n\t\tif (chatCookieCheck !== \"none\" && getCookie(\"chatAutoPopupBlock\") === \"true\") {\n\t\t\treturn;\n\t\t}\n\t\t// don't auto popup chat if any modal is open or video is playing\n\t\tlet modalAndVideoCheck = callOpenModalAndVideoFunctions();\n\t\tif (modalAndVideoCheck === true) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (modalInputDiv || (accordionInputDiv && accordionInputDiv.checked)) {\n\t\t\t// set session in case user goes to a new page before chat is auto popped\n\t\t\tsessionStorage.setItem(\"chatAutoPopupSession\", Number(Date.now()));\n\n\t\t\t// 15 second delay\n\t\t\tsetTimeout(function () {\n\t\t\t\t// need to recheck this in case modal or video opened after Thank You message closed and before chat is popped\n\t\t\t\tmodalAndVideoCheck = callOpenModalAndVideoFunctions();\n\t\t\t\tif (modalAndVideoCheck === true) {\n\t\t\t\t\tbodyDiv.addEventListener(\"click\", () => {\n\t\t\t\t\t\tmodalAndVideoCloseTimerForAccordion(isOperatorAvailable);\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (getCookie(\"chatAutoPopupBlock\") === \"true\") return;\n\n\t\t\t\topenChat(isOperatorAvailable);\n\t\t\t\tif (chatCookieCheck === \"none\") {\n\t\t\t\t\tsetAutoPopupCookie(\"chatAutoPopup\", chatCookieMaxAge);\n\t\t\t\t}\n\t\t\t\tsetAutoPopupCookie(\"chatAutoPopupBlock\", chatCookieMaxAge);\n\n\t\t\t\t// remove listener on all accordions after the first one is opened and triggers chat auto popup\n\t\t\t\tif (accordionInputDiv && accordionInputDiv.checked) {\n\t\t\t\t\tremoveAccordionClickListener();\n\t\t\t\t}\n\t\t\t}, userActionAutopopDelay);\n\t\t}\n\t}\n}\n\n// AUTO POPUP HELPER FUNCTIONS\n// Check online/offline chat status\nfunction checkChatStatus() {\n\tconst chatButtonDesktop = document.querySelector(\".js-chat-button-desktop\");\n\tif (chatButtonDesktop.classList.contains(\"chatoff\")) {\n\t\treturn false;\n\t}\n\tconst olarkTopBarText = document.querySelector(\".olark-top-bar-text\");\n\tif (!olarkTopBarText) {\n\t\treturn \"blocked\"; // olark not rendered so likely blocking 3rd party cookies\n\t}\n\n\tif (olarkTopBarText.textContent.toLowerCase().includes(\"offline\")) {\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n}\n\n// As a pre-condition to auto popping chat, call functions to check if any modal is open or a video is playing\nexport function callOpenModalAndVideoFunctions() {\n\tlet isModalOpen = checkForOpenModals();\n\tlet wistiaVideoPlayStatus = checkIfWistiaVideoPlaying();\n\tif (isModalOpen === false && wistiaVideoPlayStatus === false) {\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n}\n\n// Remove click listeners on all accordions after one has been opened and triggered chat auto pop\nfunction removeAccordionClickListener() {\n\tconst datesAndPricingAccordions = document.querySelectorAll('[accordion=\"checkbox\"]');\n\tdatesAndPricingAccordions.forEach(function (accordion) {\n\t\taccordion.removeEventListener(\"click\", accordionClickListener);\n\t});\n}\n\n// Timer function in case user has opened modal/video after accordion timer is set and before chat popup happens to pop chat after modal/video is closed\nfunction modalAndVideoCloseTimerForAccordion(isOperatorAvailable) {\n\tconst closeTimerDelay = 1500; // 1.5 second delay\n\tconst bodyDiv = document.querySelector(\"body\");\n\n\tconst modalAndVideoCheck = callOpenModalAndVideoFunctions();\n\tif (modalAndVideoCheck === false) {\n\t\tsetTimeout(function () {\n\t\t\topenChat(isOperatorAvailable);\n\t\t\tbodyDiv.removeEventListener(\"click\", () => {\n\t\t\t\tmodalAndVideoCloseTimerForAccordion(isOperatorAvailable);\n\t\t\t});\n\t\t\tremoveAccordionClickListener(); // remove listener on all accordions after the first one is open and triggers chat auto popup\n\t\t\tlet chatCookieCheck = cookieValueCheck();\n\t\t\tif (chatCookieCheck === \"none\") {\n\t\t\t\tsetAutoPopupCookie(\"chatAutoPopup\", chatCookieMaxAge);\n\t\t\t}\n\t\t\tsetAutoPopupCookie(\"chatAutoPopupBlock\", chatCookieMaxAge);\n\t\t}, closeTimerDelay);\n\t}\n}\n\n// UTILITY FUNCTIONS\n// Utility function to check cookie or session\nfunction cookieValueCheck(cookie) {\n\tlet currentTime = Number(Date.now());\n\tlet currentCookieValue;\n\tif (cookie === \"chatAutoPopupSession\") {\n\t\tcurrentCookieValue = sessionStorage.getItem(\"chatAutoPopupSession\") || currentTime;\n\t} else {\n\t\tcurrentCookieValue = Number(getCookie(`${cookie}`) || currentTime);\n\t}\n\tlet timeDiff = currentTime - currentCookieValue;\n\tif (cookie === \"chatAutoPopupSession\") {\n\t\treturn timeDiff;\n\t}\n\tif (currentCookieValue === currentTime) {\n\t\treturn \"none\";\n\t} else {\n\t\treturn timeDiff;\n\t}\n}\n\n// Utility function to set cookie\nfunction setAutoPopupCookie(cookie, expiration) {\n\tlet currentTime = Number(Date.now());\n\tlet autoPopupCookieValue;\n\tif (cookie === \"chatAutoPopup\") {\n\t\tautoPopupCookieValue = currentTime;\n\t}\n\tif (cookie === \"chatAutoPopupBlock\") {\n\t\tautoPopupCookieValue = \"true\";\n\t}\n\tdocument.cookie = `${cookie}=${autoPopupCookieValue}; path=/; domain=nathab.com; max-age=${expiration}`; // 43200 = 12 hour expiration, seconds\n}\n\n// Utility function to auto open chat, clear session, and push event\nfunction openChat(isOperatorAvailable) {\n\tif (isOperatorAvailable !== true) return;\n\tolark(\"api.box.expand\");\n\tpushEvent(\"Olark_Chat\", \"Auto Popup\");\n\tsessionStorage.removeItem(\"chatAutoPopupSession\");\n\n\tconst chatButtonStartChatClass = \".olark-button.olark-survey-form-submit\";\n\twaitUntilElementExists(chatButtonStartChatClass).then(chatStartClickListener);\n\n\tfunction chatStartClickListener() {\n\t\tconst chatButtonStartChat = document.querySelector(chatButtonStartChatClass);\n\t\tchatButtonStartChat.addEventListener(\"click\", function (e) {\n\t\t\tpushEvent(\"Olark_Chat\", \"Auto Popup\", \"Chat Started\");\n\t\t});\n\t}\n}\n// Utility function to check whether chat box open\nexport function isChatOpen() {\n\tconst olarkContainer = document.querySelector(\"#olark-container\");\n\tlet isChatBoxOpen = false;\n\n\tif (olarkContainer && !olarkContainer.classList.contains(\"olark-hidden\")) {\n\t\tisChatBoxOpen = true;\n\t}\n\n\treturn isChatBoxOpen;\n}\n\n// add click listener and auto popup chat when accordion is opened, gets called after dates accordion is dynamically built\nexport function autoPopupChatAccordionClickListener() {\n\tconst datesAndPricingAccordions = document.querySelectorAll('[accordion=\"checkbox\"]');\n\tdatesAndPricingAccordions.forEach(function (accordion) {\n\t\taccordion.addEventListener(\"click\", accordionClickListener);\n\t});\n}\n\nfunction accordionClickListener(event) {\n\tif (event.target.checked) {\n\t\tlet accordionID = event.target.getAttribute(\"id\");\n\t\tautoPopChatUserAction(`input[id=\"${accordionID}\"]`); // NOW THAT OLARK IS WRAPPED IN FUNCTION, THIS ISN'T AVAILABLE FOR USE HERE\n\t}\n}\n","//\n\n// Is there a better way to handle this like [enso].js-enso-on?\n\n// Function - Modernize Enso\nexport function enso() {\n\tconst ensoElements = [...document.querySelectorAll(\".enso-overlay-link\")];\n\n\tif (!ensoElements) return;\n\tfor (const element of ensoElements) {\n\t\tlet ensoOverlayContentElement = element.closest(\".enso-overlay-content\");\n\t\tlet ensoElement = ensoOverlayContentElement.closest(\"[enso]\");\n\t\tcopyEnsoLinkToParentAttribute(element);\n\t\telement.remove();\n\t\tunWrap(ensoOverlayContentElement);\n\t\tensoOverlayContentElement.remove();\n\t\taddTabKeyDownEvent(ensoElement);\n\t}\n}\n\n// FUNCTION - Move Enso Link to parent element with enso attribute\nfunction copyEnsoLinkToParentAttribute(element) {\n\tlet getLink = element.getAttribute(\"onclick\");\n\tgetLink = getLink.replace('self.location.href=\"', \"\").replace('\"', \"\");\n\tlet targetEnso = element.closest(\"[enso]\");\n\tif (targetEnso) {\n\t\ttargetEnso.setAttribute(\"enso\", getLink);\n\t}\n}\n\n// Function - Upwrap element\nfunction unWrap(element) {\n\tconst parent = element.parentNode;\n\twhile (element.firstChild) {\n\t\tparent.insertBefore(element.firstChild, element);\n\t}\n}\n\n// Function - Add in tab keydown event\nfunction addTabKeyDownEvent(element) {\n\tlet overlayVisible = false;\n\tdocument.addEventListener(\"keydown\", (event) => {\n\t\tif (event.key === \"Tab\" && element) {\n\t\t\tevent.preventDefault();\n\t\t\toverlayVisible = !overlayVisible;\n\t\t\tif (overlayVisible) {\n\t\t\t\telement.classList.add(\"js-enso-on\");\n\t\t\t\taddEnsoClickListener(element);\n\t\t\t} else {\n\t\t\t\telement.classList.remove(\"js-enso-on\");\n\t\t\t\tremoveEnsoClickListener(element);\n\t\t\t}\n\t\t}\n\t});\n}\n\n// Function - Setup link href\nfunction setupLink(e) {\n\te.preventDefault();\n\tlet goToUrl = this.getAttribute(\"enso\"); // this was the key\n\twindow.location.href = goToUrl;\n}\n\n// Function - Add click event listener\nfunction addEnsoClickListener(element) {\n\telement.addEventListener(\"click\", setupLink, false);\n}\n\n// Function - Remove click event listener\nfunction removeEnsoClickListener(element) {\n\telement.removeEventListener(\"click\", setupLink);\n}\n","export function isDialogSupported() {\n\t// Directly check for the existence of HTMLDialogElement in the window\n\tif (!window.HTMLDialogElement) return false;\n\n\t// Check if 'show' and 'close' methods are part of the HTMLDialogElement's prototype\n\tconst dialogPrototype = window.HTMLDialogElement.prototype;\n\n\t// Return boolean\n\treturn typeof dialogPrototype.show === \"function\" && typeof dialogPrototype.close === \"function\";\n}\n","import { checkForOpenModals } from \"../../assets/js/utilities.js\";\n\nexport function observeAmbientVideo() {\n\tsessionStorage.setItem(\"modalOpen\", false);\n\n\t// select it\n\tconst videos = document.querySelectorAll(\"[js-ambient-video]\");\n\n\t// check it\n\tif (videos.length === 0) return;\n\n\t// func call to assign active video, return active video element\n\tlet activeVideo = assignActiveAmbientVideo(videos);\n\n\t// resize event listener to call func to reassign active video\n\twindow.addEventListener(\"resize\", () => {\n\t\tactiveVideo = assignActiveAmbientVideo(videos);\n\t});\n\n\t// visibility event listener to call func to pause video when tab is not active\n\tdocument.addEventListener(\"visibilitychange\", () => {\n\t\thandleVisibilityChange(activeVideo);\n\t});\n\n\t// create an observer instance\n\tlet observer = new IntersectionObserver(playOrPauseAmbientVideo, {\n\t\tthreshold: 0.5 // Adjust as necessary\n\t});\n\n\t// observe active video\n\tif (activeVideo) observer.observe(activeVideo);\n}\n\n// play or pause based on tab visibility\nfunction handleVisibilityChange(activeVideo) {\n\tif (checkForOpenModals()) return;\n\n\ttoggleAmbientVideo(!document.hidden, activeVideo);\n}\n\n// find the active video\nfunction assignActiveAmbientVideo(videos) {\n\tconst isMobile = window.matchMedia(\"(orientation: portrait)\").matches;\n\n\tconst activeVideo = Array.from(videos).find((video) => {\n\t\tconst deviceType = isMobile ? \"mobile\" : \"desktop\";\n\t\tconst videoAttribute = video.getAttribute(\"js-ambient-video\");\n\n\t\tif (videoAttribute !== deviceType) {\n\t\t\ttoggleAmbientVideo(false, video); // Pause the video if it's not for the current device type\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t});\n\n\tif (activeVideo) activeVideo.classList.add(\"active\");\n\n\treturn activeVideo;\n}\n\n// play or pause based on intersection and tab visibility\nfunction playOrPauseAmbientVideo(entries) {\n\tentries.forEach((entry) => {\n\t\tlet isModalOpen = checkForOpenModals();\n\t\tif (entry.isIntersecting && !document.hidden && !isModalOpen) {\n\t\t\ttoggleAmbientVideo(true, entry.target);\n\t\t} else {\n\t\t\ttoggleAmbientVideo(false, entry.target);\n\t\t}\n\t});\n}\n\nfunction isAmbientVideoPlaying(videoElement) {\n\treturn !videoElement.paused;\n}\n\nexport function toggleAmbientVideo(shouldPlay, videoElement = null) {\n\t// If a specific video element is provided, use it\n\tif (videoElement) {\n\t\tshouldPlay ? videoElement.play() : videoElement.pause();\n\t\treturn;\n\t}\n\t// Otherwise, find the active video\n\tconst activeVideo = document.querySelector(\"[js-ambient-video].active\");\n\n\tif (activeVideo) shouldPlay ? activeVideo.play() : activeVideo.pause();\n}\n","import { isDialogSupported } from \"../_script.js\";\nimport { pushEvent, isAdmin } from \"../../../assets/js/utilities.js\";\nimport { enso } from \"../../../components/enso/_script.js\";\nimport { copyToClipboard } from \"../../../assets/js/utilities.js\";\nimport { toggleAmbientVideo } from \"../../../components/hero/_video.js\";\n\nexport async function check_url_for_generic_modal() {\n\tlet querySearch = window.location.search;\n\tconst genericQueryPatterns = [/^\\?lightbox=\\/-lightboxes\\/.+/, /^\\?modal=\\/-lightboxes\\/.+/];\n\n\t// Check if the query string matches the generic patterns\n\tif (genericQueryPatterns.some((pattern) => pattern.test(querySearch))) {\n\t\tquerySearch = normalize_generic_modal_path(querySearch);\n\t\tconst targetModalSelector = `[js-modal-generic-url=\"${querySearch}\"]`;\n\t\tlet targetModal = document.querySelector(targetModalSelector);\n\t\tif (!targetModal) {\n\t\t\ttargetModal = await fetch_generic_modal_dialog(querySearch, targetModalSelector);\n\t\t}\n\t\tshowDialog(targetModal);\n\t\tadd_event_close_modal_via_backdrop(targetModal);\n\t\tadd_event_close_modal_via_button(targetModal);\n\t\tadd_event_close_modal_via_esc(targetModal);\n\t\tenso();\n\t}\n}\n\nexport function check_links_for_generic_modal() {\n\tconst genericLinks = document.querySelectorAll(\"a[href*='/-lightboxes/']\"); // find all generic links\n\tfor (const item of genericLinks) {\n\t\tif (item.hasAttribute(\"generic\")) continue; // skip if generic attribute exists, it means it's already been processed\n\t\titem.setAttribute(\"generic\", \"\");\n\t\titem.addEventListener(\"click\", async (event) => {\n\t\t\tevent.preventDefault();\n\t\t\tlet genericURL = item.getAttribute(\"href\");\n\t\t\tlet querySearch = normalize_generic_modal_path(genericURL);\n\t\t\tlet targetModalSelector = `[js-modal-generic-url=\"${querySearch}\"]`;\n\t\t\tlet targetModal = document.querySelector(targetModalSelector);\n\n\t\t\tif (event.shiftKey) {\n\t\t\t\tlet shiftClickUrl = `https://${window.location.hostname}${window.location.pathname}?modal=${querySearch}`;\n\t\t\t\tcopyToClipboard(shiftClickUrl);\n\t\t\t}\n\n\t\t\tif (!targetModal) {\n\t\t\t\ttargetModal = await fetch_generic_modal_dialog(querySearch, targetModalSelector);\n\t\t\t\ttargetModal = document.querySelector(targetModalSelector);\n\t\t\t}\n\t\t\tshowDialog(targetModal);\n\t\t\tadd_event_close_modal_via_backdrop(targetModal);\n\t\t\tadd_event_close_modal_via_button(targetModal);\n\t\t\tadd_event_close_modal_via_esc(targetModal);\n\t\t\tenso();\n\t\t});\n\t}\n}\n\nexport function show_modal_if_url_matches_modal_attribute() {\n\tconst currentPath = window.location.pathname;\n\tconst modal = document.querySelector(\"[js-modal-generic-url]\");\n\tif (modal && modal.getAttribute(\"js-modal-generic-url\") === currentPath) {\n\t\tenso();\n\t\tif (isAdmin()) {\n\t\t\tmodal.show(); // this method to open modal allows access to CMS navbar\n\t\t} else {\n\t\t\tshowDialog(modal);\n\t\t\tadd_event_close_modal_via_backdrop(modal);\n\t\t\tadd_event_close_modal_via_button(modal);\n\t\t\tadd_event_close_modal_via_esc(modal);\n\t\t}\n\t}\n}\n\n// Function to check the size of a single image in the browser and hide/show it if necessary\nfunction check_generic_modal_image_size(modal) {\n\tconst image = modal.querySelector(\"[js-util-check-img-size]\");\n\tconst imageURL = image.getAttribute(\"js-util-check-img-size\");\n\n\tfunction evaluateImageSize() {\n\t\timage.classList.remove(\"hide\");\n\t\timage.clientWidth < 400 ? image.classList.add(\"hide\") : image.classList.remove(\"hide\");\n\t}\n\n\tif (!imageURL.includes(\".\")) {\n\t\timage.remove();\n\t\treturn;\n\t}\n\n\timage.src = imageURL;\n\n\tif (image.complete) {\n\t\tevaluateImageSize();\n\t}\n\n\timage.addEventListener(\"load\", evaluateImageSize);\n\twindow.addEventListener(\"resize\", evaluateImageSize);\n\n\tevaluateImageSize();\n}\n\nfunction normalize_generic_modal_path(modalPath) {\n\tmodalPath = modalPath.replace(/.*\\?lightbox=/, \"\");\n\tmodalPath = modalPath.replace(/.*\\?modal=/, \"\");\n\tmodalPath = modalPath.replace(/.*:\\/\\/[^\\/]*\\/-lightboxes\\//, \"/-lightboxes/\");\n\tmodalPath = modalPath.replace(/#.*/, \"\");\n\tmodalPath = modalPath.replace(/[&?].*/, \"\");\n\treturn modalPath;\n}\n\nasync function fetch_generic_modal_dialog(querySearch, targetModalSelector) {\n\ttry {\n\t\tconst response = await fetch(querySearch);\n\t\tconst fetchedDialog = await response.text();\n\t\tdocument.body.insertAdjacentHTML(\"beforeend\", fetchedDialog);\n\t\tconst modal = document.querySelector(targetModalSelector);\n\t\tif (!modal) {\n\t\t\tthrow new Error(`Modal with selector \"${targetModalSelector}\" not found in the inserted HTML.`);\n\t\t}\n\t\tcdnifyImages();\n\t\treturn modal;\n\t} catch (err) {\n\t\tconsole.warn(\"Something went wrong.\", err);\n\t}\n}\n\nfunction showDialog(modal) {\n\tif (isDialogSupported()) {\n\t\tdocument.body.classList.add(\"modal-open\");\n\t\tmodal.showModal();\n\t} else {\n\t\tpushEvent(\"Dev\", \"Dialog\", \"Not Supported\");\n\t}\n\tsessionStorage.setItem(\"modalOpen\", true);\n\ttoggleAmbientVideo(false);\n\tcheck_generic_modal_image_size(modal);\n}\n\nfunction add_event_close_modal_via_backdrop(modal) {\n\tmodal.addEventListener(\"click\", (event) => {\n\t\tif (event.target === modal) {\n\t\t\tdocument.body.classList.remove(\"modal-open\");\n\t\t\tmodal.close();\n\t\t}\n\t});\n}\n\nfunction add_event_close_modal_via_button(modal) {\n\tconst genericModalClose = modal.querySelector(\"[js-modal-generic-close]\");\n\tgenericModalClose.addEventListener(\"click\", (event) => {\n\t\tevent.preventDefault();\n\t\tdocument.body.classList.remove(\"modal-open\");\n\t\tmodal.close();\n\t});\n}\n\n// Event : if escape key is pressed (but captures all close events)\nfunction add_event_close_modal_via_esc(modal) {\n\tmodal.addEventListener(\"close\", () => {\n\t\tdocument.body.classList.remove(\"modal-open\");\n\t\tmodal.close();\n\t\tsessionStorage.setItem(\"modalOpen\", false);\n\t\ttoggleAmbientVideo(true);\n\t});\n}\n\nexport function openModalsFromShortQuerystring() {\n\tconst urlParams = new URLSearchParams(window.location.search);\n\tconst modalParam = urlParams.get(\"modal\");\n\tconst modalTypes = [\"women\"];\n\n\tif (!modalParam || modalParam.includes(\"/accommodations/\")) return; // why do we need this?\n\n\t// open generic modals from short querystrings (ex. ?modal=women)\n\tif (modalTypes.includes(modalParam)) {\n\t\tlet modal = document.querySelector(`[href*='/-lightboxes/'][href*='${modalParam}']`); // this is looking for a link to lightbox and the param word in it\n\t\tif (modal) modal.click();\n\t\treturn;\n\t}\n}\n","import { autoPopupChatAccordionClickListener } from \"../../../olark/_script.js\";\nimport { enso } from \"../../../enso/_script.js\";\nimport { check_links_for_generic_modal, openModalsFromShortQuerystring } from \"../../../modal/generic-dialog/_script.js\";\n// import $ from \"jquery\"; // USE THIS WHEN IMPORT IN HEADSCRIPTS IS DELETED OR WHEN WE VANILLA JQUERY AWAY. THE END.\n\nexport function buildDatesAccordions() {\n\tlet isDatesAccordionDone = false;\n\tlet isDatesAccordionPage = false;\n\t$.ajax({\n\t\turl: \"/_data/new-prices.json\",\n\t\tdataType: \"json\",\n\t\tsuccess: function (data) {\n\t\t\tisDatesAccordionPage = true;\n\t\t\tvar allData = data.tripData;\n\t\t\tvar pageData = [];\n\t\t\tvar sortData = function (trip) {\n\t\t\t\tif (window.location.href.indexOf(`${trip.repeaterURL}`) > -1 && trip.repeaterURL !== \"\") {\n\t\t\t\t\tpageData.push(trip);\n\t\t\t\t}\n\t\t\t};\n\t\t\tallData.forEach(sortData);\n\t\t\tvar today = new Date();\n\t\t\ttoday = today.valueOf();\n\t\t\tpageData.sort(function (a, b) {\n\t\t\t\tvar dateA = new Date(a.departure),\n\t\t\t\t\tdateB = new Date(b.departure);\n\t\t\t\treturn dateA - dateB;\n\t\t\t});\n\t\t\tvar x = 0;\n\t\t\tfor (let i = 0; i < pageData.length; i++) {\n\t\t\t\tvar newDate = new Date(pageData[i].departure);\n\t\t\t\tpageData[i].value = newDate.valueOf();\n\t\t\t\tif (pageData[i].value < today) {\n\t\t\t\t\tx++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (x == pageData.length) {\n\t\t\t\t//HARD edgecase -- there will likely never be no dates for a trip\n\t\t\t\tvar template = document.querySelector(\".js-append-accordion\");\n\t\t\t\t$(template).addClass(\"hide\");\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tpageData = pageData.slice(x);\n\t\t\t}\n\t\t\tvar months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\t\t\tpageData.forEach(function (trip) {\n\t\t\t\tvar departure = new Date(trip.departure);\n\t\t\t\tvar returnDate = new Date(trip.return);\n\t\t\t\tvar formatMonthDepart = departure.getMonth();\n\t\t\t\tvar formatMonthReturn = returnDate.getMonth();\n\t\t\t\tvar originalDeparture = trip.departure;\n\t\t\t\tvar originalReturn = trip.return;\n\t\t\t\tvar oldMonth = originalDeparture.replace(/ .*/, \"\");\n\t\t\t\tvar oldMonthReturn = originalReturn.replace(/ .*/, \"\");\n\t\t\t\ttrip.departure = trip.departure.replace(oldMonth, months[formatMonthDepart]);\n\t\t\t\ttrip.return = trip.return.replace(oldMonthReturn, months[formatMonthReturn]);\n\t\t\t\tif (trip.notes.includes(\"lightbox\") && trip.notes.includes(\"www.nathab.com\")) {\n\t\t\t\t\ttrip.notes = trip.notes.replace(\"https://www.nathab.com\", \"\");\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar sortSameDates = function () {\n\t\t\t\tfor (let i = 0; i < pageData.length; i++) {\n\t\t\t\t\tvar temp;\n\t\t\t\t\tif (i + 1 == pageData.length) {\n\t\t\t\t\t\treturn pageData;\n\t\t\t\t\t} else if (i + 1 !== pageData.length + 1) {\n\t\t\t\t\t\tif (pageData[i].departure === pageData[i + 1].departure) {\n\t\t\t\t\t\t\tvar return1 = Date.parse(pageData[i].return);\n\t\t\t\t\t\t\tvar return2 = Date.parse(pageData[i + 1].return);\n\t\t\t\t\t\t\tif (return2 < return1) {\n\t\t\t\t\t\t\t\ttemp = pageData[i];\n\t\t\t\t\t\t\t\tpageData[i] = pageData[i + 1];\n\t\t\t\t\t\t\t\tpageData[i + 1] = temp;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\tsortSameDates();\n\t\t\tvar initialYear = pageData[0].departure;\n\t\t\tvar year = initialYear.substr(initialYear.length - 4);\n\t\t\tvar allTripYears = [year];\n\t\t\tvar findYears = function (trip) {\n\t\t\t\tinitialYear = trip.departure;\n\t\t\t\tyear = initialYear.substr(initialYear.length - 4);\n\t\t\t\tif (year !== allTripYears[allTripYears.length - 1]) {\n\t\t\t\t\tallTripYears.push(year);\n\t\t\t\t}\n\t\t\t};\n\t\t\tpageData.forEach(findYears);\n\t\t\tvar tripYears = [];\n\t\t\t$.each(allTripYears, function (i, year) {\n\t\t\t\tif ($.inArray(year, tripYears) === -1) {\n\t\t\t\t\ttripYears.push(year);\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar markup = document.querySelector(\".js-trip-data\").innerHTML;\n\t\t\tvar accordion = document.querySelector(\".js-append-accordion\");\n\t\t\tvar accYear = document.querySelector(\".js-accordion-year\");\n\t\t\tvar accInput = document.querySelector(\".js-accordion-year-input\");\n\t\t\tvar tripContainer = document.querySelector(\".trip-dates\");\n\t\t\tvar buildAccordions = function (tripyear, index) {\n\t\t\t\tif (index === 0) {\n\t\t\t\t\taccYear.innerHTML = accYear.innerHTML.replace(\"${tripYears[x]}\", `${tripyear}`);\n\t\t\t\t\t$(accYear).removeClass(\"hide\");\n\t\t\t\t\t$(accYear).attr(\"for\", $(accYear).attr(\"for\").replace(\"dates-next-year\", `dates-${tripyear}`));\n\t\t\t\t\t$(accInput).attr(\"id\", $(accInput).attr(\"id\").replace(\"dates-next-year\", `dates-${tripyear}`));\n\t\t\t\t\t$(tripContainer).attr(\"class\", $(tripContainer).attr(\"class\").replace(\"trip-dates\", `trip-dates-${tripyear}`));\n\t\t\t\t} else {\n\t\t\t\t\taccYear.innerHTML = accYear.innerHTML.replace(`${tripYears[index - 1]}`, `${tripyear}`);\n\t\t\t\t\t$(accYear).removeClass(\"hide\");\n\t\t\t\t\t$(accYear).attr(\n\t\t\t\t\t\t\"for\",\n\t\t\t\t\t\t$(accYear)\n\t\t\t\t\t\t\t.attr(\"for\")\n\t\t\t\t\t\t\t.replace(`dates-${tripYears[index - 1]}`, `dates-${tripyear}`)\n\t\t\t\t\t);\n\t\t\t\t\t$(accInput).attr(\n\t\t\t\t\t\t\"id\",\n\t\t\t\t\t\t$(accInput)\n\t\t\t\t\t\t\t.attr(\"id\")\n\t\t\t\t\t\t\t.replace(`dates-${tripYears[index - 1]}`, `dates-${tripyear}`)\n\t\t\t\t\t);\n\t\t\t\t\t$(tripContainer).attr(\n\t\t\t\t\t\t\"class\",\n\t\t\t\t\t\t$(tripContainer)\n\t\t\t\t\t\t\t.attr(\"class\")\n\t\t\t\t\t\t\t.replace(`trip-dates-${tripYears[index - 1]}`, `trip-dates-${tripyear}`)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tvar titleYear = accYear.innerHTML;\n\t\t\t\ttitleYear = titleYear.replace(/\\D/g, \"\"); // regex is removing all non-digit characters\n\t\t\t\tvar dateTripFrag = document.createDocumentFragment();\n\t\t\t\tvar sortTrips = function (trip) {\n\t\t\t\t\tinitialYear = trip.departure;\n\t\t\t\t\tyear = initialYear.substr(initialYear.length - 4);\n\t\t\t\t\tif (titleYear == year) {\n\t\t\t\t\t\tvar editMarkup = eval(\"`\" + markup + \"`\"); // Evaluates the template literal in markup\n\t\t\t\t\t\tvar newTr = document.querySelector(\".js-trip-data\");\n\t\t\t\t\t\tvar cloneTr = newTr.cloneNode(true);\n\t\t\t\t\t\tcloneTr.innerHTML = editMarkup; // Correctly setting innerHTML of the cloned element\n\t\t\t\t\t\tdateTripFrag.append(cloneTr);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tpageData.forEach(sortTrips);\n\t\t\t\tvar newAcc = accordion.cloneNode(true);\n\t\t\t\t$(newAcc).removeClass(\"js-append-accordion\");\n\t\t\t\t$(newAcc).addClass(`js-${tripyear}-accordion`);\n\t\t\t\tdocument.querySelector('[wrapper=\"dates-accordion\"]').append(newAcc);\n\t\t\t\t$(\".js-append-accordion\").first().remove();\n\t\t\t\tvar tripBody = document.querySelector(\".js-append-tr\");\n\t\t\t\tvar tripHint = document.querySelector(`.trip-dates-hint-${tripyear}`);\n\t\t\t\tvar tripFinePrint = document.querySelector(`.trip-dates-fine-print-${tripyear}`);\n\t\t\t\t$(tripBody).addClass(`trips-${tripyear}`);\n\t\t\t\t$(tripBody).addClass(\"trip-wrapper\");\n\t\t\t\t$(tripBody).removeClass(\"js-append-tr\");\n\t\t\t\tif (titleYear == tripyear) {\n\t\t\t\t\ttripHint ? document.querySelector(`.trip-dates-${tripyear}`).prepend(tripHint) : null;\n\t\t\t\t\tdocument.querySelector(`.trips-${tripyear}`).append(dateTripFrag);\n\t\t\t\t\ttripFinePrint ? document.querySelector(`.trip-dates-${tripyear}`).append(tripFinePrint) : null;\n\t\t\t\t}\n\t\t\t};\n\t\t\ttripYears.forEach(buildAccordions);\n\t\t\tvar thisYear = new Date().getFullYear();\n\t\t\tvar tripWrapper = document.querySelectorAll(\".trip-wrapper\");\n\t\t\tvar eachWrap;\n\t\t\tvar hidePattern = function (pattern) {\n\t\t\t\teachWrap = pattern;\n\t\t\t\t$(eachWrap).children(\":first\").addClass(\"hide\");\n\t\t\t};\n\t\t\ttripWrapper.forEach(hidePattern);\n\t\t\t$(\".js-trip-data\").hover(\n\t\t\t\tfunction () {\n\t\t\t\t\t$(this).addClass(\"price-active\");\n\t\t\t\t\t$(\".price-active [trip-body~='price']\").removeClass(\"hide\");\n\t\t\t\t\t$(\".price-active [trip-body~='price']\").addClass(\"show-price\");\n\t\t\t\t},\n\t\t\t\tfunction () {\n\t\t\t\t\t$(\".price-active [trip-body~='price']\").removeClass(\"show-price\");\n\t\t\t\t\t$(\".price-active [trip-body~='price']\").addClass(\"hide\");\n\t\t\t\t\t$(this).removeClass(\"price-active\");\n\t\t\t\t}\n\t\t\t);\n\t\t\t$(\".price\").each(function (i, price) {\n\t\t\t\tif (price.innerHTML.includes(\"Cat\")) {\n\t\t\t\t\tprice.innerHTML = price.innerHTML.replace(/;\\s?/g, \"
\");\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t});\n\n\t\t\tvar tempAccordion = document.querySelector(\".js-temp-accordion\");\n\t\t\tvar adminUser = false;\n\t\t\tif (document.querySelectorAll(\"[enso-link]\").length > 0) {\n\t\t\t\tadminUser = true;\n\t\t\t}\n\t\t\tif (adminUser) {\n\t\t\t\t$(\".js-placeholder-toggle\").addClass(\"hide\");\n\t\t\t}\n\t\t\tvar placeholderToggle = document.querySelector(\".js-placeholder-toggle\");\n\t\t\tplaceholderToggle = placeholderToggle.innerHTML.trim();\n\t\t\tif (placeholderToggle === \"hide\" && !adminUser) {\n\t\t\t\t$(tempAccordion).addClass(\"hide\");\n\t\t\t}\n\t\t\t/////////////////////////////////\n\t\t\t// the below code hides outdated pricing accordions based on relevant trip years\n\t\t\t$(\"[js-pricing-accordion] [js-pricing-summary]\").each(function () {\n\t\t\t\tvar priceYear = this.innerHTML;\n\t\t\t\tpriceYear = priceYear.replace(/\\D/g, \"\");\n\n\t\t\t\tif (priceYear < tripYears[0]) {\n\t\t\t\t\t$(this).parent(\"[js-pricing-accordion]\").attr(\"hide\", \"all\");\n\t\t\t\t\t$(this).append(\"— *Admin view only*\");\n\t\t\t\t}\n\t\t\t});\n\t\t\t///////////////////////////\n\t\t\tisDatesAccordionDone = true;\n\t\t\tautoPopupChatAccordionClickListener();\n\t\t\tcheck_links_for_generic_modal();\n\t\t\topenModalsFromShortQuerystring();\n\n\t\t\tif (adminUser) {\n\t\t\t\tdocument.addEventListener(\"keyup\", enableAdminDates); //turn on CMS for date accordions here to allow lightboxes within accordion to open on top of page first for admins\n\t\t\t\tfunction enableAdminDates(event) {\n\t\t\t\t\tif (event.keyCode == 9) {\n\t\t\t\t\t\t$(\".js-show-for-admin-dates\").show();\n\t\t\t\t\t\tenso();\n\t\t\t\t\t\t// EVENT - CLick to editor\n\t\t\t\t\t\t$(\"body\").on(\"click\", \".js-enso-on\", function (event) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\twindow.location.href = $(this).attr(\"enso-link\");\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\terror: function () {\n\t\t\t// TODO - Handle errors oin the future\n\t\t\tconsole.log(\"NOT WORKING - NEW\");\n\t\t}\n\t});\n}\n","import { isAdmin } from \"../../../../assets/js/utilities.js\";\nimport { enso } from \"../../../enso/_script.js\";\n\nexport function showEnsoForAdmin() {\n\t$(\"[js-pricing-accordion] label\").each(function () {\n\t\tif (isAdmin()) {\n\t\t\t$(\"[js-show-for-admin]\").show();\n\t\t\tenso();\n\t\t\t// EVENT - CLick to editor\n\t\t\t$(\"body\").on(\"click\", \".js-enso-on\", function (event) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\twindow.location.href = $(this).attr(\"enso\");\n\t\t\t});\n\t\t}\n\t});\n}\n\n// Function: replace Make it Private icon/badges within pricing accordions with a button\nexport function replaceMIPImagesInPricingAccordions() {\n\tlet pricingAccordionMIPImages = document.querySelectorAll(\"[js-find-mip-badge-icons] img[src*='MIP']\");\n\n\tif (pricingAccordionMIPImages.length === 0) return;\n\n\tconst isAfrica = location.pathname.includes(\"africa\");\n\tconst buttonText = isAfrica ? \"Make It Custom\" : \"Make It Private\";\n\tconst forAttribute = isAfrica ? \"modal-custom\" : \"modal-private\";\n\tconst buttonLocationAttribute = isAfrica ? \"js-custom-location\" : \"js-private-location\";\n\tconst buttonLocation = isAfrica ? \"CUSTOM\" : \"PRIVATE\";\n\n\tpricingAccordionMIPImages.forEach((image) => {\n\t\tconst privateButtonHTML = `\n `;\n\n\t\timage.insertAdjacentHTML(\"beforebegin\", privateButtonHTML);\n\t\timage.remove();\n\t});\n}\n","// Auto-Scroll Trip Subpages\nexport function autoScroll() {\n\tconst mqSmall = window.matchMedia(\"(max-width : 767px)\");\n\tconst subpage = document.querySelector(\"[subpage~='autoscroll']\");\n\n\tif (!mqSmall.matches && subpage) {\n\t\tconst subpageTop = getOffsetTop(subpage);\n\t\tconst offset = 150;\n\n\t\twindow.scrollTo({\n\t\t\ttop: subpageTop - offset,\n\t\t\tbehavior: \"smooth\"\n\t\t});\n\t}\n}\n\n// helper function for autoScroll;\n// If the element or any of its parents are positioned non-statically (relative, absolute, fixed, or sticky),\n// you'll need to calculate the element's position manually by adding up the offsetTop values of the element\n// and all of its offset parents.\nfunction getOffsetTop(element) {\n\tlet offsetTop = 0;\n\twhile (element) {\n\t\toffsetTop += element.offsetTop;\n\t\telement = element.offsetParent;\n\t}\n\treturn offsetTop;\n}\n\n// For sub sub itinereray nav links\nexport function setTripItinerarySubSubClass() {\n\tconst links = document.querySelectorAll(\"[tripnav='nav'] a\");\n\tlinks.forEach(function (link) {\n\t\tif (link.href.includes(\"-itin\")) {\n\t\t\tlink.parentElement.classList.add(\"removeSubSub\");\n\t\t}\n\t});\n}\n\n// remove .active form parent itinerary page if child itinerary has active\nexport function removeActiveFromOtherLi() {\n\tlet activeLiElements = document.querySelectorAll(\"[tripnav~='nav'] li.active\");\n\n\tif (activeLiElements.length > 1) {\n\t\tactiveLiElements[0].classList.remove(\"active\");\n\t}\n}\n\n// Call the function to remove .active from the first li.active element if there is more than one\n\nexport function showBookOrCatalogOnMobileNav() {\n\tconst isBookOff = document.querySelector(\".booknowoff\");\n\tconst isAllBookOff = document.querySelector(\".disallow-book-now\");\n\tconst navbarMobileCatalog = document.querySelector(\"[nav-site-link--mobile~='catalog']\");\n\tconst navbarBook = document.querySelector(\"[nav-site-link--mobile~='book']\");\n\tconst mobileOnly = window.matchMedia(\"(max-width : 767px)\");\n\n\tif (mobileOnly.matches) {\n\t\tif (isBookOff || isAllBookOff) {\n\t\t\tnavbarMobileCatalog.classList.add(\"js-show-when-book-off\");\n\t\t\tnavbarBook.classList.add(\"hide\");\n\t\t}\n\t}\n}\n","// Function: Remember the trip page if user navigates away from the trip\nexport function setSessionsForBackToTripBar() {\n\tlet tripURL = window.location.href;\n\tlet tripName = document.querySelector(\"[hero~='name']\").innerText;\n\tsessionStorage.setItem(\"backToTripURL\", tripURL);\n\tsessionStorage.setItem(\"backToTripName\", tripName);\n}\n","export const countryList = [\n\t{ code: \"AF\", name: \"Afghanistan\" },\n\t{ code: \"AX\", name: \"Åland Islands\" },\n\t{ code: \"AL\", name: \"Albania\" },\n\t{ code: \"DZ\", name: \"Algeria\" },\n\t{ code: \"AS\", name: \"American Samoa\" },\n\t{ code: \"AD\", name: \"Andorra\" },\n\t{ code: \"AO\", name: \"Angola\" },\n\t{ code: \"AI\", name: \"Anguilla\" },\n\t{ code: \"AQ\", name: \"Antarctica\" },\n\t{ code: \"AG\", name: \"Antigua and Barbuda\" },\n\t{ code: \"AR\", name: \"Argentina\" },\n\t{ code: \"AM\", name: \"Armenia\" },\n\t{ code: \"AW\", name: \"Aruba\" },\n\t{ code: \"AU\", name: \"Australia\" },\n\t{ code: \"AT\", name: \"Austria\" },\n\t{ code: \"AZ\", name: \"Azerbaijan\" },\n\t{ code: \"BS\", name: \"Bahamas\" },\n\t{ code: \"BH\", name: \"Bahrain\" },\n\t{ code: \"BD\", name: \"Bangladesh\" },\n\t{ code: \"BB\", name: \"Barbados\" },\n\t{ code: \"BY\", name: \"Belarus\" },\n\t{ code: \"BE\", name: \"Belgium\" },\n\t{ code: \"BZ\", name: \"Belize\" },\n\t{ code: \"BJ\", name: \"Benin\" },\n\t{ code: \"BM\", name: \"Bermuda\" },\n\t{ code: \"BT\", name: \"Bhutan\" },\n\t{ code: \"BO\", name: \"Bolivia (Plurinational State of)\" },\n\t{ code: \"BQ\", name: \"Bonaire, Sint Eustatius and Saba\" },\n\t{ code: \"BA\", name: \"Bosnia and Herzegovina\" },\n\t{ code: \"BW\", name: \"Botswana\" },\n\t{ code: \"BV\", name: \"Bouvet Island\" },\n\t{ code: \"BR\", name: \"Brazil\" },\n\t{ code: \"IO\", name: \"British Indian Ocean Territory\" },\n\t{ code: \"BN\", name: \"Brunei Darussalam\" },\n\t{ code: \"BG\", name: \"Bulgaria\" },\n\t{ code: \"BF\", name: \"Burkina Faso\" },\n\t{ code: \"BI\", name: \"Burundi\" },\n\t{ code: \"CV\", name: \"Cabo Verde\" },\n\t{ code: \"KH\", name: \"Cambodia\" },\n\t{ code: \"CM\", name: \"Cameroon\" },\n\t{ code: \"CA\", name: \"Canada\" },\n\t{ code: \"KY\", name: \"Cayman Islands\" },\n\t{ code: \"CF\", name: \"Central African Republic\" },\n\t{ code: \"TD\", name: \"Chad\" },\n\t{ code: \"CL\", name: \"Chile\" },\n\t{ code: \"CN\", name: \"China\" },\n\t{ code: \"CX\", name: \"Christmas Island\" },\n\t{ code: \"CC\", name: \"Cocos (Keeling) Islands\" },\n\t{ code: \"CO\", name: \"Colombia\" },\n\t{ code: \"KM\", name: \"Comoros\" },\n\t{ code: \"CG\", name: \"Congo\" },\n\t{ code: \"CD\", name: \"Congo (Democratic Republic of the)\" },\n\t{ code: \"CK\", name: \"Cook Islands\" },\n\t{ code: \"CR\", name: \"Costa Rica\" },\n\t{ code: \"CI\", name: \"Côte d'Ivoire\" },\n\t{ code: \"HR\", name: \"Croatia\" },\n\t{ code: \"CU\", name: \"Cuba\" },\n\t{ code: \"CW\", name: \"Curaçao\" },\n\t{ code: \"CY\", name: \"Cyprus\" },\n\t{ code: \"CZ\", name: \"Czech Republic\" },\n\t{ code: \"DK\", name: \"Denmark\" },\n\t{ code: \"DJ\", name: \"Djibouti\" },\n\t{ code: \"DM\", name: \"Dominica\" },\n\t{ code: \"DO\", name: \"Dominican Republic\" },\n\t{ code: \"EC\", name: \"Ecuador\" },\n\t{ code: \"EG\", name: \"Egypt\" },\n\t{ code: \"SV\", name: \"El Salvador\" },\n\t{ code: \"GQ\", name: \"Equatorial Guinea\" },\n\t{ code: \"ER\", name: \"Eritrea\" },\n\t{ code: \"EE\", name: \"Estonia\" },\n\t{ code: \"SZ\", name: \"Eswatini\" },\n\t{ code: \"ET\", name: \"Ethiopia\" },\n\t{ code: \"FK\", name: \"Falkland Islands (Malvinas)\" },\n\t{ code: \"FO\", name: \"Faroe Islands\" },\n\t{ code: \"FJ\", name: \"Fiji\" },\n\t{ code: \"FI\", name: \"Finland\" },\n\t{ code: \"FR\", name: \"France\" },\n\t{ code: \"GF\", name: \"French Guiana\" },\n\t{ code: \"PF\", name: \"French Polynesia\" },\n\t{ code: \"TF\", name: \"French Southern Territories\" },\n\t{ code: \"GA\", name: \"Gabon\" },\n\t{ code: \"GM\", name: \"Gambia\" },\n\t{ code: \"GE\", name: \"Georgia\" },\n\t{ code: \"DE\", name: \"Germany\" },\n\t{ code: \"GH\", name: \"Ghana\" },\n\t{ code: \"GI\", name: \"Gibraltar\" },\n\t{ code: \"GR\", name: \"Greece\" },\n\t{ code: \"GL\", name: \"Greenland\" },\n\t{ code: \"GD\", name: \"Grenada\" },\n\t{ code: \"GP\", name: \"Guadeloupe\" },\n\t{ code: \"GU\", name: \"Guam\" },\n\t{ code: \"GT\", name: \"Guatemala\" },\n\t{ code: \"GG\", name: \"Guernsey\" },\n\t{ code: \"GN\", name: \"Guinea\" },\n\t{ code: \"GW\", name: \"Guinea-Bissau\" },\n\t{ code: \"GY\", name: \"Guyana\" },\n\t{ code: \"HT\", name: \"Haiti\" },\n\t{ code: \"HM\", name: \"Heard Island and McDonald Islands\" },\n\t{ code: \"VA\", name: \"Holy See\" },\n\t{ code: \"HN\", name: \"Honduras\" },\n\t{ code: \"HK\", name: \"Hong Kong\" },\n\t{ code: \"HU\", name: \"Hungary\" },\n\t{ code: \"IS\", name: \"Iceland\" },\n\t{ code: \"IN\", name: \"India\" },\n\t{ code: \"ID\", name: \"Indonesia\" },\n\t{ code: \"IR\", name: \"Iran (Islamic Republic of)\" },\n\t{ code: \"IQ\", name: \"Iraq\" },\n\t{ code: \"IE\", name: \"Ireland\" },\n\t{ code: \"IM\", name: \"Isle of Man\" },\n\t{ code: \"IL\", name: \"Israel\" },\n\t{ code: \"IT\", name: \"Italy\" },\n\t{ code: \"JM\", name: \"Jamaica\" },\n\t{ code: \"JP\", name: \"Japan\" },\n\t{ code: \"JE\", name: \"Jersey\" },\n\t{ code: \"JO\", name: \"Jordan\" },\n\t{ code: \"KZ\", name: \"Kazakhstan\" },\n\t{ code: \"KE\", name: \"Kenya\" },\n\t{ code: \"KI\", name: \"Kiribati\" },\n\t{ code: \"KP\", name: \"Korea (Democratic People's Republic of)\" },\n\t{ code: \"KR\", name: \"Korea (Republic of)\" },\n\t{ code: \"KW\", name: \"Kuwait\" },\n\t{ code: \"KG\", name: \"Kyrgyzstan\" },\n\t{ code: \"LA\", name: \"Lao People's Democratic Republic\" },\n\t{ code: \"LV\", name: \"Latvia\" },\n\t{ code: \"LB\", name: \"Lebanon\" },\n\t{ code: \"LS\", name: \"Lesotho\" },\n\t{ code: \"LR\", name: \"Liberia\" },\n\t{ code: \"LY\", name: \"Libya\" },\n\t{ code: \"LI\", name: \"Liechtenstein\" },\n\t{ code: \"LT\", name: \"Lithuania\" },\n\t{ code: \"LU\", name: \"Luxembourg\" },\n\t{ code: \"MO\", name: \"Macao\" },\n\t{ code: \"MG\", name: \"Madagascar\" },\n\t{ code: \"MW\", name: \"Malawi\" },\n\t{ code: \"MY\", name: \"Malaysia\" },\n\t{ code: \"MV\", name: \"Maldives\" },\n\t{ code: \"ML\", name: \"Mali\" },\n\t{ code: \"MT\", name: \"Malta\" },\n\t{ code: \"MH\", name: \"Marshall Islands\" },\n\t{ code: \"MQ\", name: \"Martinique\" },\n\t{ code: \"MR\", name: \"Mauritania\" },\n\t{ code: \"MU\", name: \"Mauritius\" },\n\t{ code: \"YT\", name: \"Mayotte\" },\n\t{ code: \"MX\", name: \"Mexico\" },\n\t{ code: \"FM\", name: \"Micronesia (Federated States of)\" },\n\t{ code: \"MD\", name: \"Moldova (Republic of)\" },\n\t{ code: \"MC\", name: \"Monaco\" },\n\t{ code: \"MN\", name: \"Mongolia\" },\n\t{ code: \"ME\", name: \"Montenegro\" },\n\t{ code: \"MS\", name: \"Montserrat\" },\n\t{ code: \"MA\", name: \"Morocco\" },\n\t{ code: \"MZ\", name: \"Mozambique\" },\n\t{ code: \"MM\", name: \"Myanmar\" },\n\t{ code: \"NA\", name: \"Namibia\" },\n\t{ code: \"NR\", name: \"Nauru\" },\n\t{ code: \"NP\", name: \"Nepal\" },\n\t{ code: \"NL\", name: \"Netherlands\" },\n\t{ code: \"NC\", name: \"New Caledonia\" },\n\t{ code: \"NZ\", name: \"New Zealand\" },\n\t{ code: \"NI\", name: \"Nicaragua\" },\n\t{ code: \"NE\", name: \"Niger\" },\n\t{ code: \"NG\", name: \"Nigeria\" },\n\t{ code: \"NU\", name: \"Niue\" },\n\t{ code: \"NF\", name: \"Norfolk Island\" },\n\t{ code: \"MK\", name: \"North Macedonia\" },\n\t{ code: \"MP\", name: \"Northern Mariana Islands\" },\n\t{ code: \"NO\", name: \"Norway\" },\n\t{ code: \"OM\", name: \"Oman\" },\n\t{ code: \"PK\", name: \"Pakistan\" },\n\t{ code: \"PW\", name: \"Palau\" },\n\t{ code: \"PS\", name: \"Palestine, State of\" },\n\t{ code: \"PA\", name: \"Panama\" },\n\t{ code: \"PG\", name: \"Papua New Guinea\" },\n\t{ code: \"PY\", name: \"Paraguay\" },\n\t{ code: \"PE\", name: \"Peru\" },\n\t{ code: \"PH\", name: \"Philippines\" },\n\t{ code: \"PN\", name: \"Pitcairn\" },\n\t{ code: \"PL\", name: \"Poland\" },\n\t{ code: \"PT\", name: \"Portugal\" },\n\t{ code: \"PR\", name: \"Puerto Rico\" },\n\t{ code: \"QA\", name: \"Qatar\" },\n\t{ code: \"RE\", name: \"Réunion\" },\n\t{ code: \"RO\", name: \"Romania\" },\n\t{ code: \"RU\", name: \"Russian Federation\" },\n\t{ code: \"RW\", name: \"Rwanda\" },\n\t{ code: \"BL\", name: \"Saint Barthélemy\" },\n\t{ code: \"SH\", name: \"Saint Helena, Ascension and Tristan da Cunha\" },\n\t{ code: \"KN\", name: \"Saint Kitts and Nevis\" },\n\t{ code: \"LC\", name: \"Saint Lucia\" },\n\t{ code: \"MF\", name: \"Saint Martin (French part)\" },\n\t{ code: \"PM\", name: \"Saint Pierre and Miquelon\" },\n\t{ code: \"VC\", name: \"Saint Vincent and the Grenadines\" },\n\t{ code: \"WS\", name: \"Samoa\" },\n\t{ code: \"SM\", name: \"San Marino\" },\n\t{ code: \"ST\", name: \"Sao Tome and Principe\" },\n\t{ code: \"SA\", name: \"Saudi Arabia\" },\n\t{ code: \"SN\", name: \"Senegal\" },\n\t{ code: \"RS\", name: \"Serbia\" },\n\t{ code: \"SC\", name: \"Seychelles\" },\n\t{ code: \"SL\", name: \"Sierra Leone\" },\n\t{ code: \"SG\", name: \"Singapore\" },\n\t{ code: \"SX\", name: \"Sint Maarten (Dutch part)\" },\n\t{ code: \"SK\", name: \"Slovakia\" },\n\t{ code: \"SI\", name: \"Slovenia\" },\n\t{ code: \"SB\", name: \"Solomon Islands\" },\n\t{ code: \"SO\", name: \"Somalia\" },\n\t{ code: \"ZA\", name: \"South Africa\" },\n\t{ code: \"GS\", name: \"South Georgia and the South Sandwich Islands\" },\n\t{ code: \"SS\", name: \"South Sudan\" },\n\t{ code: \"ES\", name: \"Spain\" },\n\t{ code: \"LK\", name: \"Sri Lanka\" },\n\t{ code: \"SD\", name: \"Sudan\" },\n\t{ code: \"SR\", name: \"Suriname\" },\n\t{ code: \"SJ\", name: \"Svalbard and Jan Mayen\" },\n\t{ code: \"SE\", name: \"Sweden\" },\n\t{ code: \"CH\", name: \"Switzerland\" },\n\t{ code: \"SY\", name: \"Syrian Arab Republic\" },\n\t{ code: \"TW\", name: \"Taiwan, Province of China\" },\n\t{ code: \"TJ\", name: \"Tajikistan\" },\n\t{ code: \"TZ\", name: \"Tanzania, United Republic of\" },\n\t{ code: \"TH\", name: \"Thailand\" },\n\t{ code: \"TL\", name: \"Timor-Leste\" },\n\t{ code: \"TG\", name: \"Togo\" },\n\t{ code: \"TK\", name: \"Tokelau\" },\n\t{ code: \"TO\", name: \"Tonga\" },\n\t{ code: \"TT\", name: \"Trinidad and Tobago\" },\n\t{ code: \"TN\", name: \"Tunisia\" },\n\t{ code: \"TR\", name: \"Turkey\" },\n\t{ code: \"TM\", name: \"Turkmenistan\" },\n\t{ code: \"TC\", name: \"Turks and Caicos Islands\" },\n\t{ code: \"TV\", name: \"Tuvalu\" },\n\t{ code: \"UG\", name: \"Uganda\" },\n\t{ code: \"UA\", name: \"Ukraine\" },\n\t{ code: \"AE\", name: \"United Arab Emirates\" },\n\t{ code: \"GB\", name: \"United Kingdom of Great Britain and Northern Ireland\" },\n\t{ code: \"US\", name: \"United States\" },\n\t{ code: \"UM\", name: \"United States Minor Outlying Islands\" },\n\t{ code: \"UY\", name: \"Uruguay\" },\n\t{ code: \"UZ\", name: \"Uzbekistan\" },\n\t{ code: \"VU\", name: \"Vanuatu\" },\n\t{ code: \"VE\", name: \"Venezuela (Bolivarian Republic of)\" },\n\t{ code: \"VN\", name: \"Viet Nam\" },\n\t{ code: \"VG\", name: \"Virgin Islands (British)\" },\n\t{ code: \"VI\", name: \"Virgin Islands (U.S.)\" },\n\t{ code: \"WF\", name: \"Wallis and Futuna\" },\n\t{ code: \"EH\", name: \"Western Sahara\" },\n\t{ code: \"YE\", name: \"Yemen\" },\n\t{ code: \"ZM\", name: \"Zambia\" },\n\t{ code: \"ZW\", name: \"Zimbabwe\" }\n];\n","// Function : Smarty : Select Address\nexport function selectAddress(streetVal, cityVal, stateVal, zipVal, smarty) {\n\tlet userCountry = localStorage.getItem(\"country\") || \"unknown\";\n\tif (userCountry !== \"US\") return;\n\n\tsmarty.streets.forEach((street) => {\n\t\tstreet.value = streetVal;\n\t});\n\tsmarty.cities.forEach((city) => {\n\t\tcity.value = cityVal;\n\t});\n\tsmarty.states.forEach((state) => {\n\t\tstate.value = stateVal;\n\t});\n\tsmarty.zips.forEach((zip) => {\n\t\tzip.value = zipVal;\n\t});\n\tsmarty.countries.forEach((country) => {\n\t\tcountry.value = \"United States\";\n\t});\n\temptyMenu(smarty);\n}\n\n// Function : Empty Element\nexport function emptyMenu(smarty) {\n\tsmarty.menus.forEach((menu) => {\n\t\tvar children = Array.prototype.slice.call(menu.childNodes);\n\t\tchildren.forEach(function (child) {\n\t\t\tmenu.removeChild(child);\n\t\t});\n\t});\n}\n\n// Function : Smarty : Build Menu\nexport function buildAddressMenu(suggestions, smarty) {\n\temptyMenu(smarty);\n\tsuggestions.forEach(function (suggestion) {\n\t\tsmarty.menus.forEach((menu) => {\n\t\t\tlet div = document.createElement(\"div\");\n\t\t\tdiv.setAttribute(\"smarty\", \"selector\");\n\t\t\tdiv.className = \"js-smarty-selector\";\n\t\t\tdiv.innerHTML = `${suggestion.street_line} ${suggestion.city}, ${suggestion.state} ${suggestion.zipcode}`;\n\t\t\tdiv.addEventListener(\"click\", () => selectAddress(suggestion.street_line, suggestion.city, suggestion.state, suggestion.zipcode, smarty));\n\t\t\tmenu.appendChild(div);\n\t\t});\n\t});\n}\n\nexport function initSmarty(form) {\n\tlet smarty = {};\n\t// Create Object : Smarty : Selectors\n\tsmarty.menus = document.querySelectorAll(`${form} .js-smarty-menu`);\n\tsmarty.streets = document.querySelectorAll(`${form} .js-smarty-street`);\n\tsmarty.suites = document.querySelectorAll(`${form} .js-smarty-street-2`);\n\tsmarty.cities = document.querySelectorAll(`${form} .js-smarty-city`);\n\tsmarty.states = document.querySelectorAll(`${form} .js-smarty-state`);\n\tsmarty.zips = document.querySelectorAll(`${form} .js-smarty-zip`);\n\tsmarty.countries = document.querySelectorAll(`${form} .js-smarty-country`);\n\n\tfunction suggestNow(street, smarty) {\n\t\tif (street.value.length < 4) {\n\t\t\treturn;\n\t\t}\n\t\tif (street.value) {\n\t\t\tsmartySuggestions(street.value, smarty);\n\t\t}\n\t}\n\n\t// Function : Smarty : Ajax Post to Smarty Streets\n\tfunction smartySuggestions(search, smarty) {\n\t\tlet ref = `${location.protocol}//${window.location.hostname}`;\n\t\tfetch(`https://us-autocomplete-pro.api.smartystreets.com/lookup?key=91583922427951116&search=${search}&max_results=5`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\thost: \"us-autocomplete-pro.api.smartystreets.com\",\n\t\t\t\treferer: ref\n\t\t\t}\n\t\t})\n\t\t\t.then(function (response) {\n\t\t\t\treturn response.json();\n\t\t\t})\n\t\t\t.then(function (data) {\n\t\t\t\tif (data.suggestions) {\n\t\t\t\t\tbuildAddressMenu(data.suggestions, smarty);\n\t\t\t\t} else {\n\t\t\t\t\temptyMenu(smarty);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(function (err) {\n\t\t\t\tconsole.warn(\"Something went wrong.\", err);\n\t\t\t});\n\t}\n\n\t// Event : Smarty : Handle typing into street address\n\tsmarty.streets.forEach((street) => {\n\t\tvar current = -1;\n\n\t\tstreet.addEventListener(\n\t\t\t\"keyup\",\n\t\t\t_.throttle(function (event) {\n\t\t\t\tif (street.value.length < 4 || street.value.length > 25) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (event.keyCode === 38 || event.keyCode === 40 || event.keyCode === 13) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsuggestNow(street, smarty);\n\t\t\t}, 1250)\n\t\t);\n\n\t\tstreet.addEventListener(\"keyup\", function (event) {\n\t\t\tif (street.value.length < 4) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.keyCode === 38) {\n\t\t\t\tvar checkExist = setInterval(function () {\n\t\t\t\t\tif (street.nextElementSibling.hasChildNodes() === true) {\n\t\t\t\t\t\tclearInterval(checkExist);\n\t\t\t\t\t}\n\t\t\t\t}, 100);\n\t\t\t\tif (street.nextElementSibling.hasChildNodes() === true) {\n\t\t\t\t\tif (current === 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tstreet.nextElementSibling.children[current].classList.remove(\"focus\");\n\t\t\t\t\tcurrent--;\n\t\t\t\t\tstreet.nextElementSibling.children[current].classList.add(\"focus\");\n\t\t\t\t}\n\t\t\t} else if (event.keyCode === 40) {\n\t\t\t\tvar checkExist = setInterval(function () {\n\t\t\t\t\tif (street.nextElementSibling.hasChildNodes() === true) {\n\t\t\t\t\t\tclearInterval(checkExist);\n\t\t\t\t\t}\n\t\t\t\t}, 100);\n\t\t\t\tif (street.nextElementSibling.hasChildNodes() === true) {\n\t\t\t\t\tif (current === street.nextElementSibling.children.length - 1) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (current > -1) {\n\t\t\t\t\t\tstreet.nextElementSibling.children[current].classList.remove(\"focus\");\n\t\t\t\t\t}\n\t\t\t\t\tcurrent++;\n\t\t\t\t\tstreet.nextElementSibling.children[current].classList.add(\"focus\");\n\t\t\t\t}\n\t\t\t} else if (event.keyCode === 13) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (street.nextElementSibling.children[current].classList.contains(\"focus\")) {\n\t\t\t\t\tvar simulateClick = function (elem) {\n\t\t\t\t\t\t// Create our event (with options)\n\t\t\t\t\t\tvar evt = new MouseEvent(\"click\", {\n\t\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\t\tcancelable: true,\n\t\t\t\t\t\t\tview: window\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If cancelled, don't dispatch our event\n\t\t\t\t\t\tvar canceled = !elem.dispatchEvent(evt);\n\t\t\t\t\t};\n\t\t\t\t\tsimulateClick(street.nextElementSibling.children[current]);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tcurrent = -1;\n\t\t\t}\n\t\t});\n\t});\n\n\t// Event : Smarty : When suite or city field gains focus\n\tsmarty.suites.forEach((suite) => {\n\t\tsuite.addEventListener(\"focus\", function () {\n\t\t\temptyMenu(smarty);\n\t\t});\n\t});\n\n\tsmarty.cities.forEach((city) => {\n\t\tcity.addEventListener(\"focus\", function () {\n\t\t\temptyMenu(smarty);\n\t\t});\n\t});\n}\n","let urlParamstoCookiesList = [\"gclid\", \"msclkid\", \"fbclid\", \"utmterm\", \"cid\"];\n\nexport function setOptsOnMarketoForm() {\n\tdocument.querySelector(\"#optInNHA\").value = true;\n\tdocument.querySelector(\"#optInWebinar\").value = true;\n\tdocument.querySelector(\"#optInStories\").value = true;\n\tdocument.querySelector(\"#optInSurveys\").value = true;\n\tdocument.querySelector(\"#optInTripDrips\").value = true;\n\tdocument.querySelector(\"#optInSalesperson\").value = true;\n}\n\nexport function setSMSOptsOnMarketoForm() {\n\tdocument.querySelector(\"#optInSMS\").value = true;\n}\n\nexport function isFormValid(formName) {\n\tvar invalidCount = $(formName).find(\":invalid\").length;\n\tif (invalidCount > 0) {\n\t\t$(formName).find(\":invalid\").addClass(\"js-invalid\");\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n}\n\nexport function isNewsletterChecked(formName) {\n\treturn document.querySelector(`${formName} ${formName}-requestNewsletter`).checked;\n}\n\nexport function isSMSOptinChecked(formName) {\n\treturn document.querySelector(`${formName} ${formName}-Optin-SMS`).checked;\n}\n\n// Add event listener to name input to remove special characters\nexport function initJsFormatName() {\n\tconst nameInputs = document.querySelectorAll(\"[js-format-name]\");\n\n\tif (!nameInputs) return;\n\n\tnameInputs.forEach((input) => {\n\t\tinput.addEventListener(\"blur\", () => {\n\t\t\tencodeSpecialChars(input);\n\t\t});\n\t});\n}\n\nfunction encodeSpecialChars(input) {\n\tlet inputValue = input.value;\n\n\tif (inputValue.match(/&/g)) input.value = inputValue.replace(/&/g, \"and\");\n\n\tif (inputValue.match(/[!@#$%^*(),.?\":{}|<>]/g)) input.value = inputValue.replace(/[!@#$%^*(),.?\":{}|<>]/g, \"\");\n}\n\n// Add event listener to phone input\nexport function initJsFormatPhone() {\n\t// select it\n\tconst phoneInputs = document.querySelectorAll(\"[js-format-phone]\");\n\n\t// check it\n\tif (!phoneInputs) return;\n\n\t// handle it\n\tphoneInputs.forEach((input) => {\n\t\tinput.addEventListener(\"blur\", () => {\n\t\t\tformatAndValidatePhoneNumber(input);\n\t\t});\n\t});\n}\n\n// Format and validate phone numbers\nexport function formatAndValidatePhoneNumber(phoneInput) {\n\tlet phoneNumber = phoneInput.value.replace(/\\D/g, \"\");\n\n\tif (phoneNumber.length >= 3) {\n\t\tphoneNumber = \"(\" + phoneNumber.substr(0, 3) + \") \" + phoneNumber.substr(3);\n\t\tif (phoneNumber.length > 9) {\n\t\t\tphoneNumber = phoneNumber.slice(0, 9) + \"-\" + phoneNumber.slice(9);\n\t\t}\n\t}\n\n\tphoneInput.value = phoneNumber;\n\n\tif (phoneInput.hasAttribute(\"required\")) {\n\t\tconst phonePattern = /^\\(\\d{3}\\) \\d{3}-\\d{4}$/;\n\t\tif (!phonePattern.test(phoneNumber)) {\n\t\t\tphoneInput.classList.add(\"js-invalid\");\n\t\t\tphoneInput.setCustomValidity(\"invalid\");\n\t\t} else {\n\t\t\tphoneInput.classList.remove(\"js-invalid\");\n\t\t\tphoneInput.setCustomValidity(\"\");\n\t\t}\n\t} else {\n\t\tphoneInput.classList.remove(\"js-invalid\");\n\t\tphoneInput.setCustomValidity(\"\");\n\t}\n}\n\nexport function setNewsletterCheckbox() {\n\tlet listOfCheckboxes = document.querySelectorAll(\".js-set-by-country\");\n\tlistOfCheckboxes.forEach((element) => {\n\t\telement.setAttribute(\"checked\", \"checked\");\n\t});\n}\n\n// BUG? This may break if two ctas are used without a page refresh\n// Also this code is confusing especially the [].forEach .... is this using lodash or vanilla js\nexport function specificTarget(inputID, labelFor, listName, targetName) {\n\tvar targetList = document.querySelectorAll(`${inputID}, ${labelFor}, ${listName}`);\n\t[].forEach.call(targetList, function (target) {\n\t\tif ($(target).is('[list^=\"replace\"]') && $(target).is('[id^=\"replace\"]')) {\n\t\t\t$(target).attr(\"list\", $(target).attr(\"list\").replace(\"replace\", `${targetName}`));\n\t\t\t$(target).attr(\"id\", $(target).attr(\"id\").replace(\"replace\", `${targetName}`));\n\t\t} else if ($(target).is('[id^=\"replace\"]')) {\n\t\t\t$(target).attr(\"id\", $(target).attr(\"id\").replace(\"replace\", `${targetName}`));\n\t\t} else if ($(target).is('[for^=\"replace\"]')) {\n\t\t\t$(target).attr(\"for\", $(target).attr(\"for\").replace(\"replace\", `${targetName}`));\n\t\t}\n\t});\n}\n\nexport function mktoButtonClick() {\n\t$(\".mktoButton\").first().click();\n}\n\nexport function pushUtmToMarketoForm() {\n\ttry {\n\t\tdocument.querySelector(\"#utmcampaign\").value = utmObject.utmcampaign || \"\";\n\t\tdocument.querySelector(\"#utmcontent\").value = utmObject.utmcontent || \"\";\n\t\tdocument.querySelector(\"#utmmedium\").value = utmObject.utmmedium || \"\";\n\t\tdocument.querySelector(\"#utmsource\").value = utmObject.utmsource || \"\";\n\t\tdocument.querySelector(\"#utmterm\").value = utmObject.utmterm || \"\";\n\n\t\t$(\"#gclid\").val(utmObject.gclid || \"\");\n\t\t$(\"#fbclid\").val(utmObject.fbclid || \"\");\n\t\t$(\"#msclkid\").val(utmObject.msclkid || \"\");\n\t\t$(\"#cid\").val(utmObject.cid || \"\");\n\t} catch (error) {\n\t\tconsole.error(\"Error: \", error);\n\t}\n}\n\nexport function initMarketoFormBasics(formName) {\n\t// First Name\n\tdocument.querySelector(\"#LastName\").value = document.querySelector(`${formName} ${formName}-last_name`).value;\n\tdocument.querySelector(\"#FirstName\").value = document.querySelector(`${formName} ${formName}-first_name`).value;\n\tdocument.querySelector(\"#Email\").value = document.querySelector(`${formName} ${formName}-email`).value;\n\tdocument.querySelector(\"#LeadSource\").value = \"www.nathab.com\";\n\n\t// Set Click IDs from Cookie, or param if cookie is missing\n\turlParamstoCookiesList.forEach(function (parameter) {\n\t\t$(`#${parameter}`).val(utmObject[parameter]);\n\t});\n\n\t// Set Recent Conversion Action\n\tdocument.querySelector(\"#recentConversionAction\").value = document.querySelector(`${formName} [rca~=\"value\"]`).value;\n\n\t// ReferredAt = document.URL;\n\tdocument.querySelector(\"#requestedAt\").value = document.URL;\n\n\t// Referring Website from cookie\n\t$(\"#referringWebsite\").val(utmObject.referringWebsite || \"\");\n}\n\nexport function initMarketoFormCatalogBasic(formName) {\n\tdocument.querySelector(\"#Address\").value = document.querySelector(`${formName} ${formName}-pdfRequestHomeStreet`).value;\n\tdocument.querySelector(\"#addressLine2\").value = document.querySelector(`${formName} ${formName}-pdfRequestHomeStreet2`).value;\n\tdocument.querySelector(\"#City\").value = document.querySelector(`${formName} ${formName}-pdfRequestHomeCity`).value;\n\tdocument.querySelector(\"#State\").value = document.querySelector(`${formName} ${formName}-pdfRequestHomeState`).value;\n\tdocument.querySelector(\"#PostalCode\").value = document.querySelector(`${formName} ${formName}-pdfRequestHomeZIP`).value;\n\tvar countryValue = $(formName).find(`${formName}-pdfRequestHomeCountry`).val();\n\tdocument.querySelector(\"#Country\").value = countryValue;\n\tif (document.querySelector(`${formName} ${formName}-informationRequestPhone` != null)) {\n\t\tdocument.querySelector(\"#Phone\").value = document.querySelector(`${formName} ${formName}-informationRequestPhone`).value;\n\t}\n}\n\nexport function initMarketoFormCatalogExtra(formName) {\n\tdocument.querySelector(\"#temp8CatReferralSource\").value = document.querySelector(`${formName} ${formName}-find-nathab`).value;\n\tdocument.querySelector(\"#temp9CatReferralName\").value = document.querySelector(`${formName} ${formName}-friend-referral`).value;\n\tdocument.querySelector(\"#temp10CatPartySize\").value = document.querySelector(`${formName} ${formName}-party-size`).value;\n\tdocument.querySelector(\"#temp11CatBudget\").value = document.querySelector(`${formName} ${formName}-trip-budget`).value;\n\tdocument.querySelector(\"#temp12CatAvailability\").value = document.querySelector(`${formName} ${formName}-seasonYearInfo`).value;\n\tdocument.querySelector(\"#temp13CatTripSpecifics\").value = document.querySelector(`${formName} ${formName}-itinRequest`).value;\n\n\tif (document.querySelector(`${formName} ${formName}-company_name` != null)) {\n\t\tdocument.querySelector(\"#Company\").value = document.querySelector(`${formName} ${formName}-company_name`).value;\n\t}\n\n\t// Previous traveled checkboxes\n\tif (document.querySelector(`${formName} ${formName}-previously-traveled-africa`).checked) {\n\t\tdocument.querySelector(\"#previousTravelinAfrica\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-previously-traveled-alaska`).checked) {\n\t\tdocument.querySelector(\"#previousTravelinAlaska\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-previously-traveled-antarctica`).checked) {\n\t\tdocument.querySelector(\"#previousTravelinAntarctica\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-previously-traveled-arctic`).checked) {\n\t\tdocument.querySelector(\"#previousTravelinArctic\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-previously-traveled-asia`).checked) {\n\t\tdocument.querySelector(\"#previousTravelinAsia\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-previously-traveled-central-america`).checked) {\n\t\tdocument.querySelector(\"#previousTravelinCentralAmerica\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-previously-traveled-galapagos`).checked) {\n\t\tdocument.querySelector(\"#previousTravelinGalapagos\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-previously-traveled-south-america`).checked) {\n\t\tdocument.querySelector(\"#previousTravelinSouthAmerica\").value = true;\n\t}\n\n\t// Interests Checkboxes\n\tif (document.querySelector(`${formName} ${formName}-destination-polar-bears`).checked) {\n\t\tdocument.querySelector(\"#interestinPolarBears\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-africa`).checked) {\n\t\tdocument.querySelector(\"#interestinAfrica\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-galapagos`).checked) {\n\t\tdocument.querySelector(\"#interestinGalapagos\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-northern`).checked) {\n\t\tdocument.querySelector(\"#interestinAlaskaNorth\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-central-america`).checked) {\n\t\tdocument.querySelector(\"#interestinCentralAmerica\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-national-parks`).checked) {\n\t\tdocument.querySelector(\"#interestinUSNatlParks\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-asia-pacific`).checked) {\n\t\tdocument.querySelector(\"#interestinAsiaPacific\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-south-america`).checked) {\n\t\tdocument.querySelector(\"#interestinSouthAmerica\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-europe`).checked) {\n\t\tdocument.querySelector(\"#interestinEurope\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-destination-antarctica`).checked) {\n\t\tdocument.querySelector(\"#interestinPolar\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-interest-general-nature`).checked) {\n\t\tdocument.querySelector(\"#interestinGeneralNature\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-interest-nature-photography`).checked) {\n\t\tdocument.querySelector(\"#interestinPhoto\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-interest-family`).checked) {\n\t\tdocument.querySelector(\"#interestinFamily\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-interest-hiking-kayaking`).checked) {\n\t\tdocument.querySelector(\"#interestinActive\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-interest-cruising`).checked) {\n\t\tdocument.querySelector(\"#interestinCruises\").value = true;\n\t}\n\tif (document.querySelector(`${formName} ${formName}-interest-custom`).checked) {\n\t\tdocument.querySelector(\"#interestinCustom\").value = true;\n\t}\n\n\t// Travel Frequency\n\tvar travelFrequency = document.querySelectorAll(`${formName} [name='travel-frequency']`);\n\ttravelFrequency.forEach((radio) => {\n\t\tif (radio.checked) {\n\t\t\tdocument.querySelector(\"#temp15CatTravelFrequency\").value = radio.value;\n\t\t}\n\t});\n}\n\nexport function initMarketoFormOptins() {\n\tdocument.querySelector(\"#optInNHA\").value = true;\n\tdocument.querySelector(\"#optInWebinar\").value = true;\n\tdocument.querySelector(\"#optInStories\").value = true;\n\tdocument.querySelector(\"#optInSurveys\").value = true;\n\tdocument.querySelector(\"#optInTripDrips\").value = true;\n\tdocument.querySelector(\"#optInSalesperson\").value = true;\n}\n\nexport function toggleButtonDisabled(button) {\n\tbutton.setAttribute(\"disabled\", \"true\");\n\tsetTimeout(function () {\n\t\tbutton.removeAttribute(\"disabled\");\n\t}, 15000);\n}\n\nexport function isThisSpam(formName) {\n\tvar fields = [\"first_name\", \"last_name\"];\n\tfor (const field of fields) {\n\t\tlet target = `${formName}-${field}`;\n\t\tvar spamCheck = document.querySelector(`${formName} ${target}`).value;\n\t\tif (spamCheck.match(/[!@#$%^&*(),.?\":{}|<>]/g)) {\n\t\t\treturn true;\n\t\t}\n\t}\n}\n\nexport function validateForm(formName) {\n\tvar invalidCount = $(formName).find(\":invalid\").length;\n\tif (invalidCount > 0) {\n\t\t$(formName).find(\":invalid\").addClass(\"js-invalid\");\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n}\n\nexport function setRequiredFields(formName) {\n\t$(formName).find(\"[js-required]\").attr(\"required\", \"\");\n}\n\nexport function unSetRequiredFields(formName) {\n\t$(formName).find(\"[js-required]\").removeAttr(\"required\");\n}\n\n// Disable sibling(ish) checkboxes after x checkbox is checked\nexport function limitCheckboxes(form) {\n\tlet arrayOfCheckboxLists = document.querySelectorAll(`${form} [js-limit]`); // sort of vague\n\tarrayOfCheckboxLists.forEach((checkboxList) => {\n\t\tlet max = parseInt(checkboxList.getAttribute(\"js-limit\"), 10);\n\t\tlet arrayOfCheckboxes = checkboxList.querySelectorAll(\"input[type='checkbox']\");\n\t\tlet totalChecked = 0;\n\n\t\tarrayOfCheckboxes.forEach((checkbox) => {\n\t\t\tcheckbox.addEventListener(\"change\", () => {\n\t\t\t\tif (checkbox.checked) {\n\t\t\t\t\ttotalChecked++;\n\t\t\t\t} else {\n\t\t\t\t\ttotalChecked--;\n\t\t\t\t}\n\t\t\t\tif (totalChecked > max) {\n\t\t\t\t\tcheckbox.checked = false;\n\t\t\t\t\ttotalChecked--;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n}\n\nexport function updateFormButtonText(formName) {\n\tvar originalButtonText = $(formName).find(\".js-button-submit\").text();\n\t$(formName).find(\".js-button-submit\").prop(\"disabled\", \"true\");\n\tsetTimeout(function () {\n\t\t$(formName).find(\".js-button-submit\").text(\"Saving ...\");\n\t}, 500);\n\tsetTimeout(function () {\n\t\t$(formName).find(\".js-button-submit\").text(\"Thank You!\");\n\t}, 2000);\n\tsetTimeout(function () {\n\t\t$(formName).find(\".js-button-submit\").text(originalButtonText);\n\t\t$(formName).find(\".js-button-submit\").prop(\"disabled\", \"\");\n\t}, 5000);\n}\n","import { countryList } from \"../../../components/lists/country-list/_country-list.js\";\nimport { pushEvent, pushEventFacebook, pushEventBing, saveUserCountryToLocalStorage } from \"../../../assets/js/utilities.js\";\nimport { initSmarty } from \"../../../assets/js/smartypants.js\";\nimport { initJsFormatPhone, initJsFormatName, setOptsOnMarketoForm, isFormValid, pushUtmToMarketoForm, toggleButtonDisabled, isThisSpam } from \"../../../assets/js/global-form-functions.js\";\nimport { isSMSOptinChecked, setSMSOptsOnMarketoForm } from \"../../../assets/js/global-form-functions.js\";\nimport { toggleAmbientVideo } from \"../../../components/hero/_video.js\";\n\n// clear session storage preventing OM CTA from showing\nexport function clearOMSessionStorage() {\n\tsessionStorage.setItem(\"preventOMCta\", \"false\");\n}\n\nexport function pageVisitCounter(cookieName, urlPath) {\n\tlet visits = Cookies.get(cookieName);\n\tif (visits > 2) {\n\t\treturn;\n\t}\n\tif (!visits) {\n\t\tvisits = 1;\n\t} else {\n\t\tvisits = parseInt(visits) + 1;\n\t}\n\tCookies.set(cookieName, visits, {\n\t\texpires: 30,\n\t\tpath: urlPath\n\t});\n\n\tpageVisitCheck(cookieName, visits);\n}\n\nfunction pageVisitCheck(name, visitCount) {\n\t// prettier-ignore\n\tif ((name === \"itin-kbyg\" && visitCount === 2) || (name === \"itin\" && visitCount === 1)) {\n\t\titineraryModal();\n\t}\n}\nasync function itineraryModal() {\n\tawait saveUserCountryToLocalStorage();\n\tlet userCountry = localStorage.getItem(\"country\") || \"unknown\";\n\n\tconst urlPathname = window.location.pathname;\n\n\t// prevent OM CTAs from showing on pages where we've auto popped the itinerary modal\n\tif (urlPathname.includes(\"itinerary\")) {\n\t\tsessionStorage.setItem(\"preventOMCta\", \"true\");\n\t}\n\n\tlet viewportWidth = window.innerWidth;\n\tif (viewportWidth < 1025) {\n\t\treturn;\n\t}\n\n\tlet itinerary = new Object();\n\titinerary.formName = \"#form-itinerary\";\n\titinerary.eventAction = \"\";\n\titinerary.catalog = false;\n\titinerary.smsElementParent = document.querySelector(\".js-sms-checkbox-itinerary\");\n\titinerary.smsElement = document.querySelector(\"[js-itinerary-sms]\");\n\titinerary.phoneElementInput = document.querySelector(\"[js-itinerary-phone-toggle]\");\n\titinerary.phoneElementLabel = document.querySelector('[for~=\"form-itinerary-phone\"]');\n\titinerary.catalogElement = document.querySelector(\"[js-itinerary-catalog-toggle]\");\n\titinerary.locationSelector = \"js-itinerary-location\";\n\titinerary.locationFirstElement = document.querySelector(`[${itinerary.locationSelector}]`);\n\titinerary.locationAllElements = document.querySelectorAll(`[${itinerary.locationSelector}]`);\n\n\titinerary.catalogCheckbox = document.querySelectorAll(\"[js-itinerary-switch]\");\n\titinerary.catalogAllElements = document.querySelectorAll(\"[js-itinerary-]\");\n\titinerary.locationValue = \"Unknown\";\n\titinerary.firstInput = document.querySelector(\"[itinerary-form-label]\");\n\n\tlet catalogFieldWrappersForItinerary = document.querySelectorAll(\"[js-itinerary-toggle-catalog]\"),\n\t\tcatalogRequiredFieldsForItinerary = document.querySelectorAll(\"[js-itinerary-field-required]\"),\n\t\titineraryScreenRequired = document.querySelector(\".js-itinerary-required\"),\n\t\titineraryScreenThankYou = document.querySelector(\".js-itinerary-thankyou\");\n\n\tinitJsFormatPhone();\n\tinitJsFormatName();\n\n\tsetTimeout(() => {\n\t\tif (userCountry === \"US\") {\n\t\t\tinitSmarty(itinerary.formName);\n\t\t\titinerary.smsElementParent.classList.remove(\"hide\");\n\t\t\tsmsCheckbox();\n\t\t}\n\t}, 1000);\n\n\t// Event - When SMS checkbox changes do stuff\n\tfunction smsCheckbox() {\n\t\titinerary.smsElement.addEventListener(\"input\", function () {\n\t\t\tif (this.checked) {\n\t\t\t\titinerary.phoneElementInput.setAttribute(\"required\", \"\");\n\t\t\t\titinerary.phoneElementLabel.setAttribute(\"itinerary-form-label\", \"required\");\n\t\t\t} else {\n\t\t\t\titinerary.phoneElementInput.removeAttribute(\"required\");\n\t\t\t\titinerary.phoneElementLabel.setAttribute(\"itinerary-form-label\", \"\");\n\t\t\t\titinerary.phoneElementInput.classList.remove(\"js-invalid\");\n\t\t\t}\n\t\t});\n\t}\n\n\t// EVENT - Add event listener to all elements with the locationSelector\n\titinerary.locationAllElements.forEach((element) => {\n\t\telement.addEventListener(\"click\", function () {\n\t\t\tsessionStorage.setItem(\"modalOpen\", true);\n\n\t\t\t// pause ambient video when modal is opened\n\t\t\ttoggleAmbientVideo(false);\n\n\t\t\tconst countryInput = document.querySelectorAll(`${itinerary.formName} .js-smarty-country`);\n\t\t\tif (userCountry !== \"unknown\") {\n\t\t\t\tcountryInput.forEach((input) => {\n\t\t\t\t\tconst country = countryList.filter((country) => userCountry === country.code);\n\t\t\t\t\tinput.value = country[0].name;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (checkMarketoForm() === false) {\n\t\t\t\tinitMarketoForm();\n\t\t\t}\n\n\t\t\tpushEvent(\"eNews\", \"Itinerary\", \"Open\");\n\n\t\t\tsetTimeout(() => {\n\t\t\t\titinerary.firstInput.focus();\n\t\t\t}, 1000);\n\t\t});\n\t});\n\n\titinerary.locationFirstElement.click();\n\n\t// Event - When catalog request checkbox changes do stuff\n\titinerary.catalogElement.addEventListener(\"change\", function () {\n\t\tif (this.checked) {\n\t\t\ttoggleCatalogFieldsForItinerary(\"show\");\n\t\t} else {\n\t\t\ttoggleCatalogFieldsForItinerary(\"hide\");\n\t\t}\n\t});\n\n\t// EVENT - Handle submit of required form\n\tdocument.querySelector(\".js-itinerary-button-required\").addEventListener(\"click\", function (e) {\n\t\te.preventDefault();\n\t\tpostFormItinerary();\n\t});\n\n\tfunction toggleCatalogFieldsForItinerary(action) {\n\t\tif (action === \"show\") {\n\t\t\titinerary.catalog = true;\n\t\t\tcatalogFieldWrappersForItinerary.forEach((element) => {\n\t\t\t\telement.classList.remove(\"hide\");\n\t\t\t});\n\t\t\tcatalogRequiredFieldsForItinerary.forEach((element) => {\n\t\t\t\telement.setAttribute(\"required\", \"\");\n\t\t\t});\n\t\t} else {\n\t\t\titinerary.catalog = false;\n\t\t\tcatalogFieldWrappersForItinerary.forEach((element) => {\n\t\t\t\telement.classList.add(\"hide\");\n\t\t\t});\n\t\t\tcatalogRequiredFieldsForItinerary.forEach((element) => {\n\t\t\t\telement.removeAttribute(\"required\");\n\t\t\t});\n\t\t}\n\t}\n\n\tfunction copyItineraryFieldsToMarketoForm() {\n\t\tlet fieldsToCopyArray = document.querySelectorAll(`${itinerary.formName} [mrkto-field]`);\n\t\tfieldsToCopyArray.forEach((field) => {\n\t\t\tlet mrktoFieldSelector = field.getAttribute(\"mrkto-field\");\n\t\t\tif (field.value) {\n\t\t\t\tdocument.querySelector(mrktoFieldSelector).value = field.value;\n\t\t\t}\n\t\t});\n\t}\n\n\tfunction postFormItinerary() {\n\t\tlet retryLimit = 3,\n\t\t\tretryAttempt = 0;\n\n\t\t// Validate form\n\t\tlet isValid = isFormValid(itinerary.formName);\n\t\tif (isValid === false) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for spam\n\t\tif (isThisSpam(itinerary.formName) === true) {\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleButtonDisabled(document.querySelector(\".js-itinerary-button-required\"));\n\n\t\t// Check if marketo form has been loaded, if not retry with limits\n\t\tif (checkMarketoForm() === false && retryAttempt < retryLimit) {\n\t\t\tinitMarketoForm(function () {\n\t\t\t\tretryAttempt++;\n\t\t\t\tpostFormItinerary();\n\t\t\t});\n\t\t}\n\n\t\tMktoForms2.whenReady(function () {\n\t\t\tlet optins = \"\";\n\n\t\t\tpushUtmToMarketoForm(); // function lives in global\n\t\t\tdocument.querySelector(\"#isEmailSignup\").value = true;\n\t\t\tdocument.querySelector(\"#sourceDetail\").value = \"Trip Subpage\";\n\t\t\tdocument.querySelector(\"#requestedAt\").value = document.URL;\n\t\t\tdocument.querySelector(\"#LeadSource\").value = \"www.nathab.com\";\n\t\t\tdocument.querySelector(\"#recentConversionAction\").value = \"Itinerary Pop-Up\";\n\t\t\tdocument.querySelector(\"#referringWebsite\").value = utmObject.referringWebsite || \"\";\n\n\t\t\tcopyItineraryFieldsToMarketoForm(itinerary.formName); // Used for both required and optional\n\n\t\t\tsetOptsOnMarketoForm();\n\n\t\t\tif (isSMSOptinChecked(itinerary.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isSMSSignup\").value = true;\n\t\t\t\toptins += \" SMS\";\n\t\t\t\tsetSMSOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\tif (itinerary.catalog === true) {\n\t\t\t\tdocument.querySelector(\"#temp\").value = \"CatRequestIsTrue\";\n\t\t\t\tdocument.querySelector(\"#isCatalogRequested\").value = true;\n\t\t\t\toptins += \" Catalog\";\n\t\t\t}\n\n\t\t\t// stupid edge case just to get a comma in the string\n\t\t\toptins = optins.replace(\"SMS Catalog\", \"SMS, Catalog\");\n\n\t\t\toptins = optins || \" no optins\"; // if empty string, set to no optins\n\t\t\tlet pushEventString = `Submitted w/${optins}`;\n\n\t\t\tpushEvent(\"eNews\", \"Itinerary\", pushEventString);\n\n\t\t\tmarketoSubmitFormItin();\n\t\t\tpushEventFacebook();\n\t\t\tpushEventBing();\n\n\t\t\tsetTimeout(() => {\n\t\t\t\titineraryScreenRequired.classList.add(\"hide\");\n\t\t\t\titineraryScreenThankYou.classList.remove(\"hide\");\n\t\t\t\titineraryScreenThankYou.scrollTop = 0;\n\t\t\t}, 2750);\n\t\t});\n\t}\n\n\tfunction marketoSubmitFormItin() {\n\t\tif (checkMarketoForm() === false) {\n\t\t\tpushEvent(\"Marketo\", \"Form\", \"Not Loaded during marketoSubmitForm()\");\n\t\t}\n\n\t\tMktoForms2.whenReady(function (form) {\n\t\t\tform.submit();\n\t\t});\n\t}\n}\n","import { pushEvent, pushEventFacebook, pushEventBing, saveUserCountryToLocalStorage } from \"../../../assets/js/utilities.js\";\nimport { initJsFormatPhone, initJsFormatName, setOptsOnMarketoForm, isFormValid, isNewsletterChecked, setNewsletterCheckbox, pushUtmToMarketoForm, toggleButtonDisabled, isThisSpam } from \"../../../assets/js/global-form-functions.js\";\nimport { isSMSOptinChecked, setSMSOptsOnMarketoForm } from \"../../../assets/js/global-form-functions.js\";\nimport { toggleAmbientVideo } from \"../../../components/hero/_video.js\";\n\nexport async function customModal() {\n\tawait saveUserCountryToLocalStorage();\n\tlet userCountry = localStorage.getItem(\"country\") || \"unknown\";\n\n\tlet pageURL = document.URL;\n\tlet custom = new Object();\n\tcustom.formName = \"#form-custom\";\n\tcustom.newsletter = false;\n\tcustom.smsElementParent = document.querySelectorAll(\".js-sms-checkbox-custom\");\n\tcustom.smsElement = document.querySelector(\"[js-custom-sms]\");\n\tcustom.phoneElementInput = document.querySelector(\"[js-custom-phone-toggle]\");\n\tcustom.phoneElementLabel = document.querySelector('[for~=\"form-custom-phone\"]');\n\tcustom.locationSelector = \"js-custom-location\";\n\tcustom.locationFirstElement = document.querySelector(`[${custom.locationSelector}]`);\n\tcustom.locationAllElements = document.querySelectorAll(`[${custom.locationSelector}]`);\n\tcustom.firstInput = document.querySelector(\"[custom-form-label]\");\n\n\tlet customScreenRequired = document.querySelector(\".js-custom-required\"),\n\t\tcustomScreenThankYou = document.querySelector(\".js-custom-thankyou\");\n\n\tinitJsFormatPhone();\n\tinitJsFormatName();\n\n\tfunction insert_group_sizes_into_custom_form() {\n\t\tconst minSizeAsideSelector = document.querySelector(\".js-custom-aside-minimum-text\");\n\t\tconst partySizeElement = document.querySelector(\".js-custom-form-party-size\");\n\t\tif (!minSizeAsideSelector || !partySizeElement) return;\n\n\t\tconst groupMin = partySizeElement.getAttribute(\"min\");\n\t\tconst groupMax = partySizeElement.getAttribute(\"max\");\n\t\tlet groupMinValue = parseNumber(groupMin);\n\t\tconst groupMaxValue = parseNumber(groupMax) || 15; // Default max if not set (would be a rare case where max is not set and MIP is used)\n\n\t\t// udpate aside text with min group size\n\t\tconst minSizeAsideText = minSizeAsideSelector.textContent;\n\t\tconst groupMinText = groupMinValue ? `${groupMinValue} guests` : \"approximately half the maximum size of our regularly scheduled departures\";\n\n\t\tconst updatedText = minSizeAsideText.replace(\"${minGroupSize}\", groupMinText);\n\t\tminSizeAsideSelector.innerHTML = updatedText;\n\n\t\t// if no min, set to half of max for Party Size field\n\t\tif (!groupMinValue) groupMinValue = Math.floor(groupMaxValue / 2);\n\n\t\t// create options for Party Size select field\n\t\tif (groupMinValue <= groupMaxValue) {\n\t\t\tlet optionsHTML = \"\";\n\n\t\t\tfor (let i = groupMinValue; i <= groupMaxValue; i++) {\n\t\t\t\tif (i === groupMinValue) {\n\t\t\t\t\toptionsHTML += ``;\n\t\t\t\t} else if (i === groupMaxValue) {\n\t\t\t\t\toptionsHTML += ``;\n\t\t\t\t} else {\n\t\t\t\t\toptionsHTML += ``;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpartySizeElement.insertAdjacentHTML(\"beforeend\", optionsHTML);\n\n\t\t\t// Add event listener to remove Min/Max from label if selected\n\t\t\tpartySizeElement.addEventListener(\"change\", function () {\n\t\t\t\tconst selectedOption = partySizeElement.options[partySizeElement.selectedIndex];\n\t\t\t\tupdateOptionText(\"remove\", selectedOption, groupMinValue, groupMaxValue);\n\t\t\t});\n\n\t\t\t// Add event listener to add Min/Max back if the select dropdown is opened again without losing focus\n\t\t\tpartySizeElement.addEventListener(\"mousedown\", function () {\n\t\t\t\tconst selectedOption = partySizeElement.options[partySizeElement.selectedIndex];\n\t\t\t\tupdateOptionText(\"add\", selectedOption, groupMinValue, groupMaxValue);\n\t\t\t});\n\n\t\t\t// Add event listener to add Min/Max back if the select dropdown is opened again without losing focus using the keyboard\n\t\t\tpartySizeElement.addEventListener(\"keydown\", function () {\n\t\t\t\tconst selectedOption = partySizeElement.options[partySizeElement.selectedIndex];\n\t\t\t\tupdateOptionText(\"add\", selectedOption, groupMinValue, groupMaxValue);\n\t\t\t});\n\n\t\t\t// Add event listener to update the displayed value when the select dropdown loses focus (needed if value hasn't changed)\n\t\t\tpartySizeElement.addEventListener(\"blur\", function () {\n\t\t\t\tconst selectedOption = partySizeElement.options[partySizeElement.selectedIndex];\n\t\t\t\tupdateOptionText(\"remove\", selectedOption, groupMinValue, groupMaxValue);\n\t\t\t});\n\t\t}\n\t}\n\tinsert_group_sizes_into_custom_form();\n\n\tfunction parseNumber(value) {\n\t\tconst match = value.match(/(\\d+)/);\n\t\treturn match ? parseInt(value, 10) : NaN;\n\t}\n\n\t// add/remove Min/Max from label\n\tfunction updateOptionText(action, option, groupMinValue, groupMaxValue) {\n\t\tif (option.value == groupMinValue) {\n\t\t\toption.textContent = action === \"remove\" ? groupMinValue : `Min ${groupMinValue}`;\n\t\t} else if (option.value == groupMaxValue) {\n\t\t\toption.textContent = action === \"remove\" ? groupMaxValue : `Max ${groupMaxValue}`;\n\t\t}\n\t}\n\n\t// Event - When SMS checkbox changes do stuff\n\tcustom.smsElement.addEventListener(\"input\", function () {\n\t\tif (this.checked) {\n\t\t\tcustom.phoneElementInput.setAttribute(\"required\", \"\");\n\t\t\tcustom.phoneElementLabel.setAttribute(\"custom-form-label\", \"required\");\n\t\t} else {\n\t\t\tcustom.phoneElementInput.removeAttribute(\"required\");\n\t\t\tcustom.phoneElementLabel.setAttribute(\"custom-form-label\", \"\");\n\t\t\tcustom.phoneElementInput.classList.remove(\"js-invalid\");\n\t\t}\n\t});\n\n\t// Add event listener to all elements that can open this modal\n\tcustom.locationAllElements.forEach((element) => {\n\t\t//check eNews box for users in US, India, and Australia\n\t\tif (userCountry === \"US\" || userCountry === \"IN\" || userCountry === \"AU\") {\n\t\t\tsetNewsletterCheckbox();\n\t\t\tcustom.smsElementParent.forEach((checkbox) => {\n\t\t\t\tcheckbox.classList.remove(\"hide\");\n\t\t\t});\n\t\t}\n\t\telement.addEventListener(\"click\", function () {\n\t\t\tsessionStorage.setItem(\"modalOpen\", true);\n\n\t\t\t// pause ambient video when modal is opened\n\t\t\ttoggleAmbientVideo(false);\n\n\t\t\tif (checkMarketoForm() === false) {\n\t\t\t\tinitMarketoForm();\n\t\t\t}\n\t\t\tpushEvent(\"Misc\", \"Custom\", \"Open\");\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tcustom.firstInput.focus();\n\t\t\t}, 1000);\n\t\t});\n\t});\n\n\t// Check for #custom in links\n\tlet linksWithHash = document.querySelectorAll(\"a[href^='#']\");\n\tlet linksWithHashNormalized = [];\n\tlinksWithHash.forEach((link) => {\n\t\tlet href = link.getAttribute(\"href\").toLowerCase();\n\t\tif (href.includes(\"#custom\")) {\n\t\t\tlinksWithHashNormalized.push(link);\n\t\t}\n\t});\n\tlet linksWithLightbox = document.querySelectorAll(\"a[href~='?lightbox=custom']\");\n\tlet linksCombined = [...linksWithHashNormalized, ...linksWithLightbox];\n\taddClickEvents(linksCombined);\n\tfunction addClickEvents(list) {\n\t\tlist.forEach((element) => {\n\t\t\telement.addEventListener(\"click\", function (e) {\n\t\t\t\te.preventDefault();\n\t\t\t\tcustom.locationFirstElement.click();\n\t\t\t});\n\t\t});\n\t}\n\n\t// Check for #hash or ?lightbox=value in URL\n\tif (pageURL.indexOf(\"#custom\") > 0 || pageURL.indexOf(\"#Custom\") > 0 || window.location.search.match(/lightbox\\=custom/i)) {\n\t\tcustom.locationFirstElement.click();\n\t}\n\n\t// EVENT - Handle submit of required form\n\tdocument.querySelector(\".js-custom-button-required\").addEventListener(\"click\", function (e) {\n\t\te.preventDefault();\n\t\tpostFormCustom();\n\t});\n\n\tfunction copyCustomFieldsToMarketoForm() {\n\t\tlet fieldsToCopyArray = document.querySelectorAll(`${custom.formName} [mrkto-field]`);\n\t\tfieldsToCopyArray.forEach((field) => {\n\t\t\tlet mrktoFieldSelector = field.getAttribute(\"mrkto-field\");\n\t\t\tif (field.value) {\n\t\t\t\tdocument.querySelector(mrktoFieldSelector).value = field.value;\n\t\t\t}\n\t\t});\n\t}\n\n\tfunction postFormCustom() {\n\t\tlet retryLimit = 3,\n\t\t\tretryAttempt = 0;\n\n\t\t// Validate form\n\t\tlet isValid = isFormValid(custom.formName);\n\t\tif (isValid === false) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for spam\n\t\tif (isThisSpam(custom.formName) === true) {\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleButtonDisabled(document.querySelector(\".js-custom-button-required\"));\n\n\t\t// Check if marketo form has been loaded, if not retry with limits\n\t\tif (checkMarketoForm() === false && retryAttempt < retryLimit) {\n\t\t\tinitMarketoForm(function () {\n\t\t\t\tretryAttempt++;\n\t\t\t\tpostFormCustom();\n\t\t\t});\n\t\t}\n\n\t\tMktoForms2.whenReady(function () {\n\t\t\tlet optins = \"\";\n\n\t\t\tpushUtmToMarketoForm(); // function lives in global\n\t\t\tdocument.querySelector(\"#requestedAt\").value = document.URL;\n\t\t\tdocument.querySelector(\"#LeadSource\").value = \"www.nathab.com\";\n\t\t\tdocument.querySelector(\"#sourceDetail\").value = \"Custom Africa Question\";\n\t\t\tdocument.querySelector(\"#recentConversionAction\").value = \"Custom Africa Question\";\n\t\t\tdocument.querySelector(\"#referringWebsite\").value = utmObject.referringWebsite || \"\";\n\t\t\tdocument.querySelector(\"#isAskQuestion\").value = true;\n\n\t\t\tcopyCustomFieldsToMarketoForm(custom.formName); // Used for both required and optional\n\n\t\t\tif (isNewsletterChecked(custom.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isEmailSignup\").value = true;\n\t\t\t\toptins += \" eNews\";\n\t\t\t\tsetOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\tif (isSMSOptinChecked(custom.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isSMSSignup\").value = true;\n\t\t\t\toptins += \" SMS\";\n\t\t\t\tsetSMSOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\t// stupid edge case just to get a comma in the string\n\t\t\toptins = optins.replace(\"eNews SMS\", \"eNews, SMS\");\n\n\t\t\toptins = optins || \" no optins\"; // if empty string, set to no optins\n\n\t\t\tlet pushEventString = `Submitted w/${optins}`;\n\t\t\tpushEvent(\"Misc\", \"Custom\", pushEventString);\n\n\t\t\tmarketoSubmitFormCustom();\n\n\t\t\tpushEventFacebook();\n\t\t\tpushEventBing();\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tcustomScreenRequired.classList.add(\"hide\");\n\t\t\t\tcustomScreenThankYou.classList.remove(\"hide\");\n\t\t\t\tcustomScreenThankYou.scrollTop = 0;\n\t\t\t}, 2750);\n\t\t});\n\t}\n\n\tfunction marketoSubmitFormCustom() {\n\t\tif (checkMarketoForm() === false) {\n\t\t\tpushEvent(\"Marketo\", \"Form\", \"Not Loaded during marketoSubmitForm()\");\n\t\t}\n\n\t\tMktoForms2.whenReady(function (form) {\n\t\t\tform.submit();\n\t\t});\n\t}\n}\n","import { pushEvent, pushEventFacebook, pushEventBing, saveUserCountryToLocalStorage } from \"../../../assets/js/utilities.js\";\nimport { initJsFormatPhone, initJsFormatName, setOptsOnMarketoForm, isFormValid, isNewsletterChecked, setNewsletterCheckbox, pushUtmToMarketoForm, toggleButtonDisabled, isThisSpam } from \"../../../assets/js/global-form-functions.js\";\nimport { isSMSOptinChecked, setSMSOptsOnMarketoForm } from \"../../../assets/js/global-form-functions.js\";\nimport { toggleAmbientVideo } from \"../../../components/hero/_video.js\";\n\nexport async function privateModal() {\n\tawait saveUserCountryToLocalStorage();\n\tlet userCountry = localStorage.getItem(\"country\") || \"unknown\";\n\n\tlet pageURL = document.URL;\n\tlet privateModal = new Object();\n\tprivateModal.formName = \"#form-private\";\n\tprivateModal.newsletter = false;\n\tprivateModal.smsElementParent = document.querySelectorAll(\".js-sms-checkbox-private\");\n\tprivateModal.smsElement = document.querySelector(\"[js-private-sms]\");\n\tprivateModal.phoneElementInput = document.querySelector(\"[js-private-phone-toggle]\");\n\tprivateModal.phoneElementLabel = document.querySelector('[for~=\"form-private-phone\"]');\n\tprivateModal.locationSelector = \"js-private-location\";\n\tprivateModal.locationFirstElement = document.querySelector(`[${privateModal.locationSelector}]`);\n\tprivateModal.locationAllElements = document.querySelectorAll(`[${privateModal.locationSelector}]`);\n\tprivateModal.firstInput = document.querySelector(\"[private-form-label]\");\n\n\tlet privateScreenRequired = document.querySelector(\".js-private-required\"),\n\t\tprivateScreenThankYou = document.querySelector(\".js-private-thankyou\");\n\n\tinitJsFormatPhone();\n\tinitJsFormatName();\n\n\t// Function - insert trip name and MIP min group size into aside text\n\tfunction insertTripNameIntoAsideText() {\n\t\tconst asideTextSelector = document.querySelector(\".js-private-aside-text\");\n\t\tconst questionTextSelector = document.querySelector(\".js-private-question-text\");\n\n\t\tif (asideTextSelector && questionTextSelector) {\n\t\t\tlet asideText = asideTextSelector.innerHTML;\n\t\t\tlet questionText = questionTextSelector.innerHTML;\n\n\t\t\tlet tripName = document.querySelector(\".js-tripName\").textContent;\n\t\t\tif (tripName.startsWith(\"The \")) {\n\t\t\t\ttripName = tripName.replace(\"The \", \"\");\n\t\t\t}\n\n\t\t\tfunction updateTripName(selector, oldText) {\n\t\t\t\tlet updatedText = oldText.replace(\"${tripName}\", tripName);\n\t\t\t\tselector.innerHTML = updatedText;\n\t\t\t}\n\n\t\t\tupdateTripName(asideTextSelector, asideText);\n\t\t\tupdateTripName(questionTextSelector, questionText);\n\t\t}\n\t}\n\tinsertTripNameIntoAsideText();\n\n\tfunction insert_group_sizes_into_private_form() {\n\t\tconst minSizeAsideSelector = document.querySelector(\".js-private-aside-minimum-text\");\n\t\tconst partySizeElement = document.querySelector(\".js-private-form-party-size\");\n\t\tif (!minSizeAsideSelector || !partySizeElement) return;\n\n\t\tconst groupMin = partySizeElement.getAttribute(\"min\");\n\t\tconst groupMax = partySizeElement.getAttribute(\"max\");\n\t\tlet groupMinValue = parseNumber(groupMin);\n\t\tconst groupMaxValue = parseNumber(groupMax) || 15; // Default max if not set (would be a rare case where max is not set and MIP is used)\n\n\t\t// udpate aside text with min group size\n\t\tconst minSizeAsideText = minSizeAsideSelector.textContent;\n\t\tconst groupMinText = groupMinValue ? `${groupMinValue} guests` : \"approximately half the maximum size of our regularly scheduled departures\";\n\n\t\tconst updatedText = minSizeAsideText.replace(\"${minGroupSize}\", groupMinText);\n\t\tminSizeAsideSelector.innerHTML = updatedText;\n\n\t\t// if no min, set to half of max for Party Size field\n\t\tif (!groupMinValue) groupMinValue = Math.floor(groupMaxValue / 2);\n\n\t\t// create options for Party Size select field\n\t\tif (groupMinValue <= groupMaxValue) {\n\t\t\tlet optionsHTML = \"\";\n\n\t\t\tfor (let i = groupMinValue; i <= groupMaxValue; i++) {\n\t\t\t\tif (i === groupMinValue) {\n\t\t\t\t\toptionsHTML += ``;\n\t\t\t\t} else if (i === groupMaxValue) {\n\t\t\t\t\toptionsHTML += ``;\n\t\t\t\t} else {\n\t\t\t\t\toptionsHTML += ``;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpartySizeElement.insertAdjacentHTML(\"beforeend\", optionsHTML);\n\n\t\t\t// Add event listener to remove Min/Max from label if selected\n\t\t\tpartySizeElement.addEventListener(\"change\", function () {\n\t\t\t\tconst selectedOption = partySizeElement.options[partySizeElement.selectedIndex];\n\t\t\t\tupdateOptionText(\"remove\", selectedOption, groupMinValue, groupMaxValue);\n\t\t\t});\n\n\t\t\t// Add event listener to add Min/Max back if the select dropdown is opened again without losing focus\n\t\t\tpartySizeElement.addEventListener(\"mousedown\", function () {\n\t\t\t\tconst selectedOption = partySizeElement.options[partySizeElement.selectedIndex];\n\t\t\t\tupdateOptionText(\"add\", selectedOption, groupMinValue, groupMaxValue);\n\t\t\t});\n\n\t\t\t// Add event listener to add Min/Max back if the select dropdown is opened again without losing focus using the keyboard\n\t\t\tpartySizeElement.addEventListener(\"keydown\", function () {\n\t\t\t\tconst selectedOption = partySizeElement.options[partySizeElement.selectedIndex];\n\t\t\t\tupdateOptionText(\"add\", selectedOption, groupMinValue, groupMaxValue);\n\t\t\t});\n\n\t\t\t// Add event listener to update the displayed value when the select dropdown loses focus (needed if value hasn't changed)\n\t\t\tpartySizeElement.addEventListener(\"blur\", function () {\n\t\t\t\tconst selectedOption = partySizeElement.options[partySizeElement.selectedIndex];\n\t\t\t\tupdateOptionText(\"remove\", selectedOption, groupMinValue, groupMaxValue);\n\t\t\t});\n\t\t}\n\t}\n\tinsert_group_sizes_into_private_form();\n\n\tfunction parseNumber(value) {\n\t\tconst match = value.match(/(\\d+)/);\n\t\treturn match ? parseInt(value, 10) : NaN;\n\t}\n\n\t// add/remove Min/Max from label\n\tfunction updateOptionText(action, option, groupMinValue, groupMaxValue) {\n\t\tif (option.value == groupMinValue) {\n\t\t\toption.textContent = action === \"remove\" ? groupMinValue : `Min ${groupMinValue}`;\n\t\t} else if (option.value == groupMaxValue) {\n\t\t\toption.textContent = action === \"remove\" ? groupMaxValue : `Max ${groupMaxValue}`;\n\t\t}\n\t}\n\n\t// Event - When SMS checkbox changes do stuff\n\tfunction smsCheckbox() {\n\t\tprivateModal.smsElement.addEventListener(\"input\", function () {\n\t\t\tif (this.checked) {\n\t\t\t\tprivateModal.phoneElementInput.setAttribute(\"required\", \"\");\n\t\t\t\tprivateModal.phoneElementLabel.setAttribute(\"private-form-label\", \"required\");\n\t\t\t} else {\n\t\t\t\tprivateModal.phoneElementInput.removeAttribute(\"required\");\n\t\t\t\tprivateModal.phoneElementLabel.setAttribute(\"private-form-label\", \"\");\n\t\t\t\tprivateModal.phoneElementInput.classList.remove(\"js-invalid\");\n\t\t\t}\n\t\t});\n\t}\n\n\tprivateModal.locationAllElements.forEach((element) => {\n\t\t//pre-check eNews box for users in US, India, and Australia\n\t\tif (userCountry === \"US\" || userCountry === \"IN\" || userCountry === \"AU\") {\n\t\t\tsetNewsletterCheckbox();\n\t\t\tprivateModal.smsElementParent.forEach((checkbox) => {\n\t\t\t\tcheckbox.classList.remove(\"hide\");\n\t\t\t});\n\t\t\tsmsCheckbox();\n\t\t}\n\t\telement.addEventListener(\"click\", function () {\n\t\t\tsessionStorage.setItem(\"modalOpen\", true);\n\n\t\t\t// pause ambient video when modal is opened\n\t\t\ttoggleAmbientVideo(false);\n\n\t\t\tif (checkMarketoForm() === false) {\n\t\t\t\tinitMarketoForm();\n\t\t\t}\n\t\t\tpushEvent(\"Misc\", \"Make It Private\", \"Open\");\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tprivateModal.firstInput.focus();\n\t\t\t}, 1000);\n\t\t});\n\t});\n\n\t// Check for #private in links\n\tlet linksWithHash = document.querySelectorAll(\"a[href^='#']\");\n\tlet linksWithHashNormalized = [];\n\tlinksWithHash.forEach((link) => {\n\t\tlet href = link.getAttribute(\"href\").toLowerCase();\n\t\tif (href.includes(\"#private\")) {\n\t\t\tlinksWithHashNormalized.push(link);\n\t\t}\n\t});\n\tlet linksWithLightbox = document.querySelectorAll(\"a[href~='?lightbox=private']\");\n\tlet linksCombined = [...linksWithHashNormalized, ...linksWithLightbox];\n\taddClickEvents(linksCombined);\n\tfunction addClickEvents(list) {\n\t\tlist.forEach((element) => {\n\t\t\telement.addEventListener(\"click\", function (e) {\n\t\t\t\te.preventDefault();\n\t\t\t\tprivateModal.locationFirstElement.click();\n\t\t\t});\n\t\t});\n\t}\n\n\t// Check for #hash or ?lightbox=value in URL\n\tif (pageURL.indexOf(\"#private\") > 0 || pageURL.indexOf(\"#Private\") > 0 || window.location.search.match(/lightbox\\=private/i)) {\n\t\tprivateModal.locationFirstElement.click();\n\t}\n\n\t// EVENT - Handle submit of required form\n\tdocument.querySelector(\".js-private-button-required\").addEventListener(\"click\", function (e) {\n\t\te.preventDefault();\n\t\tpostFormPrivate();\n\t});\n\n\tfunction copyPrivateFieldsToMarketoForm() {\n\t\tlet fieldsToCopyArray = document.querySelectorAll(`${privateModal.formName} [mrkto-field]`);\n\t\tfieldsToCopyArray.forEach((field) => {\n\t\t\tlet mrktoFieldSelector = field.getAttribute(\"mrkto-field\");\n\t\t\tif (field.value) {\n\t\t\t\tdocument.querySelector(mrktoFieldSelector).value = field.value;\n\t\t\t}\n\t\t});\n\t\t// set hidden form textarea id=\" askaQuestionText\" to visible form text; fixes ${tripName} not getting populated in Marketo\n\t\tdocument.querySelector(\"#askaQuestionText\").value = document.querySelector(\"#form-private-askaQuestionText\").value;\n\t}\n\n\tfunction postFormPrivate() {\n\t\tlet retryLimit = 3,\n\t\t\tretryAttempt = 0;\n\n\t\t// Validate form\n\t\tlet isValid = isFormValid(privateModal.formName);\n\t\tif (isValid === false) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for spam\n\t\tif (isThisSpam(privateModal.formName) === true) {\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleButtonDisabled(document.querySelector(\".js-private-button-required\"));\n\n\t\t// Check if marketo form has been loaded, if not retry with limits\n\t\tif (checkMarketoForm() === false && retryAttempt < retryLimit) {\n\t\t\tinitMarketoForm(function () {\n\t\t\t\tretryAttempt++;\n\t\t\t\tpostFormPrivate();\n\t\t\t});\n\t\t}\n\n\t\tMktoForms2.whenReady(function () {\n\t\t\tlet optins = \"\";\n\n\t\t\tpushUtmToMarketoForm(); // function lives in global\n\t\t\tdocument.querySelector(\"#requestedAt\").value = document.URL;\n\t\t\tdocument.querySelector(\"#LeadSource\").value = \"www.nathab.com\";\n\t\t\tdocument.querySelector(\"#sourceDetail\").value = \"Make It Private Question\";\n\t\t\tdocument.querySelector(\"#recentConversionAction\").value = \"Make It Private Question\";\n\t\t\tdocument.querySelector(\"#referringWebsite\").value = utmObject.referringWebsite || \"\";\n\t\t\tdocument.querySelector(\"#isAskQuestion\").value = true;\n\n\t\t\tcopyPrivateFieldsToMarketoForm(privateModal.formName); // Used for both required and optional\n\n\t\t\tif (isNewsletterChecked(privateModal.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isEmailSignup\").value = true;\n\t\t\t\toptins += \" eNews\";\n\t\t\t\tsetOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\tif (isSMSOptinChecked(privateModal.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isSMSSignup\").value = true;\n\t\t\t\toptins += \" SMS\";\n\t\t\t\tsetSMSOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\t// stupid edge case just to get a comma in the string\n\t\t\toptins = optins.replace(\"eNews SMS\", \"eNews, SMS\");\n\n\t\t\toptins = optins || \" no optins\"; // if empty string, set to no optins\n\t\t\tlet pushEventString = `Submitted w/${optins}`;\n\n\t\t\tpushEvent(\"Misc\", \"Make It Private\", pushEventString);\n\n\t\t\tmarketoSubmitFormPrivate();\n\n\t\t\tpushEventFacebook();\n\t\t\tpushEventBing();\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tprivateScreenRequired.classList.add(\"hide\");\n\t\t\t\tprivateScreenThankYou.classList.remove(\"hide\");\n\t\t\t\tprivateScreenThankYou.scrollTop = 0;\n\t\t\t}, 2750);\n\t\t});\n\t}\n\n\tfunction marketoSubmitFormPrivate() {\n\t\tif (checkMarketoForm() === false) {\n\t\t\tpushEvent(\"Marketo\", \"Form\", \"Not Loaded during marketoSubmitForm()\");\n\t\t}\n\n\t\tMktoForms2.whenReady(function (form) {\n\t\t\tform.submit();\n\t\t});\n\t}\n}\n","import { countryList } from \"../../../components/lists/country-list/_country-list.js\";\nimport { pushEvent, pushEventFacebook, pushEventBing, saveUserCountryToLocalStorage } from \"../../../assets/js/utilities.js\";\nimport { initJsFormatPhone, initJsFormatName, setOptsOnMarketoForm, isFormValid, isNewsletterChecked, setNewsletterCheckbox, pushUtmToMarketoForm, toggleButtonDisabled, isThisSpam } from \"../../../assets/js/global-form-functions.js\";\nimport { isSMSOptinChecked, setSMSOptsOnMarketoForm } from \"../../../assets/js/global-form-functions.js\";\nimport { initSmarty } from \"../../../assets/js/smartypants.js\";\nimport { autoPopChatUserAction } from \"../../olark/_script.js\";\nimport { toggleAmbientVideo } from \"../../../components/hero/_video.js\";\n\nexport async function pdfModal() {\n\tawait saveUserCountryToLocalStorage();\n\tlet userCountry = localStorage.getItem(\"country\") || \"unknown\";\n\n\tlet pageURL = document.querySelector(\".js-page-url\").innerText.trim();\n\tlet getPageURL = pageURL.split(\"/\");\n\tlet pdf = new Object();\n\tpdf.formName = \"#form-pdf\";\n\tpdf.eventAction = \"\";\n\tpdf.catalog = false;\n\tpdf.catalogElement = document.querySelector(\"[js-pdf-catalog-toggle]\");\n\tpdf.smsElementParent = document.querySelector(\".js-sms-checkbox-pdf\");\n\tpdf.smsElement = document.querySelector(\"[js-pdf-sms]\");\n\tpdf.phoneElementInput = document.querySelector(\"[js-pdf-phone-toggle]\");\n\tpdf.phoneElementLabel = document.querySelector('[for~=\"form-pdf-phone\"]');\n\tpdf.emailElement = document.querySelector(\"[js-pdf-form-email]\");\n\tpdf.locationSelector = \"js-pdf-location\";\n\tpdf.locationFirstElement = document.querySelector(`[${pdf.locationSelector}]`);\n\tpdf.locationAllElements = document.querySelectorAll(`[${pdf.locationSelector}]`);\n\tpdf.locationValue = \"PDF\";\n\tpdf.linkSelector = document.querySelector(\"#printpdf\");\n\tpdf.linkHref = `https://nathab-pdf.s3.amazonaws.com/${getPageURL[2]}.pdf`;\n\tpdf.linkSelector.setAttribute(\"href\", pdf.linkHref);\n\tpdf.recentTripPDFRequest = $(\"h1\").text();\n\tpdf.firstInput = document.querySelector(\"[pdf-form-label]\");\n\n\tlet catalogFieldWrappersForPdf = document.querySelectorAll(\"[js-pdf-toggle-catalog]\"),\n\t\tcatalogRequiredFieldsForPdf = document.querySelectorAll(\"[js-pdf-field-required]\"),\n\t\tpdfScreenRequired = document.querySelector(\".js-pdf-required\"),\n\t\tpdfScreenThankYou = document.querySelector(\".js-pdf-thankyou\");\n\n\tinitJsFormatPhone();\n\tinitJsFormatName();\n\n\t// // EVENT - Generate image in aside from hero image\n\t// let pdfAsideImage = document.querySelector(\".js-pdf-aside-image\");\n\t// let heroImageSrc = document.querySelector('[jstemplate=\"trip\"]').src;\n\t// pdfAsideImage.setAttribute(\"src\", heroImageSrc);\n\n\t// Event - When catalog request checkbox changes do stuff\n\tpdf.catalogElement.addEventListener(\"input\", function () {\n\t\tif (this.checked) {\n\t\t\ttoggleCatalogFieldsForPdf(\"show\");\n\t\t\tpdf.emailElement.setAttribute(\"pdf-form-field\", \"100%\");\n\t\t\tpushEvent(\"Misc\", \"PDF\", \"Show Catalog Form\");\n\t\t} else {\n\t\t\ttoggleCatalogFieldsForPdf(\"hide\");\n\t\t\tpdf.emailElement.setAttribute(\"pdf-form-field\", \"50%\");\n\t\t\tpushEvent(\"Misc\", \"PDF\", \"Hide Catalog Form\");\n\t\t}\n\t});\n\n\t// Event - When SMS checkbox changes do stuff\n\tfunction smsCheckbox() {\n\t\tpdf.smsElement.addEventListener(\"input\", function () {\n\t\t\tif (this.checked) {\n\t\t\t\tpdf.phoneElementInput.setAttribute(\"required\", \"\");\n\t\t\t\tpdf.phoneElementLabel.setAttribute(\"pdf-form-label\", \"required\");\n\t\t\t} else {\n\t\t\t\tpdf.phoneElementInput.removeAttribute(\"required\");\n\t\t\t\tpdf.phoneElementLabel.setAttribute(\"pdf-form-label\", \"\");\n\t\t\t\tpdf.phoneElementInput.classList.remove(\"js-invalid\");\n\t\t\t}\n\t\t});\n\t}\n\n\t// EVENT - Add event listener to all elements with the locationSelector\n\tpdf.locationAllElements.forEach((element) => {\n\t\telement.addEventListener(\"click\", function () {\n\t\t\tsessionStorage.setItem(\"modalOpen\", true);\n\n\t\t\t// pause ambient video when modal is opened\n\t\t\ttoggleAmbientVideo(false);\n\n\t\t\tconst countryInput = document.querySelectorAll(`${pdf.formName} .js-smarty-country`);\n\n\t\t\tif (userCountry !== \"unknown\") {\n\t\t\t\tcountryInput.forEach((input) => {\n\t\t\t\t\tconst country = countryList.filter((country) => userCountry === country.code);\n\t\t\t\t\tinput.value = country[0].name;\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (userCountry === \"US\") {\n\t\t\t\tsetNewsletterCheckbox();\n\t\t\t\tinitSmarty(pdf.formName);\n\t\t\t\tpdf.smsElementParent.classList.remove(\"hide\");\n\t\t\t\tsmsCheckbox();\n\t\t\t} else if (userCountry === \"IN\" || userCountry === \"AU\") {\n\t\t\t\tsetNewsletterCheckbox();\n\t\t\t}\n\t\t\tif (checkMarketoForm() === false) {\n\t\t\t\tinitMarketoForm();\n\t\t\t}\n\t\t\tif (pdf.locationValue !== \"URL\") {\n\t\t\t\tpdf.locationValue = element.getAttribute(pdf.locationSelector);\n\t\t\t}\n\t\t\tpushEvent(\"Misc\", pdf.locationValue, \"Open\");\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tpdf.firstInput.focus();\n\t\t\t}, 1000);\n\t\t});\n\t});\n\n\t// EVENT - Check for #refer or in URL\n\tlet linksWithHash = document.querySelectorAll(\"a[href^='#']\");\n\tlet linksWithHashNormalized = [];\n\tlinksWithHash.forEach((link) => {\n\t\tlet href = link.getAttribute(\"href\").toLowerCase();\n\t\tif (href.includes(\"#pdf\")) {\n\t\t\tlinksWithHashNormalized.push(link);\n\t\t}\n\t});\n\tlet linksWithLightbox = document.querySelectorAll(\"a[href~='?lightbox=pdf']\");\n\tlet linksCombined = [...linksWithHashNormalized, ...linksWithLightbox];\n\taddClickEvents(linksCombined);\n\tfunction addClickEvents(list) {\n\t\tlist.forEach((element) => {\n\t\t\telement.addEventListener(\"click\", function (e) {\n\t\t\t\te.preventDefault();\n\t\t\t\tpdf.locationValue = \"Link\";\n\t\t\t\tpdf.locationFirstElement.click();\n\t\t\t});\n\t\t});\n\t}\n\n\t// EVENT - Check for #hash or ?lightbox=value in URL\n\tif (pageURL.indexOf(\"#pdf\") > 0 || pageURL.indexOf(\"#pdf\") > 0 || window.location.search.match(/lightbox\\=pdf/i)) {\n\t\tpdf.locationValue = \"URL\"; //default\n\t\tpdf.locationFirstElement.click();\n\t}\n\n\t// EVENT - Handle submit of required form\n\tdocument.querySelector(\".js-pdf-button-required\").addEventListener(\"click\", function (e) {\n\t\te.preventDefault();\n\t\tpostFormpdf();\n\t\tautoPopChatUserAction(\"#modal-pdf\"); // NOW THAT OLARK IS WRAPPED IN FUNCTION, THIS ISN'T AVAILABLE FOR USE HERE\n\t});\n\n\tfunction toggleCatalogFieldsForPdf(action) {\n\t\tif (action === \"show\") {\n\t\t\tpdf.catalog = true;\n\t\t\tcatalogFieldWrappersForPdf.forEach((element) => {\n\t\t\t\telement.classList.remove(\"hide\");\n\t\t\t});\n\t\t\tcatalogRequiredFieldsForPdf.forEach((element) => {\n\t\t\t\telement.setAttribute(\"required\", \"\");\n\t\t\t});\n\t\t} else {\n\t\t\tpdf.catalog = false;\n\t\t\tcatalogFieldWrappersForPdf.forEach((element) => {\n\t\t\t\telement.classList.add(\"hide\");\n\t\t\t});\n\t\t\tcatalogRequiredFieldsForPdf.forEach((element) => {\n\t\t\t\telement.removeAttribute(\"required\");\n\t\t\t});\n\t\t}\n\t}\n\n\tfunction copyFieldsToMarketoForm() {\n\t\tlet fieldsToCopyArray = document.querySelectorAll(`${pdf.formName} [mrkto-field]`);\n\t\tfieldsToCopyArray.forEach((field) => {\n\t\t\tlet mrktoFieldSelector = field.getAttribute(\"mrkto-field\");\n\t\t\tif (field.value) {\n\t\t\t\tdocument.querySelector(mrktoFieldSelector).value = field.value;\n\t\t\t}\n\t\t});\n\t}\n\n\tfunction postFormpdf() {\n\t\tlet retryLimit = 3,\n\t\t\tretryAttempt = 0;\n\n\t\t// Validate form\n\t\tlet isValid = isFormValid(pdf.formName);\n\t\tif (isValid === false) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for spam\n\t\tif (isThisSpam(pdf.formName) === true) {\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleButtonDisabled(document.querySelector(\".js-pdf-button-required\"));\n\n\t\t// Check if marketo form has been loaded, if not retry with limits\n\t\tif (checkMarketoForm() === false && retryAttempt < retryLimit) {\n\t\t\tinitMarketoForm(function () {\n\t\t\t\tretryAttempt++;\n\t\t\t\tpostFormpdf();\n\t\t\t});\n\t\t}\n\n\t\tMktoForms2.whenReady(function () {\n\t\t\tlet optins = \"\";\n\n\t\t\tpushUtmToMarketoForm(); // function lives in global\n\n\t\t\tdocument.querySelector(\"#recentTripPDFURL\").value = pdf.linkHref;\n\t\t\tdocument.querySelector(\"#recentTripPDFRequest\").value = pdf.recentTripPDFRequest;\n\t\t\tdocument.querySelector(\"#sourceDetail\").value = pdf.locationValue;\n\t\t\tdocument.querySelector(\"#requestedAt\").value = document.URL;\n\t\t\tdocument.querySelector(\"#LeadSource\").value = \"www.nathab.com\";\n\t\t\tdocument.querySelector(\"#recentConversionAction\").value = \"PDF Download\";\n\t\t\tdocument.querySelector(\"#referringWebsite\").value = utmObject.referringWebsite || \"\";\n\t\t\tdocument.querySelector(\"#isPDFDownload\").value = true;\n\n\t\t\tif (isNewsletterChecked(pdf.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isEmailSignup\").value = true;\n\t\t\t\toptins += \" eNews,\";\n\t\t\t\tsetOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\tif (isSMSOptinChecked(pdf.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isSMSSignup\").value = true;\n\t\t\t\toptins += \" SMS\";\n\t\t\t\tsetSMSOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\tif (pdf.catalog === true) {\n\t\t\t\tdocument.querySelector(\"#isCatalogRequested\").value = true;\n\t\t\t\tdocument.querySelector(\"#temp\").value = \"CatRequestIsTrue\";\n\t\t\t\toptins += \" Catalog\";\n\t\t\t}\n\n\t\t\toptins = optins || \" no optins\"; // if empty string, set to no optins\n\t\t\toptins = optins.endsWith(\",\") ? optins.slice(0, -1) : optins; // get rid of unnecessary ','\n\n\t\t\tlet pushEventString = `Submitted w/${optins}`;\n\t\t\tpushEvent(\"Misc\", pdf.locationValue, pushEventString);\n\n\t\t\tcopyFieldsToMarketoForm(pdf.formName);\n\n\t\t\tmarketoSubmitFormPdf();\n\n\t\t\tpushEventFacebook();\n\t\t\tpushEventBing();\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tpdfScreenRequired.classList.add(\"hide\");\n\t\t\t\tpdfScreenThankYou.classList.remove(\"hide\");\n\t\t\t\twindow.open(pdf.linkHref, \"_blank\");\n\t\t\t\tpdfScreenThankYou.scrollTop = 0;\n\t\t\t}, 2750);\n\t\t});\n\t}\n\n\tfunction marketoSubmitFormPdf() {\n\t\tif (checkMarketoForm() === false) {\n\t\t\tpushEvent(\"Marketo\", \"Form\", \"Not Loaded during marketoSubmitForm()\");\n\t\t}\n\n\t\tMktoForms2.whenReady(function (form) {\n\t\t\tform.submit();\n\t\t});\n\t}\n}\n","import { pushEvent, pushEventFacebook, pushEventBing, saveUserCountryToLocalStorage } from \"../../../assets/js/utilities.js\";\nimport { initJsFormatPhone, initJsFormatName, setOptsOnMarketoForm, setSMSOptsOnMarketoForm, isSMSOptinChecked, isFormValid, isNewsletterChecked, setNewsletterCheckbox, pushUtmToMarketoForm, toggleButtonDisabled, isThisSpam } from \"../../../assets/js/global-form-functions.js\";\nimport { initSmarty } from \"../../../assets/js/smartypants.js\";\nimport { autoPopChatUserAction } from \"../../olark/_script.js\";\nimport { toggleAmbientVideo } from \"../../../components/hero/_video.js\";\n\nexport async function askModal() {\n\tawait saveUserCountryToLocalStorage();\n\tlet userCountry = localStorage.getItem(\"country\") || \"unknown\";\n\n\tlet ask = new Object();\n\task.formName = \"#form-ask\";\n\task.newsletter = false;\n\task.catalog = false;\n\task.catalogElement = document.querySelector(\"[js-ask-catalog-toggle]\");\n\task.smsElementParent = document.querySelector(\".js-sms-checkbox-ask\");\n\task.smsElement = document.querySelector(\"[js-ask-sms]\");\n\task.phoneElementInput = document.querySelector(\"[js-ask-phone-toggle]\");\n\task.phoneElementLabel = document.querySelector('[for~=\"form-ask-phone\"]');\n\task.locationSelector = \"js-ask-location\";\n\task.locationFirstElement = document.querySelector(`[${ask.locationSelector}]`);\n\task.locationAllElements = document.querySelectorAll(`[${ask.locationSelector}]`);\n\task.locationValue = \"Unknown\";\n\task.firstInput = document.querySelector(\"[ask-form-label]\");\n\n\tlet catalogFieldWrappersForAsk = document.querySelectorAll(\"[js-ask-toggle-catalog]\"),\n\t\tcatalogRequiredFieldsForAsk = document.querySelectorAll(\"[js-ask-field-required]\"),\n\t\taskScreenRequired = document.querySelector(\".js-ask-required\"),\n\t\taskScreenThankYou = document.querySelector(\".js-ask-thankyou\");\n\n\tinitJsFormatPhone();\n\tinitJsFormatName();\n\n\t// Function - insert trip name into aside text\n\tfunction insertTripNameIntoAsideText() {\n\t\tconst asideTextSelector = document.querySelector(\".js-ask-aside-text\");\n\t\tconst questionTextSelector = document.querySelector(\".js-ask-question-text\");\n\t\tlet asideText = asideTextSelector.innerHTML;\n\t\tlet questionText = questionTextSelector.innerHTML;\n\n\t\tlet tripName = document.querySelector(\".js-tripName\").textContent;\n\t\tif (tripName.startsWith(\"The \")) {\n\t\t\ttripName = tripName.replace(\"The \", \"\");\n\t\t}\n\n\t\tfunction updateTripName(selector, oldText) {\n\t\t\tlet updatedText = oldText.replace(\"${tripName}\", tripName);\n\t\t\tselector.innerHTML = updatedText;\n\t\t}\n\n\t\tupdateTripName(asideTextSelector, asideText);\n\t\tupdateTripName(questionTextSelector, questionText);\n\t}\n\tinsertTripNameIntoAsideText();\n\n\t// Event - When catalog request checkbox changes do stuff\n\task.catalogElement.addEventListener(\"input\", function () {\n\t\tif (this.checked) {\n\t\t\ttoggleCatalogFieldsForAsk(\"show\");\n\t\t\tpushEvent(\"Misc\", \"Ask\", \"Show Catalog Form\");\n\t\t} else {\n\t\t\ttoggleCatalogFieldsForAsk(\"hide\");\n\t\t\tpushEvent(\"Misc\", \"Ask\", \"Hide Catalog Form\");\n\t\t}\n\t});\n\n\t// Event - When SMS checkbox changes do stuff\n\task.smsElement.addEventListener(\"input\", function () {\n\t\tif (this.checked) {\n\t\t\task.phoneElementInput.setAttribute(\"required\", \"\");\n\t\t\task.phoneElementLabel.setAttribute(\"ask-form-label\", \"required\");\n\t\t} else {\n\t\t\task.phoneElementInput.removeAttribute(\"required\");\n\t\t\task.phoneElementLabel.setAttribute(\"ask-form-label\", \"\");\n\t\t\task.phoneElementInput.classList.remove(\"js-invalid\");\n\t\t}\n\t});\n\n\t// Add event listener to all elements that can open this modal\n\task.locationAllElements.forEach((element) => {\n\t\telement.addEventListener(\"click\", function () {\n\t\t\tsessionStorage.setItem(\"modalOpen\", true);\n\n\t\t\t// pause ambient video when modal is opened\n\t\t\ttoggleAmbientVideo(false);\n\n\t\t\t//check eNews box for users in US, India, and Australia\n\t\t\tif (userCountry === \"US\") {\n\t\t\t\tsetNewsletterCheckbox();\n\t\t\t\tinitSmarty(ask.formName);\n\t\t\t\task.smsElementParent.classList.remove(\"hide\");\n\t\t\t} else if (userCountry === \"IN\" || userCountry === \"AU\") {\n\t\t\t\tsetNewsletterCheckbox();\n\t\t\t}\n\t\t\tif (checkMarketoForm() === false) {\n\t\t\t\tinitMarketoForm();\n\t\t\t}\n\t\t\tif (ask.locationValue !== \"Ask Question URL\") {\n\t\t\t\task.locationValue = element.getAttribute(ask.locationSelector);\n\t\t\t}\n\t\t\tpushEvent(\"Misc\", ask.locationValue, \"Open\");\n\n\t\t\tsetTimeout(() => {\n\t\t\t\task.firstInput.focus();\n\t\t\t}, 1000);\n\t\t});\n\t});\n\n\t// Check for #refer in links\n\tlet linksWithHash = document.querySelectorAll(\"a[href^='#']\");\n\tlet linksWithHashNormalized = [];\n\tlinksWithHash.forEach((link) => {\n\t\tlet href = link.getAttribute(\"href\").toLowerCase();\n\t\tif (href.includes(\"#ask\")) {\n\t\t\tlinksWithHashNormalized.push(link);\n\t\t}\n\t});\n\tlet linksWithLightbox = document.querySelectorAll(\"a[href~='?lightbox=ask']\");\n\tlet linksCombined = [...linksWithHashNormalized, ...linksWithLightbox];\n\taddClickEvents(linksCombined);\n\tfunction addClickEvents(list) {\n\t\tlist.forEach((element) => {\n\t\t\telement.addEventListener(\"click\", function (e) {\n\t\t\t\te.preventDefault();\n\t\t\t\task.locationFirstElement.click();\n\t\t\t});\n\t\t});\n\t}\n\n\t// Check for #hash or ?lightbox=value in URL\n\tif (document.URL.indexOf(\"#ask\") > 0 || document.URL.indexOf(\"#Ask\") > 0 || window.location.search.match(/lightbox\\=ask/i)) {\n\t\task.locationValue = \"Ask Question URL\";\n\t\task.locationFirstElement.click();\n\t}\n\n\t// EVENT - Handle submit of required form\n\tdocument.querySelector(\".js-ask-button-required\").addEventListener(\"click\", function (e) {\n\t\te.preventDefault();\n\t\tpostFormAsk();\n\t\tautoPopChatUserAction(\"#modal-ask\"); // NOW THAT OLARK IS WRAPPED IN FUNCTION, THIS ISN'T AVAILABLE FOR USE HERE\n\t});\n\n\tfunction toggleCatalogFieldsForAsk(action) {\n\t\tif (action === \"show\") {\n\t\t\task.catalog = true;\n\t\t\tcatalogFieldWrappersForAsk.forEach((element) => {\n\t\t\t\telement.classList.remove(\"hide\");\n\t\t\t});\n\t\t\tcatalogRequiredFieldsForAsk.forEach((element) => {\n\t\t\t\telement.setAttribute(\"required\", \"\");\n\t\t\t});\n\t\t} else {\n\t\t\task.catalog = false;\n\t\t\tcatalogFieldWrappersForAsk.forEach((element) => {\n\t\t\t\telement.classList.add(\"hide\");\n\t\t\t});\n\t\t\tcatalogRequiredFieldsForAsk.forEach((element) => {\n\t\t\t\telement.removeAttribute(\"required\");\n\t\t\t});\n\t\t}\n\t}\n\n\tfunction copyaskFieldsToMarketoForm() {\n\t\tlet fieldsToCopyArray = document.querySelectorAll(`${ask.formName} [mrkto-field]`);\n\t\tfieldsToCopyArray.forEach((field) => {\n\t\t\tlet mrktoFieldSelector = field.getAttribute(\"mrkto-field\");\n\t\t\tif (field.value) {\n\t\t\t\tdocument.querySelector(mrktoFieldSelector).value = field.value;\n\t\t\t}\n\t\t});\n\n\t\t// set hidden form textarea id=\" askaQuestionText\" to visible form text; fixes ${tripName} not getting populated in Marketo\n\t\tdocument.querySelector(\"#askaQuestionText\").value = document.querySelector(\"#form-ask-askaQuestionText\").value;\n\t}\n\n\tfunction postFormAsk() {\n\t\tlet retryLimit = 3,\n\t\t\tretryAttempt = 0;\n\t\t// Validate form\n\t\tlet isValid = isFormValid(ask.formName);\n\n\t\tif (isValid === false) {\n\t\t\treturn;\n\t\t}\n\t\t// Check for spam\n\t\tif (isThisSpam(ask.formName) === true) {\n\t\t\treturn;\n\t\t}\n\t\ttoggleButtonDisabled(document.querySelector(\".js-ask-button-required\"));\n\t\t// Check if marketo form has been loaded, if not retry with limits\n\t\tif (checkMarketoForm() === false && retryAttempt < retryLimit) {\n\t\t\tinitMarketoForm(function () {\n\t\t\t\tretryAttempt++;\n\t\t\t\tpostFormAsk();\n\t\t\t});\n\t\t}\n\t\tMktoForms2.whenReady(function () {\n\t\t\tlet optins = \"\";\n\t\t\tpushUtmToMarketoForm(); // function lives in global\n\t\t\tdocument.querySelector(\"#requestedAt\").value = document.URL;\n\t\t\tdocument.querySelector(\"#LeadSource\").value = \"www.nathab.com\";\n\t\t\tdocument.querySelector(\"#sourceDetail\").value = \"Ask a Question\";\n\t\t\tdocument.querySelector(\"#recentConversionAction\").value = \"Ask a Question\";\n\t\t\tdocument.querySelector(\"#referringWebsite\").value = utmObject.referringWebsite || \"\";\n\t\t\tdocument.querySelector(\"#isAskQuestion\").value = true;\n\t\t\tcopyaskFieldsToMarketoForm(ask.formName); // Used for both required and optional\n\n\t\t\tif (isNewsletterChecked(ask.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isEmailSignup\").value = true;\n\t\t\t\toptins += \" eNews,\";\n\t\t\t\tsetOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\tif (isSMSOptinChecked(ask.formName) === true) {\n\t\t\t\tdocument.querySelector(\"#isSMSSignup\").value = true;\n\t\t\t\toptins += \" SMS\";\n\t\t\t\tsetSMSOptsOnMarketoForm();\n\t\t\t}\n\n\t\t\tif (ask.catalog === true) {\n\t\t\t\tdocument.querySelector(\"#isCatalogRequested\").value = true;\n\t\t\t\tdocument.querySelector(\"#temp\").value = \"CatRequestIsTrue\";\n\t\t\t\toptins += \" Catalog\";\n\t\t\t}\n\n\t\t\toptins = optins || \" no optins\"; // if empty string, set to no optins\n\t\t\toptins = optins.endsWith(\",\") ? optins.slice(0, -1) : optins; // get rid of unnecessary ','\n\n\t\t\tlet pushEventString = `Submitted w/${optins}`;\n\t\t\tpushEvent(\"Misc\", ask.locationValue, pushEventString);\n\n\t\t\tmarketoSubmitFormAsk();\n\t\t\tpushEventFacebook();\n\t\t\tpushEventBing();\n\n\t\t\tsetTimeout(() => {\n\t\t\t\taskScreenRequired.classList.add(\"hide\");\n\t\t\t\taskScreenThankYou.classList.remove(\"hide\");\n\t\t\t\taskScreenThankYou.scrollTop = 0;\n\t\t\t}, 2750);\n\t\t});\n\t}\n\n\tfunction marketoSubmitFormAsk() {\n\t\tif (checkMarketoForm() === false) {\n\t\t\tpushEvent(\"Marketo\", \"Form\", \"Not Loaded during marketoSubmitForm()\");\n\t\t}\n\t\tMktoForms2.whenReady(function (form) {\n\t\t\tform.submit();\n\t\t});\n\t}\n}\n","export function convertOldSlideshowToNew() {\n\tconst imageContainers = document.querySelectorAll(\".js-old-slideshow-images\");\n\tif (!imageContainers.length) return;\n\n\tlet slides = \"\";\n\n\tfor (const imageContainer of imageContainers) {\n\t\tconst images = imageContainer.querySelectorAll(\"img\");\n\t\tif (!images.length) continue;\n\n\t\tfor (const image of images) {\n\t\t\tconst alt = image.getAttribute(\"alt\") || \" \";\n\t\t\tlet src = image.getAttribute(\"src\") || image.getAttribute(\"data-src\");\n\n\t\t\tif (!src) continue;\n\n\t\t\tconst domain = \"https://www.nathab.com\";\n\t\t\tconst cdn = \"https://cdn.filestackcontent.com/A6dTpd53SmIg0pBfJJhgAz/resize=width:1600,fit:max/quality=value:60/cache=expiry:31536000/compress/\";\n\t\t\tconst doubleDomain = domain + domain;\n\n\t\t\tsrc = domain + src;\n\t\t\tsrc = src.replace(doubleDomain, domain);\n\t\t\tsrc = cdn + src;\n\n\t\t\tslides += `\n\t\t\t\t