!function(e){if("object"==typeof exports)module.exports=e();else{var n=window.Cookies,o=window.Cookies=e();o.noConflict=function(){return window.Cookies=n,o}}}(function(){function e(){for(var e=0,n={};e1){if("number"==typeof(i=e({path:"/"},t.defaults,i)).expires){var s=new Date;s.setMilliseconds(s.getMilliseconds()+864e5*i.expires),i.expires=s}try{c=JSON.stringify(r),/^[\{\[]/.test(c)&&(r=c)}catch(e){}return r=o.write?o.write(r,n):encodeURIComponent(String(r)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=encodeURIComponent(String(n)),n=n.replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent),n=n.replace(/[\(\)]/g,escape),document.cookie=[n,"=",r,i.expires&&"; expires="+i.expires.toUTCString(),i.path&&"; path="+i.path,i.domain&&"; domain="+i.domain,i.secure?"; secure":""].join("")}n||(c={});for(var a=document.cookie?document.cookie.split("; "):[],p=/(%[0-9A-Z]{2})+/g,d=0;d'); $body.append($supportDiv); var need_legacy = false; for(i in this.cssSuportTest){ var test = this.cssSuportTest[i]; $supportDiv.css(test.property,test.value); if($supportDiv.css(test.property) !== test.value){ $body.addClass('bk-no-'+test.property+"_"+test.value); need_legacy = true; } } $supportDiv.remove(); if(need_legacy){//only punish old browsers BookingKitApp.loadCssUrl(window.BKVars.legacyCss) } } }catch(err) { console.log(err.message); } finally { } }, generateSessionId: function () { BookingKitApp.logger("generateSessionId"); return 'xxxxxxxx-'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }) + this.sessionSeed; }, checkSeed: function (cookie) { BookingKitApp.logger("checkSeed"); return !!cookie.match('[0-9a-z]+\-' + this.sessionSeed); }, bk_loadDates: function (el) { BookingKitApp.logger("bk_loadDates"); //reload selected or first if (jQuery(".calendar-selected-day a").length > 0) { jQuery(".calendar-selected-day a").eq(0).click(); } else if (jQuery(".bk-active-day a").length > 0) { jQuery(".bk-active-day a").eq(0).click(); } else { jQuery(".bk-cal-action a").eq(0).click(); } }, bk_setActiveDate: function (el) { BookingKitApp.logger("bk_setActiveDate"); var activeClass = el.getAttribute('data-activeclass') || ""; var newClass = "bk-active-day "+activeClass; jQuery('.calendar-day-number').removeClass('bk-active-day').removeClass(activeClass); el.parentNode.className = el.parentNode.className + " "+newClass; BookingKitApp.skipHashNavigation = true; var hash = el.getAttribute("href").replace(/#\!\/|#/, ""); if (hash) { window.location.hash = "!/" + hash; } BookingKitApp.selectCalendarTimeFilter(''); // CORE2-1393/CORE2-1501: AvailableSlotsFilterCalendar: BookingKitApp.filterExperienceColumns(el); }, bk_setActiveDurationAndRemoveErrors: function (el) { let selectedDurationElement = jQuery(el); if (selectedDurationElement.hasClass('sold-out')) { return } if (selectedDurationElement.hasClass('bk-detail-duration-wrapper')) { jQuery('[name=event_date_id]').removeAttr('value'); jQuery('#bk-pricelist').empty(); jQuery('.bk-detail-buttons .bk-detail-go-checkout.on-select-event-date-show').hide(); BookingKitApp.resetButton('.bk-detail-pick-time-slot-title'); } if (selectedDurationElement.hasClass('bk-detail-bookingdates-item-active')) { jQuery('.bk-flexible-duration .bk-starting-time-error').hide(); } selectedDurationElement.parents('.bk-3-col-grid').find('.selected').removeClass('selected'); selectedDurationElement.addClass('selected'); }, prevDay: function () { BookingKitApp.logger("prevDay"); jQuery("#bk-detail-calendar .bk-cal-action").eq(this.getCurrentDate() - 1).find("a").click(); }, nextDay: function () { BookingKitApp.logger("nextDay"); jQuery("#bk-detail-calendar .bk-cal-action").eq(this.getCurrentDate() + 1).find("a").click(); }, getCurrentDate: function () { BookingKitApp.logger("getCurrentDate"); return jQuery("#bk-detail-calendar .bk-cal-action").index(jQuery(".bk-active-day")); }, autoPopup: function (element) { BookingKitApp.logger("autoPopup"); this.handleCartPadding(); //check auto popup var hash = window.location.hash; if (hash.match(/#bkCartLink/)) { jQuery("#bkCartLink").click(); window.location.hash = hash.replace(/\/?#bkCartLink/g, ""); } }, handleCartPadding: function () { BookingKitApp.logger("handleCartPadding"); this.cartSpacer.height(jQuery("#bkCartBar").height()); }, setContinueButtonClass: function(className){ BookingKitApp.logger("setContinueButtonClass"); jQuery('.continueShopping').addClass(className); }, lightbox: function (url, loadContent, lightBoxOptions) { BookingKitApp.logger("lightbox"); loadContent = loadContent || false; var defaultOptions = { animation: 'fade-in', confirmClose: false, allowMobileRedirect: true, closeOnBackdropClick: true, } lightBoxOptions = jQuery.extend(defaultOptions, lightBoxOptions || {}); if (typeof BookingKitApp.DefaultLanguage !== 'undefined') { this.setLanguage(BookingKitApp.DefaultLanguage); } //read sizes this.hideCart(); var $window = jQuery(window); var wHeight = $window.height(); var wWidth = $window.width(); //add exception for websites that have a wrong doctype declaration if (typeof screen == "object" && screen.availHeight < wHeight) { wHeight = screen.availHeight; } var scrollTop = $window.scrollTop(); var $body = jQuery("body"); //be sure all other lightboxes are closed this.removeLightBox(true); //create LB container var $lbCt = jQuery('
'); $lbCt.attr("role","dialog"); $lbCt.attr("aria-modal","true"); $lbCt.attr("aria-label", this._t('booking dialog')) //generate backdrop var $backdrop = jQuery('
'); //add close button var $lbClose = jQuery(BookingKitApp.lightBoxCloseBtnHtml); $lbClose.attr('id', ''); $lbClose.attr('rel', 'closeIframe'); $lbClose.addClass('bk-close-btn'); $lbClose.show(); //$lbClose = jQuery('.bk-close-btn'); //prevent bg scrolling jQuery("#bkBgScrollPrevent").height(wHeight).addClass("active"); jQuery("#bkBgKeepPos").css("top", (-1 * scrollTop) + parseInt($body.css("margin-top"))); $lbCt.data('options', lightBoxOptions); $backdrop.append($lbCt); var iHeight = $lbCt.innerHeight(); var iWidth = $lbCt.innerWidth(); $backdrop.click(function (event) { event.stopPropagation(); if(lightBoxOptions.closeOnBackdropClick){ BookingKitApp.closeLightbox(event); } }).children().click(function (event) { event.stopPropagation(); }); $lbClose.on('click keydown', function (event) { if (event.type === 'click' || (event.type === 'keydown' && event.key === 'Enter')) { event.stopPropagation(); BookingKitApp.closeLightbox(event); } }); //append back btn var $backBtn = jQuery(''); $backBtn.attr({ style: "display: none;", rel: "continueShopping", role: "button", tabindex: "0", "aria-label": "Go back to continue shopping" }) .addClass("continueShopping") .html( jQuery('') .attr({ 'class': 'bk-translation-text', 'data-original-text': 'continue shopping' }) .text(this._t("continue shopping")) ); $backBtn.on('click keydown', function (event) { if (event.type === 'click' || event.key === 'Enter') { event.preventDefault(); event.stopPropagation(); BookingKitApp.closeLightbox(event); } }); function loadInIframe() { //load iframe in container var myIframe = document.createElement("iframe"); myIframe.id = "bkIframe"; myIframe.src = this.appendUrlParam(url, {"pageWidth": iWidth}); myIframe.height = iHeight; myIframe.width = iWidth; myIframe.className = "alphaBg"; myIframe.title = 'bookingkit-checkout'; myIframe.allow="payment"; $lbCt.append(myIframe); //attach iframe navigation event if (jQuery.isFunction(jQuery.fn.on)) { jQuery(myIframe).on('load', function () { BookingKitApp.loadBkPage(BookingKitApp.appendUrlParam(BookingKitApp.CurrentActionUrl, {})); }); } else { jQuery(myIframe).load(function () { BookingKitApp.loadBkPage(BookingKitApp.appendUrlParam(BookingKitApp.CurrentActionUrl, {})); }); } //resize the iframe for iphone myIframe.width = $lbCt.width(); myIframe.height = $lbCt.height(); } if (loadContent) { //load bk content $lbCt.html('
'); this.loadBkPage(this.globalWidgetUrl, "bookingKitContainer", "attachListeners", $lbCt); } else { if(lightBoxOptions.allowMobileRedirect && BookingKitApp.checkoutShouldBeOpenedAsATab()){ try{ window.top.location.href = url; }catch (e){ BookingKitApp.log(e); BookingKitApp.startCheckoutFocusTrap(); loadInIframe.call(this); requestAnimationFrame(() => {document.getElementById('bkIframe')?.contentWindow?.focus()}); } } else { BookingKitApp.startCheckoutFocusTrap(); loadInIframe.call(this); requestAnimationFrame(() => {document.getElementById('bkIframe')?.contentWindow?.focus()}); } } $backdrop.hide(); $lbCt.append($backBtn); $lbCt.append($lbClose); $body.append($backdrop); $backdrop.fadeIn('fast'); //position it $lbCt.css("top", jQuery(window).height()); var wh_AB = (this.Version == 'v.2')? 0.02 : 0.01; $lbCt.animate({ top: wHeight * wh_AB }); }, expressCheckoutStart: function () { jQuery('.bk-close-btn').hide(); jQuery('a[rel="closeIframe"]').hide(); jQuery('a[rel="continueShopping"]').hide(); jQuery('[rel=continueShopping]').hide(); }, expressCheckoutEnd: function (params) { if (jQuery('#bookingKitContainer').length && jQuery('#bookingKitContainer').width() > 700 && !BookingKitApp.mobilecheck()) { jQuery('.bk-close-btn').show(); jQuery('a[rel="closeIframe"]').show(); if (params.showContinueShopping) { jQuery('a[rel="continueShopping"]').show(); jQuery('[rel=continueShopping]').show(); } } }, closeLightbox: function (event) { BookingKitApp.logger("closeLightbox"); var $lbCt = jQuery("#bk-lightbox_ct"); if( $lbCt.length === 0 ){ return; } var options = $lbCt.data('options') || {}; if(typeof options.beforeClose === 'function'){ try { if(!options.beforeClose(event)){ return; } } catch (e) {} } if (options.confirmClose) { if (confirm(this._t("Wollen Sie das Buchungsfenster wirklich schließen?"))) { this.removeLightBox(); BookingKitApp.stopCheckoutFocusTrap(); } } else { this.removeLightBox(); BookingKitApp.stopCheckoutFocusTrap(); } }, removeLightBox : function(toOpenNew){ BookingKitApp.logger("removeLightBox"); toOpenNew = toOpenNew || false; var $lbCt = jQuery("#bk-lightbox_ct"); if( $lbCt.length === 0 ){ return; } var options = $lbCt.data('options') || {}; $lbCt.animate({ top: -1 * jQuery(window).height() }, function () { jQuery("#bk-lightbox_backdrop").fadeOut("fast", function () { jQuery("#bk-lightbox_backdrop").remove(); var scrollTop = parseInt(jQuery("#bkBgKeepPos").css("top")); jQuery("#bkBgKeepPos").css("top", 0); jQuery("#bkBgScrollPrevent").height("auto").removeClass("active"); jQuery(window).scrollTop((-1 * scrollTop) + parseInt(jQuery("body").css("margin-top"))); if(!toOpenNew){ BookingKitApp.updateCart(true); BookingKitApp.bk_loadDates(); } }); if(typeof options.afterClose === 'function'){ try { options.afterClose(); } catch (e) {} } }); }, updateCart: function (pop) { BookingKitApp.logger("updateCart"); //make sure you are looking at your own session pop = pop || false; var params = pop ? {'pop': 'true'} : {}; jQuery("#bkCartCt").show(); this.loadBkPage( this.appendUrlParam(this.CartUrl, params), 'bkCartCt', {'autoPopup': null,'attachListeners':'#bkCartCt'} ); }, hideCart: function () { BookingKitApp.logger("hideCart"); //jQuery("#bkCartCt").children().fadeOut("fast",function(){this.remove()}); if (typeof jQuery.slideDown !== 'undefined' && jQuery.isFunction(jQuery.slideDown) ) { jQuery("#bkCartCt").slideDown("normal", function () { this.innerHTML = "" }); this.cartSpacer.slideDown("normal", function () { BookingKitApp.cartSpacer.height(0) }); } else { jQuery("#bkCartCt").hide(); this.cartSpacer.hide(); } }, popCart: function () { BookingKitApp.logger("popCart"); jQuery("#bkCartBar").addClass("popUpScale"); }, _t: function (string) { BookingKitApp.logger("_t"); if (typeof BookingKitApp.translations[this.lang] != 'undefined' && typeof BookingKitApp.translations[this.lang][string] != 'undefined') { return BookingKitApp.translations[this.lang][string]; } return string; }, changeLanguage: function (language) { BookingKitApp.logger("changeLanguage"); this.setLanguage(language); var _this = this; jQuery('.bk-translation-text').each(function (index, element) { if (typeof jQuery(element).attr('data-original-text') != 'undefined') { jQuery(element).text(_this._t(jQuery(element).attr('data-original-text'))); } }); }, setSession: function(data){ if(typeof data.session_id === 'undefined' || typeof data.seed === 'undefined'){ return; } this.sessionSeed = data.seed; this.BKSessionId = data.session_id; if(BookingKitApp.validateCookie(data.session_id)){ BKClientCookies.set(this.cookieName, data.session_id); } }, setLanguage: function (language) { BookingKitApp.logger("setLanguage"); this.lang = language; }, fixAddBookingPosition: function(){ BookingKitApp.logger("fixAddBookingPosition"); var $document = jQuery(document); var $container = jQuery('#bookingKitContainer .bk-detail-content'); var total_scroll = $document.scrollTop(); if (BookingKitApp.pos_top) { if (total_scroll > BookingKitApp.pos_top) { $container.addClass('sticky'); } else { $container.removeClass('sticky'); } } }, handleWindowScrollEvent: function() { BookingKitApp.logger("handleWindowScrollEvent"); this.fixAddBookingPosition(); }, initControls: function (el) { BookingKitApp.logger("initControls"); this.bk_loadDates(null); //image slider if(jQuery.isFunction(jQuery.fn.on)) { jQuery('#bookingKitContainer').off('click','.bk-img-slider-left'); jQuery('#bookingKitContainer').on('click','.bk-img-slider-left', function (e) { e.preventDefault(); bkSlideImage('prev'); return false; }); jQuery('#bookingKitContainer').off('click','.bk-img-slider-right'); jQuery('#bookingKitContainer').on('click','.bk-img-slider-right',function (e) { e.preventDefault(); bkSlideImage('next'); return false; }); jQuery('#bookingKitContainer').off('click','.bk-image-slider img'); jQuery('#bookingKitContainer').on('click','.bk-image-slider img', function (e){ e.preventDefault(); var index = BookingKitApp.getDataAttribute('index', jQuery(this)); bkSlideImageNumber(index); return false; }); jQuery('#bookingKitContainer').off('click','#bk-button-change-language'); jQuery('#bookingKitContainer').on('click','#bk-button-change-language', function (e) { e.preventDefault(); e.stopPropagation(); BookingKitApp.openLanguageDialog(); }); jQuery('#bookingKitContainer').mouseup(function(e){ BookingKitApp.closeMenus(e); }); jQuery('#bookingKitContainer').off('click','.bk-detail-description .bk-detail-desc-read-more a'); jQuery('#bookingKitContainer').on('click','.bk-detail-description .bk-detail-desc-read-more a', function (e){ e.preventDefault(); e.stopPropagation(); $this = jQuery(this); $this.closest('.bk-detail-description').find('.bk-detail-desc').toggleClass('bk-detail-desc-compress'); if ($this.html() == BookingKitApp.getDataAttribute('text-off', $this)){ $this.html(BookingKitApp.getDataAttribute('text-on', $this)); } else { $this.html(BookingKitApp.getDataAttribute('text-off', $this)); } }); jQuery('#bookingKitContainer').off('click','a.bk-detail-bookingdates-item-active'); jQuery('#bookingKitContainer').on('click','a.bk-detail-bookingdates-item-active',function (el){ if(BookingKitApp.lbLinkTarget != 'blank') { el.preventDefault(); el.stopPropagation(); } BookingKitApp.selectEventDateDetail(this); }); jQuery('#bookingKitContainer').off('click', '.bk-detail-go-checkout, .bk-detail-bookingdates-item-active[data-action="addToCart"]'); jQuery('#bookingKitContainer').on('click', '.bk-detail-go-checkout, .bk-detail-bookingdates-item-active[data-action="addToCart"]', function (e){ //Do not prevent this event var $this = jQuery(this); var event_id = jQuery("[name=event_date_id]").val(); var inLeadTime = jQuery("[name=in_lead_time]").val(); if (event_id != ""){ var href = BookingKitApp.getDataAttribute("base-href", $this); $this.data('ident',event_id); href = href.replace('EVENT_DATE_ID', event_id); if (inLeadTime == "1"){ href = href.replace('addToCart', 'inLeadTime'); } $this.attr("href", href); BookingKitApp.cartLinkClick(e, $this); } }); jQuery('#bookingKitContainer').off('click','.bk-detail-choose-date-title.on'); jQuery('#bookingKitContainer').on('click','.bk-detail-choose-date-title.on',function (e){ e.preventDefault(); e.stopPropagation(); $this = jQuery(this); $this.parents('.bk-detail-right-column').find('.bk-date-btn').click(); }); jQuery('#bookingKitContainer').off('click','.bk-detail-pick-time-slot-title.on'); jQuery('#bookingKitContainer').on('click','.bk-detail-pick-time-slot-title.on',function (e){ e.preventDefault(); e.stopPropagation(); var $this = jQuery(this); var $window = jQuery(window); var wWidth = $window.width(); var mobileBreakPoint = 550; var $bookingdates = $this.next('.bk-detail-bookingdates'); $bookingdates.show(); if (($bookingdates.html()).trim() == "") { BookingKitApp.reloadEventDates(this); } if (wWidth < mobileBreakPoint) { bkScrollToChooseDate(); } // handle aria-expanded attribute var trigger = jQuery('.bk-detail-pick-time-slot-title'); if (trigger.attr('aria-expanded') === 'false') { handleSlotSelect(trigger); } }); jQuery('#bkCartCt').off('click','#bkCartLink'); jQuery('#bkCartCt').on('click','#bkCartLink',function (e){ if(BookingKitApp.lbLinkTarget != 'blank') { e.preventDefault(); e.stopPropagation(); $this = jQuery(this); BookingKitApp.lightbox($this.attr('href')); return false; } }); jQuery('#bookingKitContainer').off('click', '.bk-detail-item'); jQuery('#bookingKitContainer').on('click', '.bk-detail-item', function (e){ BookingKitApp.bk_setActiveDurationAndRemoveErrors(this); }); jQuery('#bookingKitContainer').off('click', '.bk-flexible-duration .bk-detail-go-checkout'); jQuery('#bookingKitContainer').on('click', '.bk-flexible-duration .bk-detail-go-checkout', function (e) { var $this = jQuery(this) var event_id = jQuery("[name=event_date_id]").val(); var inLeadTime = jQuery("[name=in_lead_time]").val(); var starting_error = jQuery('.bk-flexible-duration .bk-starting-time-error'); if(BookingKitApp.lbLinkTarget != 'blank') { e.preventDefault(); e.stopPropagation(); } if (event_id != ""){ starting_error.hide(); var href = BookingKitApp.getDataAttribute("base-href", $this); $this.data('ident',event_id); href = href.replace('EVENT_DATE_ID', event_id); if (inLeadTime == "1"){ href = href.replace('addToCart', 'inLeadTime'); } $this.attr("href", href) BookingKitApp.cartLinkClick(e, $this); } else { e.preventDefault(); e.stopPropagation(); starting_error.show(); starting_error.closest('.scrollable').animate({scrollTop:0},'fast') } }); jQuery('#bookingKitContainer').off('click', '.bk-pricelist-update'); jQuery('#bookingKitContainer').on('click', '.bk-pricelist-update', function (){ var $this = jQuery(this) var url = $this.data('pricelist-href'); var targetId = $this.data('pricelist-target'); var callback = $this.data('callback'); BookingKitApp.loadBkPage(url, targetId, callback, $this); }); jQuery('#bookingKitContainer').off('click','.bk-offers-display-more a'); jQuery('#bookingKitContainer').on('click','.bk-offers-display-more a', function (){ jQuery('#bookingKitContainer .bk-offers-container .bk-offers-item.extra').show(); jQuery('.bk-offers-display-more').remove(); }); jQuery(window).on('resize', this.resizePage.bind(this)); } else { jQuery('#bookingKitContainer .bk-img-slider-left').die('click'); jQuery('#bookingKitContainer .bk-img-slider-left').live('click', function(e){ e.preventDefault(); bkSlideImage('prev'); return false; }); jQuery('#bookingKitContainer .bk-img-slider-right').die('click'); jQuery('#bookingKitContainer .bk-img-slider-right').live('click', function(e){ e.preventDefault(); bkSlideImage('next'); return false; }); jQuery('#bookingKitContainer .bk-image-slider img').die('click'); jQuery('#bookingKitContainer .bk-image-slider img').live('click', function(e){ e.preventDefault(); var index = BookingKitApp.getDataAttribute('index', jQuery(this)); bkSlideImageNumber(index); return false; }); jQuery('#bookingKitContainer #bk-button-change-language').die('click'); jQuery('#bookingKitContainer #bk-button-change-language').live('click', function(e){ e.preventDefault(); e.stopPropagation(); BookingKitApp.openLanguageDialog(); }); jQuery('#bookingKitContainer').mouseup(function (e) { BookingKitApp.closeMenus(e); }); jQuery('#bookingKitContainer .bk-detail-description .bk-detail-desc-read-more a').die('click'); jQuery('#bookingKitContainer .bk-detail-description .bk-detail-desc-read-more a').live('click', function(e){ e.preventDefault(); e.stopPropagation(); $this = jQuery(this); $this.closest('.bk-detail-description').find('.bk-detail-desc').toggleClass('bk-detail-desc-compress'); if ($this.html() == BookingKitApp.getDataAttribute('text-off', $this)){ $this.html(BookingKitApp.getDataAttribute('text-on', $this)); } else { $this.html(BookingKitApp.getDataAttribute('text-off', $this)); } }); jQuery('#bookingKitContainer .bk-detail-bookingdates-item-active').die('click'); jQuery('#bookingKitContainer .bk-detail-bookingdates-item-active').live('click', function(e){ e.preventDefault(); e.stopPropagation(); BookingKitApp.selectEventDateDetail(this); }); jQuery('#bookingKitContainer .bk-detail-go-checkout, #bookingKitContainer .bk-detail-bookingdates-item-active[data-action="addToCart"]').live('click', function (e){ var $this = jQuery(this); var event_id = jQuery("[name=event_date_id]").val(); var inLeadTime = jQuery("[name=in_lead_time]").val(); if (event_id != ""){ var href = BookingKitApp.getDataAttribute("base-href", $this); $this.data('ident',event_id); href = href.replace('EVENT_DATE_ID', event_id); if (inLeadTime == "1"){ href = href.replace('addToCart', 'inLeadTime'); } $this.attr("href", href) BookingKitApp.cartLinkClick(e, $this); } }); jQuery('#bookingKitContainer .bk-detail-go-checkout').die('click'); jQuery('#bookingKitContainer .bk-detail-go-checkout').live('click', function(e){ $this = jQuery(this); var event_id = jQuery("[name=event_date_id]").val(); if (event_id != "" ){ var href = BookingKitApp.getDataAttribute("base-href", $this); $this.data('ident',event_id); href = href.replace('EVENT_DATE_ID', event_id); $this.attr("href", href); BookingKitApp.cartLinkClick(e, $this); } }); jQuery('#bookingKitContainer .bk-detail-choose-date-title.on').die('click'); jQuery('#bookingKitContainer .bk-detail-choose-date-title.on').live('click', function(e){ e.preventDefault(); e.stopPropagation(); $this = jQuery(this); $this.parents('.bk-detail-right-column').find('.bk-date-btn').click(); }); jQuery('#bookingKitContainer .bk-detail-pick-time-slot-title.on').die('click'); jQuery('#bookingKitContainer .bk-detail-pick-time-slot-title.on').live('click', function(e){ e.preventDefault(); e.stopPropagation(); var $this = jQuery(this); var $window = jQuery(window); var wWidth = $window.width(); var mobileBreakPoint = 550; var $bookingdates = $this.next('.bk-detail-bookingdates'); $bookingdates.show(); if (($bookingdates.html()).trim() == "") { BookingKitApp.reloadEventDates(this); } if (wWidth < mobileBreakPoint) { bkScrollToChooseDate(); } }); jQuery('#bkCartCt #bkCartLink').die('click'); jQuery('#bkCartCt #bkCartLink').live('click', function(e){ if(BookingKitApp.lbLinkTarget != 'blank') { e.preventDefault(); e.stopPropagation(); $this = jQuery(this); BookingKitApp.lightbox($this.attr('href')); return false; } else { } }); jQuery('#bookingKitContainer .bk-offers-display-more a').die('click'); jQuery('#bookingKitContainer .bk-offers-display-more a').live('click', function (){ jQuery('#bookingKitContainer .bk-offers-container .bk-offers-item.extra').show(); jQuery('.bk-offers-display-more').remove(); }); jQuery(window).resize(this.resizePage.bind(this)); } //check if the description is overflowed if (jQuery('.bk-detail-desc-compress').length && jQuery('.bk-detail-desc-compress').get(0).scrollHeight <= jQuery('.bk-detail-desc-compress').innerHeight()) { jQuery('.bk-detail-desc').removeClass('bk-detail-desc-compress'); jQuery('.bk-detail-desc-read-more').hide(); } this.inIframe = window.top != window.self; if(this.forceLbLinkTarget){ this.lbLinkTarget = this.forceLbLinkTarget; }else if(this.inIframe){ this.lbLinkTarget = 'blank'; } //var checkout_dimension = BookingKitApp.AB_Checkout_version == 'v.1' ? 'Checkout v.2':'Checkout v.1'; //BK_ga('bkTracker.set', 'dimension2', checkout_dimension); BookingKitApp.setSelectedLanguage(); BookingKitApp.initExtWidgets(); }, resizePage: function(){ BookingKitApp.logger("resizePage"); this.resizeDates(); }, isDetailPage: function (){ BookingKitApp.logger("isDetailPage"); return jQuery('.bk-detail-content').length && this.Version == 'v.2'; }, isListEventByDatePage: function (){ BookingKitApp.logger("isListEventByDatePage"); return jQuery('.bk-event-by-date-content').length && this.Version == 'v.2'; }, isListEventPage: function (){ BookingKitApp.logger("isListEventPage"); return jQuery('.bk-event-content').length && this.Version == 'v.2'; }, addAfterInit: function (js) { BookingKitApp.logger("addAfterInit"); this.afterInitCode += ";" + js; }, afterInit: function () { BookingKitApp.logger("afterInit"); eval(this.afterInitCode); this.afterInitCode = ""; this.checkBkRefParameter(); //addCartCt jQuery("body").append('
'); this.updateCart(true); jQuery(window).focus(function () { if (jQuery("#bk-lightbox_ct").length == 0) { BookingKitApp.updateCart(); } }); try { var version = this.getWidgetEmbedVersion(); this.captureInsight('widget_loaded', { 'embed_version': version, 'widget_version': 'v.3', }); } catch (e) { console.error(e.message); } }, getWidgetEmbedVersion: function(){ //find the embed script var scripts = document.getElementsByTagName('script') var bkScript = null; for(var script in scripts){ if(scripts[script].src && scripts[script].src.match(/bookingkit(.*)bkscript/)){ bkScript = scripts[script]; break; } } if(!bkScript){ return 'NOT_FOUND'; } if(!bkScript.src.match(/bkscript\.js\.php/)){ return 'embed_v.3.1'; } if(bkScript.src.match(/\bcw\b/)){ return 'embed_v.3.0'; } if(bkScript.src.match(/bkscript\.js\.php\?[v|e]=/)){ return 'embed_v.2.0'; } this.captureInsight('invalid_embed_script', { 'src': bkScript.src }); if(bkScript.src.match(/bkscript\.js\.php$/)){ return 'INVALID'; //or v1 but that should no longer be in use } return 'UNKNOWN'; }, addBeforeInit: function (js) { BookingKitApp.logger("addBeforeInit"); this.beforeInitCode += ";" + js; }, beforeInit: function () { BookingKitApp.logger("beforeInit"); this.pickUpSession(); eval(this.beforeInitCode); this.beforeInitCode = ""; //add scrollstopper var $body = jQuery("body"); this.cartSpacer = jQuery('
'); $body.append(this.cartSpacer); //check support for css this.checkCssSupport($body); }, insertBkContent: function (data, targetId) { BookingKitApp.logger('insertBkContent'); var target = document.getElementById(targetId); if (target) { document.getElementById(targetId).innerHTML = data.html; if (targetId == 'bookingKitContainer'){ BookingKitApp.trackProducts() } } if (jQuery('#bookingKitContainer').width() < 550){ if (jQuery('#bookingKitContainer .bk-detail-content .bk-date-btn:visible').length > 0 && BookingKitApp.pos_top == 0){ var $stickyButton = jQuery('#bk-sticky-btn'); if($stickyButton.length === 0){ //add sticky button $stickyButton = jQuery('.bk-scroll-to-choose-date').first().clone().prop('id','bk-sticky-btn') jQuery('.bk-detail-content').first().append($stickyButton); } var offset = parseInt($stickyButton.css('border-top-width')); BookingKitApp.pos_top = jQuery('#bookingKitContainer .bk-detail-content .bk-date-btn:visible').offset().top - offset; jQuery(window).scroll(function () { if (BookingKitApp.documentScrollTimer) { clearTimeout(BookingKitApp.documentScrollTimer); // clear any previous pending timer } BookingKitApp.documentScrollTimer = setTimeout(function(){ BookingKitApp.handleWindowScrollEvent()}, 10); // set new timer }); } } }, skipHashNavigation: false, updateHashNavigation: function (el) { BookingKitApp.logger("updateHashNavigation"); BookingKitApp.skipHashNavigation = true; var url = el.getAttribute("href"); try{ var hash = url.split('#').pop(); hash = hash.replace(/\!\//, ''); if (hash) { window.location.hash = "!/" + hash; } setTimeout("BookingKitApp.skipHashNavigation = false;", 200); bkScrollToElement(document.getElementById('bookingKitContainer')); BookingKitApp.initControls(el); }catch (e) { BookingKitApp.logger('failed to update hash navigation') } }, getHashNavigation: function () { BookingKitApp.logger("getHashNavigation"); var hash = window.location.hash; var hashNav = { path: null, query: null }; if (hash) { var navString = hash.replace(/#\!\/|#/, "").split("?"); hashNav.path = navString[0].split("/"); //historically we dropped navigation with a single path if(hashNav.path.length < 2){ hashNav.path = null; } if(navString.length > 1) { hashNav.query = {}; var query = navString[1].split("&"); for (var i = 0; i < query.length; i++) { var pair = query[i].split("="); hashNav.query[pair[0]] = pair[1] || null; } } } return hashNav; }, clearHashNavigation: function () { BookingKitApp.logger("clearHashNavigation"); BookingKitApp.skipHashNavigation = true; window.location.hash = ""; }, tabDownListener: function (e) { if (e.key === 'Tab') { e.preventDefault(); const activeEl = window.document.activeElement; const activeElName = activeEl?.attributes?.getNamedItem('rel')?.value if(activeElName === 'continueShopping'){ if(e?.shiftKey){ $("[rel=closeIframe]").focus(); return; } requestAnimationFrame(() => {document.getElementById('bkIframe')?.contentWindow?.focus()}); return; } if(activeElName === 'closeIframe'){ if(e?.shiftKey){ requestAnimationFrame(() => {document.getElementById('bkIframe')?.contentWindow?.focus()}); return; } $("[rel=continueShopping]").focus(); return; } if(e?.shiftKey){ $("[rel=continueShopping]").focus(); } else{ document.getElementById('bkIframe')?.contentWindow?.focus(); } } }, focusContinueShopping: function(){ requestAnimationFrame(() => $("[rel=closeIframe]").focus()); }, startCheckoutFocusTrap: function(){ window.addEventListener('keydown', this.tabDownListener); window.addEventListener('focus',this.focusContinueShopping); }, stopCheckoutFocusTrap: function(){ window.removeEventListener('keydown', this.tabDownListener); window.removeEventListener('focus',this.focusContinueShopping); }, hashChange: function () { BookingKitApp.logger("hashChange"); BookingKitApp.resetRef(); if (!BookingKitApp.skipHashNavigation) { var hashNav = BookingKitApp.getHashNavigation(); var url = BookingKitApp.BaseUrl; var targetId = 'bookingKitContainer'; var customWidgetParam = ''; if (BookingKitApp.customWidget != ''){ customWidgetParam = "&cw=" + BookingKitApp.customWidget; } if (hashNav.path) { switch (hashNav.path[0]) { case "e": var eventIdent = (BookingKitApp.eventIdent !== null ? BookingKitApp.eventIdent : hashNav.path[1] ); if (eventIdent != ''){ url = BookingKitApp.EventUrl + "&e=" + eventIdent + customWidgetParam; } break; case "v": url = BookingKitApp.ListUrl + "&v=" + hashNav.path[1]; break; case "d": url = BookingKitApp.ListByDateUrl + "&date=" + hashNav.path[1] + customWidgetParam ; break; case "cal-d": url = BookingKitApp.CustomGridUrl + "&date=" + hashNav.path[1]; break; case "offers": url = BookingKitApp.ListOffers ; break; case "o": if (BookingKitApp.customWidget == '' && hashNav.path[3] != ''){ customWidgetParam = "&cw=" + hashNav.path[3]; } url = BookingKitApp.OfferUrl + "&o=" + hashNav.path[1] + customWidgetParam ; break; } } BookingKitApp.loadBkPageFallback(url, targetId, 'initExtWidgets'); } }, resetRef: function(){ BookingKitApp.logger("resetRefParam"); this.Ref = this.EmbedRef; }, captureInsight: function (eventName, additionalParams) { if (typeof posthog !== 'undefined') { posthog.capture(eventName, additionalParams); } }, captureClickInsight: function ($trackable) { try { if(typeof $trackable.data('insights-name') === 'undefined') { return; } var context = $trackable.data('insights-context') || 'widget_no_context'; var componentName = context + '.' + $trackable.data('insights-name'); var eventProperties = $trackable.data('insights-params') || {}; eventProperties['element'] = componentName; eventProperties['Page Name'] = document.title; BookingKitApp.captureInsight('click', eventProperties); } catch (e) { BookingKitApp.logger(e); } }, /*@deprecated*/ trackEvent: function (category, action, label, nonInteraction) { try{ BookingKitApp.captureInsight(action, {category: category, label: label}) }catch (e){ BookingKitApp.logger(e); } BookingKitApp.logger("trackEvent"); category = category || null; action = action || null; label = label || null; nonInteraction = nonInteraction || null; var dataEvent = {}; if (nonInteraction){ dataEvent = { nonInteraction: true }; } if (category && action) { BK_ga('bkTracker.send', 'event', category, action, label, dataEvent); } }, forwardToGA: function(){ BK_ga.apply(BK_ga, arguments); }, trackProducts: function () { BookingKitApp.logger("trackProducts"); if (typeof BK_ga == "function") { var page = 'widget/detail'; var title = 'Widget - Event Detail'; if (jQuery(".detailGaData").length > 0) { BookingKitApp.trackProduct("ec:addProduct", jQuery(".detailGaData")); BK_ga('bkTracker.ec:setAction', 'detail'); } if (jQuery(".listGaData").length > 0) { BookingKitApp.trackProduct("ec:addImpression", jQuery(".listGaData")); page = BookingKitApp.isListEventByDatePage()?'widget/list_by_date':'widget/list'; title = BookingKitApp.isListEventByDatePage()?'Widget - Event calender list':'Widget - Event list'; } BK_ga('bkTracker.send', 'pageview',{'page':page,'title':title}); } }, trackProduct: function (ga_function, $dataObjs, once) { BookingKitApp.logger("trackProduct"); once = once || false; $dataObjs.each(function (index, el) { var $dataObj = jQuery(el); var gaData = {}; jQuery.each($dataObj.data(), function (prop, data) { if (prop.substr(0, 2) == "ga") { gaData[prop.substr(2)] = data; } }); BK_ga("bkTracker." + ga_function, gaData); if (once) { //to make sure we only track once per load //we'll just remove the data from the dome $dataObj.remove(); } }); }, getNavigator: function () { BookingKitApp.logger("getNavigator"); //disabled for now var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (/trident/i.test(M[1])) { tem = /\brv[ :]+(\d+)/g.exec(ua) || []; return 'IE ' + (tem[1] || ''); } if (M[1] === 'Chrome') { tem = ua.match(/\bOPR\/(\d+)/); if (tem != null) return 'Opera ' + tem[1]; } M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?']; if ((tem = ua.match(/version\/(\d+)/i)) != null) M.splice(1, 1, tem[1]); return M.join(' '); }, addToCart: function ($el, e) { BookingKitApp.logger("addToCart"); var el = $el.get(0); //open add cart dialog var url = el.href; params = { url:window.location.href }; if (this.template) { params.t = this.template; } //track homepage url = this.appendUrlParam(url, params); this.lightbox(url); //track action BookingKitApp.trackProduct("ec:addProduct", $el); BK_ga('bkTracker.ec:setAction', 'add'); //BK_ga('bkTracker.send', 'event', 'UX', 'click', 'add to cart'); }, checkBkRefParameter: function () { try { //bkref param in url will overwrite the referrer var url = window.top.location.pathname + window.top.location.search; var refParam = this.getQueryParameter(url, 'bkref') if (refParam){ BookingKitApp.logger("checkBkRefParameter - refParam", refParam); this.Ref = refParam; this.EmbedRef = refParam; } var bklinkParam = this.getQueryParameter(url, 'bklink'); var bklinkStorage = this.clientStorage(60*60*24*14); if (bklinkParam){ BookingKitApp.logger("checkBkRefParameter - bklink", bklinkParam); this.BKLink = bklinkParam; bklinkStorage.set('bklink', bklinkParam); } else { this.BKLink = bklinkStorage.get('bklink'); } } catch (e) { return false; } }, appendUrlParam: function (url, param) { BookingKitApp.logger("appendUrlParam"); var concatenator = url.indexOf("?") >= 0 ? "&" : "?"; var str = []; //add session id param.sid = this.BKSessionId; for (var p in param) if (param.hasOwnProperty(p)) { str.push(encodeURIComponent(p) + "=" + encodeURIComponent(param[p])); } //preview function for versioning, remove when not in use if(this.overrideVersion){ str.push('bkwv='+this.overrideVersion); } //split the fragment from the url var parts = url.split("#"); var fullUrl = parts[0] + concatenator + str.join("&") + (parts[1] ? "#" + parts[1] : ""); try{ var linker = new window.gaplugins.Linker(BK_ga.getByName('bkTracker')); return linker.decorate(fullUrl); }catch (e){ } return fullUrl; }, handleHashQuery: function (key, value) { switch (key) { case this.CheckoutSuccessHashParam: var url = BookingKitApp.CheckoutContinueUrl; url = this.appendUrlParam(url, {'token': value, 'rd': 0}) BookingKitApp.lightbox(url,null,{ allowMobileRedirect: false, closeOnBackdropClick: false, beforeClose: function(){ return true; }, afterClose: function(){ //drop the hash query var hashNav = BookingKitApp.getHashNavigation(); var newHash = hashNav.path ? "#!/" + hashNav.path.join("/"): ''; window.location.hash = newHash; BookingKitApp.initControls(); } }); return true; break; default: break; } return false; }, loadBkPageFallback: function (url, targetId, callback, el) { BookingKitApp.logger("loadBkPageFallback"); var originalUrl = url; var hashNav = BookingKitApp.getHashNavigation(); var functName = callback; callback = {}; callback[functName] = el;//process the hash query if (hashNav.query) { var handleSuccess = true; for (var key in hashNav.query) { handleSuccess = handleSuccess && BookingKitApp.handleHashQuery(key, hashNav.query[key]); } if(handleSuccess){ return //do not load the page if we handled the hash query } } if (hashNav.path) { //if we have a valid hashtag navigation remove models from url url = url.replace(/(\?|\&)(v|e)\=([^&|\s]+)/g, ""); //add correct path (events || detail) switch (hashNav.path[0]) { case "e": if (hashNav.path[1] != ''){ url = url.replace(/onPage\/([a-zA-Z]+)\//g, "onPage/detail/"); this.vendor = this.vendor || this.getQueryParameter(originalUrl, 'v'); if (this.vendor) { url = this.appendUrlParam(url, {'v':this.vendor}); } else if(BookingKitApp.eventIdent !== null) { url = this.appendUrlParam(url, {'e':BookingKitApp.eventIdent}); } } break; case "v": url = url.replace(/onPage\/([a-zA-Z]+)\//g, "onPage/events/"); break; case "d": url = originalUrl.replace(/onPage\/([a-zA-Z]+)\//g, "onPage/eventsByDate/"); hashNav.path[0] = 'date'; break; case "cal-d": url = originalUrl.replace(/onPage\/([a-zA-Z]+)\//g, "onPage/calGrid/"); hashNav.path[0] = 'date'; break; case "vouchers": url = BookingKitApp.VoucherList; break; case "offers": url = BookingKitApp.ListOffers ; break; case "o": url = BookingKitApp.OfferUrl ; break; } //then add the hash navigation if (BookingKitApp.eventIdent === null) { var getChar = url.indexOf("?") >= 0 ? "&" : "?"; url += getChar + hashNav.path[0] + "=" + hashNav.path[1]; if (hashNav.length > 2) { if (hashNav.length > 3){ if(url.match(hashNav.path[2]) === null){ //do not overwrite params url += '&' + hashNav.path[2] + "=" + hashNav.path[3]; } } callback["doClick"] = hashNav.path[2]; } } } this.loadBkPage(url, targetId, callback, el); }, loadBkPage: function (url, targetId, callback, el) { BookingKitApp.logger("loadBkPage"); var targetId = targetId || 'bookingKitContainer'; var delay = 1; if (el && !(el instanceof jQuery) && el.hasAttribute('data-loader-target')) { delay = 500; var target = document.getElementById(el.getAttribute('data-loader-target')); target.innerHTML = '
'; } var bkScript = document.createElement('script'); var concatenator = url.indexOf("?") >= 0 ? "&" : "?"; bkScript.type = "text/javascript"; bkScript.id = "script_" + targetId; var params = { targetId: targetId, browserlang: this.browserLanguage, url: encodeURIComponent(window.location.href) } if (this.template) { params.t = this.template; } this.vendor = this.vendor || this.getQueryParameter(url, 'v'); if (this.vendor) { params.v = this.vendor; } var src = this.appendUrlParam(url, params); if(!BookingKitApp.Ref) { BookingKitApp.Ref = this.getQueryParameter(url, 'ref'); } if (BookingKitApp.Ref) { src += "&ref=" + BookingKitApp.Ref; } if (BookingKitApp.BKLink) { src += "&bklink=" + BookingKitApp.BKLink; } if (Object.prototype.toString.call(BookingKitApp.saleParams) == "[object Object]" && Object.keys(BookingKitApp.saleParams).length > 0) { Object.keys(BookingKitApp.saleParams).forEach(function (key) { if (!isNaN(key)) { if (!src.indexOf('&sale_params[]=' + BookingKitApp.saleParams[key]) >= 0) { src += '&sale_params[]=' + BookingKitApp.saleParams[key]; } } else { src += '&sale_params[' + key + ']=' + BookingKitApp.saleParams[key]; } }); } setTimeout(function () { bkScript.src = src; document.body.appendChild(bkScript); bkScript.onload = function () { if (callback) { if (typeof callback !== "object") { var functName = callback; callback = {}; callback[functName] = el; } jQuery.each(callback, function (funcName, params) { if (typeof BookingKitApp[funcName] == "function") { if(Array.isArray(params)){ BookingKitApp[funcName].apply(BookingKitApp, params); return; } BookingKitApp[funcName](params); } }); } if(targetId === 'bookingKitContainer' && window.postMessage && typeof url === 'string' && url.indexOf('checkout2') < 0){ window.postMessage('bk_script_inserted_content','*'); } if(targetId === 'bk-ev-grid_ct' && window.postMessage && typeof url === 'string'){ window.postMessage('bk_script_inserted_calendar_content','*'); } //clean up after thyself jQuery(this).remove(); }; }, delay); }, getCallBack: function(el){ BookingKitApp.logger("getCallBack"); var callback_string = el.getAttribute("data-callback") || null; var callbacks = {}; if(callback_string){ var functions = callback_string.split(","); for(var i=0; i 2) { hashNav.path.splice(2, 1); //third key is the "doClick" key this.skipHashNavigation = true; newHash = "#!/" + hashNav.path.join("/"); window.location.hash = newHash; this.skipHashNavigation = false; } } }, checkoutShouldBeOpenedAsATab() { // Not already an iframe return window?.self !== window?.top || location?.protocol !== 'https:'; }, updateIframeState: function (controller, action, version, language, test) { BookingKitApp.logger("updateIframeState"); language = language || false; if (language){ this.lang = language; } if (jQuery('#bookingKitContainer').length && jQuery('#bookingKitContainer').width() < 700 && BookingKitApp.mobilecheck()){ jQuery('a[rel="closeIframe"]').show(); } else { jQuery('a[rel="closeIframe"]').show(); jQuery('.bk-close-btn').attr('tabindex', '0'); switch (action) { case "addToCart": case "index": case "success": case "inLeadTime": jQuery('a[rel="continueShopping"]').fadeIn("fast", function () { jQuery('a[rel="continueShopping"]').attr("style", ""); }); break; default: jQuery('a[rel="continueShopping"]').fadeOut("fast"); break; } if (action == 'addToCart' || action == 'success' || action == 'inLeadTime') { jQuery('.bk-close-btn').removeClass('detail'); } else if (action == 'error') { jQuery('.bk-close-btn').addClass('med'); } else { jQuery('.bk-close-btn').addClass('detail'); } } //update "Continue Button" text jQuery('[rel=continueShopping]').html(this._t("continue shopping")); }, redirectTo: function (url) { BookingKitApp.logger("redirectTo"); window.location = BookingKitApp.appendUrlParam(url,[]); }, addDefaultJquery: function () { BookingKitApp.logger("addDefaultJquery"); var bkJqueryScript = document.createElement('script'); var head = document.getElementsByTagName("head")[0] || document.documentElement; bkJqueryScript.type = "text/javascript"; bkJqueryScript.src = "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"; var done = false; bkJqueryScript.onload = bkJqueryScript.onreadystatechange = function () { if (!done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { done = true; //execute on load BookingKitApp.jQVersion = jQuery.fn.jquery; jQuery.noConflict(); initBk(); // Handle memory leak in IE bkJqueryScript.onload = bkJqueryScript.onreadystatechange = null; if (head && bkJqueryScript.parentNode) { head.removeChild(bkJqueryScript); } } }; head.insertBefore(bkJqueryScript, head.firstChild); }, docIsReady: false, docReady: function () { BookingKitApp.logger("docReady"); if (BookingKitApp.docIsReady) { return false; } BookingKitApp.docIsReady = true; if (!window.jQuery) { window.bkBreakEndlessLoop = -5; if ((typeof window.Muse !== "undefined" || typeof window.requirejs !== "undefined")) { //quick and ugly for requirejs //wait for requirejs and for Muse builder var jQueryLoaded = setInterval(function () { window.bkBreakEndlessLoop++; if (typeof window.jQuery != "undefined") { clearInterval(jQueryLoaded); //execute on load BookingKitApp.jQVersion = jQuery.fn.jquery; if(!BookingKitApp.hasRequiredOfjQuery()) { BookingKitApp.addDefaultJquery(); }else{ initBk(); } } else if (window.bkBreakEndlessLoop >= 0) { clearInterval(jQueryLoaded); BookingKitApp.addDefaultJquery(); } }, 500); } else { //load our own BookingKitApp.addDefaultJquery(); } } else { jQuery(document).ready(function () { BookingKitApp.jQVersion = jQuery.fn.jquery; if(!BookingKitApp.hasRequiredOfjQuery()) { BookingKitApp.addDefaultJquery(); }else{ initBk(); } }); } }, readyStateChange: function () { BookingKitApp.logger("readyStateChange"); if (document.readyState === "complete") { this.docReady(); } }, internalLinkClick: function (event, element) { BookingKitApp.logger("internalLinkClick"); event.preventDefault(); var callback = BookingKitApp.getCallBack(element); BookingKitApp.loadBkPage(element.getAttribute("data-href"), element.getAttribute("data-targetId"), callback, element); return false; }, cartLinkClick: function (event, element) { BookingKitApp.logger("cartLinkClick"); var $element = jQuery(element); var action = BookingKitApp.getDataAttribute("action", $element); if (action && typeof(BookingKitApp[action]) == "function" && BookingKitApp.lbLinkTarget != 'blank') { event.preventDefault(); BookingKitApp[action]($element, event); return false; } }, hasRequiredOfjQuery: function(){ return BookingKitApp.hasMinJQueryVersion() && BookingKitApp.checkRequiredOfjQuery(); }, checkRequiredOfjQuery : function() { var $body = jQuery("body"); if($body.length == 0){ return false; } for(var i = 0; i < BookingKitApp.requiredJqueryFunctions.length; i++) { if( typeof $body[BookingKitApp.requiredJqueryFunctions[i]] !== 'function'){ return false; } } return true; }, hasMinJQueryVersion: function () { if(typeof BookingKitApp.jQVersion != 'string'){ //we don't know, safer to load return false; } var curParts = BookingKitApp.jQVersion.split('.'); var minParts = BookingKitApp.minJqVersion.split('.'); for (var i = 0; i < minParts.length; ++i) { minParts[i] = parseInt(minParts[i]); curParts[i] = parseInt(curParts[i]); if (curParts.length == i) { return true; } if (minParts[i] == curParts[i]) { continue; } else if (minParts[i] < curParts[i]) { return true; } else { return false; } } return true; }, attachListeners: function (scope) { BookingKitApp.logger("attachListeners"); scope = scope || '#bookingKitContainer'; var $scope = jQuery(scope); jQuery($scope).on("click", '*', function (e) { var $target = jQuery(this); BookingKitApp.captureClickInsight($target); if ($target.is('a[rel="bkIntLink"]')) { e.stopImmediatePropagation(); return BookingKitApp.internalLinkClick(e, this); } if ($target.is('a[rel="bkLbLink"]')) { return BookingKitApp.cartLinkClick(e, this); } if ($target.is('a[rel=".bk-scroll-to-cal"]')) { bkScrollToCal(); e.stopImmediatePropagation(); return false; } if ($target.is('.bk-scroll-to-choose-date')) { e.preventDefault(); bkScrollToChooseDate(); return false; } // CORE2-1393/CORE2-1501: AvailableSlotsFilterCalendar: if ($target.is('#available_spots_filter_checkbox')) { return BookingKitApp.filterExperienceColumns($target); } }); // Create IE + others compatible event handler var messageEvent = (window.addEventListener ? "addEventListener" : "attachEvent") == "attachEvent" ? "onmessage" : "message"; // Listen to message from child window jQuery(window).off(messageEvent).on(messageEvent, function (event) { if (typeof event.originalEvent != 'undefined' && typeof event.originalEvent.data != 'undefined' && typeof event.originalEvent.data.action != 'undefined' && typeof BookingKitApp[event.originalEvent.data.action] != 'undefined') { var params = event.originalEvent.data.params != 'undefined' ? event.originalEvent.data.params : []; BookingKitApp[event.originalEvent.data.action].apply(BookingKitApp, params); } }); jQuery($scope).on("mousedown", 'a', function (e) { var link = jQuery(e.target).closest('a').get(0); if(!link.href){ return } if(link.href.slice(0, BookingKitApp.CheckoutDomain.length) !== BookingKitApp.CheckoutDomain){ return; } link.href = BookingKitApp.appendUrlParam(link.href,[]); }); }, getScrollParent: function (element, includeHidden, includeAuto) { BookingKitApp.logger("getScrollParent"); var style = getComputedStyle(element); includeAuto = includeAuto || false; var excludeStaticParent = style.position === "absolute"; var overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : (includeAuto ? /(auto|scroll)/ : /scroll/); // /(auto|scroll)/; if (style.position === "fixed") return window; for (var parent = element; (parent = parent.parentElement);) { if(parent.tagName.toLocaleUpperCase() == "BODY"){ return window; } style = getComputedStyle(parent); if (excludeStaticParent && style.position === "static") { continue; } if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)){ return parent; } } return window; }, openLanguageDialog: function () { BookingKitApp.logger("openLanguageDialog"); jQuery('.bk-header-languages').toggle(); var $parent = jQuery('.bk-header-languages').prev('.bk-header-language-container'); $parent.attr('aria-expanded', true); }, closeMenus: function (e) { BookingKitApp.logger("closeMenus"); handleCalendarClosing('bk-detail-choose-date-title', 'bk-header-calendar-container'); var container_calendar = jQuery('.bk-header-calendar-container'); var validate = true; if (container_calendar.length && jQuery(e.target).closest('.bk-header-calendar-container').length === 0) { container_calendar.hide(); jQuery('.bk-detail-choose-date-title').attr('aria-expanded', false); container_calendar.html(''); } else { //click on the calendandar validate = false; } var container_languages = jQuery('.bk-header-languages'); if (container_languages.length && jQuery(e.target).closest('.bk-header-languages').length === 0) { container_languages.hide(); var $parent = container_languages.prev('.bk-header-language-container'); $parent.attr('aria-expanded', false); } var container_dates= jQuery('.bk-detail-bookingdates'); if (container_dates.length && jQuery(e.target).closest('.bk-detail-bookingdates').length === 0) { handleCalendarClosing('bk-detail-pick-time-slot-title', 'bk-detail-bookingdates'); container_dates.hide(); } else { //click on the list of dates validate = false; } if (validate){ BookingKitApp.validateFormWidget(); } }, selectCalendarTimeFilter: function (e) { const allElements = document.querySelectorAll('.bk-edli'); if( jQuery('#time-filter-btn-'+e).attr('class')?.includes('select')) { jQuery('#time-filter-btn-'+e).removeClass('select'); allElements.forEach((el) => { el.style.display = ''; }); } else { jQuery('.time-filter-btn').removeClass('select'); jQuery('#time-filter-btn-'+e).addClass('select'); allElements.forEach((el) => { const eventTime =el.dataset.eventTime.split(':'); const timeInMin = Number(eventTime?.[0]) * 60 + Number(eventTime?.[1]) if(e === 'morning') { if(timeInMin <= 720){ el.style.display = ''; } else { el.style.display = 'none'; } } if(e === 'afternoon') { if(timeInMin > 720 && timeInMin <= 1080){ el.style.display = ''; } else { el.style.display = 'none'; } } if(e === 'evening') { if(timeInMin > 1080){ el.style.display = ''; } else { el.style.display = 'none'; } } }); } }, filterExperienceColumns() { const checkbox = document.getElementById('available_spots_filter_checkbox'); if (!checkbox) { return; } const experienceColumns = Array.from( document.getElementsByClassName('bk-edl') ).filter( element => !element.classList.contains('no-availabilities-in-calendar') ); const noAvailabilitiesMessages = Array.from( document.getElementsByClassName('no-availabilities-in-calendar') ); experienceColumns.forEach(function (experienceColumn, experienceColumnIndex) { const dates = Array.from( experienceColumn.querySelectorAll('.bk-edli') ); let numberOfDates = dates.length; dates.forEach(function (date) { // there should be just one in each date: const anchor = date.querySelector('a'); if (anchor && anchor?.classList?.contains('disabled')) { if (checkbox.checked) { date.style.display = 'none'; numberOfDates--; } else { date.style.display = 'block'; numberOfDates++; } } }); if (noAvailabilitiesMessages[experienceColumnIndex] !== undefined) { if (checkbox.checked && numberOfDates === 0) { noAvailabilitiesMessages[experienceColumnIndex].removeAttribute('hidden'); } else { noAvailabilitiesMessages[experienceColumnIndex].setAttribute('hidden', 'hidden'); } } }); }, resizeDates: function(){ BookingKitApp.logger("resizeDates"); jQuery('.bk-detail-bookingdates').each(function () { $eventDateContainer = jQuery(this); if ($eventDateContainer.height()){ $eventDateContainer.css('max-height',''); $eventDateContainer.removeClass('scrollable'); var top = $eventDateContainer.parent().position().top + $eventDateContainer.parent().height(); var margin = 60; var footer_height = jQuery('#bkCartBar').height(); var height = parseInt(jQuery(window).height() - top - footer_height - margin); height = height > 250 ? height : 250; var myHeight = $eventDateContainer.height(); if (myHeight >= height) { $eventDateContainer.css('max-height' , height + 'px'); $eventDateContainer.addClass('scrollable'); } else { $eventDateContainer.css('max-height','auto'); $eventDateContainer.removeClass('scrollable'); } } }); }, selectDateDetail : function (e){ BookingKitApp.logger("selectDateDetail"); this.closeMenus(e); this.resizeDates(); var select_time = false; jQuery('.on-select-event-date-show').hide(); if (typeof BookingKitApp.getDataAttribute('day-text', jQuery(e)) !== 'undefined'){ // coming from the calendar var day_text = e.getAttribute('data-day-text'); var day_date = e.getAttribute('data-date'); var day_url = e.getAttribute('data-href'); jQuery('[name=event_date]').val(day_url); jQuery('.bk-detail-choose-date-title span.text').html(day_text); jQuery('[name=date]').val(day_date); BookingKitApp.resetButton('.bk-detail-pick-time-slot-title'); $container_timeslots = jQuery('#' + e.getAttribute('data-targetid')); if ($container_timeslots.find('#bookingKitContainer_inner:not(.bk-flexible-duration) .bk-detail-bookingdates-item').length == 1){ select_time = true; } } jQuery('.on-select-date-show').show(); jQuery('.bk-detail-choose-date-title').addClass("ok"); jQuery('.bk-detail-choose-date-title').removeClass("wrong"); jQuery('.bk-detail-pick-time-slot-title').addClass('on'); if (select_time) { $container_timeslots.find('.bk-detail-bookingdates-item-active').click(); } else { jQuery('.bk-detail-bookingdates').show(); } jQuery('.bk-date-btn').each(function () { var btn = jQuery(this); var href = BookingKitApp.getDataAttribute('href', btn); if (typeof href !== 'undefined' && jQuery('[name=date]').val() != '') { var d = new Date(jQuery('[name=date]').val()); if (!isNaN(d.getTime())) { var params = {'date': jQuery('[name=date]').val(), 'month': d.getMonth() + 1, 'year' : d.getFullYear()}; href = BookingKitApp.appendUrlParam(href, params); btn.data('href', href); btn.attr('data-href', href); } } }); if (jQuery('.bk-detail-bookingdates .selected').length) { jQuery('[name=event_date_id]').val(BookingKitApp.getDataAttribute('event-date-id', jQuery('.bk-detail-bookingdates .selected'))); } }, displayCalendar: function (e){ BookingKitApp.logger("displayCalendar"); handleCalendarDisplay(e); jQuery('.bk-detail-content .bk-date-btn').addClass('off'); jQuery('.bk-header-calendar-container').show(); jQuery('.bk-detail-choose-date-title').addClass('on'); jQuery('.bk-detail-bookingdates').hide(); var $document = jQuery("html, body"); var currentScroll = $document.scrollTop() var viewport = jQuery(window).height() + currentScroll var end_calendar = jQuery('.bk-header-calendar:visible').offset().top + jQuery('.bk-header-calendar:visible').outerHeight(); var newScroll = null; if(BookingKitApp.pos_top && BookingKitApp.pos_top < currentScroll){ newScroll = BookingKitApp.pos_top } if( end_calendar > viewport ){ var space = 20; newScroll = $document.scrollTop() + (end_calendar - viewport) + space; } if(newScroll !== null){ $document.stop().animate({scrollTop:newScroll},'fast'); } }, selectEventDateDetail : function (obj){ BookingKitApp.logger("selectEventDateDetail"); var obj = jQuery(obj); var display_free_seats = BookingKitApp.getDataAttribute('display-free-seats', obj) == 1; var event_date_id = BookingKitApp.getDataAttribute('event-date-id', obj); var event_text = BookingKitApp.getDataAttribute('event-text', obj); var event_class = BookingKitApp.getDataAttribute('event-class', obj); var event_free = BookingKitApp.getDataAttribute('event-free', obj); var alert_icon = BookingKitApp.getDataAttribute('alert-icon', obj); var alert_text = BookingKitApp.getDataAttribute('alert-text', obj); if (!obj.parents('.bk-flexible-duration').length) { this.closeMenus(obj); } jQuery('.on-select-event-date-show').show(); jQuery('.bk-detail-pick-time-slot-title span.text').html(event_text); jQuery('.bk-detail-pick-time-slot-title').addClass("ok"); jQuery('.bk-detail-pick-time-slot-title').removeClass("wrong"); if (alert_icon != '' && alert_text != ""){ jQuery('.bk-detail-alert-checkout .icon').attr('src', alert_icon); jQuery('.bk-detail-alert-checkout .text').text(alert_text); jQuery('.bk-detail-alert-checkout').show(); } else { jQuery('.bk-detail-alert-checkout .icon').attr('src', ''); jQuery('.bk-detail-alert-checkout .text').text(''); jQuery('.bk-detail-alert-checkout').hide(); } jQuery('[name=event_date_id]').val(event_date_id); var inLeadTime = BookingKitApp.getDataAttribute('in-lead-time', obj); jQuery('[name=in_lead_time]').val(inLeadTime); jQuery('.bk-detail-go-checkout').each(function (index){ var $btn = jQuery(this); var href = BookingKitApp.getDataAttribute("base-href", $btn); $btn.data('ident',event_date_id); href = href.replace('EVENT_DATE_ID', event_date_id); if (inLeadTime){ href = href.replace('addToCart', 'inLeadTime'); } $btn.attr("href", href); }); BookingKitApp.trackEvent('widget.v2', 'selectEventDateDetail'); BookingKitApp.validateFormWidget(); }, resetButton : function (id_obj){ BookingKitApp.logger("resetButton"); var object = jQuery(id_obj); jQuery(id_obj + ' span.text').html(BookingKitApp.getDataAttribute('default-text', object)); jQuery('[name=' + BookingKitApp.getDataAttribute('input-name', jQuery(id_obj)) + ']').val(''); object.removeClass('ok'); object.removeClass('wrong'); // handle aria-expanded attribute if (id_obj === '.bk-detail-pick-time-slot-title' || object.attr('aria-expanded') === 'false') { handleSlotSelect(object); } }, reloadEventDates : function (element){ BookingKitApp.logger("reloadEventDates"); var url = jQuery('[name=event_date]').val(); var target = jQuery(element).next('.bk-detail-bookingdates').attr('id'); var callback = 'selectDateDetail'; if (url != ''){ BookingKitApp.loadBkPage(url, target, callback, element); } }, validateFormWidget : function (){ BookingKitApp.logger("validateFormWidget"); /**** validation widget ****/ var bt_make_a_booking = jQuery('.bk-detail-choose-date-title'); var bt_pick_a_date = jQuery('.bk-detail-pick-time-slot-title'); var event_date_ok = jQuery('[name=event_date]').val() != ''; var event_date_id_ok = jQuery('[name=event_date_id]').val() != ''; var error = false; if (bt_make_a_booking.hasClass('on') && !event_date_ok){ bt_make_a_booking.addClass("wrong"); jQuery('.bk-detail-error-date').show(); error = true; } if (bt_pick_a_date.hasClass('on') && !event_date_id_ok){ bt_pick_a_date.addClass("wrong"); jQuery('.bk-detail-error-date').show(); error = true; } if (!error){ jQuery('.bk-detail-error-date').hide(); } }, afterChangeLanguage : function (){ BookingKitApp.logger("afterChangeLanguage"); BookingKitApp.setSelectedLanguage(); //check if the description is overflowed if (jQuery('.bk-detail-desc-compress').length && jQuery('.bk-detail-desc-compress').get(0).scrollHeight <= jQuery('.bk-detail-desc-compress').innerHeight()) { jQuery('.bk-detail-desc').removeClass('bk-detail-desc-compress'); jQuery('.bk-detail-desc-read-more').hide(); } jQuery('.bk-header-languages').hide(); if ( jQuery('.calendar-day-number a').length ) { jQuery('.calendar-day-number a').get(0).click(); } BookingKitApp.initExtWidgets(); }, parseUrl: function(url){ BookingKitApp.logger("parseUrl"); var urlParams = {}; url.replace( new RegExp("([^?=&]+)(=([^&]*))?", "g"), function($0, $1, $2, $3) { urlParams[$1] = $3; } ); return urlParams; }, getQueryParameter: function(url, param){ BookingKitApp.logger("getQueryParameter"); var parsedUrl = this.parseUrl(url); if (typeof parsedUrl[param] !== 'undefined') { return parsedUrl[param]; } else { return false; } }, initExtWidgets: function () { BookingKitApp.logger("initExtWidgets"); BookingKitApp.bk_loadDates(); jQuery('.bk_ext_widget.bk_ew_loading').each(function (index,el) { var $widget_ct = jQuery(el); var initializer = $widget_ct.data('initializer'); if(typeof initializer != 'undefined'){ BookingKitApp[initializer]($widget_ct); } }); }, initTripadvisorLarge: function ($widget_ct) { BookingKitApp.logger("initTripadvisorLarge"); var url = 'https://www.tripadvisor.com/WidgetEmbed-selfserveprop?writereviewlink=false&rating=false&border=false&uniq=_bkTaLg&iswide=true&popIdx=false&nreviews=4&display_version=2'; url += '&locationId='+$widget_ct.data('locationid'); url += '&lang='+BookingKitApp.lang; var reviewScript = document.createElement('script'); reviewScript.type = "text/javascript"; reviewScript.src = url; target = window.document.body; target.appendChild(reviewScript); reviewScript.onload = function(){ window.taValidate(); $widget_ct.removeClass('bk_ew_loading'); }; }, initTripadvisorSmall: function ($widget_ct) { BookingKitApp.logger("initTripadvisorSmall"); var url = 'https://www.tripadvisor.com/WidgetEmbed-socialButtonBubbles?color=white&size=rect&display_version=2&uniq=817&lang=en_US'; url += '&locationId='+$widget_ct.data('locationid'); url += '&lang='+BookingKitApp.lang; var reviewScript = document.createElement('script'); reviewScript.type = "text/javascript"; reviewScript.src = url; target = window.document.body; target.appendChild(reviewScript); reviewScript.onload = function(){ window.taValidate(); $widget_ct.removeClass('bk_ew_loading'); }; }, initTripadvisorSmallRepeat: function ($widget_ct) { BookingKitApp.logger("initTripadvisorSmallRepeat"); var url = 'https://www.tripadvisor.com/WidgetEmbed-socialButtonBubbles?color=white&size=rect&display_version=2&uniq=817&lang=en_US'; url += '&locationId='+$widget_ct.data('locationid'); url += '&lang='+BookingKitApp.lang; var reviewScript = document.createElement('script'); reviewScript.type = "text/javascript"; reviewScript.src = url; target = window.document.body; target.appendChild(reviewScript); reviewScript.onload = function(){ window.taValidate(); jQuery('.bk-events-item').each(function (index, el) { $widget = $widget_ct.clone(); $widget.removeClass('bk_ew_loading'); var $event_location = jQuery(this).find('.bk_list_location'); $event_location.append($widget); }); $widget_ct.remove(); } }, setSelectedLanguage: function () { var selectedLang = jQuery('.bk-languages-container').data('current-language'); if (selectedLang != this.lang) { this.setLanguage(selectedLang); } }, mobilecheck: function() { var check = false; (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); return check; }, addBgScrollLock: function () { if(!jQuery('#bkBgScrollPrevent').length){ jQuery('body').wrapInner('
'); jQuery("#bkBgScrollPrevent").wrapInner('
'); } }, clientStorage: function (validityPeriod) { return { get: function (key) { if (typeof localStorage === 'undefined') { return null; } var value = localStorage.getItem(key); if (value === null) { return null; } try { value = JSON.parse(value); } catch { localStorage.removeItem(key); return null; } if (value.setAt + (validityPeriod * 1000) < Date.now()) { localStorage.removeItem(key); return null; } return value.value; }, set: function (key, value) { if (typeof localStorage === 'undefined') { return; } localStorage.setItem(key, JSON.stringify({value, setAt: Date.now()})); } } } } //add event listeners for document loaded // to be sure fire twice on dom ready and window ready if(document.readyState == "complete"){ BookingKitApp.docReady(); }else if (document.addEventListener) { document.addEventListener("DOMContentLoaded", BookingKitApp.docReady, false); window.addEventListener("load", BookingKitApp.docReady, false); } else { // must be IE 8 document.attachEvent("onreadystatechange", BookingKitApp.readyStateChange); window.attachEvent("onload", BookingKitApp.docReady); } function bkSlideImage(direction) { var $slider = jQuery('.bk-image-slider'); var count = $slider.children('li').length; if(count==1) return; var $active = $slider.children('li.bk-active-img'); if($active.length==0) { $active = $slider.children('li').first(); $active.addClass('bk-active-img'); } if(direction=='next') { if($slider.children('li').index($active)= mobileLimit: jQuery('#bookingKitContainer').removeClass("bk-portrait") break; } switch (true){ case bkWidth < mobileLimit: jQuery('#bookingKitContainer').removeClass("bk-tablet"); break; case bkWidth < 850: jQuery('#bookingKitContainer').addClass("bk-tablet"); break; } jQuery(function() { BookingKitApp.attachListeners('#bookingKitContainer'); BookingKitApp.afterInit(); }); if(jQuery.isFunction(jQuery.fn.on)) { jQuery(window).on('load', function(){ BookingKitApp.addBgScrollLock(); }); } else { jQuery(window).load(function(){ BookingKitApp.addBgScrollLock(); }); } //hash navigation if (!('onhashchange' in window)) { var oldHref = location.href; setInterval(function() { var newHref = location.href; if (oldHref !== newHref) { var _oldHref = oldHref; oldHref = newHref; BookingKitApp.hashChange.call(window, { 'type': 'hashchange', 'newURL': newHref, 'oldURL': _oldHref }); } }, 100); } else if (window.addEventListener) { window.addEventListener("hashchange", BookingKitApp.hashChange, false); } else if (window.attachEvent) { window.attachEvent("onhashchange", BookingKitApp.hashChange); } var widget_dimension = (BookingKitApp.Version == 'v.2')? 'Widget v.2' : 'Widget v.1'; BK_ga('bkTracker.set', 'dimension1', widget_dimension); } function bkInitCalWrapper() { jQuery('.bk-cal-link').click(function() { if(bkCalScript) { bkCalScript.remove(); } var bkCalScript = document.createElement('script'); bkCalScript.type = "text/javascript"; bkCalScript.src = "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"; document.getElementsByTagName('head')[0].appendChild(bkScript); return false; }); } function filterExperiences(select) { const selectedExperience = select.options[select.selectedIndex].value; const elementsToFilter = Array.from(document.querySelectorAll('.bk-events-item')); const offersSection = document.querySelector('#offers-widget'); let offersCounter = 0; // Save initial displays if (window.initialOffersDisplay === undefined && offersSection) { window.initialOffersDisplay = offersSection?.style?.display ?? ''; } if (window.initialDisplays === undefined) { window.initialDisplays = []; } // Gather them if they are not already gathered if (window.initialDisplays.length === 0) { let initialDisplays = window.initialDisplays; elementsToFilter.forEach(element => { initialDisplays.push(element.style.display); }); window.initialDisplays = initialDisplays; } // Make all visible if not filter applied if (selectedExperience === '') { elementsToFilter.forEach((element, index) => { element.style.display = window.initialDisplays[index]; // Check if an element is an offer item if (element.classList.contains('bk-offer-item')) { offersCounter++; } }); } else { // Filter elementsToFilter.forEach((element, index) => { if (element.getAttribute('id').includes(selectedExperience)) { element.style.display = window.initialDisplays[index]; // Check if an element is an offer item if (element.classList.contains('bk-offer-item')) { offersCounter++; } } else { element.style.display = 'none'; } }); } // If there are no offers, hide the whole section if (offersSection) { if (offersCounter === 0) { offersSection.style.display = 'none'; } else { offersSection.style.display = window.initialOffersDisplay; } } } function handleCalendarDisplay(e) { // A list of legit elements we want to service: const calendarChooseTitleElements = ['bk-detail-choose-date-title']; // Next sibling is the element we want to check since the function is triggered by previous one: var nextSibling = e.nextElementSibling; if (!nextSibling) { return; } // We compare the next sibling with the allowed elements list: var shouldBeUpdated = false; var elementClasses = nextSibling.classList ?? []; calendarChooseTitleElements.forEach(function (calendarChooseTitleElement) { if (elementClasses.contains(calendarChooseTitleElement)) { shouldBeUpdated = true; } }); if (!shouldBeUpdated) { return; } // we check the next sibling's aria-expanded status: const ariaExpanded = nextSibling.getAttribute('aria-expanded'); if (!ariaExpanded) { return; } // additionally we get the arrow icon: const svgs = nextSibling.querySelectorAll('svg'); var bkArrow = svgs[svgs.length - 1]; // if the aria-expanded is false, we update it and rotate the arrow: if (ariaExpanded === 'false') { bkArrow.style.transform = 'rotate(0deg)'; bkArrow.style.transition = 'transform 0.5s'; nextSibling.setAttribute('aria-expanded', 'true'); } } function handleCalendarClosing(triggerClass, calendarClass) { // we retrieve the list o calendar triggers: var bookNowCalendarTriggers = Array.from( document.getElementsByClassName(triggerClass) ); if (bookNowCalendarTriggers.length === 0) { return; } // we retrieve the list of calendars: const calendars = Array.from( document.getElementsByClassName(calendarClass) ); if (calendars.length === 0) { return; } // we check if any of those calendars is visible: var calendarIsVisible = false; calendars.forEach(calendar => { const calendarStyle = window.getComputedStyle(calendar); if (calendarStyle.display !== 'none') { calendarIsVisible = true; } }); // we check if any of the calendar triggers is visible: bookNowCalendarTriggers.forEach(triggerElement => { const triggerElementStyle = window.getComputedStyle(triggerElement); if (triggerElementStyle.display === 'none') { return; } // if yes, we get the current state of its aria-expanded: var ariaExpanded = triggerElement.getAttribute('aria-expanded'); if (!ariaExpanded) { // skip this triggerElement return; } // we get its arrow icon: const svgs = triggerElement.querySelectorAll('svg'); var bkArrow = svgs[svgs.length - 1]; // if the aria-expanded is true meaning the calendar is open by the given trigger, // we update it and rotate the arrow back: if (calendarIsVisible && ariaExpanded === 'true') { bkArrow.style.transform = 'rotate(180deg)'; bkArrow.style.transition = 'transform 0.5s'; triggerElement.setAttribute('aria-expanded', 'false'); } }); } function handleSlotSelect(trigger) { trigger.attr('aria-expanded', 'true'); // additionally we get the arrow icon: const svgs = trigger.find('svg'); var bkArrow = svgs[svgs.length - 1]; bkArrow.style.transform = 'rotate(0deg)'; bkArrow.style.transition = 'transform 0.5s'; } !function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){if(t.getElementById("bkphjs"))return;function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.id="bkphjs",p.async=!0,p.src="https://cdn-insights.bookingkit.com/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags".split(" "),n=0;n portalchampion.guru |modal/close
`;BookingKitApp.DefaultLanguage = 'en';BookingKitApp.translations = {"cs":{"booking dialog":"booking dialog","continue shopping":"Pokra\u010dovat v n\u00e1kupu","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"da":{"booking dialog":"booking dialog","continue shopping":"forts\u00e6t indk\u00f8b","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"de":{"booking dialog":"booking dialog","continue shopping":"weiter einkaufen","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"en":{"booking dialog":"booking dialog","continue shopping":"continue shopping","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"es":{"booking dialog":"booking dialog","continue shopping":"Continuar comprando","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"fr":{"booking dialog":"booking dialog","continue shopping":"continuer les achats","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"it":{"booking dialog":"booking dialog","continue shopping":"prosegui con gli acquisti","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"nl":{"booking dialog":"booking dialog","continue shopping":"doorgaan met winkelen","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"no":{"booking dialog":"booking dialog","continue shopping":"fortsett \u00e5 handle","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"fi":{"booking dialog":"booking dialog","continue shopping":"jatka ostoksia","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"sv":{"booking dialog":"booking dialog","continue shopping":"forts\u00e4tt handla","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"el":{"booking dialog":"booking dialog","continue shopping":"\u03c3\u03c5\u03bd\u03ad\u03c7\u03b9\u03c3\u03b7 \u03b1\u03b3\u03bf\u03c1\u03ce\u03bd","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"pl":{"booking dialog":"booking dialog","continue shopping":"kontynuuj zakupy","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"pt":{"booking dialog":"booking dialog","continue shopping":"continuar a fazer compras","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"zh":{"booking dialog":"booking dialog","continue shopping":"\u7ee7\u7eed\u9009\u8d2d","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"},"ja":{"booking dialog":"booking dialog","continue shopping":"\u30b7\u30e7\u30c3\u30d4\u30f3\u30b0\u3092\u7d9a\u3051\u308b","Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?":"Wollen Sie das Buchungsfenster wirklich schlie\u00dfen?"}};/** * @param bkCheckoutInitInput The object for configuring the checkout tracking * @param bkCheckoutInitInput.gtmCode The code for tracking with gtm (nullable) * @param bkCheckoutInitInput.gaCode The code for tracking with ga (nullable) * @param bkCheckoutInitInput.currentPage The current page name where this script is loading * @param bkCheckoutInitInput.events The events tp trigger after script loads * @param bkCheckoutInitInput.vendorIdent The ident of the vendor * @param bkCheckoutInitInput.listenForMessages If to add the event listener ( true for widget ) * @param bkCheckoutInitInput.ecommerceData Current checkout state (total, currency, items..) * @param bkCheckoutInitInput.ecommerceData.value Current total of the cart * @param bkCheckoutInitInput.ecommerceData.currency Current currency of the cart * @param bkCheckoutInitInput.ecommerceData.coupon Coupon applied to the order * @param bkCheckoutInitInput.ecommerceData.transactionId A transaction id if present * @param bkCheckoutInitInput.ecommerceData.tax Taxes on the cart * @param bkCheckoutInitInput.ecommerceData.items Items of the current checkout */ function BookingkitCheckoutAnalytics(bkCheckoutInitInput) { var IS_GA_PURE = !!bkCheckoutInitInput.gaCode; var DEBUG = false; function windowHasDatalayer() { return window.dataLayer && !!window.dataLayer.find(element => element && typeof element === 'object' && element['gtm.start']); } function addGTMScript(code) { try { if (window === window.parent && !windowHasDatalayer()) { ( function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'}); var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:''; j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); }) (window,document,'script','dataLayer',code); } } catch {} } function addGAScript(code) { var googleAnalyticsStandaloneScript = document.createElement('script'); googleAnalyticsStandaloneScript.src = 'https://www.googletagmanager.com/gtag/js?id='+code; googleAnalyticsStandaloneScript.async document.head.appendChild(googleAnalyticsStandaloneScript); window.dataLayer = window.dataLayer || []; window.gtag = function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', code) } function listenForEventFromParent() { window.addEventListener('message', function (e) { // event emitted when ajax iframe views are called if (e.data && e.data === 'bk_script_inserted_content') { triggerDataLayerEvent(); triggerPageViewEvent(); var peopleCheckingExperienceNowElement = document.getElementsByClassName('bk-people-checking-experience-now')[0]; var rating = document.getElementsByClassName('rating-details')[0]; if (peopleCheckingExperienceNowElement && peopleCheckingExperienceNowElement.dataset) { try { let eventDetails = JSON.parse(peopleCheckingExperienceNowElement.dataset.eventDetails); if (typeof posthog !== 'undefined') { posthog.capture('element_view', eventDetails); } } catch {} } if (rating && rating.dataset) { try { let eventDetails = JSON.parse(rating.dataset.eventDetails); if (typeof posthog !== 'undefined') { posthog.capture('element_view', eventDetails); } } catch {} } return; } if (e.data && e.data === 'bk_script_inserted_calendar_content') { triggerDataLayerEvent(); } try { var messageData = JSON.parse(e.data); if (messageData && messageData.event_source && messageData.event_source === 'bookingkit_widget') { addEventToDataLayer(messageData); } else if ( typeof posthog !== 'undefined' && messageData && messageData.action && messageData.action === 'ph_identify' ) { posthog.identify(messageData.distinct_id); } } catch {} }); } function triggerDataLayerEvent() { var dataSetElement = document.getElementById('detailed_view_info'); if (dataSetElement && dataSetElement.dataset && dataSetElement.dataset.viewDetails) { try { let eventToTrigger = JSON.parse(dataSetElement.dataset.viewDetails); addEventToDataLayer(eventToTrigger) } catch {} } } function triggerPageViewEvent() { var pageViewElement = document.getElementById('page_view_info'); if (pageViewElement && pageViewElement.dataset) { try { let pageView = pageViewElement.dataset.pageView ?? 'widget'; addPageLoadEvent(pageView); } catch {} } } function addPageLoadEvent(pageLoaded) { var analyticsEvent = { 'event': 'page_view', 'event_source': 'bookingkit_widget', 'page_title': pageLoaded }; addEventToDataLayer(analyticsEvent); } function handlePaymentProviderSelected(ecommerceData, event) { var eventToTrigger = { event: 'select_payment_provider', event_source: 'bookingkit_widget', ecommerce: { payment_provider: event.detail.payment_provider, selected_by_user: event.detail.selected_by_user, items: ecommerceData.items, value: ecommerceData.value, currency: ecommerceData.currency }, } addEventToDataLayer(eventToTrigger); } function handlePaymentMethodSelected(ecommerceData, event) { var eventToTrigger = { event: 'select_payment_method', event_source: 'bookingkit_widget', ecommerce: { payment_provider: event.detail.payment_provider ?? 'unknown', payment_type: event.detail.payment_type ?? 'unknown', selected_by_user: event.detail.selected_by_user, items: ecommerceData.items, value: ecommerceData.value, currency: ecommerceData.currency }, } addEventToDataLayer(eventToTrigger); } function handlePaymentInfoComplete(ecommerceData, event) { var eventToTrigger = { event: 'fill_payment_details', event_source: 'bookingkit_widget', ecommerce: { payment_provider: event.detail.payment_provider ?? 'unknown', payment_type: event.detail.payment_type ?? 'unknown', selected_by_user: event.detail.selected_by_user, items: ecommerceData.items, value: ecommerceData.value, currency: ecommerceData.currency }, } addEventToDataLayer(eventToTrigger); } function handlePaymentAttempt(ecommerceData, event) { var eventToTrigger = { event: 'add_payment_info', event_source: 'bookingkit_widget', ecommerce: { payment_provider: event.detail.payment_provider ?? 'unknown', payment_type: event.detail.payment_type ?? 'unknown', items: ecommerceData.items, value: ecommerceData.value, currency: ecommerceData.currency }, } addEventToDataLayer(eventToTrigger); } function handlePaymentFailed(ecommerceData, event) { var eventToTrigger = { event: 'payment_error', event_source: 'bookingkit_widget', ecommerce: { payment_provider: event.detail.payment_provider ?? 'unknown', payment_type: event.detail.payment_type ?? 'unknown', error_message: event.detail.error_message ?? 'unknown', items: ecommerceData.items, value: ecommerceData.value, currency: ecommerceData.currency }, } addEventToDataLayer(eventToTrigger); } function handlePaymentCanceled(ecommerceData, event) { var eventToTrigger = { event: 'payment_canceled', event_source: 'bookingkit_widget', ecommerce: { payment_provider: event.detail.payment_provider ?? 'unknown', payment_type: event.detail.payment_type ?? 'unknown', error_message: event.detail.error_message ?? 'unknown', items: ecommerceData.items, value: ecommerceData.value, currency: ecommerceData.currency }, } addEventToDataLayer(eventToTrigger); } function handleDisplayExpressCheckout(event) { var eventToTrigger = { event: 'display_express_checkout', event_source: 'bookingkit_widget', payment_provider: event.detail.payment_provider ?? 'unknown' }; var incomingMethods = event.detail.payment_methods; var i = 1; incomingMethods.forEach(function (methodName) { eventToTrigger[methodName] = i; i++; }); addEventToDataLayer(eventToTrigger); } function handleNoPaymentOptionsAvailable(event) { var eventToTrigger = { event: 'no_payment_options_available', event_source: 'bookingkit_widget', payment_provider: event.detail.payment_provider ?? 'unknown' }; addEventToDataLayer(eventToTrigger); } function addEventToDataLayer(event) { if (window.parent === window) { var eventPayload = event.ecommerce ?? event; if (IS_GA_PURE) { try { gtag('event', event.event, eventPayload) if(DEBUG) { console.log('GTAG', event.event, eventPayload); } } catch {} } else { window.dataLayer = window.dataLayer || []; dataLayer.push(event); if(DEBUG) { console.log('DataLayer', event); } } processEventForInsights(event.event, eventPayload); } else { var messageToParent = JSON.stringify(event); window.parent.postMessage(messageToParent, '*'); } } function processEventForInsights(eventName, eventPayload) { if (typeof posthog === 'undefined') { return; } //deep clone otherwise we modify the payload var payload = JSON.parse(JSON.stringify(eventPayload)); try { flattenEventForInsights(eventName, payload) posthog.capture(eventName, payload); if(DEBUG) { console.log('Insights', eventName, payload); } } catch (error) {} } // This function will mutate the eventPayload object function flattenEventForInsights(eventName, eventPayload) { switch (eventName) { case 'purchase': case 'add_payment_info': case 'select_payment_provider': case 'select_payment_method': case 'fill_payment_details': case 'payment_error': case 'payment_canceled': eventPayload.total_number_of_items = 0; eventPayload.total_value_of_items= 0.00; eventPayload.number_of_tickets= 0; eventPayload.value_of_tickets= 0.00; eventPayload.number_of_vouchers= 0; eventPayload.value_of_vouchers= 0.00; eventPayload.number_of_products= 0; eventPayload.value_of_products= 0.00; eventPayload.number_of_flex_tickets= 0; eventPayload.value_of_flex_tickets= 0.00; eventPayload.items.forEach(function (item) { eventPayload.total_number_of_items += item.quantity; eventPayload.total_value_of_items += parseFloat(item.price) * item.quantity; switch (item.item_category) { case 'ticket': eventPayload.number_of_tickets += item.quantity; eventPayload.value_of_tickets += parseFloat(item.price) * item.quantity; break; case 'voucher': eventPayload.number_of_vouchers += item.quantity; eventPayload.value_of_vouchers += parseFloat(item.price) * item.quantity; break; case 'product': eventPayload.number_of_products += item.quantity; eventPayload.value_of_products += parseFloat(item.price) * item.quantity; break; case 'flex-ticket': eventPayload.number_of_flex_tickets += item.quantity; eventPayload.value_of_flex_tickets += parseFloat(item.price) * item.quantity; break; } }); delete eventPayload.items; break; case 'add_to_cart': case 'remove_from_cart': eventPayload.total_number_of_items = 0; eventPayload.total_value_of_items= 0.00; eventPayload.items.forEach(function (item) { eventPayload.total_number_of_items += item.quantity; eventPayload.total_value_of_items += parseFloat(item.price) * item.quantity; }); delete eventPayload.items; break; default: //do nothing, the event goes as is break; } //remove noise from GTM delete eventPayload["gtm.uniqueEventId"]; return eventPayload; } try { if (bkCheckoutInitInput.gtmCode) { addGTMScript(bkCheckoutInitInput.gtmCode); } if (bkCheckoutInitInput.gaCode) { addGAScript(bkCheckoutInitInput.gaCode); } if (bkCheckoutInitInput.listenForMessages) { listenForEventFromParent(); } if ( bkCheckoutInitInput.currentPage && typeof bkCheckoutInitInput.currentPage === 'string' && bkCheckoutInitInput.currentPage.length > 0 ) { addPageLoadEvent(bkCheckoutInitInput.currentPage); } if (bkCheckoutInitInput.events && Array.isArray(bkCheckoutInitInput.events)) { for (let i =0; i < bkCheckoutInitInput.events.length; i++) { addEventToDataLayer(bkCheckoutInitInput.events[i]); } } if (bkCheckoutInitInput.ecommerceData) { addEventListener( "paymentProviderSelected", function(event){ handlePaymentProviderSelected(bkCheckoutInitInput.ecommerceData, event) }, true ); addEventListener( "paymentMethodSelected", function(event){ handlePaymentMethodSelected(bkCheckoutInitInput.ecommerceData, event) }, true ); addEventListener( "paymentInfoComplete", function(event){ handlePaymentInfoComplete(bkCheckoutInitInput.ecommerceData, event) }, true ); addEventListener( "paymentAttempt", function(event){ handlePaymentAttempt(bkCheckoutInitInput.ecommerceData, event) }, true ); addEventListener( "paymentFailed", function(event){ handlePaymentFailed(bkCheckoutInitInput.ecommerceData, event) }, true ); addEventListener( "paymentCanceled", function(event){ handlePaymentCanceled(bkCheckoutInitInput.ecommerceData, event) }, true ); addEventListener( "displayExpressCheckout", function(event){ handleDisplayExpressCheckout(event) }, true ); addEventListener( "noPaymentOptionsAvailable", function(event){ handleNoPaymentOptionsAvailable(event) }, true ); } } catch {} } try{ BookingkitCheckoutAnalytics({ gtmCode: '', gaCode: '', currentPage: '', items: [], listenForMessages: true, ecommerceData: null, vendorIdent: 'ed907dac6698b274916f9fdb2fc91393', });} catch {}