const SELFBOOK_BASE_URL="https://sdk.selfbook.com",SELFBOOK_BASE_URL_V3="https://sdk-v3.selfbook.com";let SELFBOOK_BACKEND_URL="https://api.selfbook.com/api/v2";const STATSIG_CLIENT_KEY="client-PV01TCjBc3a7zunh9brJUh2fIaLwbXaH7aQH2dFpSGW",STATSIG_EXPERIMENT="ddn";let SELFBOOK_APP_VERSION="v2",SELFBOOK_APP_BASE_URL=SELFBOOK_BASE_URL;const SELFBOOK_SCRIPT_ID="selfbook_jssdk",SELFBOOK_HOTEL_ID_PROP="hotelId",SELFBOOK_API_KEY_PROP="apiKey",SELFBOOK_WIDGET_ELEMENT_ID="selfbook_sdkwidget",SELFBOOK_WIDGET_WRAPPER_ELEMENT_ID="selfbook_sdkwidget_wrapper",SELFBOOK_WIDGET_LOADING_ELEMENT="selfbook-loading",BOOTSTRAP_ACTION="WIDGET/BOOTSTRAP",SELFBOOK_HOTEL_GROUP_INFO="selfbook_hotel_group_info",BLACK_SQUARE_THEME_HOTELS=["6739"],THE_LINE_HOTELS=["68711","71661","2427"],COMPLETE_BOOKING_BTN_CLICK="Complete your reservation button click",ROUTE_PATHS={app:{confirmation:"/confirmation",wallet:"/wallet",account:"/account",settings:"/settings",reservations:"/reservations",reservationDetail:"/reservation-detail",editBooking:"/edit-booking",bookingConfirmed:"/booking-confirmed"}},INITIAL_PERSISTED_DATA={isExpired:!0,all:null,booking:null,core:null,router:null},GUEST_TYPE={ADULT:"adult",CHILD:"child",INFANT:"infants"};let initialV35AvailabilityStartEndDates={},initialCalendarResponse=null;function setOverflowHidden(t){const e=t?"hidden":"";document.body.style.overflow=e,document.documentElement.style.overflow=e}function initWidgets({apiKey:t,hotelId:e}){const n=document.createElement("script");n.type="text/javascript",n.src=`${SELFBOOK_BASE_URL_V3}/widgets/floating-search-bar.js`,document.body.appendChild(n),n.onload=function(){const n=SELFBOOK_BACKEND_URL.replace(/\/v[123]/,"");window.renderWidget(null,{backendURL:n,hotelId:e,apiKey:t})}}function initSDKBus(){const t={},e={};window.sb_sdkBus={emit(n,o){e[n]||(e[n]=[]),e[n].push(o),t[n]?.length&&t[n].forEach(t=>t(o))},on(e,n){t[e]||(t[e]=[]),t[e].push(n)},off(e,n){t[e]&&(t[e]=t[e].filter(t=>t!==n))},pull(t){const n=e[t]||[];return e[t]=[],n}}}function checkStatus(t){if(t.status>=200&&t.status<300)return t;const e=new Error(t.statusText);throw e.response=t,e}async function parseJSON(t){try{const e=await t.text();if(!e)return;return JSON.parse(e)}catch(t){console.error("parseJSON: err: ",t)}}function intervalWrapper(t,e){const n=setInterval(t,e);return function(){clearInterval(n)}}function getHotelBasicData(t){try{const e=getFromSessionStorage(SELFBOOK_HOTEL_GROUP_INFO).hotels?.filter(e=>e.id==t),n=e?.[0]||{};return getIsEnableV35(n)&&(n.app_version="v3",n.enable_v3_new_ui_version=!0),n}catch(t){return console.error("getHotelBasicData: err: ",t),{}}}function getFromSessionStorage(t){try{return JSON.parse(sessionStorage.getItem(t))}catch(t){return console.error("getFromSessionStorage: err: ",{e:t}),{}}}function getPersistedData(t){try{const e=JSON.parse(t.getItem("persist:root"));if(!e)return INITIAL_PERSISTED_DATA;const n=JSON.parse(e.booking||"{}"),o=JSON.parse(e.core||"{}"),r=JSON.parse(e?.router||"{}"),{expireTime:a}=o,s=(Date.now()-new Date(o.interactionTime))/1e3;return{isExpired:s>a,all:e,booking:n,core:o,router:r}}catch(t){return console.error("getPersistedData: err: ",t),INITIAL_PERSISTED_DATA}}function fillGuestsFields(t=[],e){const n=e.default_adult_occupancy?e.default_adult_occupancy:2;return t?.map(t=>t.type===GUEST_TYPE.ADULT?{type:GUEST_TYPE.ADULT,count:parseInt(t.count)||n}:t.type===GUEST_TYPE.CHILD&&parseInt(t.count)>0?{type:GUEST_TYPE.CHILD,count:parseInt(t.count),age:parseInt(t.age)||1,special_request:t.special_request||""}:t.type===GUEST_TYPE.INFANT&&parseInt(t.count)>0?{type:GUEST_TYPE.INFANT,count:parseInt(t.count)||1,age:parseInt(t.age)||1,special_request:t.special_request||""}:void 0).filter(Boolean)}function buildRoomsGuests(t,e){const n=e.default_adult_occupancy?e.default_adult_occupancy:2,o=()=>Math.random().toString(36).slice(2),r=["adult","child","childAges","room2Adult","room3Adult","room4Adult"].some(e=>!!t[e]);if(t.guests?.length&&!r)return Array.from({length:4},(e,r)=>{const a=0===r?"guests":`guestsRoom${r+1}`;if(!t[a])return null;const s=t[a]?.map(t=>{const e=t?.type===GUEST_TYPE.ADULT?t?.count||n:t?.count,r=t?.type===GUEST_TYPE.CHILD&&"number"==typeof t?.age;return{type:t?.type,count:Number(e),guest_details:r?[{key:o(),age:Number(t?.age)}]:void 0}});return{key:0===r?"room1":o(),data:s}}).filter(Boolean);const a=e=>Number(t[e]||0),[s,i,l,d]=["roomCount","adult","child","infants"].map(a);if(s>1&&!a("room2Adult")){const t=i||n,e=Math.floor(t/s);let r=t%s;return Array.from({length:s},(t,n)=>{const a=r>=n+1?1:0;return{key:0===n?"room1":o(),data:[{type:GUEST_TYPE.ADULT,count:e+a}]}})}const c=[];return Array.from({length:4}).forEach((e,r)=>{const s=r+1,u=0===r?i||n:a(`room${s}Adult`);if(u){const e=[{type:GUEST_TYPE.ADULT,count:u}],n=0===r?l:a(`room${s}Child`),i=t[0===r?"childAges":`room${s}ChildAges`];i?i.split(",").forEach(t=>{e.push({type:GUEST_TYPE.CHILD,count:1,guest_details:[{key:o(),age:Number(t)}]})}):n&&e.push({type:GUEST_TYPE.CHILD,count:n}),0===r&&d>0&&e.push({type:GUEST_TYPE.INFANT,count:d}),c.push({key:0===r?"room1":o(),data:e})}}),c}function buildRedirectSynxisLink(t,e){let n=`https://be.synxis.com/?hotel=${e.id}&theme=${e.synxis_theme}&config=${e.synxis_config}`;try{if(t){const{startDate:e,endDate:o,promoCode:r,groupCode:a,guests:s,iataNumber:i,couponCode:l,destinationId:d,nights:c,rate:u,hotelId:p,roomCategory:m}=t;c&&(n+=`&nights=${c}`),e&&(n+=`&arrive=${e}`),o&&(n+=`&depart=${o}`),r&&(n+=`&promo=${r}`),a&&(n+=`&group=${a}`),i&&(n+=`&iataNumber=${i}`),l&&(n+=`&couponCode=${l}`),u&&(n+=`&rate=${u}`),d&&(n+=`&destinationId=${d}`),Array.isArray(m)?n+=`&roomCategory=${m.map(t=>t).join(",")}`:m&&(n+=`&roomCategory=${m}`),s&&s.length>0?("adult"===s[0].type&&(n+=`&adult=${s[0].count}`),s[1]&&"child"===s[1].type&&(n+=`&child=${s[1].count}`)):n+="&adult=1"}}catch(t){console.error("buildRedirectSynxisLink: err: ",t)}return n}function selectShowWidgetButtonCopies(t){return t.core.showWidgetButtonCopies||{}}function selectRoute(t){return t?.router?.location?t.router.location.pathname:ROUTE_PATHS.app.editBooking}function isObjectEqual(t,e){return JSON.stringify(t)===JSON.stringify(e)}function isTemplateDomainMatch(t,e){return t?.booking_template_domain&&e?.target?.href?.includes(t.booking_template_domain)}function getElementById(t){return document?.getElementById(t)}function getIsEnableV35(t){return"v3.5"===SELFBOOK_APP_VERSION||(SELFBOOK_APP_VERSION.match(/^v3/i)&&t?.enable_v3_new_ui_version||!1)}function runDirectApplication(){console.info("(!) selfbook: widget initialization started");let t,e,n,o=!1,r=!1,a=!1,s=!1,i=!1;async function l({url:t,method:e,data:n,headers:o}){try{const r=await fetch(t,{method:e,body:n,headers:o});checkStatus(r);return await parseJSON(r)}catch(t){console.error("There was a problem with the fetch operation:",t)}}function d(o,r,s){if(!n)return;const i=getFromSessionStorage(SELFBOOK_HOTEL_GROUP_INFO);if(getIsEnableV35(r)&&("group"===i?.structure&&(o?.hotelId||o?.destinationId)||"single"===i?.structure||"multiple_properties"===i?.structure))if("group"===i?.structure&&o?.destinationId){const t=i?.hotels.find(t=>t.destination_id?.toLowerCase()===o.destinationId.toLowerCase());t&&(o.hotelId=t.id)}else o.hotelId=o?.hotelId||r?.id;setOverflowHidden(!0);const l=getElementById("selfbook_sdkwidget"),d=getElementById("selfbook_sdkwidget_wrapper");window.selfbookWidgetStore||(d.appendChild(function(){const t=document.createElement("div");return t.id="selfbook-loading",t.style.color="white",t.style.marginRight="-50%",t.style.position="absolute",t.style.top="50%",t.style.left="50%",t.style.fontFamily="sans-serif",t.style.transform="translate(-50%, -50%)",t.innerHTML='<img src="https://sdk.selfbook.com/assets/selfbook_loading_logo.svg" height="20" width="100%">',t}()),d.style.zIndex=1e11,d.style.height="100%",d.style.background="v2"===SELFBOOK_APP_VERSION?"rgba(0, 0, 0, .74)":"rgba(39, 39, 39, 0.74)",setOverflowHidden(!0)),function(){if(!0===a)return;n&&n.length>0&&n.forEach(t=>{if(t.includes(".js")){const e=document.createElement("script");e.type="text/javascript",e.src=`${SELFBOOK_APP_BASE_URL}/${t}`,document.body.appendChild(e)}});(function(){try{const t=document.createElement("script");t.innerHTML='\n !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","identify","reset","group","track","ready","alias","debug","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.src="https://cdn.segment.com/analytics.js/v1/" + key + "/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._loadOptions=e};analytics._writeKey="c77UfR3BzZDUXmAth2DaHEA8kkKhDIU2";;analytics.SNIPPET_VERSION="4.15.3";\n analytics.load("c77UfR3BzZDUXmAth2DaHEA8kkKhDIU2");\n }}();\n ',document.head.appendChild(t);const e=document.createElement("script");e.type="application/ld+json",e.innerHTML='{"@context": "http://schema.org/","@type": "SoftwareApplication","name": "SelfBook"}',document.head.appendChild(e);const n=document.createElement("script");n.src="https://onboard.triptease.io/bootstrap.js",n.async=!0,n.crossOrigin="anonymous",n.type="text/javascript",document.head.appendChild(n)}catch(t){console.error("inject3rdPartyScripts: err: ",t)}})(),a=!0}();const c=setInterval(()=>{if(window.selfbookWidgetStore){const n={hotelInfo:{apiKey:o.apiKey||e,hotelId:o.hotelId||t,hotelIdAsArg:!!o.hotelId},bookingData:{...o},hotelGroupInfo:getFromSessionStorage(SELFBOOK_HOTEL_GROUP_INFO),roomsGuests:o.roomsGuests||void 0,shouldExecuteRegularFlow:s,version:o.version};!function(){const t=document.getElementById("selfbook-loading");t&&getElementById("selfbook_sdkwidget_wrapper").removeChild(t)}(),clearInterval(c),window.selfbookWidgetStore.dispatch({type:BOOTSTRAP_ACTION,payload:n}),"none"===l.style.display&&(d.style.zIndex=1e11,d.style.height="100%",d.style.background="v2"===SELFBOOK_APP_VERSION?"rgba(0, 0, 0, .74)":"rgba(39, 39, 39, 0.74)",setOverflowHidden(!0)),setTimeout(()=>{l.style.display="block",l.setAttribute("class","slide-in")},20),setTimeout(()=>{const t=d.querySelector('[aria-modal="true"]');t&&t.focus()},250)}},100)}function c(){try{const{isExpired:t,core:e,booking:n}=getPersistedData(localStorage);if(t||!e?.hotel?.data?.id)return void function(){try{localStorage.removeItem("persist:root")}catch(t){console.error("removePersistedData: err",t)}}();const o=e.bootstrapArgs;p({...o,startDate:n.bookingForm.start_date.slice(0,10),endDate:n.bookingForm.end_date?.slice(0,10)||null,guests:n.bookingForm.guests,propertyId:n.bookingForm.property_id,persistActive:!0,hotelId:e.hotel.data.id})}catch(t){console.error("openPersistWidget: err",t)}}const u=async()=>await fetch(`${SELFBOOK_APP_BASE_URL}/asset-manifest.json`,{headers:{"content-type":"application/json"}}).then(t=>t.json()).then(t=>function(t){n=t.entrypoints}(t));async function p(e={}){try{let n=!1;e.apiKey&&await E(e.apiKey,e.hotelId);const o=getHotelBasicData(e.hotelId||t);console.log("args",e);const r=getIsEnableV35(o),a=getFromSessionStorage(SELFBOOK_HOTEL_GROUP_INFO),s="group"===a?.structure,l="single"===a?.structure,c=function(t,e=[]){if(!t||"object"!=typeof t||Array.isArray(t))return!1;for(const n in t){if(e.includes(n))continue;const o=t[n];if(null!=o&&!("string"==typeof o&&""===o.trim()||Array.isArray(o)&&0===o.length||"object"==typeof o&&!Array.isArray(o)&&0===Object.keys(o).length))return!0}return!1}(e,["version","selfbook","hotelId","destinationId"]);if(r&&((/*!initialAPIsCallsExecuted && */l&&c||s&&!i)&&(n=!0),o?.is_default_date_logic_enabled||(n=!0)),e.guests?e.guests=fillGuestsFields(e.guests,o):e.guests=[{type:GUEST_TYPE.ADULT,count:o.default_adult_occupancy?o.default_adult_occupancy:2}],o.redirect_to_synxis){const t=buildRedirectSynxisLink(e,o);return void window.open(t,"_blank").focus()}getIsEnableV35(o)&&(e.roomsGuests=buildRoomsGuests(e,o)),d(e,o,n),document.getElementsByTagName("html")[0].setAttribute("translate","no")}catch(t){console.error("bookNow: err: ",t)}}function m(t){const e={startdate:"startDate",enddate:"endDate",rateplancode:"ratePlanCode",rate:"rate",roomid:"roomId",propertyid:"propertyId",destinationid:"destinationId",room:"room",room_count:"roomCount",adult:"adult",child:"child",child_ages:"childAges",infants:"infants",room2_adult:"room2Adult",room2_child:"room2Child",room2_child_ages:"room2ChildAges",room3_adult:"room3Adult",room3_child:"room3Child",room3_child_ages:"room3ChildAges",room4_adult:"room4Adult",room4_child:"room4Child",room4_child_ages:"room4ChildAges",currency:"currency",group:"group",locale:"locale",hotel:"hotel",promo:"promo",promocode:"promocode",selfbook:"selfbook",iatanumber:"iataNumber",couponcode:"couponCode",nights:"nights",reservationid:"reservationId",lastname:"lastName",search:"search",sbsearch:"sbsearch",threeDsContinueId:"three_ds_continue_id",status:"status",roomcategory:"roomCategory",properties:"properties",source:"source",include_inclusive_fees:"includeInclusiveFees",hotelid:"hotelId",version:"version",loyaltyuseremail:"loyaltyUserEmail",loyaltyeventname:"loyaltyEventname",loyaltysignupform:"loyaltySignupForm"};return Array.from(t.entries()).reduce((t,[n,o])=>({...t,[e[n.toLowerCase()]]:o}),{})}function y(){setTimeout(()=>{const e=setInterval(()=>{if(o)return;clearInterval(e);const n=m(new URLSearchParams(window.location.search));if("true"!==n.selfbook)return;const r=getHotelBasicData(n.hotel||n.hotelId||t),a=n.version?.toLowerCase?.();SELFBOOK_APP_VERSION=a||r?.app_version||"v2",_(n,r)},100)},500)}function _(t,e={}){const n=parseInt(e?.default_adult_occupancy)||2,o=[{type:"adult",count:t.adult||n},{type:"child",count:t.child||0},{type:"infants",count:t.infants||0}];p({...t,guests:o,groupCode:t.group,promoCode:t.promo||t.promocode,hotelId:t.hotel||t.hotelId||void 0,roomCategory:"string"==typeof t.roomCategory?t.roomCategory.split(",").map(t=>t.trim()):void 0})}async function g(){!function(){const t=document.createElement("div"),e=document.createElement("div");t.setAttribute("id","selfbook_sdkwidget"),t.style.display="none",e.setAttribute("id","selfbook_sdkwidget_wrapper"),e.style.background="rgba(0, 0, 0, 0)",e.style.position="fixed",e.style.top="0",e.style.right="0",e.style.width="100%",e.style.transition="background .5s ease-out",e.appendChild(t),document.body.appendChild(e)}(),await u(),function(){if(!0!==s){if(n&&n.length>0){const t=document.getElementsByTagName("head")[0];n.forEach(e=>{if(e.includes(".css")){const n=document.createElement("link");n.rel="stylesheet",n.type="text/css",n.media="all",n.href=`${SELFBOOK_APP_BASE_URL}/${e}`,t.appendChild(n)}})}s=!0}}(),c(),document?.querySelectorAll("a").forEach(e=>{e.addEventListener("click",e=>{try{"A"!==e.target.tagName&&"A"===e.target.parentNode?.tagName&&(e.target.href=e.target.parentNode.href);const n=e.target.href||"";if(-1===n.indexOf("?"))return;const o=m(new URLSearchParams(n.substring(n.indexOf("?")))),r=getHotelBasicData(o.hotel,o.hotelId||t);if(SELFBOOK_APP_VERSION=o.version?.toLowerCase?.()||r?.app_version||"v2",r?.mobile_display_only&&window.innerWidth>=768)return;(isTemplateDomainMatch(r,e)||"true"===o.selfbook)&&(e.preventDefault(),_(o,r))}catch(t){console.error("a-element: err: ",t)}})}),"complete"===document?.readyState?y():window?.addEventListener("load",y)}function f(t){return t.toISOString()}function h(){if(window.Statsig){const t=window.Statsig.instance().getExperiment("ddn");return t&&t.value&&t.value["ddn-flow"]}return null}async function E(e,n){try{o=!0;const a=n?`?id=${n}`:"",s=await l({url:`${SELFBOOK_BACKEND_URL}/hotels/info${a}`,headers:{"content-type":"application/json","API-Key":e}});sessionStorage.setItem(SELFBOOK_HOTEL_GROUP_INFO,JSON.stringify(s));const d={...s},c=getHotelBasicData(n);c?.enable_direct_distribution_network&&await new Promise((t,e)=>{const n=document.createElement("script");n.src=`https://cdn.jsdelivr.net/npm/@statsig/js-client@3/build/statsig-js-client+session-replay+web-analytics.min.js?apikey=${STATSIG_CLIENT_KEY}`,n.async=!0,n.onload=()=>{t(n),console.log("Loaded Statsig")},n.onerror=()=>e(new Error("Failed to load Statsig script")),document.head.appendChild(n)});const u=m(new URLSearchParams(window.location.search));if(SELFBOOK_APP_VERSION=u.version?.toLowerCase?.()||c?.app_version||"v2",SELFBOOK_APP_BASE_URL=SELFBOOK_APP_VERSION.match(/^v3/i)?SELFBOOK_BASE_URL_V3:SELFBOOK_BASE_URL,"v3.5"===SELFBOOK_APP_VERSION&&(d.hotels=d?.hotels?.map(t=>({...t,enable_v3_new_ui_version:!0}))),sessionStorage.setItem(SELFBOOK_HOTEL_GROUP_INFO,JSON.stringify(d)),!i&&getIsEnableV35(c)&&c?.is_default_date_logic_enabled&&"group"!==d?.structure){const o=await async function(e,n,o){try{const r=function(){const t=new Date,e=new Date(t.getFullYear(),t.getMonth(),1),n=new Date(t.getFullYear(),t.getMonth()+2,0);return{startDate:w(e),endDate:w(n)}}(),a={start_date:r.startDate,end_date:r.endDate,currency_code:o?.currency_code||"USD",guests:[{type:"adult",count:o?.default_adult_occupancy||2}]};window.sb_sdkBus.emit("sdk-calendar-status",{type:"loading",payload:a});const s=await l({url:`${"v2"===SELFBOOK_APP_VERSION?SELFBOOK_BACKEND_URL:SELFBOOK_BACKEND_URL.replace("v2","v3")}/hotels/${n||t}/calendar`,headers:{"content-type":"application/json","API-Key":e},data:JSON.stringify(a),method:"POST"});return initialCalendarResponse=s,window.sb_sdkBus.emit("sdk-calendar-status",{type:"success",payload:s}),s.data}catch(t){window.sb_sdkBus.emit("sdk-calendar-status",{type:"error",error:t.message}),console.log(t)}}(e,n,c),r=function(t){const e=new Date,n=e.getUTCFullYear(),o=e.getUTCMonth(),r=e.getUTCDate(),a=new Date(Date.UTC(n,o,r+14));let s=t.filter(t=>function(t){const[e,n,o]=t.split("-").map(Number);return new Date(Date.UTC(e,n-1,o))}(t.date)>a&&null!=t.price);0===s.length&&(s=t.filter(t=>null!=t.price));return 0===s.length?null:s.reduce((t,e)=>e.price<t.price?e:t)}(o);if(r&&r?.date){i=!0;const o=function(t){const e=new Date(t?.date),n=new Date(e);return n.setDate(e.getDate()+(t?.min_stay?t?.min_stay:1)),{startDate:f(e),endDate:f(n)}}(r);initialV35AvailabilityStartEndDates={startDate:o.startDate,endDate:o.endDate},async function(e,n,o,r){try{const a={start_date:r.startDate?.replace(/T.*$/,""),end_date:r.endDate?.replace(/T.*$/,""),currency_code:o?.currency_code||"USD",guests:[{type:"adult",count:o?.default_adult_occupancy||2}],ddn_flow:h(),include_flex_cancel_rates:!0};window.sb_sdkBus.emit("sdk-availability-status",{type:"loading",payload:{bodydata:a}});const s=await l({url:`${"v2"===SELFBOOK_APP_VERSION?SELFBOOK_BACKEND_URL:SELFBOOK_BACKEND_URL.replace("v2","v3")}/hotels/${n||t}/availability`,headers:{"content-type":"application/json","API-Key":e},data:JSON.stringify(a),method:"POST"});return void window.sb_sdkBus.emit("sdk-availability-status",{type:"success",payload:{response:s,bodydata:a}})}catch(t){window.sb_sdkBus.emit("sdk-availability-status",{type:"error",error:t.message}),console.log(t)}}(e,n,c,o)}}return r||g(),r=!0,void(o=!1)}catch(t){console.log(t)}}const w=t=>`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`;const S=document?.getElementById("selfbook_jssdk");if(S){const n=new URL(S.getAttribute("src"));if(t=n.searchParams.get("hotelId"),e=n.searchParams.get("apiKey"),"?11howard"===window.location.search&&window.location.href.includes("staging")&&(t="66350",e="x9GTqyGB8Pboi5Tkk3fuQUrQ8qAecxzxNY0"),!e||!t)throw new Error("(!) selfbook: ApiKey and HotelId are required.");window.isSelfbookSDKActive=!0,initWidgets({apiKey:e,hotelId:t}),initSDKBus(),E(e,t),intervalWrapper(()=>{E(e,t)},3e5),function(){const t="\n #selfbook_sdkwidget {\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0px;\n right: 0px;\n }\n\n .dismiss-btn-slide-in {\n -webkit-transition: 500ms;\n -moz-transition: 500ms;\n transition: 500ms;\n transform: translateX(0)!important\n }\n\n .dismiss-btn-slide-out {\n -webkit-transition: 500ms;\n -moz-transition: 500ms;\n transition: 500ms;\n transform: translateX(300px)!important\n }\n\n .dismiss-btn-slide-out span {\n display: none;\n }\n\n .payment-summary-wrapper {\n overflow: scroll!important;\n -ms-overflow-style: none!important;\n scrollbar-width: none!important;\n }\n .payment-summary-wrapper::-webkit-scrollbar {\n display: none!important;\n }\n\n .dismiss-btn-resize-in {\n width: 46px!important;\n height: 46px!important;\n transition: 500ms;\n right: 30px!important;\n }\n\n .dismiss-btn-resize-in span {\n display: none;\n }\n\n .dismiss-btn-resize-in:hover {\n width: 217px!important;\n height: 46px!important;\n transition: all 300ms linear;\n cursor: pointer;\n }\n\n .dismiss-btn-resize-in:hover span {\n display: inline;\n height: 20px!important;\n overflow: hidden;\n }\n\n .dismiss-btn-resize-out {\n width: 46px!important;\n height: 46px!important;\n transition: 500ms;\n right: -100px!important;\n }\n\n .slide-in {\n transform: translateX(100%);\n -webkit-transform: translateX(100%);\n animation: slide-in 0.8s forwards !important;\n -webkit-animation: slide-in 0.8s forwards !important;\n z-index: 1000000000000;\n }\n\n .slide-out {\n transform: translateX(100%);\n -webkit-transform: translateX(100%);\n animation: slide-out 1s forwards !important;\n -webkit-animation: slide-out 1s forwards !important;\n z-index: -1000000000000;\n }\n\n @media screen and (max-width:495px) {\n .slide-in {\n transform: translateY(100%);\n -webkit-transform: translateY(100%);\n animation: slide-up 0.8s forwards !important;\n -webkit-animation: slide-up 0.8s forwards !important;\n z-index: 1000000000000;\n }\n .slide-out {\n transform: translateY(100%);\n -webkit-transform: translateY(100%);\n animation: slide-down 0.5s forwards !important;\n -webkit-animation: slide-down 1s forwards !important;\n z-index: -1000000000000;\n }\n }\n\n @keyframes slide-in {\n 100% {\n transform: translateX(0%);\n }\n }\n\n @-webkit-keyframes slide-in {\n 100% {\n -webkit-transform: translateX(0%);\n }\n }\n\n @keyframes slide-up {\n 100% {\n transform: translateY(0%);\n }\n }\n\n @-webkit-keyframes slide-up {\n 100% {\n -webkit-transform: translateY(0%);\n }\n }\n\n @keyframes slide-out {\n 0% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(100%);\n }\n }\n\n @-webkit-keyframes slide-out {\n 0% {\n -webkit-transform: translateX(0%);\n }\n 100% {\n -webkit-transform: translateX(100%);\n }\n }\n\n @keyframes slide-down {\n 0% {\n transform: translateY(0%);\n }\n 100% {\n transform: translateY(100%);\n }\n }\n\n @-webkit-keyframes slide-down {\n 0% {\n -webkit-transform: translateY(0%);\n }\n 100% {\n -webkit-transform: translateY(100%);\n }\n }\n ",e=document.createElement("style");e.textContent=t,document.head.append(e),function(t){const e=document.createElement("style");e.textContent=t,document.head.append(e)}(t)}()}window&&(window.sbApiLogger=function(n,o){try{l({url:`${"v2"===SELFBOOK_APP_VERSION?SELFBOOK_BACKEND_URL:SELFBOOK_BACKEND_URL.replace("v2","v3")}/hotels/${o||t}/events`,method:"POST",headers:{"content-type":"application/json","API-Key":e},data:JSON.stringify({generated_at:(new Date).toISOString(),event_source:"SDK",body:n})})}catch(t){console.log(t)}},window.book=function(t,e,n,o,r,a,s,i,l,d,c="fr",u,m,y){p({startDate:t,endDate:e,guests:n,propertyId:o,currency:r,roomId:a,ratePlanCode:s,rate:i,promoCode:l,groupCode:d,locale:c,destinationId:m,hotelId:u,roomCategory:y})},window.bookNow=p,window.closeSelfbookWidget=function(){const t=getElementById("selfbook_sdkwidget"),e=getElementById("selfbook_sdkwidget_wrapper");setOverflowHidden(!1),t.setAttribute("class","slide-out"),e.style.background="rgba(0, 0, 0, 0)",window.selfbookWidgetStore.dispatch({type:"WIDGET/SELFBOOK_WIDGET_CLOSED"}),window.selfbookWidgetStore.dispatch({type:"ANALYTICS/TRACK_EVENT",payload:{eventType:"widget closed"}}),setTimeout(()=>{t.style.display="none",e.style.zIndex=-1e11},800)})}runDirectApplication(); /* TravelClick Tumbling River Ranch HotelId: 9878526 https://www.tumblingriver.com/ */ console.log( '%cCustom script has been initialized', 'background: green; color: white;', ); function modifyExistingSbLinks() { let links = document.querySelectorAll(`a[href*='selfbook=true']`); for (let link of links) { let href = link.getAttribute('href'); if (href) { let updatedHref = href.toString().toLowerCase(); let linkObj = hrefToObj(updatedHref); let finalParams = assignObjectVals(linkObj) link.setAttribute('href', window.location.href); link.addEventListener("click", (e) => { e.preventDefault(); bookNow(finalParams); console.log('modifyExistingSbLinks()', finalParams) }); } } } modifyExistingSbLinks(); function setLocale(locale) { let localeList = { "fr-FR": "fr", "fr-fr": "fr", "fr": "fr", /* French */ "de-DE": "de", "de-de": "de", "de": "de", /* German */ "it-IT": "it", "it-it": "it", "it": "it", /* Italian */ "es-ES": "es", "es-es": "es", "es": "es", /* Spanish (Spain) */ "es-MX": "es-MX", "es-mx": "es-MX", /* Spanish (Mexico) */ "pt-PT": "pt-PT", "pt-pt": "pt-PT", "pt": "pt-PT", /* Portuguese */ "zh-CN": "zh-CN", "zh-cn": "zh-CN", /* Simplified Chinese */ "zh-TW": "zh-TW", "zh-tw": "zh-TW", /* Traditional Chinese */ "ja-JP": "ja", "ja-jp": "ja", /* Japan */ } return localeList[locale] || localeList[document.documentElement.lang] || "en"; }; // Checks the format of the inputted date and puts it in the correct order format (YYYY-MM-DD) function convertDate(date) { try { let inputDate = new Date(date); let year = inputDate.getFullYear(); let month = (inputDate.getMonth() + 1).toString().padStart(2, '0'); let day = inputDate.getDate().toString().padStart(2, '0'); return [year, month, day].join('-'); } catch (error) { console.log(error, 'convertDate'); } }; // Validates date format is 'YYYY-MM-DD' function checkDateIsISOformat(inputString) { try { let regexPattern = /^\d{4}-\d{2}-\d{2}$/; return regexPattern.test(inputString); } catch (error) { console.log(error, 'checkDateIsISOformat'); } } /* Verifies these date formats: 'DD MONTH YYYY', 'YYYY-MM-DD', 'YYYY/MM/DD', 'MM/DD/YYYY' */ function verifyFutureDate(date) { try { if (date) { if (checkDateIsISOformat(date)) { let inputDate = new Date(date); let today = new Date(); today.setHours(0, 0, 0, 0); if (inputDate >= today) { let formattedDate = inputDate.toISOString().split('T')[0]; return formattedDate; } } else { let inputDate = new Date(date); let today = new Date(); today.setHours(0, 0, 0, 0); if (inputDate >= today) { return convertDate(inputDate); } } } return ''; } catch (error) { console.log(error, 'verifyFutureDate'); } } // arrival > departure, return new departure function compareDates(arrive, depart) { try { let arrivalDate = new Date(arrive); let departureDate = new Date(depart); arrivalDate.setHours(0, 0, 0, 0); departureDate.setHours(0, 0, 0, 0); if (arrivalDate > departureDate) { arrivalDate.setDate(arrivalDate.getDate() + 1); departureDate = arrivalDate; } return departureDate.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }); } catch (error) { console.log(error, 'compareDates'); } } /* This function flattens the array / object within guests */ function pruneGuests(object) { try { let pruneObject = object; if (pruneObject.guests && Array.isArray(pruneObject.guests)) { let guests = pruneObject.guests; for (let guest of guests) { if (guest.type === 'adult' && guest.count > 0) { pruneObject.adult = guest.count; } else if (guest.type === 'child' && guest.count > 0) { pruneObject.child = guest.count; } // else if (guest.type === 'infants' && guest.count > 0) { // pruneObject.infants = guest.count; // } } delete pruneObject.guests; } // console.log('pruneObject', pruneObject); return pruneObject; } catch (error) { console.log(error, 'pruneGuests'); } } /* Fix for Currency Case Bug */ function upperCaseCurrency(currency) { try { if (!currency) { return null; } let currencyCode = currency.toUpperCase(); return currencyCode; } catch (error) { console.log(error, 'upperCaseCurrency'); } }; /* This function defines the bookNow() Object and assigns the values after running it through pruneObjectKeys(). */ function assignObjectVals(param) { try { let urlData = param; let arrive = urlData.datein || urlData.startdate; let depart = urlData.dateout || urlData.enddate; let updatedLocale = setLocale(urlData.locale); let updatedCurrency = upperCaseCurrency(urlData.currency); delete urlData.locale; delete urlData.currency; let bookNowParams = { startDate: verifyFutureDate(arrive), endDate: verifyFutureDate(depart), guests: [ { type: 'adult', count: (!urlData.adult ? null : parseInt(urlData.adult, 10)), }, { type: 'child', count: (!urlData.child ? null : parseInt(urlData.child, 10)), }, ], propertyId: urlData.propertyId, currency: updatedCurrency, roomId: urlData.roomtypeid || urlData.roomid, ratePlanCode: urlData.rate || urlData.rateplancode, promoCode: urlData.advertisementid || urlData.promocode, groupCode: urlData.group, locale: updatedLocale, hotel: 9878526, hotelId: 9878526, iataNumber: urlData.agencyid, }; // Remove any properties with null or undefined values Object.keys(bookNowParams).forEach((key) => { if (bookNowParams[key] === null || bookNowParams[key] === undefined || bookNowParams[key] === "") { delete bookNowParams[key]; } }); return bookNowParams; } catch (error) { console.log(error, 'assignObjectVals'); } }; // Create a function that parses the URL and returns an object with the params function hrefToObj(url) { try { let href = url.replace(/%20/g, ''); let parsedUrl = new URL(href); let rawParams = Object.fromEntries(parsedUrl.searchParams.entries()); let params = {}; for (let [key, value] of Object.entries(rawParams)) { params[key.toLowerCase()] = value; } return params; } catch (error) { console.log(error, 'hrefToObj'); } } // Create a direct link function objToSBlinks(params) { try { let siteUrl = `${window.location.pathname}?selfbook=true`; let sbObj = assignObjectVals(params); let prunedSBobj = pruneGuests(sbObj); let urlParams = decodeURIComponent( new URLSearchParams(prunedSBobj), ).toString(); return `${siteUrl}&${urlParams}`; } catch (error) { console.log(error, 'objToSBlinks'); } } function extractHotelID(url) { // Regular expression to match the numeric ID part of the URL let regex = /\/(\d+)/; // Execute the regular expression on the given URL let match = url.match(regex); // If there's a match, return the first capturing group (the numeric ID) // console.log('match is an array', match); return match ? match[1] : null; } /* Find booking links with specific keywords, then point them to Selfbook */ function linkReplacer() { let allTCLinks = document.querySelectorAll(`a[href*='reservations.travelclick.com'], a[href*='bookings.travelclick.com'], a[href*='reservations.tumblingriver.com']`); if (allTCLinks.length > 0) { for (let i = 0; i < allTCLinks.length; i++) { // 3 ways to check class on a CTA // if (allTCLinks[i].classList.contains("hero__booking_cta")) { // // Class 'active' exists console.log("Class 'active' is present."); // } // if (allTCLinks[i].className.startsWith("hero__booking_cta")) { // // do something // } // for (let cls of allTCLinks[i].classList) { // if (cls.startsWith("hero__booking_cta")) { // link.style.backgroundColor = "black"; // break; // Stop checking once a match is found // } // } allTCLinks[i].removeAttribute('target'); let link = allTCLinks[i].href.toString(); let hotel_id = extractHotelID(link); let tempParams = {}; let linkObj = hrefToObj(link); if (link.includes('?')) { tempParams = assignObjectVals(linkObj); } let finalParams = { ...tempParams, hotelId: hotel_id }; let sbLink = objToSBlinks(linkObj); // allTCLinks[i].href = sbLink; // allTCLinks[i].href = "?book-now"; allTCLinks[i].addEventListener('click', (e) => { e.preventDefault(); e.stopImmediatePropagation(); bookNow(finalParams); }); } } }; linkReplacer(); setInterval(linkReplacer, 1000);