{"version":3,"sources":["core/@http.js","core/@outlineAccessibility.js","core/@preloader.js","core/@scrollToElement.js","core/@sw.js","core/@urlExternalSafe.js","helpers/@formHelper.js","helpers/@formValidation.js","helpers/@reservationHelper.js","site/clickEventCloseStickyBar.js","site/clickEventCopyLinkToClipboard.js","site/clickEventShareToSocial.js","site/createElementToast.js","site/eventsFormReservation.js","site/feed.js","site/loadEventFlatpickr.js","site/loadEventGoogleMaps.js","site/loadEventSliderThumbnail.js","site/loadEventSliders.js","site/loadEventVerticalScrollBar.js","site/scrollEventStickyNav.js","site/scrollOnEvent.js","site/serviceFilterAsideMap.js","site/serviceFilterContactHostelsList.js","site/serviceFilterEventsAsideDatePicker.js","site/serviceFilterJobOffers.js","site/serviceFilterNews.js","site/serviceFilterRoutes.js","site/serviceFilterTourism.js","site/serviceModalGallery.js","site/servicePaymentMethods.js","site/serviceSearchBox.js","site/serviceValidateVoucher.js","site/submitFileUploader.js","site/submitFormDefault.js","site/submitFormSearchBox.js","site/submitReservation.js","site/toggleEventsAccordion.js","site/toggleEventsAsideFilterMap.js","site/toggleEventsFilterModal.js","site/toggleEventsLanguageSelect.js","site/toggleEventsNav.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5eA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"app.js","sourcesContent":["/*eslint-disable no-unused-vars*/\nconst http = {\n\tasync fxGet(endpoint, callback) {\n\t\ttry {\n\t\t\tconst response = await fetch(endpoint),\n\t\t\t\tdata = await response.json()\n\n\t\t\tcallback(response, data)\n\t\t}\n\t\tcatch (error) {\n\t\t\tconsole.error(error)\n\t\t}\n\t},\n\n\tasync fxPost(endpoint, formData, callback, dataLanguage) {\n\t\ttry {\n\t\t\tconst response = await fetch(endpoint, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(formData),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-type': 'application/json',\n\t\t\t\t\t'Accept-Language': `${dataLanguage}`\n\t\t\t\t}\n\t\t\t})\n\t\t\tconst data = await response.json()\n\t\t\tcallback(response, data)\n\t\t}\n\t\tcatch (error) {\n\t\t\tconsole.error(error)\n\t\t}\n\t},\n\n\tasync fxUploadFile(endpoint, formData, callback) {\n\t\ttry {\n\t\t\tconst response = await fetch(endpoint, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: formData\n\t\t\t})\n\n\t\t\tconst data = await response.json()\n\t\t\tcallback(response, data)\n\t\t}\n\t\tcatch (error) {\n\t\t\tconsole.error(error)\n\t\t}\n\t}\n}","const a11y = {\n\tel: {\n\t\thtml: document.documentElement\n\t},\n\n\tfxAddA11yClass() {\n\t\tdocument.addEventListener('keydown', e => e.key === 'Tab' && this.el.html.classList.add('a11y'))\n\t\tdocument.addEventListener('click', () => {\n\t\t\tif (this.el.html.classList.contains('a11y'))\n\t\t\t\tthis.el.html.classList.remove('a11y')\n\t\t\telse\n\t\t\t\treturn false\n\t\t})\n\t},\n\n\tinit() {\n\t\tthis.fxAddA11yClass()\n\t}\n}\n\na11y.init()","/*eslint-disable no-unused-vars*/\nconst preloader = {\n\n\tfxEnableButton(el) {\n\t\tel.classList.contains('js-preloader-file') ? el.style.pointerEvents = 'auto' : el.removeAttribute('disabled')\n\t},\n\n\tfxDisableButton(el) {\n\t\tel.classList.contains('js-preloader-file') ? el.style.pointerEvents = 'none' : el.setAttribute('disabled', true)\n\t},\n\n\tfxCreateSpinner(el) {\n\t\tconst spinner = document.createElement('div')\n\t\tspinner.classList.add('btn--loading-spinner')\n\t\tel.appendChild(spinner)\n\t},\n\n\tfxRemoveSpinner(el) {\n\t\tel.querySelector('.btn--loading-spinner').remove()\n\t},\n\n\tfxPreloaderAdd(el) {\n\t\tconst button = el.classList.contains('js-preloader-file') ? el : el.querySelector('.js-preloader')\n\t\tbutton.classList.add('btn--loading')\n\t\tthis.fxDisableButton(button)\n\t\tthis.fxCreateSpinner(button)\n\t},\n\n\tfxPreloaderRemove(el) {\n\t\tconst button = el.classList.contains('js-preloader-file') ? el : el.querySelector('.js-preloader')\n\t\tbutton.classList.remove('btn--loading')\n\t\tthis.fxEnableButton(button)\n\t\tthis.fxRemoveSpinner(button)\n\t}\n}","const scrollToElement = {\n\tel: {\n\t\tbtnScroll: document.querySelectorAll('.js-scrollto'),\n\t\theader: document.querySelector('.header')\n\t},\n\n\t// polyfilled smooth scrolling for Edge & Safari\n\tfxSmoothScrollToPolyfill(to, duration) {\n\t\tconst element = document.scrollingElement || document.documentElement,\n\t\t\tstart = element.scrollTop,\n\t\t\tchange = to - start,\n\t\t\tstartDate = +new Date()\n\n\t\t// t = current time b = start value c = change in value d = duration\n\t\tconst easeInOutQuad = (t, b, c, d) => {\n\t\t\tt /= d / 2\n\t\t\tif (t < 1) return c / 2 * t * t + b\n\t\t\tt--\n\t\t\treturn -c / 2 * (t * (t - 2) - 1) + b\n\t\t}\n\n\t\tconst animateScroll = () => {\n\t\t\tconst currentDate = +new Date(),\n\t\t\t\tcurrentTime = currentDate - startDate\n\n\t\t\telement.scrollTop = parseInt(easeInOutQuad(currentTime, start, change, duration))\n\t\t\tcurrentTime < duration ? requestAnimationFrame(animateScroll) : element.scrollTop = to\n\n\t\t}\n\t\tanimateScroll()\n\t},\n\n\tfxScrollTo(e) {\n\t\te.preventDefault()\n\t\tconst buttonScrollTo = e.currentTarget,\n\t\t\ttarget = document.getElementById(buttonScrollTo.dataset.scroll),\n\t\t\theaderHeight = this.el.header.offsetHeight,\n\t\t\tsupportsNativeSmoothScroll = 'scrollBehavior' in document.documentElement.style\n\n\t\tif (target) {\n\t\t\tif (supportsNativeSmoothScroll)\n\t\t\t\twindow.scroll({\n\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\ttop: target.offsetTop - (this.el.header ? headerHeight : 0),\n\t\t\t\t\tleft: 0\n\t\t\t\t})\n\n\t\t\telse\n\t\t\t\tthis.fxSmoothScrollToPolyfill(target.offsetTop - (this.el.header ? headerHeight : 0), 1000)\n\t\t}\n\t},\n\n\tevents() {\n\t\tthis.el.btnScroll.forEach(button => button.addEventListener('click', e => this.fxScrollTo(e)))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nscrollToElement.init()","const sw = {\n\tinit() {\n\t\t'serviceWorker' in navigator && !location.hostname.includes('localhost') && navigator.serviceWorker.register('/sw.js')\n\t}\n}\n\nsw.init()","const url = {\n\tel: {\n\t\tlinkToNewTab: document.querySelectorAll('a[target=\"_blank\"]')\n\t},\n\n\tfxFixUrlExternal() {\n\t\tthis.el.linkToNewTab.forEach(el => el.setAttribute('rel', 'noopener noreferrer'))\n\t},\n\n\tinit() {\n\t\tthis.fxFixUrlExternal()\n\t}\n}\n\nurl.init()","/* global */\nconst formHelper = {\n\tel: {\n\t\tcheckbox: document.querySelectorAll('.js-checkbox')\n\t},\n\n\tfxFormToJson(el) {\n\t\tconst indexedArray = {}\n\t\tfor (let i = 0; i < el.length; i++) {\n\t\t\tif (el[i].value) {\n\t\t\t\tif (['checkbox', 'radio'].indexOf(el[i].type) > -1 && el[i].checked || ['checkbox', 'radio', 'file', 'button'].indexOf(el[i].type) === -1)\n\t\t\t\t\tindexedArray[el[i].name] = el[i].value\n\t\t\t}\n\t\t}\n\t\treturn indexedArray\n\t},\n\n\tfxFormToURL(el) {\n\t\tconst formValues = new URLSearchParams(new FormData(el)).toString(),\n\t\t\turl = `${el.action}?${formValues}`\n\n\t\tlocation.href = url\n\t},\n\n\tfxInputEvents() {\n\t\tthis.el.checkbox.forEach(el => el.addEventListener('change', e => e.currentTarget.value = e.currentTarget.checked ? 'true' : 'false'))\n\t},\n\n\tfxShowMessage(form, msg, status = 200) {\n\t\tconst buttonSubmit = form.querySelector('.js-submit'),\n\t\t\tbuttonClear = form.querySelector('.js-clear-file'),\n\t\t\tinputHiddenValue = form.querySelector('.upload-file__value'),\n\t\t\tinputFile = form.querySelector('[type=\"file\"]'),\n\t\t\tfileName = form.querySelector('.upload-file__name')\n\n\t\t// set button disabled\n\t\tif (buttonSubmit)\n\t\t\tbuttonSubmit.disabled = true\n\n\t\tsetTimeout(() => {\n\t\t\tbuttonSubmit.removeAttribute('disabled')\n\t\t\tbuttonSubmit.style.display = 'inherit'\n\t\t\tstatus === 200 && form.reset()\n\n\t\t\tif (inputFile) {\n\t\t\t\tform.value = ''\n\t\t\t\tinputHiddenValue.value = ''\n\t\t\t\tfileName.textContent = ''\n\t\t\t\tbuttonClear && setTimeout(() => buttonClear.style.display = 'none', 0)\n\t\t\t}\n\t\t}, 3500)\n\t},\n\n\tinit() {\n\t\tthis.fxInputEvents()\n\t}\n}\n\nformHelper.init()","/* global Bouncer createElementToast */\nconst formValidation = {\n\tel: {\n\t\thtml: document.documentElement,\n\t\tbody: document.body,\n\t\tinputNumber: document.querySelectorAll('[type=number]:not(.js-range-date)'),\n\t\tpastDate: document.querySelectorAll('.js-past-date'),\n\t\tfutureDate: document.querySelectorAll('.js-future-date'),\n\t\trangeDate: document.querySelectorAll('.js-range-date')\n\t},\n\n\tfxInitBouncer(form) {\n\t\tnew Bouncer(form.dataset.selector, {\n\t\t\tdisableSubmit: true,\n\t\t\tfieldClass: 'form__error', // Applied to fields with errors\n\t\t\terrorClass: 'form__error-message', // Applied to the error message for invalid fields\n\t\t\tfieldPrefix: 'form__field--', // If a field doesn't have a name or ID, one is generated with this prefix\n\t\t\terrorPrefix: 'form__error--', // Prefix used for error message IDs,\n\t\t\t// Override default Patterns\n\t\t\tpatterns: {\n\t\t\t\temail: /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])+/i\n\t\t\t},\n\t\t\tcustomValidations: {\n\t\t\t\tcompareFields: field => {\n\t\t\t\t\tconst selector = field.dataset.equalto,\n\t\t\t\t\t\totherField = field.form.querySelector(selector)\n\n\t\t\t\t\tif (!selector || !otherField) return false\n\n\t\t\t\t\treturn otherField.value !== field.value\n\t\t\t\t},\n\n\t\t\t\tnif: field => {\n\t\t\t\t\tif (field.classList.contains('js-nif')) {\n\t\t\t\t\t\tlet char = field.value\n\n\t\t\t\t\t\tif (char.length > 0)\n\t\t\t\t\t\t\tif (char += '', !['1', '2', '3', '5', '6', '8'].includes(char.substr(0, 1)) && !['45', '70', '71', '72', '77', '79', '90', '91', '98', '99'].includes(char.substr(0, 2))) return !1\n\n\t\t\t\t\t\tlet d, b = 9 * char[0] + 8 * char[1] + 7 * char[2] + 6 * char[3] + 5 * char[4] + 4 * char[5] + 3 * char[6] + 2 * char[7],\n\t\t\t\t\t\t\tc = b - 11 * parseInt(b / 11)\n\n\t\t\t\t\t\treturn !(d = 1 == c || 0 == c ? 0 : 11 - c, char[8] == d)\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tpastDate: field => field.classList.contains('js-past-date') && field.value > field.getAttribute('max'),\n\t\t\t\tfutureDate: field => field.classList.contains('js-future-date') && field.value < field.getAttribute('min')\n\t\t\t},\n\n\t\t\tmessages: {\n\t\t\t\tmissingValue: {\n\n\t\t\t\t\tcheckbox: form.dataset.msgRequired,\n\t\t\t\t\tradio: form.dataset.msgRequired,\n\t\t\t\t\tselect: form.dataset.msgRequired,\n\t\t\t\t\tdefault: form.dataset.msgRequired\n\t\t\t\t},\n\t\t\t\tpatternMismatch: {\n\t\t\t\t\temail: form.dataset.msgInvalidFormat,\n\t\t\t\t\turl: form.dataset.msgInvalidFormat,\n\t\t\t\t\tnumber: form.dataset.msgInvalidFormat,\n\t\t\t\t\tcolor: form.dataset.msgInvalidFormat,\n\t\t\t\t\tdate: form.dataset.msgInvalidFormat,\n\t\t\t\t\ttime: form.dataset.msgInvalidFormat,\n\t\t\t\t\tmonth: form.dataset.msgInvalidFormat,\n\t\t\t\t\tdefault: form.dataset.msgInvalidFormat\n\t\t\t\t},\n\t\t\t\toutOfRange: {\n\t\t\t\t\tover: `${form.dataset.msgMaxFormat} {max}`,\n\t\t\t\t\tunder: `${form.dataset.msgMinFormat} {min}`\n\t\t\t\t},\n\t\t\t\twrongLength: {\n\t\t\t\t\tover: `${form.dataset.msgMaxlengthFormat} {maxLength}`,\n\t\t\t\t\tunder: `${form.dataset.msgMinlengthFormat} {minLength}`\n\t\t\t\t},\n\t\t\t\tcompareFields: () => form.dataset.msgCompare,\n\t\t\t\tnif: () => form.dataset.msgInvalidFormat,\n\t\t\t\tpastDate: () => `${form.dataset.msgMaxFormat} ` + new Date().toJSON().split('T')[0],\n\t\t\t\tfutureDate: () => `${form.dataset.msgMinFormat} ` + new Date().toJSON().split('T')[0]\n\t\t\t}\n\t\t})\n\t},\n\n\tfxFieldsetBouncer(section, form) {\n\t\tlet fieldset = document.querySelector(section)\n\t\tlet errors = new Bouncer(section, {\n\t\t\tdisableSubmit: true,\n\t\t\tfieldClass: 'form__error', // Applied to fields with errors\n\t\t\terrorClass: 'form__error-message', // Applied to the error message for invalid fields\n\t\t\tfieldPrefix: 'form__field--', // If a field doesn't have a name or ID, one is generated with this prefix\n\t\t\terrorPrefix: 'form__error--', // Prefix used for error message IDs,\n\t\t\t// Override default Patterns\n\t\t\tpatterns: {\n\t\t\t\temail: /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])+/i,\n\t\t\t\turl: /(http(s?):\\/\\/)?(?!www | www\\.)[a-z0-9_-]+\\.+[a-z0-9./%&=?_:;-]+/\n\t\t\t},\n\t\t\tcustomValidations: {\n\t\t\t\tcompareFields: field => {\n\t\t\t\t\tconst selector = field.dataset.equalto,\n\t\t\t\t\t\totherField = field.form.querySelector(selector)\n\n\t\t\t\t\tif (!selector || !otherField) return false\n\n\t\t\t\t\treturn otherField.value !== field.value\n\t\t\t\t},\n\n\t\t\t\tnif: field => {\n\t\t\t\t\tif (field.classList.contains('js-nif')) {\n\t\t\t\t\t\tlet char = field.value\n\n\t\t\t\t\t\tif (char.length > 0)\n\t\t\t\t\t\t\tif (char += '', !['1', '2', '3', '5', '6', '8'].includes(char.substr(0, 1)) && !['45', '70', '71', '72', '77', '79', '90', '91', '98', '99'].includes(char.substr(0, 2))) return !1\n\n\t\t\t\t\t\tlet d, b = 9 * char[0] + 8 * char[1] + 7 * char[2] + 6 * char[3] + 5 * char[4] + 4 * char[5] + 3 * char[6] + 2 * char[7],\n\t\t\t\t\t\t\tc = b - 11 * parseInt(b / 11)\n\n\t\t\t\t\t\treturn !(d = 1 == c || 0 == c ? 0 : 11 - c, char[8] == d)\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tpastDate: field => field.classList.contains('js-past-date') && field.value > field.getAttribute('max'),\n\t\t\t\tfutureDate: field => field.classList.contains('js-future-date') && field.value < field.getAttribute('min')\n\t\t\t},\n\n\t\t\tmessages: {\n\t\t\t\tmissingValue: {\n\n\t\t\t\t\tcheckbox: form.dataset.msgRequired,\n\t\t\t\t\tradio: form.dataset.msgRequired,\n\t\t\t\t\tselect: form.dataset.msgRequired,\n\t\t\t\t\tdefault: form.dataset.msgRequired\n\t\t\t\t},\n\t\t\t\tpatternMismatch: {\n\t\t\t\t\temail: form.dataset.msgInvalidFormat,\n\t\t\t\t\turl: form.dataset.msgInvalidFormat,\n\t\t\t\t\tnumber: form.dataset.msgInvalidFormat,\n\t\t\t\t\tcolor: form.dataset.msgInvalidFormat,\n\t\t\t\t\tdate: form.dataset.msgInvalidFormat,\n\t\t\t\t\ttime: form.dataset.msgInvalidFormat,\n\t\t\t\t\tmonth: form.dataset.msgInvalidFormat,\n\t\t\t\t\tdefault: form.dataset.msgInvalidFormat\n\t\t\t\t},\n\t\t\t\toutOfRange: {\n\t\t\t\t\tover: `${form.dataset.msgMaxFormat} {max}`,\n\t\t\t\t\tunder: `${form.dataset.msgMinFormat} {min}`\n\t\t\t\t},\n\t\t\t\twrongLength: {\n\t\t\t\t\tover: `${form.dataset.msgMaxlengthFormat} {maxLength}`,\n\t\t\t\t\tunder: `${form.dataset.msgMinlengthFormat} {minLength}`\n\t\t\t\t},\n\t\t\t\tcompareFields: () => form.dataset.msgCompare,\n\t\t\t\tnif: () => form.dataset.msgInvalidFormat,\n\t\t\t\tpastDate: () => `${form.dataset.msgMaxFormat} ` + new Date().toJSON().split('T')[0],\n\t\t\t\tfutureDate: () => `${form.dataset.msgMinFormat} ` + new Date().toJSON().split('T')[0]\n\t\t\t}\n\t\t}).validateAll(fieldset)\n\n\t\treturn errors\n\t},\n\n\tfxValidate(form) {\n\t\tthis.fxInitBouncer(form)\n\t\tif (!form.checkValidity()) {\n\t\t\tcreateElementToast.fxCreateToastItem('danger', form.dataset.toastCopyError)\n\t\t}\n\t\telse {\n\t\t\treturn form.checkValidity()\n\t\t}\n\t},\n\n\tfxSetValidationAttributes() {\n\t\tthis.el.pastDate.length && this.el.pastDate.forEach(el => el.setAttribute('max', new Date().toJSON().split('T')[0]))\n\t\tthis.el.futureDate.length && this.el.futureDate.forEach(el => el.setAttribute('min', new Date().toJSON().split('T')[0]))\n\t\tthis.el.inputNumber.length && this.el.inputNumber.forEach(el => el.setAttribute('min', 0))\n\t\tif (this.el.rangeDate.length) {\n\t\t\tthis.el.rangeDate.forEach(el => {\n\t\t\t\tel.setAttribute('min', '1900')\n\t\t\t\tel.setAttribute('max', new Date().getFullYear())\n\t\t\t})\n\t\t}\n\t},\n\n\tinit() {\n\t\tthis.fxSetValidationAttributes()\n\t}\n}\n\nformValidation.init()","/* global submitPayment formValidation ga submitReservation scrollOnEvent*/\nconst reservationHelper = {\n\tel: {\n\t\tformReservation: document.querySelector('.js-form-reservation'),\n\t\tbtnRemoveDiscount: document.querySelector('.js-remove-discount'),\n\t\tinputJsRatePlan: document.querySelector('.js-rateplan'),\n\t\tcontainerSummary: document.querySelector('.content__summary')\n\t},\n\n\tvars: {\n\t\tfinalPrice: 0,\n\t\textraLargeAndUp: window.matchMedia('(min-width: 75em)'),\n\t\tmediumAndUp: window.matchMedia('(min-width: 48em)')\n\t},\n\n\tfxUpdateDesktopTableStylesColumns(target, tableCells) {\n\t\tconst activeTab = target.closest('.tab-header'),\n\t\t\tremainingTabs = activeTab.parentElement.querySelectorAll('.tab-header')\n\n\t\t//update table header tabs\n\t\tremainingTabs.forEach(el => el.classList.remove('tab-header--column-active'))\n\t\tactiveTab.classList.add('tab-header--column-active')\n\t\tdocument.querySelector('.form-table__warning-text').textContent = target.dataset.warning\n\t\tdocument.querySelector('.hero-information__warning').textContent = target.dataset.warning\n\n\t\t//update table content tabs\n\t\ttableCells.forEach(el => target.value === el.dataset.rateplan ? el.classList.add('tab-inner-row--column-active') : el.classList.remove('tab-inner-row--column-active'))\n\n\t\tdocument.querySelectorAll('.form-table--desktop .form-table__radio-input').forEach(input => target !== input ? input.checked = false : '')\n\t},\n\n\tfxUpdateDesktopTableStylesRows(target) {\n\t\tif(target.closest('.form-table__inner-row')) {\n\t\t\ttarget.value === '0' ? target.closest('.form-table__inner-row').classList.remove('row--active') : target.closest('.form-table__inner-row').classList.add('row--active')\n\t\t}\n\t},\n\n\tfxUpdateMobileTableStyles(target) {\n\t\tdocument.querySelectorAll('.form-table--mobile .form-table__radio-input').forEach(el => {\n\t\t\tif (target.dataset.rateplan === el.dataset.rateplan) {\n\t\t\t\tel.checked = true\n\t\t\t\tel.parentElement.classList.add('radio--active')\n\t\t\t\tdocument.querySelector('.hero-information__warning').textContent = target.dataset.warning\n\t\t\t}\n\t\t\telse {\n\t\t\t\tel.checked = false\n\t\t\t\tel.parentElement.classList.remove('radio--active')\n\t\t\t}\n\t\t})\n\t},\n\n\tfxSetDefaultRateInfo (container) {\n\t\tconst defaultRate = container.querySelector('.tab-header--column-active'),\n\t\t\theroWarning = document.querySelector('.hero-information__warning')\n\n\t\theroWarning.textContent = defaultRate.querySelector('.form-table__radio-input').dataset.warning\n\t},\n\n\tfxLoopElements(list, attribute, currentTargetDataset) {\n\t\tlist.forEach(el => el.style.display = el.dataset[attribute] === currentTargetDataset ? 'flex' : 'none')\n\t},\n\n\tfxGoToNextStep(button, section, formSections, headerSections) {\n\t\tconst buttons = document.querySelectorAll(button)\n\n\t\tbuttons.forEach(el => {\n\t\t\tel.addEventListener('click', e => {\n\t\t\t\te.preventDefault()\n\t\t\t\tconst target = e.currentTarget\n\n\t\t\t\tconst sectionNumber = Number(section)\n\n\t\t\t\t//section to validate\n\t\t\t\tif (target.dataset.sectionNext - 1 === sectionNumber) {\n\n\t\t\t\t\tconst reservationContainer = document.querySelector('.form--reservation')\n\n\t\t\t\t\t//-bouncer validate for section\n\t\t\t\t\tconst sectionErrors = formValidation.fxFieldsetBouncer(`.form__tab[data-section=\"${sectionNumber}\"]`, reservationContainer)\n\n\t\t\t\t\tif (sectionErrors.length === 0) {\n\t\t\t\t\t\tif (sectionNumber === 1) {\n\t\t\t\t\t\t\t//show next section according to data-section, hide siblings\n\t\t\t\t\t\t\tthis.fxLoopElements(formSections, 'section', target.dataset.sectionNext)\n\n\t\t\t\t\t\t\t//show header tab according to data-header\n\t\t\t\t\t\t\tthis.fxLoopElements(headerSections, 'header', target.dataset.headerNext)\n\n\t\t\t\t\t\t\t//change styles for sidepanel\n\t\t\t\t\t\t\ttarget.closest('.content-aside').classList.remove('content-aside--full-width')\n\t\t\t\t\t\t\ttarget.closest('.content__summary').classList.remove('content__summary--orange')\n\t\t\t\t\t\t\ttarget.style.display = 'none'\n\t\t\t\t\t\t\ttarget.closest('.content__summary').nextElementSibling.style.display = 'none'\n\n\t\t\t\t\t\t\t//update inputs\n\t\t\t\t\t\t\tthis.fxUpdateAmountAfterTax()\n\n\t\t\t\t\t\t\t//show member card fields according to selected rate plan\n\t\t\t\t\t\t\tthis.fxUpdateMemberCardFields()\n\n\t\t\t\t\t\t\tscrollOnEvent.fxScrollOnEvent(document.querySelector('.content-aside'))\n\n\t\t\t\t\t\t\t//events google analytics\n\t\t\t\t\t\t\tif (window.ga && ga.loaded)\n\t\t\t\t\t\t\t\tga('send', 'event', { 'eventCategory': 'booking', 'eventAction': 'click', 'eventLabel': 'step2', 'eventValue': 1 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (sectionNumber === 2) {\n\t\t\t\t\t\t\t//submit reservation data\n\t\t\t\t\t\t\tsubmitReservation.fxSubmitReservation(target)\n\n\t\t\t\t\t\t\t//-hide remove discount btn\n\t\t\t\t\t\t\tthis.el.btnRemoveDiscount.remove()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (sectionNumber === 3) {\n\t\t\t\t\t\t\t//show next section according to data-section, hide siblings\n\t\t\t\t\t\t\tthis.fxLoopElements(formSections, 'section', target.dataset.sectionNext)\n\n\t\t\t\t\t\t\t//submit payment method\n\t\t\t\t\t\t\tsubmitPayment.fxSubmitPaymentMethod(target)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t},\n\n\tfxUpdateAmountAfterTax() {\n\t\tdocument.querySelector('.js-amount').value = this.vars.finalPrice\n\t},\n\n\tfxUpdateMemberCardFieldsHelper(element) {\n\t\telement.querySelectorAll('.form-table__radio-input').forEach(el => el.checked && document.querySelectorAll('.js-hidden-field').forEach(field => field.dataset.card === el.dataset.ratePlanName ? field.style.display = 'flex' : field.remove()))\n\t},\n\n\tfxUpdateMemberCardFields() {\n\t\tif (this.vars.extraLargeAndUp.matches) {\n\t\t\tconst desktopContainer = this.el.formReservation.querySelector('.form-table--desktop')\n\t\t\tthis.fxUpdateMemberCardFieldsHelper(desktopContainer)\n\t\t}\n\t\telse {\n\t\t\tconst mobileContainer = this.el.formReservation.querySelector('.form-table--mobile')\n\t\t\tthis.fxUpdateMemberCardFieldsHelper(mobileContainer)\n\t\t}\n\t},\n\n\tfxUpdateInputNumberHelper(input, element) {\n\t\tconst mobileContainer = this.el.formReservation.querySelector('.form-table--mobile')\n\n\t\tinput.value = Number(input.value) || 0\n\t\tmobileContainer.querySelectorAll('.form-table__radio-input').forEach(el => el.checked && this.fxUpdateMobileTableStyles(mobileContainer, '.form-table__radio-input', el))\n\t\tinput.value >= 1 ? element.closest('.form-table__card').classList.add('card--active') : element.closest('.form-table__card').classList.remove('card--active')\n\t},\n\n\tfxUpdateCountryCode(target) {\n\t\tconst selectedCountryCode = target.options[target.selectedIndex].getAttribute('data-country-code')\n\n\t\tdocument.querySelector('.js-country-code').value = selectedCountryCode\n\t},\n\n\tfxCalculateContentSummaryHeight() {\n\t\tconst summaryContainer = document.querySelector('.content__flex-aside')\n\n\t\tif (!this.vars.extraLargeAndUp.matches) {\n\t\t\tif (summaryContainer.classList.contains('content__flex-aside--open')) {\n\t\t\t\tsummaryContainer.style.bottom = '0'\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconst bottomValue = this.vars.mediumAndUp.matches ? Number(summaryContainer.dataset.bottomMedium) : Number(summaryContainer.dataset.bottomSmall)\n\n\t\t\t\tsummaryContainer.style.bottom = `${-summaryContainer.offsetHeight + bottomValue}px`\n\t\t\t}\n\t\t}\n\t},\n\n\tfxToggleContentSummary(target) {\n\t\tconst aside = target.closest('.content__flex-aside')\n\n\t\taside.classList.contains('content__flex-aside--open') ? aside.classList.remove('content__flex-aside--open') : aside.classList.add('content__flex-aside--open')\n\t\tthis.fxCalculateContentSummaryHeight()\n\t},\n\n\tfxUpdateRatePlanValue() {\n\t\tdocument.querySelectorAll('.form-table__radio-input').forEach(el => el.checked ? this.el.inputJsRatePlan.value = el.value : '')\n\t},\n\n\tfxUpdateInfo() {\n\n\t\tconst selects = document.querySelectorAll('.form-table__select select'),\n\t\t\treservationSummary = document.querySelector('.js-reservation-summary'),\n\t\t\treservationFinalPrice = document.querySelector('.js-reservation-final-price'),\n\t\t\treservationPriceContainer = document.querySelector('.content__summary-total'),\n\t\t\treservationSubmitBtn = document.querySelector('.content__summary-button'),\n\t\t\treservationRatePlanType = document.querySelector('.content__summary-info'),\n\t\t\treservationSubtotal = document.querySelector('.js-reservation-subtotal'),\n\t\t\tbookingInput = document.querySelector('.js-booking')\n\n\t\tthis.vars.finalPrice = 0\n\t\treservationSummary.innerHTML = ''\n\t\treservationFinalPrice.innerHTML = ''\n\n\t\tlet ratePlanValue = null,\n\t\t\tratePlanName = ''\n\n\t\tselects.forEach(item => {\n\t\t\tif (item.value !== '0') {\n\t\t\t\tconst wrapper = item.closest('.js-room-info')\n\n\t\t\t\tif (this.vars.extraLargeAndUp.matches)\n\t\t\t\t\tdocument.querySelectorAll('.form-table--desktop .form-table__radio-input').forEach(input => input.checked ? ratePlanValue = input.value : '')\n\n\t\t\t\telse\n\t\t\t\t\tdocument.querySelectorAll('.form-table--mobile .form-table__radio-input').forEach(input => input.checked ? ratePlanValue = input.value : '')\n\n\t\t\t\twrapper.querySelectorAll('.js-rateplan-value').forEach(el => {\n\t\t\t\t\tif (ratePlanValue === el.dataset.rateplan) {\n\n\t\t\t\t\t\tratePlanName = el.dataset.ratePlanName\n\n\t\t\t\t\t\tconst price = Number(el.dataset.price),\n\t\t\t\t\t\t\troomPrice = (price * item.value).toFixed(2).replace('.', ','),\n\t\t\t\t\t\t\t//- room capacity, after roomPrice\n\t\t\t\t\t\t\t//- - ${wrapper.dataset.roomCapacity} ${wrapper.dataset.guestCopy}\n\t\t\t\t\t\t\tfield = `
\n\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t${Number(item.value)} x\n\t\t\t\t\t\t\t\t\t\t\t\t${wrapper.dataset.roomDescription} \n\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t= ${roomPrice}€\n\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t
`,\n\n\t\t\t\t\t\t\titemPrice = price * item.value\n\t\t\t\t\t\tthis.vars.finalPrice += itemPrice\n\n\t\t\t\t\t\treservationSummary.innerHTML += field\n\t\t\t\t\t\treservationFinalPrice.textContent = this.vars.finalPrice.toFixed(2).replace('.', ',')\n\t\t\t\t\t\treservationSubtotal.textContent = this.vars.finalPrice.toFixed(2).replace('.', ',')\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\t//show final price if more than 1 select\n\t\treservationPriceContainer.style.display = this.vars.finalPrice ? 'block' : 'none'\n\t\treservationSubmitBtn.style.display = this.vars.finalPrice ? 'inline-block' : 'none'\n\t\tbookingInput.value = this.vars.finalPrice && true\n\t\treservationRatePlanType.innerHTML = this.vars.finalPrice ? ratePlanName : ''\n\t\treservationRatePlanType.style.display = this.vars.finalPrice ? 'block' : 'none'\n\n\t\tthis.fxCalculateContentSummaryHeight()\n\t},\n\n\tinit() {\n\t\tif (this.el.formReservation) {\n\t\t\tthis.fxCalculateContentSummaryHeight()\n\t\t\tthis.fxUpdateRatePlanValue()\n\t\t}\n\t}\n}\n\nreservationHelper.init()","const clickEventCloseStickyBar = {\n\tel: {\n\t\tcontainer: document.querySelector('.js-sticky-bar'),\n\t\tcloseButton: document.querySelector('.js-sticky-bar-button')\n\t},\n\n\tfxHandleClickEvent() {\n\t\tthis.el.container.style.display = 'none'\n\t},\n\n\tevents() {\n\t\tif (!this.el.container) return\n\t\tthis.el.closeButton.addEventListener('click', () => this.fxHandleClickEvent())\n\t},\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nclickEventCloseStickyBar.init()","/* global createElementToast */\nconst clickEventCopyLinkToClipboard = {\n\tel: {\n\t\tbody: document.body,\n\t\tcopyLinkItem: document.querySelectorAll('.js-copy-link'),\n\t\tcopyLinkImage: document.querySelector('.js-copy-link-image'),\n\t\tcopyLinkText: document.querySelector('.js-copy-link-text')\n\t},\n\n\tfxCopyLinkToClipBoard(el) {\n\t\t// save current icon\n\t\tlet currentImg = this.el.copyLinkImage.src\n\n\t\t// save current text\n\t\tlet currentText = this.el.copyLinkText.textContent\n\n\t\tel.addEventListener('click', e => {\n\t\t\te.preventDefault()\n\t\t\tconst inputElement = document.createElement('input'),\n\t\t\t\turlCurrentPage = location.href,\n\t\t\t\timgSrcSuccess = this.el.copyLinkImage.dataset.imgLinkCopied\n\n\t\t\tthis.el.body.appendChild(inputElement)\n\t\t\tinputElement.value = urlCurrentPage\n\t\t\tinputElement.select()\n\t\t\tnavigator.clipboard.writeText(inputElement.value)\n\t\t\tcreateElementToast.fxCreateToastItem('success', e.currentTarget.dataset.toastCopy)\n\t\t\tthis.el.copyLinkImage.src = imgSrcSuccess\n\t\t\tthis.el.copyLinkText.textContent = 'copied'\n\t\t\tthis.el.body.removeChild(inputElement)\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.el.copyLinkImage.src = currentImg\n\t\t\t\tthis.el.copyLinkText.textContent = currentText\n\t\t\t}, 500)\n\t\t})\n\t},\n\n\tinit() {\n\t\tfor (const element of this.el.copyLinkItem)\n\t\t\tthis.fxCopyLinkToClipBoard(element)\n\t}\n\n}\n\nclickEventCopyLinkToClipboard.init()","const clickEventShareToSocial = {\n\tel: {\n\t\tsocialItems: document.querySelectorAll('.js-social')\n\t},\n\n\tfxPopupCenter(url, w = 600, h = 400) {\n\t\tconst dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left,\n\t\t\tdualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top,\n\t\t\twidth = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width,\n\t\t\theight = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height,\n\t\t\tleft = width / 2 - w / 2 + dualScreenLeft,\n\t\t\ttop = height / 2 - h / 2 + dualScreenTop,\n\t\t\tnewWindow = window.open(url, 'Share', `scrollbars=yes, width=${w}, height=${h}, top=${top}, left=${left}`)\n\t\t// Puts focus on the newWindow \n\t\twindow.focus && newWindow.focus()\n\t},\n\n\tfxShareUrl(el) {\n\t\tconst encodedShareUrl = decodeURIComponent(location.href)\n\t\treturn `${el.dataset.url}${encodedShareUrl}`\n\t},\n\n\tevents() {\n\t\tfor (const networks of this.el.socialItems)\n\t\t\tnetworks.addEventListener('click', e => this.fxPopupCenter(this.fxShareUrl(e.currentTarget)))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n\n}\n\nclickEventShareToSocial.init()","const createElementToast = {\n\tel: {\n\t\tbody: document.body,\n\t\ttoastSubmit: document.querySelectorAll('.js-toast-submit')\n\t},\n\n\tfxCreateToastMainContainerOnDOM() {\n\t\t// check if DOM already have parent container for toasts\n\t\tif (!document.querySelector('.toast')) {\n\t\t\tconst newToastContainer = '
'\n\t\t\tthis.el.body.insertAdjacentHTML('beforeend', newToastContainer)\n\t\t}\n\t},\n\n\tfxCreateToastItem(type, copy) {\n\t\t// call function that sets parent container\n\t\tthis.fxCreateToastMainContainerOnDOM()\n\n\t\t// save variable let (let it change)\n\t\tlet iconType\n\n\t\t// condition for which type of icon will be placed inside toast\n\t\tswitch (type) {\n\t\t\tcase 'success':\n\t\t\t\ticonType = `\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t`\n\t\t\t\tbreak\n\t\t\tcase 'warning':\n\t\t\t\ticonType = `\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t`\n\t\t\t\tbreak\n\n\t\t\tcase 'danger':\n\t\t\t\ticonType = `\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t`\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\ticonType = `\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t`\n\t\t\t\tbreak\n\t\t}\n\n\t\t// Creating toast message container as dom element\n\t\tconst toastItemElement = document.createElement('div')\n\n\t\t// Add toast__item class to it\n\t\ttoastItemElement.classList.add('toast__item')\n\n\t\t// If there is a type, add that type as class\n\t\ttype && toastItemElement.classList.add(type)\n\n\t\t// Everything that goes inside each toast item\n\t\tconst toastContent = `\n\t\t\t
\n\t\t\t\t${iconType}\n\t\t\t
\n\t\t\t
\n\t\t\t\t${copy}\n\t\t\t
\n\t\t`\n\n\t\t// insert the rest of toas inside toast item element\n\t\ttoastItemElement.insertAdjacentHTML('beforeend', toastContent)\n\n\t\t// append each toast to parent container toast\n\t\tdocument.querySelector('.toast').appendChild(toastItemElement)\n\n\t\t// insert active class for animation\n\t\tsetTimeout(() => toastItemElement.classList.add('active'), 100)\n\n\t\t// remove active class and container\n\t\tsetTimeout(() => {\n\t\t\ttoastItemElement.classList.remove('active')\n\t\t\tsetTimeout(() => toastItemElement.remove(), 500)\n\t\t}, 3000)\n\t},\n\n\tfxCallToast(el) {\n\t\t// prevent default if is a link calling toast\n\t\tel.preventDefault()\n\n\t\t// get data atribute data-toast-type on target\n\t\tconst toastType = el.currentTarget.dataset.toastType\n\n\t\t// get data atribute data-toast-copy on target\n\t\tconst toastCopy = el.currentTarget.dataset.toastCopy\n\n\t\tthis.fxCreateToastItem(toastType, toastCopy)\n\t},\n\n\tevents() {\n\t\t// in case we want toast once click on button or link\n\t\tthis.el.toastSubmit.forEach(el => el.addEventListener('click', e => this.fxCallToast(e)))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\ncreateElementToast.init()","/* global reservationHelper */\nconst eventsFormReservation = {\n\tel: {\n\t\tformReservation: document.querySelector('.js-form-reservation'),\n\t\tformTabs: document.querySelectorAll('.form__tab'),\n\t\tformReservationHeader: document.querySelectorAll('.form-reservation__header'),\n\t\tformSelects: document.querySelectorAll('.form-table__select select'),\n\t\tformSelectCountryName: document.querySelector('.form__field-select[name=\"ClientCountryName\"]'),\n\t\ttableCells: document.querySelectorAll('.tab-inner-row'),\n\t\ttableHeadings: document.querySelectorAll('.tab-header'),\n\t\tbtnToggleContentSummary: document.querySelector('.content__summary-toggle'),\n\t\troomTypeInputs: document.querySelectorAll('.js-room-type'),\n\t\troomTypeReset: document.querySelector('.js-room-type-reset')\n\t},\n\n\tvars: {\n\t\textraLargeAndUp: window.matchMedia('(min-width: 75em)'),\n\t\tmediumAndUp: window.matchMedia('(min-width: 48em)')\n\t},\n\n\tfxEvents() {\n\t\t//set default rate warning\n\t\treservationHelper.fxSetDefaultRateInfo(document.querySelector('.form-table--desktop'))\n\t\t\n\t\t//updateStyles\n\t\tif (this.vars.extraLargeAndUp.matches) {\n\t\t\tdocument.querySelectorAll('.form-table--desktop .form-table__radio-input').forEach(el => el.addEventListener('click', e => reservationHelper.fxUpdateDesktopTableStylesColumns(e.currentTarget, this.el.tableCells)))\n\n\t\t\t//update styles inner-rows\n\t\t\tthis.el.formSelects.forEach(el => el.addEventListener('change', e => reservationHelper.fxUpdateDesktopTableStylesRows(e.currentTarget)))\n\n\t\t}\n\t\telse\n\t\t\tdocument.querySelectorAll('.form-table--mobile .form-table__radio-input').forEach(el => el.addEventListener('change', e => reservationHelper.fxUpdateMobileTableStyles(e.currentTarget)))\n\n\t\t//update Country code\n\t\tthis.el.formSelectCountryName.addEventListener('change', e => reservationHelper.fxUpdateCountryCode(e.currentTarget))\n\t\t//toggle content summary on click - mobile\n\t\tthis.el.btnToggleContentSummary.addEventListener('click', e => reservationHelper.fxToggleContentSummary(e.currentTarget))\n\n\t\tthis.el.roomTypeInputs.forEach(el => el.addEventListener('change', e => this.fxToggleFilterRoomType(e.currentTarget)))\n\n\t\tthis.el.roomTypeReset.addEventListener('click', () => this.fxToggleFilterRoomTypeReset())\n\t},\n\n\tfxToggleFilterRoomType(element) {\n\n\t\tif (element.checked) {\n\t\t\tdocument.querySelector('.js-room-type-reset').style.display = 'flex'\n\n\t\t\tconst selector = this.vars.extraLargeAndUp.matches ? '.form-table__row' : '.form-table__card',\n\t\t\t\tdisplayStyle = this.vars.extraLargeAndUp.matches ? 'flex' : 'block'\n\n\t\t\tif (element.id === 'beds') {\n\t\t\t\tdocument.querySelectorAll(`${selector}[data-room-type=\"quartos\"]`).forEach(el => this.vars.extraLargeAndUp.matches ? el.style.display = 'none' : el.closest('.form-table__card-container').style.display = 'none')\n\t\t\t\tdocument.querySelectorAll(`${selector}[data-room-type=\"camas\"]`).forEach(el => this.vars.extraLargeAndUp.matches ? el.style.display = `${displayStyle}` : el.closest('.form-table__card-container').style.display = `${displayStyle}`)\n\t\t\t} else {\n\t\t\t\tdocument.querySelectorAll(`${selector}[data-room-type=\"camas\"]`).forEach(el => this.vars.extraLargeAndUp.matches ? el.style.display = 'none' : el.closest('.form-table__card-container').style.display = 'none')\n\t\t\t\tdocument.querySelectorAll(`${selector}[data-room-type=\"quartos\"]`).forEach(el => this.vars.extraLargeAndUp.matches ? el.style.display = `${displayStyle}` : el.closest('.form-table__card-container').style.display = `${displayStyle}`)\n\t\t\t}\n\t\t}\n\t},\n\n\tfxToggleFilterRoomTypeReset() {\n\t\tthis.el.roomTypeInputs.forEach(el => el.checked = false)\n\t\tdocument.querySelector('.js-room-type-reset').removeAttribute('style')\n\n\t\tconst selector = this.vars.extraLargeAndUp.matches ? '.form-table__row' : '.form-table__card'\n\t\tdocument.querySelectorAll(`${selector}[data-room-type=\"camas\"], ${selector}[data-room-type=\"quartos\"]`).forEach(el => this.vars.extraLargeAndUp.matches ? el.removeAttribute('style') : el.closest('.form-table__card-container').removeAttribute('style'))\n\t},\n\n\tfxUpdateSidePanel() {\n\t\t///-update side panel on select/input number change or rateplan change\n\t\tconst selects = document.querySelectorAll('.form-table__select select')\n\t\tconst inputs = document.querySelectorAll('.form-table__radio-input')\n\t\tselects.forEach(el => el.addEventListener('change', () => reservationHelper.fxUpdateInfo()))\n\t\tinputs.forEach(el => el.addEventListener('change', () => reservationHelper.fxUpdateInfo()))\n\t},\n\n\tinit() {\n\t\tif (this.el.formReservation) {\n\t\t\tthis.fxEvents()\n\t\t\tthis.fxUpdateSidePanel()\n\t\t\treservationHelper.fxGoToNextStep('.js-form-reservation-next', '1', this.el.formTabs, this.el.formReservationHeader)\n\t\t\treservationHelper.fxGoToNextStep('.js-form-reservation-next', '2', this.el.formTabs, this.el.formReservationHeader)\n\t\t\treservationHelper.fxGoToNextStep('.js-form-reservation-next', '3', this.el.formTabs, this.el.formReservationHeader)\n\t\t}\n\t}\n}\n\neventsFormReservation.init()","/* global Instafeed loadEventSliders */\nconst feed = {\n\n\tel: {\n\t\tcontainer: document.getElementById('instafeed')\n\t},\n\n\tevents() {\n\t\tconst feed = new Instafeed({\n\t\t\taccessToken: this.el.container.dataset.token,\n\t\t\ttemplate: `\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t`,\n\t\t\tafter: () => loadEventSliders.init()\n\t\t})\n\t\tfeed.run()\n\t},\n\n\tinit() {\n\t\tthis.el.container && this.events()\n\t}\n}\n\nfeed.init()","/* global flatpickr, rangePlugin */\nconst loadEventFlatpickr = {\n\tel: {\n\t\tinputCheckIn: document.querySelector('.js-form-check-in'),\n\t\tinputCheckOut: document.querySelector('.js-form-check-out'),\n\t\tflatPickerContainer: document.querySelectorAll('.js-form-flatpickr')\n\t},\n\n\tfxInitFlatpickr(el) {\n\t\t// save in a variable options of flatpickr\n\t\tconst flatpickrOptions = {\n\t\t\tlocale: el.dataset.language,\n\t\t\t// single mode is default\n\t\t\tmode: 'single',\n\t\t\t// minDate is the minimum date that can be selected\n\t\t\tminDate: 'today',\n\t\t\tdateFormat: 'Y-m-d',\n\t\t\t//allow input is for make sure validation works when nothing is selected\n\t\t\tallowInput: true,\n\t\t\tdisableMobile: 'true',\n\t\t\tplugins: [new rangePlugin({ input: this.el.inputCheckOut })]\n\t\t}\n\n\t\tflatpickr(el, flatpickrOptions)\n\t},\n\n\tevents() {\n\n\t\t// Responsible for datepicker on Check in and Check out input\n\t\tthis.el.flatPickerContainer.forEach(el => this.fxInitFlatpickr(el))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nloadEventFlatpickr.init()\n","/* global google */\nconst loadEventGoogleMaps = {\n\tel: {\n\t\tbody: document.querySelector('body'),\n\t\tmap: document.querySelector('.js-map'),\n\t\tasideItemCardInfo: document.querySelectorAll('.js-aside-item'),\n\t\tbuttonWithMapLocation: document.querySelectorAll('.js-button-with-map-location')\n\t},\n\n\tfxHandleCreateScriptTag(el) {\n\t\t// Check if map element exists\n\t\tif (!el) return\n\n\t\t// save key in variable\n\t\tconst googleMapsKey = this.el.body.getAttribute('data-google-map-key')\n\n\t\t// Create the script tag, set the appropriate attributes\n\t\tlet script = document.createElement('script')\n\n\t\t// Set the source of the script\n\t\tscript.src = `https://maps.googleapis.com/maps/api/js?${googleMapsKey && 'key='}${googleMapsKey}&callback=initMap`\n\t\tscript.async = true\n\n\t\t// Attach your callback function to the `window` object\n\t\twindow.initMap = () => {\n\t\t\t// it has to be called this.el.map in order to not create a new script tag on each page load that has js.map and other class for use google maps instance\n\t\t\tthis.fxLoadMap(this.el.map)\n\t\t}\n\n\t\t// Save footer element\n\t\tconst footer = document.querySelector('.footer')\n\n\t\t// Append the script tag to the right after footer\n\t\tfooter.parentNode.insertBefore(script, footer.nextSibling)\n\t},\n\n\tfxLoadMap(el) {\n\t\t// Variables that we can set in the mapOptions\n\t\tconst mapZoomControl = el.dataset.mapZoomControl && JSON.parse(el.dataset.mapZoomControl),\n\t\t\tmapFullScreenControl = el.dataset.mapFullScreenControl && JSON.parse(el.dataset.mapFullScreenControl),\n\t\t\tmapStreetViewControl = el.dataset.mapStreetViewControl && JSON.parse(el.dataset.mapStreetViewControl),\n\t\t\tmapScaleControl = el.dataset.mapScaleControl && JSON.parse(el.dataset.mapScaleControl),\n\t\t\tmapRotateControl = el.dataset.mapRotateControl && JSON.parse(el.dataset.mapRotateControl),\n\t\t\tmapScrollWheel = el.dataset.mapScrollWheel && JSON.parse(el.dataset.mapScrollWheel),\n\t\t\tmapLatitude = el.dataset.mapLatitude && Number(el.dataset.mapLatitude),\n\t\t\tmapLongitude = el.dataset.mapLongitude && Number(el.dataset.mapLongitude)\n\n\t\t// Set options for each map\n\t\tconst mapOptions = {\n\t\t\tcenter: {\n\t\t\t\tlat: mapLatitude ? mapLatitude : 0,\n\t\t\t\tlng: mapLongitude ? mapLongitude : 0\n\t\t\t},\n\t\t\tzoom: 11,\n\t\t\tdisableDefaultUI: true,\n\t\t\tscrollwheel: mapScrollWheel ? true : false,\n\t\t\tzoomControl: mapZoomControl ? true : false,\n\t\t\tscaleControl: mapScaleControl ? true : false,\n\t\t\tstreetViewControl: mapStreetViewControl ? true : false,\n\t\t\trotateControl: mapRotateControl ? true : false,\n\t\t\tfullscreenControl: mapFullScreenControl ? true : false\n\t\t}\n\n\t\t// Create the map\n\t\tconst map = new google.maps.Map(el, mapOptions)\n\n\t\t// return map\n\t\treturn map\n\t},\n\n\tfxUpdateHrefButtonOverMap(el) {\n\n\t\t// Get map\n\t\tconst findMap = this.el.map\n\n\t\t// get attributes of map - latitude, longitude\n\t\tconst mapLatitude = findMap && findMap.getAttribute('data-map-latitude')\n\t\tconst mapLongitude = findMap && findMap.getAttribute('data-map-longitude')\n\n\t\t// set href to button\n\t\tel.href = `https://www.google.com/maps/dir//${mapLatitude},${mapLongitude}`\n\t},\n\n\tevents() {\n\t\t// Responsible for creating the script tag and inserting it after the footer - this way we can load map only when is needed\n\t\tthis.fxHandleCreateScriptTag(this.el.map)\n\n\t\t// Update the href attribute of the buttons with the map location\n\t\tthis.el.buttonWithMapLocation.forEach(el => this.fxUpdateHrefButtonOverMap(el))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nloadEventGoogleMaps.init()","/* global Swiper */\nconst loadEventSliderWithThumbnail = {\n\n\t// this is a function that is used dynamically on modal aside-gallery-modal, that´s why we don´t init this function once load the page\n\tfxInitSliderThumbnail(sliderContainer, sliderContainerThumbnail, initialSlide) {\n\t\t// swiper instance of thumbnail\n\t\tconst swiperThumbnail = new Swiper(sliderContainerThumbnail, {\n\t\t\tinitialSlide,\n\t\t\tspaceBetween: 10,\n\t\t\tslidesPerView: 3,\n\t\t\tfreeMode: true,\n\t\t\twatchSlidesVisibility: true,\n\t\t\twatchSlidesProgress: true,\n\t\t\tmousewheel: {\n\t\t\t\treleaseOnEdges: true\n\t\t\t},\n\n\t\t\tbreakpoints: {\n\t\t\t\t768: { //tablet up\n\t\t\t\t\tslidesPerView: 6\n\t\t\t\t},\n\t\t\t\t1024: { //small desktop up\n\t\t\t\t\tslidesPerView: 8\n\t\t\t\t},\n\t\t\t\t1440: { // desktop up\n\t\t\t\t\tslidesPerView: 10\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\t// swiper instance of main slider\n\t\tnew Swiper(sliderContainer, {\n\t\t\tinitialSlide,\n\t\t\tspaceBetween: 10,\n\t\t\tnavigation: {\n\t\t\t\tnextEl: '.swiper-button-next',\n\t\t\t\tprevEl: '.swiper-button-prev'\n\t\t\t},\n\t\t\tthumbs: {\n\t\t\t\tswiper: swiperThumbnail\n\t\t\t},\n\n\t\t\ton: {\n\t\t\t\tslideChange: e => {\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tconst captionHeading = e.el.querySelector('.swiper-slide-active').getAttribute('data-figcaption-heading')\n\n\t\t\t\t\t\tconst captionCopy = e.el.querySelector('.swiper-slide-active').getAttribute('data-figcaption-copy')\n\n\t\t\t\t\t\tdocument.querySelector('.js-slider-thumbnail-caption-heading').textContent = captionHeading\n\t\t\t\t\t\tdocument.querySelector('.js-slider-thumbnail-caption-copy').textContent = captionCopy\n\t\t\t\t\t}, 1)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nloadEventSliderWithThumbnail","/* global Swiper */\nconst loadEventSliders = {\n\tel: {\n\t\tsliderContainer: document.querySelectorAll('.js-slider'),\n\t\tsliderDestroy: document.querySelectorAll('.js-slider-destroy-on-screen-wide')\n\t},\n\n\tvars: {\n\t\twideAndUp: window.matchMedia('(min-width: 90em)')\n\t},\n\n\tfxInitSlider(el) {\n\t\tconst sliderCentered = el.dataset.sliderCentered && JSON.parse(el.dataset.sliderCentered),\n\t\t\tsliderDelay = el.dataset.sliderDelay && JSON.parse(el.dataset.sliderDelay),\n\t\t\tsliderLoop = el.dataset.sliderLoop && JSON.parse(el.dataset.sliderLoop),\n\t\t\tsliderAutoPlay = el.dataset.sliderAutoplay && JSON.parse(el.dataset.sliderAutoplay),\n\t\t\tsliderSizeWide = el.dataset.sliderWide && JSON.parse(el.dataset.sliderWide),\n\t\t\tsliderSizeLarge = el.dataset.sliderLarge && JSON.parse(el.dataset.sliderLarge),\n\t\t\tsliderSizeMedium = el.dataset.sliderMedium && JSON.parse(el.dataset.sliderMedium),\n\t\t\tsliderSizeSmall = el.dataset.sliderSmall && JSON.parse(el.dataset.sliderSmall),\n\t\t\tsliderSizeAuto = el.dataset.sliderAuto && JSON.parse(el.dataset.sliderAuto),\n\t\t\tsliderPaginationType = el.dataset.sliderPaginationType && el.dataset.sliderPaginationType,\n\t\t\tsliderSpaceBetween = el.dataset.sliderSpaceBetween && JSON.parse(el.dataset.sliderSpaceBetween),\n\t\t\tsliderOnInteraction = el.dataset.sliderOnInteraction && JSON.parse(el.dataset.sliderOnInteraction),\n\t\t\tsliderNoSwipe = el.dataset.sliderNoSwipe && JSON.parse(el.dataset.sliderNoSwipe),\n\t\t\tsliderFreeMode = el.dataset.sliderFreemode && JSON.parse(el.dataset.sliderFreemode),\n\t\t\tsliderFreeModeSticky = el.dataset.sliderFreemodeSticky && JSON.parse(el.dataset.sliderFreemodeSticky),\n\t\t\tsliderKeyboard = el.dataset.sliderKeyboard && JSON.parse(el.dataset.sliderKeyboard),\n\t\t\tsliderMouseWheel = el.dataset.sliderMousewheel && JSON.parse(el.dataset.sliderMousewheel),\n\t\t\tsliderScroll = el.dataset.sliderScroll && JSON.parse(el.dataset.sliderScroll),\n\t\t\tsliderSpeed = el.dataset.sliderSpeed && JSON.parse(el.dataset.sliderSpeed),\n\t\t\tslidesPerGroup = el.dataset.sliderGroup && JSON.parse(el.dataset.sliderGroup),\n\t\t\tslidesPerColumn = el.dataset.sliderColumn && JSON.parse(el.dataset.sliderColumn)\n\n\t\tconst swiperInstance = new Swiper(el, {\n\t\t\tslidesPerView: sliderSizeAuto ? 'auto' : sliderSizeSmall ? sliderSizeSmall : 1,\n\t\t\twatchSlidesVisibility: sliderSizeAuto && true,\n\t\t\tcenteredSlides: sliderCentered ? sliderCentered : false,\n\t\t\tcenteredSlidesBounds: sliderCentered ? true : false,\n\t\t\tloop: sliderLoop ? sliderLoop : false,\n\t\t\tspaceBetween: sliderSpaceBetween ? sliderSpaceBetween : 0,\n\t\t\tnoSwiping: sliderNoSwipe ? sliderNoSwipe : false,\n\t\t\tspeed: sliderSpeed ? sliderSpeed : 300,\n\t\t\tfreeMode: sliderFreeMode ? sliderFreeMode : false,\n\t\t\tfreeModeSticky: sliderFreeMode && sliderFreeModeSticky ? sliderFreeModeSticky : false,\n\t\t\tslideToClickedSlide: sliderFreeMode ? true : false,\n\t\t\tslidesPerGroup: slidesPerGroup ? slidesPerGroup : 1,\n\t\t\tslidesPerColumn: slidesPerColumn ? slidesPerColumn : 1,\n\t\t\twatchOverflow: true,\n\t\t\tmousewheel: sliderFreeMode ? {\n\t\t\t\treleaseOnEdges: true\n\t\t\t} : sliderMouseWheel ? sliderMouseWheel : false,\n\n\t\t\tkeyboard: {\n\t\t\t\tenabled: sliderKeyboard ? sliderKeyboard : false\n\t\t\t},\n\n\t\t\tnavigation: {\n\t\t\t\tnextEl: el.querySelector('.swiper-button-next'),\n\t\t\t\tprevEl: el.querySelector('.swiper-button-prev')\n\t\t\t},\n\n\t\t\tpagination: {\n\t\t\t\tel: el.parentNode.querySelector('.swiper-pagination'),\n\t\t\t\tclickable: sliderPaginationType ? false : true,\n\t\t\t\ttype: sliderPaginationType ? sliderPaginationType : 'bullets' //\"bullets\", \"fraction\", \"progressbar\" or \"custom\" (default:\"bullets\")\n\t\t\t},\n\n\t\t\tscrollbar: {\n\t\t\t\tel: sliderScroll ? el.parentNode.querySelector('.swiper-scrollbar') : null,\n\t\t\t\thide: sliderScroll && true\n\t\t\t},\n\n\t\t\tautoplay: sliderAutoPlay === true ? {\n\t\t\t\tdelay: sliderDelay ? sliderDelay : 5000,\n\t\t\t\tdisableOnInteraction: sliderOnInteraction ? sliderOnInteraction : false\n\t\t\t} : false,\n\n\t\t\tbreakpoints: {\n\t\t\t\t768: { //tablet up\n\t\t\t\t\tslidesPerView: sliderSizeAuto ? 'auto' : sliderSizeMedium ? sliderSizeMedium : sliderSizeSmall ? sliderSizeSmall : 1\n\t\t\t\t},\n\t\t\t\t1024: { //small desktop up\n\t\t\t\t\tslidesPerView: sliderSizeAuto ? 'auto' : sliderSizeLarge ? sliderSizeLarge : sliderSizeMedium ? sliderSizeMedium : sliderSizeSmall ? sliderSizeSmall : 1\n\t\t\t\t},\n\t\t\t\t1440: { // desktop up\n\t\t\t\t\tslidesPerView: sliderSizeAuto ? 'auto' : sliderSizeWide ? sliderSizeWide : sliderSizeLarge ? sliderSizeLarge : sliderSizeMedium ? sliderSizeMedium : sliderSizeSmall ? sliderSizeSmall : 1\n\t\t\t\t}\n\t\t\t},\n\n\t\t\ton: {\n\n\t\t\t\tinit: () => setTimeout(() => window.dispatchEvent(new Event('resize')), 100),\n\n\t\t\t\tbeforeInit: () => {\n\t\t\t\t\t// this is for sliders that contains cards beta -> on screens 1440px and above the first card is bigger than the others\n\t\t\t\t\tif (this.vars.wideAndUp.matches && el.classList.contains('js-slider-destroy-on-screen-wide')) {\n\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t[...el.querySelectorAll('.swiper-slide')].map(el => (el.style.width = '100%'))\n\t\t\t\t\t\t\tswiperInstance.disable()\n\t\t\t\t\t\t}, 1000)\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tresize: () => {\n\t\t\t\t\t// this is for sliders that contains cards beta -> on screens 1440px and above the first card is bigger than the others\n\t\t\t\t\tif (this.vars.wideAndUp.matches && el.classList.contains('js-slider-destroy-on-screen-wide')) {\n\t\t\t\t\t\t[...el.querySelectorAll('.swiper-slide')].map(el => (el.style.width = '100%', el.parentNode.style.transform = 'none'))\n\t\t\t\t\t\tswiperInstance.disable()\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tswiperInstance.enable()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t},\n\n\tinit() {\n\t\tthis.el.sliderContainer.forEach(el => this.fxInitSlider(el))\n\t}\n}\nloadEventSliders.init()","/* global Swiper */\nconst loadEventVerticalScrollBar = {\n\tel: {\n\t\tverticalScrollBarContainer: document.querySelectorAll('.js-vertical-scrollbar')\n\t},\n\n\tfxInitVerticalScrollbar(el) {\n\n\t\t// Swiper options\n\t\tconst verticalSwiperScrollOptions = {\n\t\t\tdirection: 'vertical',\n\t\t\tslidesPerView: 'auto',\n\t\t\tfreeMode: true,\n\t\t\tmousewheel: true,\n\t\t\tscrollbar: {\n\t\t\t\tsnapOnRelease: false,\n\t\t\t\tdraggable: true,\n\t\t\t\tel: el.querySelector('.swiper-scrollbar')\n\t\t\t}\n\t\t\t\n\t\t}\n\n\t\t// Initialize Swiper\n\t\tnew Swiper(el, verticalSwiperScrollOptions)\n\t},\n\n\tinit() {\n\t\t// Loop through each vertical scrollbar container\n\t\twindow.addEventListener('load', () => this.el.verticalScrollBarContainer.forEach(el => this.fxInitVerticalScrollbar(el)))\n\n\t}\n}\nloadEventVerticalScrollBar.init()","const scrollEventStickyNav = {\n\tel: {\n\t\theader: document.querySelector('.header'),\n\t\tmainWrapper: document.querySelector('.wrapper'),\n\t\tstickyElement: document.querySelector('.js-sticky-nav')\n\t},\n\n\tfxHandleStickyElementOnScroll() {\n\t\t// I know about sticky property in css, but I had to do in javascript because header has logo with box shadow and position out of header, that´s why I did everything with javascript\n\n\t\t// check if page has sticky element\n\t\tif (!this.el.stickyElement) return\n\n\t\t// save current padding top value as a string\n\t\tlet mainWrapperPaddingTopValue = window.getComputedStyle(this.el.mainWrapper).getPropertyValue('padding-top')\n\n\t\t// convert string padding top to a number\n\t\tlet mainWrapperPaddingTopNumber = parseInt(mainWrapperPaddingTopValue, 10)\n\n\t\t// get height of sticky element\n\t\tconst stickyNavHeight = this.el.stickyElement.offsetHeight\n\n\t\t// final position is equal sticky element initial position minus height of header\n\t\tlet stickyFinalPosition = this.el.stickyElement.offsetTop - this.el.header.offsetHeight - stickyNavHeight\n\n\t\t// add listener scroll\n\t\twindow.addEventListener('scroll', () => {\n\t\t\t// check if scroll has reached sticky element\n\t\t\tif (stickyFinalPosition > window.scrollY) {\n\t\t\t\t// if not - remove classes on elements and add padding top initial value on main\n\t\t\t\tthis.el.stickyElement.classList.remove('pinned')\n\t\t\t\tthis.el.header.classList.remove('sticky-nav-pinned')\n\t\t\t\tthis.el.mainWrapper.style.paddingTop = `${mainWrapperPaddingTopNumber}px`\n\t\t\t} else {\n\t\t\t\t// if yes - add classes and new padding top value on main\n\t\t\t\tthis.el.stickyElement.classList.add('pinned')\n\t\t\t\tthis.el.header.classList.add('sticky-nav-pinned')\n\t\t\t\tthis.el.mainWrapper.style.paddingTop = `${mainWrapperPaddingTopNumber + stickyNavHeight}px`\n\t\t\t}\n\t\t})\n\t},\n\n\tinit() {\n\t\twindow.addEventListener('load', () => this.fxHandleStickyElementOnScroll())\n\t}\n}\n\nscrollEventStickyNav.init()","const scrollOnEvent = {\n\tel: {\n\t\theader: document.querySelector('.header'),\n\t\theroBooking: document.querySelector('.hero-headline--no-pattern')\n\t},\n\n\tvars: {\n\t\ttimeToStartScroll: 300,\n\t\theaderHeight: document.querySelector('.header').offsetHeight\n\t},\n\n\tfxScrollOnEvent(el) {\n\t\tconst elementOffset = el.offsetTop,\n\t\t\telementFinalOffset = elementOffset - this.vars.headerHeight\n\n\t\tsetTimeout(() => window.scrollTo(0, elementFinalOffset), this.vars.timeToStartScroll)\n\t},\n\n\tfxScrollSmoothOnEvent(el) {\n\t\tconst elementOffset = el.offsetTop,\n\t\t\telementFinalOffset = elementOffset - this.vars.headerHeight\n\n\t\tsetTimeout(() => window.scrollTo({ top: elementFinalOffset, behavior: 'smooth' }), this.vars.timeToStartScroll)\n\t},\n\n\tinit() {\n\t\tthis.el.heroBooking && this.fxScrollOnEvent(this.el.heroBooking)\n\t}\n}\n\nscrollOnEvent.init()","/* global http google loadEventSliders loadEventGoogleMaps toggleEventsFilterModal scrollOnEvent */\nconst serviceFilterAsideMap = {\n\tel: {\n\t\tbody: document.body,\n\t\tmainContainer: document.querySelector('.js-filter-map'),\n\t\tfilterType: document.querySelectorAll('[data-filter-type]'),\n\t\tfilterInputAndSelectListener: document.querySelectorAll('.js-filter-change-listener'),\n\t\tmapWithMarker: document.querySelector('.js-map-with-markers')\n\t},\n\n\tvars: {\n\t\tcurrentPage: 1,\n\t\textraLargeAndUp: window.matchMedia('(min-width: 75em)')\n\t},\n\n\tfxHandleFilterOnChangeSelectOrInput(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// reset pagination\n\t\tthis.vars.currentPage = 1\n\n\t\t// Responsible for set values of radio buttons and select elements on data attribute called 'data filter id' and make sure that when user select mobile version, the desktop version is selected as well\n\t\ttoggleEventsFilterModal.fxHandleSelectAndInputValue(el)\n\n\t\t// filter results on change of radio button or select\n\t\tthis.fxFilter(this.el.mainContainer)\n\t},\n\n\tfxUpdatePagination(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// set pagination to page selected\n\t\tthis.vars.currentPage = el.textContent\n\n\t\t// Remove all active classes on options\n\t\tdocument.querySelectorAll('.js-filter-pagination-item').forEach(el => el.classList.remove('active'))\n\n\t\t// filter results on pagination selected\n\t\tthis.fxFilter(this.el.mainContainer)\n\t},\n\n\tfxGetSelectedFilterForSummaryResults(filterId) {\n\t\t// get selected filter type\n\t\tconst typeSelected = document.querySelector(`[data-filter-type='${filterId}'`)\n\t\t// save which select option has been selected\n\t\tconst optionSelected = typeSelected.querySelector('select').options.selectedIndex\n\t\t// return text from this option selected - this way we make sure that we return the exact same value as the one in select element\n\t\treturn typeSelected.querySelector('select').options[optionSelected].text\n\t},\n\n\tfxRenderSummaryResults(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// set the number of results with data.length\n\t\t\tdocument.querySelector('.js-filter-summary-counter').textContent = data.totalRecords\n\n\t\t\t// save variables for later use\n\t\t\tlet filterRegion\n\t\t\tlet filterLocation\n\t\t\tlet filterCategories\n\n\t\t\t// populate variables \n\t\t\tfilterRegion = this.fxGetSelectedFilterForSummaryResults('region')\n\t\t\tfilterLocation = this.fxGetSelectedFilterForSummaryResults('location')\n\t\t\tfilterCategories = this.fxGetSelectedFilterForSummaryResults('category')\n\n\t\t\t// set each result with variables created above\n\t\t\tdocument.querySelector('.js-filter-summary-first-selected').textContent = filterRegion\n\t\t\tdocument.querySelector('.js-filter-summary-second-selected').textContent = filterLocation\n\t\t\tdocument.querySelector('.js-filter-summary-third-selected').textContent = filterCategories\n\n\t\t}\n\n\t},\n\n\tfxRenderAsideResults(response, data) {\n\n\t\tif (response.status === 200) {\n\n\t\t\t// first we need to get rid of the old results\n\t\t\tdocument.querySelectorAll('.aside-filter-map__item').forEach(el => el.remove())\n\n\t\t\t// set variables for later use\n\t\t\tlet cardsAsideFilterMap\n\t\t\tlet imageSliderItem\n\n\t\t\t// CARDS\n\t\t\t//then we need to render the new results looping through the data\n\t\t\tdata.items.map((el, index) => {\n\n\t\t\t\t// set this variable in order to use it only if labelValue is true\n\t\t\t\tconst label = el.labelValue && `\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t${el.labelValue}€\n\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t${el.labelCopy}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t`\n\t\t\t\t//save card structure in a variable\n\t\t\t\tcardsAsideFilterMap =\n\t\t\t\t\t`\n\t\t\t\t\t\t
  • \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t
    ${el.beforeHeading}
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t
    ${el.caption}
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    ${el.heading}
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t
    ${el.beforeHeading}
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t\t
    ${el.caption}
    \n\t\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    ${el.heading}
    \n\t\t\t\t\t\t\t\t\t
    ${el.copy}
    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
  • \n\t\t\t\t\t`\n\t\t\t\t// insert wrap container inside container (aside-filter-map__list) that is already in the DOM\n\t\t\t\tdocument.querySelector('.aside-filter-map__list').insertAdjacentHTML('beforeend', cardsAsideFilterMap);\n\n\t\t\t\t// loop through data with slider image in order to build the slider\n\t\t\t\t[...el.imageSlider].map(el => {\n\t\t\t\t\timageSliderItem = `\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t${el.alt}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    \n\t\t\t\t\t`\n\t\t\t\t\t// insert each slider in swiper-wrapper right after create swiper-slide\n\t\t\t\t\tdocument.querySelectorAll('.aside-filter-map__item')[index].querySelector('.swiper-wrapper').insertAdjacentHTML('beforeend', imageSliderItem)\n\n\t\t\t\t})\n\t\t\t\t// load swiper - in order to make swiper slider work\n\t\t\t\tloadEventSliders.fxInitSlider(document.querySelectorAll('.js-slider')[index])\n\t\t\t})\n\n\t\t\t// PAGINATION\n\t\t\tconst paginationContainer = document.querySelector('.js-filter-pagination')\n\t\t\tpaginationContainer.innerHTML = ''\n\t\t\t// check if there is pagination\n\t\t\tif (data.numberOfPages > 0) {\n\t\t\t\t// first we remove all pagination build before\n\t\t\t\t// loop through numberOfPages in order to create each item element\n\t\t\t\tfor (let i = 0; i < data.numberOfPages; i++) {\n\t\t\t\t\tpaginationContainer.innerHTML += ``\n\t\t\t\t}\n\n\t\t\t\tfor (const pageItems of document.querySelectorAll('.js-filter-pagination-item'))\n\t\t\t\t\tpageItems.addEventListener('click', e => {\n\t\t\t\t\t\tthis.fxUpdatePagination(e.currentTarget)\n\t\t\t\t\t\tscrollOnEvent.fxScrollSmoothOnEvent(document.querySelector('.aside-filter-map'))\n\t\t\t\t\t})\n\n\t\t\t\tdocument.querySelector(`[data-aside-filter-pagination=\"${this.vars.currentPage}\"]`).classList.add('active')\n\t\t\t}\n\t\t}\n\t},\n\n\tfxRenderMarkersOnMapResults(response, data) {\n\t\t// check if map element is the one with markers\n\t\tif (!this.el.mapWithMarker) return\n\n\t\t// init map\n\t\tconst map = loadEventGoogleMaps.fxLoadMap(this.el.mapWithMarker)\n\n\t\t// this is for map initialization with all markers on viewport\n\t\tconst bounds = new google.maps.LatLngBounds()\n\n\t\t// set variables with null value\n\t\tlet cardMap\n\t\tlet imageSliderItemMapCard\n\t\tlet markers = []\n\t\tlet infoWindows = []\n\n\t\t// image marker icon default\n\t\tconst imageMarker = {\n\t\t\turl: this.el.mapWithMarker.dataset.mapMarkerImage\n\t\t}\n\n\t\t// image marker icon hovered or selected\n\t\tconst imageMarkerHovered = {\n\t\t\turl: this.el.mapWithMarker.dataset.mapMarkerImageHovered\n\t\t}\n\n\t\t// reset all markers\n\t\tmarkers.forEach(el => el.setMap(null))\n\n\t\t// responsible for toggle markers and info windows on click\n\t\tfunction handleToggleMarkersAndInfoWindows() {\n\t\t\tmarkers.forEach(el => el.setIcon(imageMarker))\n\t\t\tinfoWindows.forEach(el => el.close())\n\t\t}\n\n\t\t// responsible for toggle only markers\n\t\tfunction handleToggleOnlyMarkers() {\n\t\t\tmarkers.forEach(el => el.setIcon(imageMarker))\n\t\t}\n\n\t\t// responsible for change markers on hover each card item on aside\n\t\tdocument.querySelectorAll('.js-aside-item').forEach(el => {\n\t\t\tel.addEventListener('mouseenter', e => {\n\t\t\t\tconst heading = e.currentTarget.querySelector('.js-aside-heading').textContent\n\t\t\t\tmarkers.find(marker => {\n\t\t\t\t\tif (marker.title === heading) {\n\t\t\t\t\t\tmarker.setIcon(imageMarkerHovered)\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tmarker.setIcon(imageMarker)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\t// check if status is success\n\t\tif (response.status === 200) {\n\n\t\t\t// loop through data, build markers and cardsMap (called here as infoWindow)\n\t\t\tdata.itemsMap.map(el => {\n\t\t\t\t// set this variable in order to use it only if labelValue is true\n\t\t\t\tconst labelMapCard = el.labelValue && `\n\t\t\t\t\t
    \n\t\t\t\t\t\t${el.labelValue}€\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t${el.labelCopy}\n\t\t\t\t\t
    \n\t\t\t\t`\n\t\t\t\t// set this variable in order to build each swiper slide\n\t\t\t\tconst wrapSliders = [...el.imageSlider].map(el => {\n\t\t\t\t\timageSliderItemMapCard = `\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t`\n\t\t\t\t\treturn imageSliderItemMapCard\n\t\t\t\t})\n\n\t\t\t\t// build cardMap on markers\n\t\t\t\tcardMap =\n\t\t\t\t\t`\n\t\t\t\t\t\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t${wrapSliders}\n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t${labelMapCard}\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
    ${el.beforeHeading}
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    ${el.heading}
    \n\t\t\t\t\t\t\t
    ${el.caption}
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t
    \n\t\t\t\t`\n\n\t\t\t\t// transform latitude and longitude to Number\n\t\t\t\tconst lat = Number(el.latitude)\n\t\t\t\tconst lng = Number(el.longitude)\n\n\t\t\t\t// set markers options\n\t\t\t\tconst markerOptions = {\n\t\t\t\t\tposition: {\n\t\t\t\t\t\tlat,\n\t\t\t\t\t\tlng\n\t\t\t\t\t},\n\t\t\t\t\tmap,\n\t\t\t\t\ticon: imageMarker,\n\t\t\t\t\ttitle: el.heading,\n\t\t\t\t\tanimation: google.maps.Animation.DROP,\n\t\t\t\t\toptimized: false\n\t\t\t\t}\n\n\t\t\t\t// create marker instance\n\t\t\t\tconst marker = new google.maps.Marker()\n\t\t\t\t// set options of markers\n\t\t\t\tmarker.setOptions(markerOptions)\n\n\t\t\t\t// set infoWindow options\n\t\t\t\tconst infoWindowOptions = {\n\t\t\t\t\tcontent: cardMap,\n\t\t\t\t\tmaxWidth: 240\n\t\t\t\t}\n\n\t\t\t\t// Create an info window instance\n\t\t\t\tconst infoWindow = new google.maps.InfoWindow()\n\t\t\t\t// set options of infoWindow\n\t\t\t\tinfoWindow.setOptions(infoWindowOptions)\n\n\t\t\t\t// LISTENERS\n\t\t\t\t// click listener on each marker - it opens infoWindow, change icon of marker to hovered, set zom on map \n\t\t\t\tmarker.addListener('click', () => {\n\n\t\t\t\t\thandleToggleMarkersAndInfoWindows()\n\t\t\t\t\tmarker.setIcon(imageMarkerHovered)\n\t\t\t\t\tmap.setZoom(8)\n\n\t\t\t\t\tinfoWindow.open({\n\t\t\t\t\t\tanchor: marker,\n\t\t\t\t\t\tmap,\n\t\t\t\t\t\tshouldFocus: true\n\t\t\t\t\t})\n\t\t\t\t})\n\n\t\t\t\t// mouseover listener on each marker - it change marker icon to hovered\n\t\t\t\tmarker.addListener('mouseover', () => {\n\t\t\t\t\thandleToggleOnlyMarkers()\n\t\t\t\t\tmarker.setIcon(imageMarkerHovered)\n\t\t\t\t})\n\n\t\t\t\t// this make sure that infoWindow and markers selected before are set to default\n\t\t\t\tinfoWindows.push(infoWindow)\n\t\t\t\tmarkers.push(marker)\n\n\t\t\t\t// map click listener - it closes all infoWindows and set markers to default\n\t\t\t\tmap.addListener('click', () => {\n\t\t\t\t\tmarker.setIcon(imageMarker)\n\t\t\t\t\tinfoWindow.close()\n\t\t\t\t})\n\n\t\t\t\t// map drag listener - it closes all infoWindows and set markers to default\n\t\t\t\tmap.addListener('drag', () => {\n\t\t\t\t\tmarker.setIcon(imageMarker)\n\t\t\t\t\tinfoWindow.close()\n\t\t\t\t})\n\n\t\t\t\t// infoWindow listener - domready - it makes sure that infoWindow hide close button and initialize swiper\n\t\t\t\tinfoWindow.addListener('domready', () => {\n\t\t\t\t\tdocument.querySelectorAll('.gm-style-iw-d')[0].style.overflow = 'auto'\n\t\t\t\t\tdocument.querySelectorAll('.js-slider').forEach(el => loadEventSliders.fxInitSlider(el))\n\t\t\t\t\tmap.setCenter(map.getCenter())\n\t\t\t\t})\n\n\t\t\t\t// this get position of each marker\n\t\t\t\tbounds.extend(marker.getPosition())\n\t\t\t\t// and set bounds to map in order to show markers on viewport\n\t\t\t\tmap.fitBounds(bounds)\n\t\t\t})\n\t\t}\n\t},\n\n\tfxGetFilterID(filterId) {\n\t\t// find filter type from parameter and get filter ID\n\t\treturn document.querySelector(`[data-filter-type='${filterId}'`).getAttribute('data-filter-id')\n\t},\n\n\tfxFilter(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// set variables let (let it change)\n\t\tlet filterRegion\n\t\tlet filterLocation\n\t\tlet filterCategories\n\n\t\t// populate variables\n\t\tfilterRegion = this.fxGetFilterID('region')\n\t\tfilterLocation = this.fxGetFilterID('location')\n\t\tfilterCategories = this.fxGetFilterID('category')\n\n\t\t// get endpoint\n\t\tconst endpoint = el.getAttribute('data-action-filter-map')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\tregion: filterRegion ? filterRegion : 'all',\n\t\t\tlocation: filterLocation ? filterLocation : 'all',\n\t\t\tcategory: filterCategories ? filterCategories : 'all',\n\t\t\tpage: this.vars.currentPage\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// call function that will build cards\n\t\t\tthis.fxRenderAsideResults(response, data)\n\n\t\t\t// call function that will build map markers\n\t\t\tthis.fxRenderMarkersOnMapResults(response, data)\n\n\t\t\t// call function that will fill summary results\n\t\t\tthis.fxRenderSummaryResults(response, data)\n\t\t}\n\n\t\t// call api\n\t\thttp.fxPost(endpoint, formData, callback, languageParameter)\n\t},\n\n\tevents() {\n\t\t// Responsible for all events on select and radio buttons\n\t\tthis.el.filterInputAndSelectListener.forEach(el => el.addEventListener('change', e => this.fxHandleFilterOnChangeSelectOrInput(e)))\n\n\t\t// Responsible for filter on load page\n\t\twindow.addEventListener('load', () => this.fxFilter(this.el.mainContainer))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nserviceFilterAsideMap.init()","/* global http toggleEventsFilterModal */\nconst serviceFilterContactHostelsList = {\n\tel: {\n\t\tbody: document.body,\n\t\tmainContainer: document.querySelector('.js-filter-contact-list'),\n\t\tfilterInputAndSelectListener: document.querySelectorAll('.js-filter-change-listener'),\n\t\tloadMoreButton: document.querySelector('.js-filter-loadmore-listener')\n\t},\n\n\tvars: {\n\t\tcurrentPage: 1\n\t},\n\n\tfxHandleFilterOnChangeSelectOrInput(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// reset pagination\n\t\tthis.vars.currentPage = 1\n\n\t\t// Responsible for set values of radio buttons and select elements on data attribute called \"data filter id\" and make sure that when user select mobile version, the desktop version is selected as well\n\t\ttoggleEventsFilterModal.fxHandleSelectAndInputValue(el)\n\n\t\t// filter results on change of radio button or select\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tfxUpdatePagination() {\n\t\t// increase the current page\n\t\tthis.vars.currentPage += 1\n\n\t\t// filter results on pagination selected\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tfxRenderCards(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// this condition is needed to make sure that when user select a new filter, the results are filtered again\n\t\t\tif (this.vars.currentPage === 1) {\n\t\t\t\t// remove all the cards\n\t\t\t\tdocument.querySelectorAll('.list-content__list-item').forEach(el => el.remove())\n\t\t\t}\n\n\t\t\t//set variables for later use\n\t\t\tlet contentListItem\n\n\t\t\t//then we need to render the new results looping through the data\n\t\t\tdata.items.map(el => {\n\n\t\t\t\t//save card structure in a variable\n\t\t\t\tcontentListItem =\n\t\t\t\t\t`\n\t\t\t\t\t
  • \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t${el.title}\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t${el.email}\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t${el.phone}\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t${el.addressText}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    \n\t\t\t\t\t
  • \n\t\t\t\t\t`\n\t\t\t\t// insert wrap container inside container (list-content__list) that is already in the DOM\n\t\t\t\tdocument.querySelector('.list-content__list').insertAdjacentHTML('beforeend', contentListItem)\n\t\t\t})\n\n\t\t\tif (!data.loadMore) {\n\t\t\t\tthis.el.loadMoreButton.style.display = 'none'\n\t\t\t}\n\t\t}\n\t},\n\n\tfxGetSelectedFilterForSummaryResults(filterId) {\n\t\t// get selected filter type\n\t\tconst typeSelected = document.querySelector(`[data-filter-type=\"${filterId}\"`)\n\t\t// save which select option has been selected\n\t\tconst optionSelected = typeSelected.querySelector('select').options.selectedIndex\n\t\t// return text from this option selected - this way we make sure that we return the exact same value as the one in select element\n\t\treturn typeSelected.querySelector('select').options[optionSelected].text\n\t},\n\n\tfxRenderSummaryRouteResults(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// set the number of results with data.length\n\t\t\tdocument.querySelector('.js-filter-summary-counter').textContent = data.totalRecords\n\n\t\t\t// save variables for later use\n\t\t\tlet filterRegion\n\t\t\tlet filterLocation\n\n\t\t\t// populate variables \n\t\t\tfilterRegion = this.fxGetSelectedFilterForSummaryResults('region')\n\t\t\tfilterLocation = this.fxGetSelectedFilterForSummaryResults('location')\n\n\t\t\t// set each result with variables created above\n\t\t\tdocument.querySelector('.js-filter-summary-first-selected').textContent = filterRegion\n\t\t\tdocument.querySelector('.js-filter-summary-second-selected').textContent = filterLocation\n\t\t}\n\t},\n\n\tfxGetFilterID(filterId) {\n\t\t// find filter type from parameter and get filter ID\n\t\treturn document.querySelector(`[data-filter-type=\"${filterId}\"`).getAttribute('data-filter-id')\n\t},\n\n\tfxFilterRoutes(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// set variables let (let it change)\n\t\tlet filterRegion\n\t\tlet filterLocation\n\n\t\t// populate variables\n\t\tfilterRegion = this.fxGetFilterID('region')\n\t\tfilterLocation = this.fxGetFilterID('location')\n\n\t\t// get endpoint\n\t\tconst endpoint = el.getAttribute('data-action-contacts')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\tregion: filterRegion ? filterRegion : 'all',\n\t\t\tlocation: filterLocation ? filterLocation : 'all',\n\t\t\tpage: this.vars.currentPage\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// call function that will build cards\n\t\t\tthis.fxRenderCards(response, data)\n\n\t\t\t// call function that will fill summary results\n\t\t\tthis.fxRenderSummaryRouteResults(response, data)\n\t\t}\n\n\t\t// call api\n\t\thttp.fxPost(endpoint, formData, callback, languageParameter)\n\t},\n\n\tevents() {\n\t\t// check if element exists\n\t\tif (!this.el.mainContainer) return\n\n\t\t// Responsible for all events on select and radio buttons\n\t\tthis.el.filterInputAndSelectListener.forEach(el => el.addEventListener('change', e => this.fxHandleFilterOnChangeSelectOrInput(e)))\n\n\t\t// Responsible for pagination \n\t\tthis.el.loadMoreButton && this.el.loadMoreButton.addEventListener('click', () => this.fxUpdatePagination())\n\n\t\t// Responsible for filter on load page\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nserviceFilterContactHostelsList.init()","/* global flatpickr http loadEventSliders toggleEventsFilterModal */\nconst serviceFilterEventsAsideDatePicker = {\n\tel: {\n\t\tbody: document.body,\n\t\tasideDatePickerContainer: document.querySelector('.js-aside-date-picker'),\n\t\tflatPickerContainer: document.querySelector('.js-init-date-picker'),\n\t\tmainContainer: document.querySelector('.js-filter-events')\n\t},\n\n\tfxFilterEvents(element) {\n\t\tif (!element) return\n\n\t\t// set variables let (let it change)\n\t\tlet filterRegion\n\t\tlet filterLocation\n\n\t\t// populate variables\n\t\tfilterRegion = this.fxGetFilterID('regionEvents')\n\t\tfilterLocation = this.fxGetFilterID('locationEvents')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\teventDate: 'all',\n\t\t\tregion: filterRegion ? filterRegion : 'allRegions',\n\t\t\tlocation: filterLocation ? filterLocation : 'allLocations'\n\t\t}\n\n\t\t// get attributes in order to call api when page is loaded\n\t\tconst apiEndPointOnLoadPage = this.el.asideDatePickerContainer.getAttribute('data-action-news-cards')\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// call function that will fill summary results\n\t\t\tthis.fxRenderSummaryEventsResults(response, data)\n\n\t\t\t//update datepicker\n\t\t\tthis.fxInitFlatpickr(this.el.flatPickerContainer, response, data)\n\t\t\t// console.log(response, data)\n\t\t}\n\n\t\t// call api\n\t\thttp.fxPost(apiEndPointOnLoadPage, formData, callback, languageParameter)\n\t},\n\n\tfxBuildCardWhenThereIsNoEvent() {\n\t\t// get attributes in order to call api\n\t\tconst cardEmptySrcImage = this.el.asideDatePickerContainer.getAttribute('data-card-empty-src')\n\n\t\t// get attributes in order to call api\n\t\tconst cardEmptyCopy = this.el.asideDatePickerContainer.getAttribute('data-card-empty-copy')\n\n\t\t// check if user already opened gallery, if yes we remove everything inside modal\n\t\tdocument.querySelector('.aside-date-picker__slider-wrap') && document.querySelector('.aside-date-picker__slider-wrap').remove()\n\n\t\tconst cardEmptyNoEvent =\n\t\t\t`\n\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t

    ${cardEmptyCopy}

    \n\t\t\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t\n\t\t\t
    \n\t\t`\n\n\t\t// insert wrap container inside container (aside-gallery-modal) that is already in the DOM\n\t\tdocument.querySelector('.aside-date-picker__slider').insertAdjacentHTML('beforeend', cardEmptyNoEvent)\n\t},\n\n\tfxBuildSliderWithCards(response, data) {\n\t\t// check if response is success\n\t\tif (response.status === 200) {\n\t\t\t// check if user already opened gallery, if yes we remove everything inside modal\n\t\t\tdocument.querySelector('.aside-date-picker__slider-wrap') && document.querySelector('.aside-date-picker__slider-wrap').remove()\n\n\t\t\t// save container that goes inside aside-gallery-modal\n\t\t\tconst cardEventOnSlider =\n\t\t\t\t`\n\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\n\t\t\t\t\t
    \n\t\t\t\t`\n\n\t\t\t// insert wrap container inside container (aside-gallery-modal) that is already in the DOM\n\t\t\tdocument.querySelector('.aside-date-picker__slider').insertAdjacentHTML('beforeend', cardEventOnSlider)\n\n\t\t\t// do a loop in data variable in order to get each content inside array\n\t\t\tdata.map(el => {\n\t\t\t\t// get selector swiper wrapper that is inside modal and insert node element\n\t\t\t\tdocument.querySelector('.aside-date-picker__slider-wrap .swiper-wrapper').innerHTML +=\n\t\t\t\t\t`\n\t\t\t\t\t\n\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t${el.eventDate}\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t

    ${el.eventHeading}

    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t`\n\t\t\t})\n\t\t\tsetTimeout(() => loadEventSliders.fxInitSlider(document.querySelector('.js-slider')), 1)\n\t\t}\n\t},\n\n\tfxHandleGetEventInfoFromUniqueDay(data, submissionType) {\n\n\t\t// save in a variable the day that user is on page\n\t\tlet findSelectedDateOnLoadPage\n\n\t\t// save in a variable the day that user clicked on datepicker\n\t\tlet findSelectedDateOnFilterItems\n\n\t\t// save in a variable parameter that goes with apiEndPoint\n\t\tlet getApiParameter\n\n\t\t// save endPoint that will be used to call api\n\t\tlet apiEndPoint\n\n\t\t// get attributes in order to call api\n\t\tconst actionAttribute = this.el.asideDatePickerContainer.getAttribute('data-action-news-cards')\n\n\t\t// check if page has been load or user clicked on datepicker\n\t\tif (submissionType === 'load') {\n\t\t\t// get atribute from element that has class today - it returns a string with date \"YYYY-MM-DD\"\n\t\t\tfindSelectedDateOnLoadPage = document.querySelector('.today') && document.querySelector('.today').getAttribute('aria-label')\n\n\t\t\t// we loop through response from api and find which event date is equal atribute saved before\n\t\t\tgetApiParameter = data.items.find(el => el.eventDate === findSelectedDateOnLoadPage)\n\n\t\t\t// if we don´t find any date that is equal to atribute saved before we return a card saying that there are no events\n\t\t\tif (!getApiParameter) {\n\t\t\t\tthis.fxBuildCardWhenThereIsNoEvent()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t} else {\n\t\t\t// get atribute from element that has class selected - it returns a string with date \"YYYY-MM-DD\"\n\t\t\tfindSelectedDateOnFilterItems = document.querySelector('.selected').getAttribute('aria-label')\n\n\t\t\t// we loop through response from api and find which event date is equal atribute saved before\n\t\t\tgetApiParameter = data.items.find(el => el.eventDate === findSelectedDateOnFilterItems)\n\n\t\t\t// if we don´t find any date that is equal to atribute saved before we return a card saying that there are no events\n\t\t\tif (!getApiParameter) {\n\t\t\t\tthis.fxBuildCardWhenThereIsNoEvent()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// get apiEndPoint \n\t\tapiEndPoint = `${actionAttribute}${getApiParameter.eventDate} `\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set variables let (let it change)\n\t\tlet filterRegion\n\t\tlet filterLocation\n\n\t\t// populate variables\n\t\tfilterRegion = this.fxGetFilterID('regionEvents')\n\t\tfilterLocation = this.fxGetFilterID('locationEvents')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\teventDate: getApiParameter.eventDate,\n\t\t\tregion: filterRegion ? filterRegion : 'allRegions',\n\t\t\tlocation: filterLocation ? filterLocation : 'allLocations'\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// call function that will build cards\n\t\t\tthis.fxBuildSliderWithCards(response, data)\n\t\t}\n\n\t\t// GET function - from @http.js file\n\t\thttp.fxPost(apiEndPoint, formData, callback, languageParameter)\n\t},\n\n\tfxInitFlatpickr(el, response, data) {\n\n\t\tif (response.status === 200) {\n\t\t\t// function responsible for color each date picker that has an event\n\t\t\tconst fxHandleColorPickerDate = (data, submissionType) => {\n\t\t\t\t// first we loop through all the dates that are in the response\n\t\t\t\tdata.items.forEach(cardEvent => {\n\t\t\t\t\t// then we loop through all the dates that are in the flatpickr date picker\n\t\t\t\t\tdocument.querySelectorAll('.flatpickr-day').forEach(el => {\n\t\t\t\t\t\t// we save in a variable the atribute value of the date picker - it comes like this: \"YYYY-MM-DD\" - you can change it ate ariaDateFormat inside flatpickrOptions\n\t\t\t\t\t\tconst dateOnPicker = el.getAttribute('aria-label')\n\n\t\t\t\t\t\t// check if date on response is equal to date on flatpickr date picker\n\t\t\t\t\t\tif (cardEvent.eventDate === dateOnPicker) {\n\t\t\t\t\t\t\t// if yes we add class active on the date picker\n\t\t\t\t\t\t\tel.classList.add('is-active')\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\n\t\t\t\t// than we call this function in order to build cards\n\t\t\t\tthis.fxHandleGetEventInfoFromUniqueDay(data, submissionType)\n\t\t\t}\n\n\t\t\tconst flatpickrOptions = {\n\t\t\t\tlocale: el.dataset.language,\n\t\t\t\tinline: true,\n\t\t\t\tdateFormat: 'Y-m-d',\n\t\t\t\tariaDateFormat: 'Y-m-d',\n\n\t\t\t\tonReady: () => {\n\t\t\t\t\tfxHandleColorPickerDate(data, 'load')\n\t\t\t\t},\n\n\t\t\t\tonChange: () => {\n\t\t\t\t\tfxHandleColorPickerDate(data, 'filter')\n\t\t\t\t},\n\n\t\t\t\tonMonthChange: () => {\n\t\t\t\t\tfxHandleColorPickerDate(data, 'load')\n\t\t\t\t},\n\n\t\t\t\tonYearChange: () => {\n\t\t\t\t\tfxHandleColorPickerDate(data, 'load')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tflatpickr(el, flatpickrOptions)\n\t\t}\n\n\t},\n\n\tfxHandleFilterOnChangeSelectOrInput(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// Responsible for set values of radio buttons and select elements on data attribute called \"data filter id\" and make sure that when user select mobile version, the desktop version is selected as well\n\t\ttoggleEventsFilterModal.fxHandleSelectAndInputValue(el)\n\n\t\t// filter results on change of radio button or select\n\t\tthis.fxFilterEvents(this.el.mainContainer)\n\t},\n\n\tfxGetSelectedFilterForSummaryResults(filterId) {\n\t\t// get selected filter type\n\t\tconst typeSelected = document.querySelector(`[data-filter-type=\"${filterId}\"`)\n\t\t// save which select option has been selected\n\t\tconst optionSelected = typeSelected.querySelector('select').options.selectedIndex\n\t\t// return text from this option selected - this way we make sure that we return the exact same value as the one in select element\n\t\treturn typeSelected.querySelector('select').options[optionSelected].text\n\t},\n\n\tfxRenderSummaryEventsResults(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// set the number of results with data.length\n\t\t\tdocument.querySelector('.js-filter-summary-counter').textContent = data.totalRecords\n\n\t\t\t// save variables for later use\n\t\t\tlet filterRegion\n\t\t\tlet filterLocation\n\n\t\t\t// populate variables \n\t\t\tfilterRegion = this.fxGetSelectedFilterForSummaryResults('regionEvents')\n\t\t\tfilterLocation = this.fxGetSelectedFilterForSummaryResults('locationEvents')\n\n\t\t\t// set each result with variables created above\n\t\t\tdocument.querySelector('.js-filter-summary-first-selected').textContent = filterRegion\n\t\t\tdocument.querySelector('.js-filter-summary-second-selected').textContent = filterLocation\n\t\t}\n\t},\n\n\tfxGetFilterID(filterId) {\n\t\t// find filter type from parameter and get filter ID\n\t\treturn document.querySelector(`[data-filter-type=\"${filterId}\"`).getAttribute('data-filter-id')\n\t},\n\n\tevents() {\n\t\t// Responsible for first time initialization of the flatpickr date picker and call api\n\t\tthis.fxFilterEvents(this.el.asideDatePickerContainer)\n\n\t\t//update calendar on input/select change according to region/location\n\t\tthis.el.mainContainer.querySelectorAll('.js-filter-change-listener').forEach((el) => {\n\t\t\tel.addEventListener('change', (e) => {\n\t\t\t\tthis.fxHandleFilterOnChangeSelectOrInput(e)\n\t\t\t})\n\t\t})\n\t},\n\n\tinit() {\n\t\tif (!this.el.mainContainer) return\n\t\tthis.events()\n\t}\n}\n\nserviceFilterEventsAsideDatePicker.init()","/* global http toggleEventsFilterModal */\nconst serviceFilterJobOffers = {\n\tel: {\n\t\tbody: document.body,\n\t\tmainContainer: document.querySelector('.js-filter-jobs'),\n\t\tfilterInputAndSelectListener: document.querySelectorAll('.js-filter-change-listener'),\n\t\tloadMoreButton: document.querySelector('.js-filter-loadmore-listener')\n\t},\n\n\tvars: {\n\t\tcurrentPage: 1\n\t},\n\n\tfxHandleFilterOnChangeSelectOrInput(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// reset pagination\n\t\tthis.vars.currentPage = 1\n\n\t\t// Responsible for set values of radio buttons and select elements on data attribute called \"data filter id\" and make sure that when user select mobile version, the desktop version is selected as well\n\t\ttoggleEventsFilterModal.fxHandleSelectAndInputValue(el)\n\n\t\t// filter results on change of radio button or select\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tfxUpdatePagination() {\n\t\t// increase the current page\n\t\tthis.vars.currentPage += 1\n\n\t\t// filter results on pagination selected\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tfxRenderCards(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// this condition is needed to make sure that when user select a new filter, the results are filtered again\n\t\t\tif (this.vars.currentPage === 1) {\n\t\t\t\t// remove all the cards\n\t\t\t\tdocument.querySelectorAll('.cards-container__item').forEach(el => el.remove())\n\t\t\t}\n\n\t\t\t//set variables for later use\n\t\t\tlet card\n\n\t\t\t//then we need to render the new results looping through the data\n\t\t\tdata.items.map(el => {\n\n\t\t\t\t//save card structure in a variable\n\t\t\t\tcard =\n\t\t\t\t\t`\n\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t${el.title}\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t${el.location}\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t

    ${el.title}

    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t`\n\t\t\t\t// insert wrap container inside container (list-content__list) that is already in the DOM\n\t\t\t\tdocument.querySelector('.cards-container__grid').insertAdjacentHTML('beforeend', card)\n\t\t\t})\n\n\t\t\tif (!data.loadMore) {\n\t\t\t\tthis.el.loadMoreButton.style.display = 'none'\n\t\t\t}\n\t\t}\n\t},\n\n\tfxGetSelectedFilterForSummaryResults(filterId) {\n\t\t// get selected filter type\n\t\tconst typeSelected = document.querySelector(`[data-filter-type=\"${filterId}\"`)\n\t\t// save which select option has been selected\n\t\tconst optionSelected = typeSelected.querySelector('select').options.selectedIndex\n\t\t// return text from this option selected - this way we make sure that we return the exact same value as the one in select element\n\t\treturn typeSelected.querySelector('select').options[optionSelected].text\n\t},\n\n\tfxRenderSummaryRouteResults(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// set the number of results with data.length\n\t\t\tdocument.querySelector('.js-filter-summary-counter').textContent = data.totalRecords\n\n\t\t\t// save variables for later use\n\t\t\tlet filterRegion\n\t\t\tlet filterLocation\n\n\t\t\t// populate variables \n\t\t\tfilterRegion = this.fxGetSelectedFilterForSummaryResults('region')\n\t\t\tfilterLocation = this.fxGetSelectedFilterForSummaryResults('hostel')\n\n\t\t\t// set each result with variables created above\n\t\t\tdocument.querySelector('.js-filter-summary-first-selected').textContent = filterRegion\n\t\t\tdocument.querySelector('.js-filter-summary-second-selected').textContent = filterLocation\n\t\t}\n\t},\n\n\tfxGetFilterID(filterId) {\n\t\t// find filter type from parameter and get filter ID\n\t\treturn document.querySelector(`[data-filter-type=\"${filterId}\"`).getAttribute('data-filter-id')\n\t},\n\n\tfxFilterRoutes(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// set variables let (let it change)\n\t\tlet filterRegion\n\t\tlet filterHostel\n\n\t\t// populate variables\n\t\tfilterRegion = this.fxGetFilterID('region')\n\t\tfilterHostel = this.fxGetFilterID('hostel')\n\n\t\t// get endpoint\n\t\tconst endpoint = el.getAttribute('data-action-job-cards')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\tregion: filterRegion ? filterRegion : 'all',\n\t\t\thostel: filterHostel ? filterHostel : 'all',\n\t\t\tpage: this.vars.currentPage\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// call function that will build cards\n\t\t\tthis.fxRenderCards(response, data)\n\n\t\t\t// call function that will fill summary results\n\t\t\tthis.fxRenderSummaryRouteResults(response, data)\n\t\t}\n\n\t\t// call api\n\t\thttp.fxPost(endpoint, formData, callback, languageParameter)\n\t},\n\n\tevents() {\n\t\t// check if element exists\n\t\tif (!this.el.mainContainer) return\n\n\t\t// Responsible for all events on select and radio buttons\n\t\tthis.el.filterInputAndSelectListener.forEach(el => el.addEventListener('change', e => this.fxHandleFilterOnChangeSelectOrInput(e)))\n\n\t\t// Responsible for pagination \n\t\tthis.el.loadMoreButton && this.el.loadMoreButton.addEventListener('click', () => this.fxUpdatePagination())\n\n\t\t// Responsible for filter on load page\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nserviceFilterJobOffers.init()","/* global http */\nconst serviceFilterNews = {\n\tel: {\n\t\tbody: document.body,\n\t\tmainContainer: document.querySelector('.js-filter-loadmore'),\n\t\tloadMoreButton: document.querySelector('.js-filter-loadmore-listener')\n\t},\n\n\tvars: {\n\t\tcurrentPage: 1\n\t},\n\n\tfxUpdatePagination() {\n\n\t\t// increase the current page\n\t\tthis.vars.currentPage += 1\n\n\t\t// filter results on pagination selected\n\t\tthis.fxFilterNews(this.el.mainContainer)\n\t},\n\n\tfxRenderCards(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t//set variables for later use\n\t\t\tlet cardsBetaGrid\n\n\t\t\t//then we need to render the new results looping through the data\n\t\t\tdata.items.map(el => {\n\n\t\t\t\t//save card structure in a variable\n\t\t\t\tcardsBetaGrid =\n\t\t\t\t\t`\n\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t${el.date}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t

    \n\t\t\t\t\t\t\t\t\t${el.title}\n\t\t\t\t\t\t\t\t

    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t`\n\t\t\t\t// insert wrap container inside container (cards-container__grid) that is already in the DOM\n\t\t\t\tdocument.querySelector('.cards-container__grid').insertAdjacentHTML('beforeend', cardsBetaGrid)\n\n\t\t\t})\n\n\t\t\tif (!data.loadMore) {\n\t\t\t\tthis.el.loadMoreButton.style.display = 'none'\n\t\t\t}\n\t\t}\n\t},\n\n\tfxFilterNews(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// get endpoint\n\t\tconst endpoint = el.getAttribute('data-action-loadmore')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\tpage: this.vars.currentPage\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// call function that will build cards\n\t\t\tthis.fxRenderCards(response, data)\n\t\t}\n\n\t\t// call api\n\t\thttp.fxPost(endpoint, formData, callback, languageParameter)\n\t},\n\n\tevents() {\n\t\t// check if element exists\n\t\tif (!this.el.loadMoreButton) return\n\n\t\t// Responsible for pagination \n\t\tthis.el.loadMoreButton && this.el.loadMoreButton.addEventListener('click', () => this.fxUpdatePagination())\n\n\t\t// Responsible for filter on load page\n\t\tthis.fxFilterNews(this.el.mainContainer)\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nserviceFilterNews.init()","/* global http toggleEventsFilterModal */\nconst serviceFilterRoutes = {\n\tel: {\n\t\tbody: document.body,\n\t\tmainContainer: document.querySelector('.js-filter-route'),\n\t\tfilterInputAndSelectListener: document.querySelectorAll('.js-filter-change-listener'),\n\t\tloadMoreButton: document.querySelector('.js-filter-loadmore-listener')\n\t},\n\n\tvars: {\n\t\tcurrentPage: 1\n\t},\n\n\tfxHandleFilterOnChangeSelectOrInput(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// reset pagination\n\t\tthis.vars.currentPage = 1\n\n\t\t// Responsible for set values of radio buttons and select elements on data attribute called \"data filter id\" and make sure that when user select mobile version, the desktop version is selected as well\n\t\ttoggleEventsFilterModal.fxHandleSelectAndInputValue(el)\n\n\t\t// filter results on change of radio button or select\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tfxUpdatePagination() {\n\t\t// increase the current page\n\t\tthis.vars.currentPage += 1\n\n\t\t// filter results on pagination selected\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tfxRenderCards(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// this condition is needed to make sure that when user select a new filter, the results are filtered again\n\t\t\tif (this.vars.currentPage === 1) {\n\t\t\t\t// remove all the cards\n\t\t\t\tdocument.querySelectorAll('.cards-container__item').forEach(el => el.remove())\n\t\t\t}\n\n\t\t\t//set variables for later use\n\t\t\tlet card\n\n\t\t\t//then we need to render the new results looping through the data\n\t\t\tdata.items.map(el => {\n\n\t\t\t\t//save card structure in a variable\n\t\t\t\tcard =\n\t\t\t\t\t`\n\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\"${el.heading}\"\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t${el.lead}\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t

    ${el.heading}

    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t${el.button}\n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t`\n\t\t\t\t// insert wrap container inside container (list-content__list) that is already in the DOM\n\t\t\t\tdocument.querySelector('.cards-container__grid').insertAdjacentHTML('beforeend', card)\n\t\t\t})\n\n\t\t\tif (!data.loadMore) {\n\t\t\t\tthis.el.loadMoreButton.style.display = 'none'\n\t\t\t}\n\t\t}\n\t},\n\n\tfxGetSelectedFilterForSummaryResults(filterId) {\n\t\t// get selected filter type\n\t\tconst typeSelected = document.querySelector(`[data-filter-type=\"${filterId}\"`)\n\t\t// save which select option has been selected\n\t\tconst optionSelected = typeSelected.querySelector('select').options.selectedIndex\n\t\t// return text from this option selected - this way we make sure that we return the exact same value as the one in select element\n\t\treturn typeSelected.querySelector('select').options[optionSelected].text\n\t},\n\n\tfxRenderSummaryRouteResults(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// set the number of results with data.length\n\t\t\tdocument.querySelector('.js-filter-summary-counter').textContent = data.totalRecords\n\n\t\t\t// save variables for later use\n\t\t\tlet filterRegion\n\t\t\tlet filterLocation\n\n\t\t\t// populate variables \n\t\t\tfilterRegion = this.fxGetSelectedFilterForSummaryResults('region')\n\t\t\tfilterLocation = this.fxGetSelectedFilterForSummaryResults('location')\n\n\t\t\t// set each result with variables created above\n\t\t\tdocument.querySelector('.js-filter-summary-first-selected').textContent = filterRegion\n\t\t\tdocument.querySelector('.js-filter-summary-second-selected').textContent = filterLocation\n\t\t}\n\t},\n\n\tfxGetFilterID(filterId) {\n\t\t// find filter type from parameter and get filter ID\n\t\treturn document.querySelector(`[data-filter-type=\"${filterId}\"`).getAttribute('data-filter-id')\n\t},\n\n\tfxFilterRoutes(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// set variables let (let it change)\n\t\tlet filterRegion\n\t\tlet filterLocation\n\n\t\t// populate variables\n\t\tfilterRegion = this.fxGetFilterID('region')\n\t\tfilterLocation = this.fxGetFilterID('location')\n\n\t\t// get endpoint\n\t\tconst endpoint = el.getAttribute('data-action-route-cards')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\tregion: filterRegion ? filterRegion : 'all',\n\t\t\tlocation: filterLocation ? filterLocation : 'all',\n\t\t\tpage: this.vars.currentPage\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// call function that will build cards\n\t\t\tthis.fxRenderCards(response, data)\n\n\t\t\t// call function that will fill summary results\n\t\t\tthis.fxRenderSummaryRouteResults(response, data)\n\t\t}\n\n\t\t// call api\n\t\thttp.fxPost(endpoint, formData, callback, languageParameter)\n\t},\n\n\tevents() {\n\t\t// check if element exists\n\t\tif (!this.el.mainContainer) return\n\n\t\t// Responsible for all events on select and radio buttons\n\t\tthis.el.filterInputAndSelectListener.forEach(el => el.addEventListener('change', e => this.fxHandleFilterOnChangeSelectOrInput(e)))\n\n\t\t// Responsible for pagination\n\t\tthis.el.loadMoreButton && this.el.loadMoreButton.addEventListener('click', () => this.fxUpdatePagination())\n\n\t\t// Responsible for filter on load page\n\t\tthis.fxFilterRoutes(this.el.mainContainer)\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nserviceFilterRoutes.init()","/* global http toggleEventsFilterModal scrollEventStickyNav */\nconst serviceFilterTourism = {\n\tel: {\n\t\tbody: document.body,\n\t\tmainContainer: document.querySelector('.js-filter-tourism'),\n\t\tfilterInputAndSelectListener: document.querySelectorAll('.js-filter-change-listener'),\n\t\tloadMoreButton: document.querySelector('.js-filter-loadmore-listener'),\n\t\tfilterTabs: document.querySelectorAll('[data-filter-tab]')\n\t},\n\n\tvars: {\n\t\tcurrentPage: 1\n\t},\n\n\tfxHandleFilterOnChangeSelectOrInput(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// reset pagination\n\t\tthis.vars.currentPage = 1\n\n\t\t// Responsible for set values of radio buttons and select elements on data attribute called \"data filter id\" and make sure that when user select mobile version, the desktop version is selected as well\n\t\ttoggleEventsFilterModal.fxHandleSelectAndInputValue(el)\n\n\t\t// filter results on change of radio button or select\n\t\tthis.fxFilterTourism(this.el.mainContainer)\n\t},\n\n\tfxUpdatePagination() {\n\t\t// increase the current page\n\t\tthis.vars.currentPage += 1\n\n\t\t// filter results on pagination selected\n\t\tthis.fxFilterTourism(this.el.mainContainer)\n\t},\n\n\tfxRenderCards(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// this condition is needed to make sure that when user select a new filter, the results are filtered again\n\t\t\tif (this.vars.currentPage === 1) {\n\t\t\t\t// remove all the cards\n\t\t\t\tdocument.querySelectorAll('.cards-container__item').forEach(el => el.remove())\n\t\t\t}\n\n\t\t\t//set variables for later use\n\t\t\tlet card\n\n\t\t\t//then we need to render the new results looping through the data\n\t\t\tdata.items.map(el => {\n\n\t\t\t\t//save card structure in a variable\n\t\t\t\tcard =\n\t\t\t\t\t`\n\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\"${el.heading}\"\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t${el.lead}\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t

    ${el.heading}

    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\t${el.button}\n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t`\n\t\t\t\t// insert wrap container inside container (list-content__list) that is already in the DOM\n\t\t\t\tdocument.querySelector('.cards-container__grid').insertAdjacentHTML('beforeend', card)\n\t\t\t})\n\n\t\t\tif (!data.loadMore) {\n\t\t\t\tthis.el.loadMoreButton.style.display = 'none'\n\t\t\t}\n\n\t\t\t// this must be here in order to sticky nav work. Just in case we have sticky nav after filtering\n\t\t\tscrollEventStickyNav.fxHandleStickyElementOnScroll()\n\t\t}\n\t},\n\n\tfxGetSelectedFilterForSummaryResults(filterId) {\n\t\t// get selected filter type\n\t\tconst typeSelected = document.querySelector(`[data-filter-type=\"${filterId}\"`)\n\t\t// save which select option has been selected\n\t\tconst optionSelected = typeSelected.querySelector('select').options.selectedIndex\n\t\t// return text from this option selected - this way we make sure that we return the exact same value as the one in select element\n\t\treturn typeSelected.querySelector('select').options[optionSelected].text\n\t},\n\n\tfxRenderSummaryRouteResults(response, data) {\n\t\tif (response.status === 200) {\n\n\t\t\t// set the number of results with data.length\n\t\t\tdocument.querySelector('.js-filter-summary-counter').textContent = data.totalRecords\n\n\t\t\t// set variables let (let it change)\n\t\t\tlet categories\n\t\t\tlet subCategories\n\n\t\t\t// populate variables\n\t\t\tcategories = this.fxGetSelectedFilterForSummaryResults('category')\n\n\t\t\tsubCategories = this.fxGetSelectedFilterForSummaryResults('subCategory')\n\n\t\t\t// set each result with variables created above\n\t\t\tdocument.querySelector('.js-filter-summary-first-selected').textContent = categories\n\n\t\t\t// set each result with variables created above\n\t\t\tdocument.querySelector('.js-filter-summary-second-selected').textContent = subCategories\n\n\t\t}\n\t},\n\n\tfxGetFilterID(filterId) {\n\t\t// find filter type from parameter and get filter ID\n\t\treturn document.querySelector(`[data-filter-type=\"${filterId}\"`).getAttribute('data-filter-id')\n\t},\n\n\tfxFilterTourism(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// set variables let (let it change)\n\t\tlet category\n\t\tlet subCategory\n\n\t\t// populate variables\n\t\tcategory = this.fxGetFilterID('category')\n\t\tsubCategory = this.fxGetFilterID('subCategory')\n\n\t\t// get endpoint\n\t\tconst endpoint = el.getAttribute('data-action-tourism-cards')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\tcategory: category ? category : 'allCategories',\n\t\t\tsubcategory: subCategory ? subCategory : 'allSubCategories',\n\t\t\tpage: this.vars.currentPage\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// call function that will build cards\n\t\t\tthis.fxRenderCards(response, data)\n\n\t\t\t// call function that will fill summary results\n\t\t\tthis.fxRenderSummaryRouteResults(response, data)\n\t\t}\n\n\t\t// call api\n\t\thttp.fxPost(endpoint, formData, callback, languageParameter)\n\t},\n\n\tevents() {\n\t\t// check if element exists\n\t\tif (!this.el.mainContainer) return\n\n\t\t// Responsible for all events on select and radio buttons\n\t\tthis.el.filterInputAndSelectListener.forEach(el => el.addEventListener('change', e => this.fxHandleFilterOnChangeSelectOrInput(e)))\n\n\t\t// Responsible for pagination \n\t\tthis.el.loadMoreButton && this.el.loadMoreButton.addEventListener('click', () => this.fxUpdatePagination())\n\n\t\t// Responsible for filter on load page\n\t\tthis.fxFilterTourism(this.el.mainContainer)\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nserviceFilterTourism.init()","/* global http loadEventSliderWithThumbnail*/\nconst serviceModalGallery = {\n\tel: {\n\t\tbody: document.querySelector('body'),\n\t\tmainWrapperPage: document.querySelector('.wrapper'),\n\t\tmodalContainer: document.querySelector('.aside-gallery-modal'),\n\t\ttoggleModal: document.querySelectorAll('.js-modal-gallery-toggle')\n\t},\n\n\tfxToggleModal(e, index) {\n\t\t// check if parent element has class that opens modal\n\t\tif (e.currentTarget.closest('.aside-gallery').classList.contains('modal-opened')) {\n\t\t\t// if yes we remove class and class that hide scrollbar\n\t\t\te.currentTarget.closest('.aside-gallery').classList.remove('modal-opened')\n\t\t\tthis.el.body.classList.remove('no-scroll-hidden')\n\n\t\t}\n\t\telse {\n\t\t\t// if not we add class on parent / hide scrollbar and call api\n\t\t\te.currentTarget.closest('.aside-gallery').classList.add('modal-opened')\n\t\t\tthis.el.body.classList.add('no-scroll-hidden')\n\n\t\t\t// we receive index in order to check which image on gallery has been clicked\n\t\t\tthis.fxHandleApiCall(index)\n\t\t}\n\t},\n\n\tfxHandleApiCall(index) {\n\t\t// get attributes in order to call api\n\t\tconst apiEndPoint = this.el.mainWrapperPage.getAttribute('data-action-modal-gallery')\n\t\tconst hostelId = this.el.mainWrapperPage.getAttribute('data-hostel-id')\n\n\t\t// concat attributes\n\t\tconst finalEndPoint = `${apiEndPoint}${hostelId} `\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t// set formData\n\t\tconst formData = {\n\t\t\thostelId\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => this.fxBuildModalGallery(response, data, index)\n\n\t\t// GET function - from @http.js file\n\t\thttp.fxPost(finalEndPoint, formData, callback, languageParameter)\n\t},\n\n\tfxBuildModalGallery(response, data, index) {\n\t\t// check if response is success\n\t\tif (response.status === 200) {\n\n\t\t\t// check if user already opened gallery, if yes we remove everything inside modal\n\t\t\tdocument.querySelector('.aside-gallery-modal__wrap') && document.querySelector('.aside-gallery-modal__wrap').remove()\n\n\t\t\t// save container that goes inside aside-gallery-modal\n\t\t\tconst modalGalleryContent =\n\t\t\t\t`\n\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t`\n\n\t\t\t// insert wrap container inside container (aside-gallery-modal) that is already in the DOM\n\t\t\tthis.el.modalContainer.insertAdjacentHTML('beforeend', modalGalleryContent)\n\n\t\t\t// create element a in order to addEventListener click on it and work properly close modal action\n\t\t\tconst toggleModalButton = document.createElement('a')\n\n\t\t\t// add class to this element created\n\t\t\ttoggleModalButton.classList.add('aside-gallery-modal__close', 'js-modal-gallery-toggle')\n\n\t\t\t// insert element created inside modal__wrap\n\t\t\tdocument.querySelector('.aside-gallery-modal__wrap').appendChild(toggleModalButton)\n\n\t\t\t// addEventListener to this element created\n\t\t\ttoggleModalButton.addEventListener('click', e => this.fxToggleModal(e))\n\n\t\t\t// do a loop in data variable in order to get each content inside array\n\t\t\tdata.map(el => {\n\t\t\t\t// get selector swiper wrapper that is inside modal and insert node element\n\t\t\t\tdocument.querySelectorAll('.aside-gallery-modal__slider .swiper-wrapper').forEach(element => element.innerHTML += `\n\t\t\t\t\t\n\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t
    \n\t\t\t\t`)\n\t\t\t})\n\n\t\t\t// call function of swiper in order to init swiper with thumbnail - index is responsible for set initialSlide once we know which image has been clicked\n\t\t\tloadEventSliderWithThumbnail.fxInitSliderThumbnail(document.querySelector('.js-slider-thumbnail-main'), document.querySelector('.js-slider-thumbnail'), index)\n\t\t}\n\t},\n\n\tevents() {\n\t\t// Responsible for open modal and call api once js-modal-gallery-toggle clicked - We have index as a parameter that is really important in order to check which item as been clicked and then show it first when modal is opened\n\t\tdocument.querySelectorAll('.js-modal-gallery-toggle').forEach((el, index) => el.addEventListener('click', e => this.fxToggleModal(e, index)))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nserviceModalGallery.init()","/* global http */\n/*eslint-disable no-unused-vars*/\nconst submitPayment = {\n\tel: {\n\t\tbody: document.body,\n\t\tbtnSubmitPaymentMethod: document.querySelector('.js-submit-payment-method'),\n\t\tcontainerPaymentInfo: document.querySelector('.js-payment-info'),\n\t\tlogoPaymentType: document.querySelectorAll('.js-payment-type-logo'),\n\t\tform: document.querySelector('.js-form-reservation')\n\t},\n\n\tfxSubmitPaymentMethod(el) {\n\t\tconst endpoint = el.dataset.action,\n\t\t\tlanguageParameter = this.el.body.dataset.language,\n\t\t\tpaymentInputs = document.querySelectorAll('.form__field-input[name=PaymentType]'),\n\t\t\tbookingId = this.el.form.querySelector('.js-booking-id').value,\n\t\t\tmethodPayment = [...paymentInputs].find(radio => radio.checked).value\n\n\t\t//add bookingLines to data\n\t\tconst data = {\n\t\t\t'bookingId': bookingId,\n\t\t\t'PaymentType': methodPayment\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => {\n\t\t\t// do something\n\t\t\tif (response.status === 200) {\n\t\t\t\tthis.fxDisplayWaitingMessage(el, false)\n\t\t\t\tthis.fxDisplayPaymentMethod(data)\n\t\t\t}\n\t\t}\n\t\tthis.fxDisplayWaitingMessage(el, true)\n\t\thttp.fxPost(endpoint, data, callback, languageParameter)\n\t},\n\n\tfxDisplayWaitingMessage(el, action) {\n\t\tconst message =\n\t\t\t`\n\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t${el.dataset.waitingMessage}\n\t\t\t\t
    \n\t\t\t`\n\n\t\tthis.el.containerPaymentInfo.innerHTML = action ? message : ''\n\t},\n\n\tfxInjectScript(source, element) {\n\t\tconst promise = new Promise((resolve, reject) => {\n\t\t\tconst script = document.createElement('script')\n\t\t\tscript.src = source\n\t\t\tscript.addEventListener('load', resolve)\n\t\t\tscript.addEventListener('error', e => reject(e.error))\n\t\t\tthis.el.body.appendChild(script)\n\t\t})\n\n\t\treturn promise.then(\n\t\t\t() => {\n\t\t\t\tconst location = this.el.form.dataset.actionConfirmReservation,\n\t\t\t\t\tbookingId = this.el.form.querySelector('.js-booking-id').value,\n\t\t\t\t\turl = `${location}?bookingId=${bookingId}`,\n\t\t\t\t\t[languageParameterSC, languageParameterLC] = this.el.body.dataset.language.split('-')\n\t\t\t\t/*eslint-disable no-undef*/\n\t\t\t\tswitch (element) {\n\t\t\t\t\tcase 'VMC':\n\t\t\t\t\t\tpaymentInfoVMC = document.createElement('form')\n\t\t\t\t\t\tpaymentInfoVMC.classList.add('paymentWidgets')\n\t\t\t\t\t\tpaymentInfoVMC.action = url\n\t\t\t\t\t\tpaymentInfoVMC.dataset.brands = 'VISA MASTER'\n\t\t\t\t\t\tthis.el.containerPaymentInfo.appendChild(paymentInfoVMC)\n\n\t\t\t\t\t\twpwlOptions = {\n\t\t\t\t\t\t\tonReady: () => {\n\t\t\t\t\t\t\t\tdocument.querySelector('.wpwl-label-cvv').textContent = 'CVV'\n\t\t\t\t\t\t\t\tdocument.querySelector('.wpwl-control-cvv').placeholder = 'CVV'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tlocale: `${languageParameterSC}`,\n\t\t\t\t\t\t\tstyle: 'card',\n\t\t\t\t\t\t\tpaymentTarget: '_top',\n\t\t\t\t\t\t\tbillingAddress: {},\n\t\t\t\t\t\t\tmandatoryBillingFields: {\n\t\t\t\t\t\t\t\tcountry: true,\n\t\t\t\t\t\t\t\tstate: true,\n\t\t\t\t\t\t\t\tcity: true,\n\t\t\t\t\t\t\t\tpostcode: true,\n\t\t\t\t\t\t\t\tstreet1: true\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonAfterSubmit: () => {\n\t\t\t\t\t\t\t\t//events google analytics\n\t\t\t\t\t\t\t\tif (window.ga && ga.loaded)\n\t\t\t\t\t\t\t\t\tga('send', 'event', { 'eventCategory': 'booking', 'eventAction': 'click', 'eventLabel': 'step4credit', 'eventValue': 1 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\n\t\t\t\t\tcase 'MBWAY':\n\t\t\t\t\t\tpaymentInfoMBWay = document.createElement('form')\n\t\t\t\t\t\tpaymentInfoMBWay.classList.add('paymentWidgets')\n\t\t\t\t\t\tpaymentInfoMBWay.action = url\n\t\t\t\t\t\tpaymentInfoMBWay.dataset.brands = 'MBWAY'\n\t\t\t\t\t\tthis.el.containerPaymentInfo.appendChild(paymentInfoMBWay)\n\t\t\t\t\t\twpwlOptions = {\n\t\t\t\t\t\t\tlocale: `${languageParameterSC}`,\n\t\t\t\t\t\t\tstyle: 'card',\n\t\t\t\t\t\t\tpaymentTarget: '_top',\n\t\t\t\t\t\t\terrorMessages: {\n\t\t\t\t\t\t\t\tmbwayEmailOrPhoneMandatory: 'Por favor preencha o campo de nº de telemóvel'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonAfterSubmit: () => {\n\t\t\t\t\t\t\t\t//events google analytics\n\t\t\t\t\t\t\t\tif (window.ga && ga.loaded)\n\t\t\t\t\t\t\t\t\tga('send', 'event', { 'eventCategory': 'booking', 'eventAction': 'click', 'eventLabel': 'step4mbway', 'eventValue': 1 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t/*eslint-enable*/\n\t\t\t},\n\t\t\terror => console.log(error)\n\t\t)\n\t},\n\n\tfxDisplayPaymentMethod(data) {\n\n\t\tthis.el.logoPaymentType.forEach(el => el.style.display = data.tipoPagamento === el.dataset.paymentMethod ? 'block' : 'none')\n\n\t\tconst endpoint = 'https://eu-prod.oppwa.com/v1/paymentWidgets.js?checkoutId=',\n\t\t\ttype = data.tipoPagamento\n\n\t\tif (type === 'MB') {\n\t\t\tconst date = data.dataLimite.split('T'),\n\t\t\t\tdateLimite = date[0],\n\t\t\t\ttimeLimite = date[1]\n\n\t\t\tconst paymentInfo =\n\t\t\t\t`\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
    Entidade${data.entidade}
    Referência${data.referencia}
    Valor${data.valor}
    Data limite${dateLimite} ${timeLimite}
    \n\t\t\t\t`\n\t\t\tthis.el.containerPaymentInfo.nextElementSibling.classList.remove('d-none')\n\t\t\tthis.el.containerPaymentInfo.innerHTML = paymentInfo\n\n\t\t}\n\n\t\telse {\n\t\t\tthis.fxInjectScript(`${endpoint}${data.id}`, type === 'VMC' ? 'VMC' : type === 'MBWAY' ? 'MBWAY' : '')\n\t\t}\n\n\t}\n}","/* global flatpickr createElementToast */\nconst serviceSearchBox = {\n\tel: {\n\t\tformContainer: document.querySelector('.js-searchbox-form'),\n\t\tgroupContainer: document.querySelectorAll('.js-searchbox-detect-click-outside'),\n\t\ttoggleModal: document.querySelectorAll('.js-searchbox-toggle-modal'),\n\t\ttabs: document.querySelectorAll('.js-searchbox-tab'),\n\t\tselectedItem: document.querySelectorAll('.js-searchbox-select-item'),\n\t\tcounterButton: document.querySelectorAll('.js-searchbox-counter-button'),\n\t\tcounterValue: document.querySelector('.js-searchbox-counter-value'),\n\t\tcounterLabelValue: document.querySelector('.js-searchbox-counter-label-value'),\n\t\tinputCheckIn: document.querySelector('.js-searchbox-check-in'),\n\t\tinputCheckOut: document.querySelector('.js-searchbox-check-out'),\n\t\tflatPickerContainer: document.querySelectorAll('.js-searchbox-date-picker'),\n\t\tpromoValue: document.querySelector('.js-searchbox-promocode-value')\n\t},\n\n\tvars: {\n\t\tcurrentNumberOfGuests: 0\n\t},\n\n\tfxHandleCounter(el) {\n\t\t// get attribute that define if button is for increase or decrease counter\n\t\tconst buttonClicked = el.currentTarget.getAttribute('data-searchbox-counter')\n\n\t\t// if button has attribute increase, we increment on our variable, if not we subtract it\n\t\tif (buttonClicked === 'increase') {\n\t\t\tthis.vars.currentNumberOfGuests += 1\n\t\t}\n\t\telse {\n\t\t\t// this if is for make sure that number does not go below zero\n\t\t\tif (this.vars.currentNumberOfGuests === 0) return\n\t\t\tthis.vars.currentNumberOfGuests -= 1\n\t\t}\n\n\t\t// This condition is for label inside container, we hide it if number of guests is different than zero\n\t\tif (this.vars.currentNumberOfGuests != 0) {\n\t\t\t// Add class on parentNode in order to hide label and indicate only new value\n\t\t\tel.currentTarget.closest('.searchbox__control-group').classList.add('updated')\n\t\t}\n\t\telse {\n\t\t\tel.currentTarget.closest('.searchbox__control-group').classList.remove('updated')\n\t\t}\n\n\t\t// set text content on our modal with variable that has been increased or subtracted\n\t\tthis.el.counterValue.textContent = this.vars.currentNumberOfGuests\n\n\t\t// set value on input with variable that has been increased or subtracted\n\t\tthis.el.counterLabelValue.value = this.vars.currentNumberOfGuests || ''\n\t},\n\n\tfxHandlePromoCode(event) {\n\t\t// This condition is for label inside container, we hide it if the input if filled.\n\t\tif (event.currentTarget.value != '' || document.activeElement === event.currentTarget) {\n\t\t\t// Add class on parentNode in order to hide label and indicate only new value\n\t\t\tevent.currentTarget.closest('.searchbox__control-group').classList.add('updated')\n\t\t}\n\t\telse {\n\t\t\tevent.currentTarget.closest('.searchbox__control-group').classList.remove('updated')\n\t\t}\n\t},\n\n\tfxSwitchTabs(el) {\n\t\t// General function that resets all form - show labels and reset counter\n\t\tthis.fxResetSearchBox()\n\n\t\t// remove all active classes from any tab\n\t\tthis.el.tabs.forEach(el => el.classList.remove('active'))\n\n\t\t// add active class to current target\n\t\tel.currentTarget.classList.add('active')\n\t},\n\n\tfxSwitchSelectListOnceClicked(el) {\n\t\t// get attribute to detect witch tab has been clicked\n\t\tconst searchBoxTab = el.currentTarget.getAttribute('data-searchbox-tab')\n\n\t\t// check if has element\n\t\tif (!document.querySelector(`.searchbox-select__list--${searchBoxTab}`)) return\n\n\t\t// remove all show classes from any container\n\t\tdocument.querySelectorAll('.searchbox-select__list').forEach(el => el.classList.remove('show'))\n\n\t\t// find container that has class that ends with data attribute of clicked tab and add class show\n\t\tdocument.querySelector(`.searchbox-select__list--${searchBoxTab}`).classList.add('show')\n\t},\n\n\tfxToggleModalSearchBox(el) {\n\t\t// check if current target of click has class focused, if yes, just remove it, if not, add it\n\t\tif (el.currentTarget.parentNode.classList.contains('focused')) {\n\t\t\tel.currentTarget.parentNode.classList.remove('focused')\n\t\t}\n\t\telse {\n\t\t\tthis.el.toggleModal.forEach(el => el.parentNode.classList.remove('focused'))\n\t\t\tel.currentTarget.parentNode.classList.add('focused')\n\t\t}\n\t},\n\n\tfxAddSelectValueToForm(el) {\n\t\t// save value of selected item\n\t\tconst valueOfItemSelected = el.currentTarget.textContent\n\t\tconst codeOfItemSelected = el.currentTarget.getAttribute('data-option-code')\n\n\t\t// first we find parent focused class and add updated class in order to hide label from container\n\t\tel.currentTarget.closest('.focused').classList.add('updated')\n\n\t\t// remove class focused - responsible for close modal after select any item\n\t\tel.currentTarget.closest('.focused').classList.remove('focused')\n\n\t\t// update text on container that shows item selected\n\t\tdocument.querySelector('.js-searchbox-select-value').textContent = valueOfItemSelected\n\n\t\t// update value on input select\n\t\tdocument.querySelector('.js-searchbox-select-tag').value = codeOfItemSelected\n\t},\n\n\tfxInitFlatpickr(el) {\n\t\t// save in a variable options of flatpickr\n\t\tconst flatpickrOptions = {\n\t\t\tlocale: el.dataset.language,\n\t\t\t// this mode enable user to choose two dates, check in and check out\n\t\t\tmode: 'range',\n\t\t\t// minDate is the minimum date that can be selected\n\t\t\tminDate: 'today',\n\t\t\t// inline is for display date in the same line with input\n\t\t\tinline: true,\n\t\t\tdateFormat: 'Y-m-d',\n\n\t\t\t// onValueUpdate is a callback that is called when the user changes the date\n\t\t\tonValueUpdate: selectedDates => {\n\n\t\t\t\t// get date selected by user for check in\n\t\t\t\tconst checkInDate = flatpickr.formatDate(selectedDates[0], 'Y-m-d')\n\n\t\t\t\t// get date selected by user for check in\n\t\t\t\tconst checkOutDate = selectedDates[1] ? flatpickr.formatDate(selectedDates[1], 'Y-m-d') : ''\n\n\t\t\t\t// validate same date selection\n\t\t\t\tif (checkOutDate === checkInDate) {\n\t\t\t\t\tcreateElementToast.fxCreateToastItem('danger', this.el.formContainer.dataset.toastCopyErrorSameDateSelection)\n\t\t\t\t\t// remove class focused - responsible for close modal after select any item\n\t\t\t\t\tdocument.querySelector('.searchbox__control-group--date').classList.remove('focused')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// fill check in and check out fields\n\t\t\t\tthis.el.inputCheckIn.value = checkInDate\n\t\t\t\tthis.el.inputCheckOut.value = checkOutDate\n\n\t\t\t\tif (checkOutDate) {\n\t\t\t\t\t// first we find parent focused class and add updated class in order to hide label from container\n\t\t\t\t\tdocument.querySelector('.searchbox__control-group--date').classList.add('updated')\n\n\t\t\t\t\t// remove class focused - responsible for close modal after select any item\n\t\t\t\t\tdocument.querySelector('.searchbox__control-group--date').classList.remove('focused')\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tflatpickr(el, flatpickrOptions)\n\t},\n\n\tfxCheckClickEventOutSideSearchBox(event) {\n\t\t// save a variable if target of click event is inside any container - groupContainer\n\t\tconst filterClick = [...this.el.groupContainer].filter(el => el.contains(event.target))\n\n\t\t// if none of containers have been clicked, we remove class focused on all search box\n\t\tfilterClick.length === 0 && this.el.toggleModal.forEach(el => el.parentNode.classList.remove('focused'))\n\t},\n\n\tfxResetSearchBox() {\n\t\tthis.el.formContainer.reset()\n\t\t// Remove class updated in all containers - responsible for show labels\n\t\tthis.el.formContainer.querySelectorAll('.searchbox__control-group').forEach(el => el.classList.remove('updated'))\n\n\t\t// reset number of guests\n\t\tthis.vars.currentNumberOfGuests = 0\n\n\t\t// reset counter value\n\t\tthis.el.counterValue.textContent = 0\n\n\t\t// reset counter label\n\t\tthis.el.counterLabelValue.value = ''\n\n\t\t// reset text default on select hostel list\n\t\tdocument.querySelector('.js-searchbox-select-value').textContent = 'Para onde vais?'\n\t},\n\n\tevents() {\n\t\t// Responsible for close modals if user click outside container\n\t\twindow.addEventListener('click', event => this.fxCheckClickEventOutSideSearchBox(event))\n\n\t\t// Responsible for toggle Modal on each input\n\t\tthis.el.toggleModal.forEach(el => el.addEventListener('click', e => this.fxToggleModalSearchBox(e)))\n\n\t\t// Responsible for change counter value on input of guests quantity \n\t\tthis.el.counterButton.forEach(el => el.addEventListener('click', e => this.fxHandleCounter(e)))\n\n\t\t// Responsible to handle state of the promocode\n\t\tlet input = document.getElementsByClassName('js-searchbox-promocode-value');\n\t\tif(input.length > 0){\n\t\t\tfor (const eventName of ['click', 'focus', 'blur']) {\n\t\t\t\tthis.el.promoValue.addEventListener(eventName, e => this.fxHandlePromoCode(e))\n\t\t\t}\n\t\t}\n\n\t\t// Responsible for switch tabs - Portugal or International\n\t\tthis.el.tabs.forEach(el => el.addEventListener('click', e => this.fxSwitchTabs(e)))\n\n\t\t// Responsible for switch select list - Portugal or International\n\t\tthis.el.tabs.forEach(el => el.addEventListener('click', e => this.fxSwitchSelectListOnceClicked(e)))\n\n\t\t// click event for selected item on select dropdown - Responsible for insert value to select form\n\t\tthis.el.selectedItem.forEach(el => el.addEventListener('click', e => this.fxAddSelectValueToForm(e)))\n\n\t\t// Responsible for datepicker on Check in and Check out input\n\t\tthis.el.flatPickerContainer.forEach(el => this.fxInitFlatpickr(el))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nserviceSearchBox.init()\n","/* global http submitReservation */\nconst validateVoucher = {\n\tel: {\n\t\tbody: document.body,\n\t\tbtnSubmitVoucher: document.querySelector('.js-submit-voucher-code'),\n\t\tinputVoucherCode: document.querySelector('.js-voucher-code'),\n\t\tinputAmount: document.querySelector('.js-amount'),\n\t\tcontainerSummary: document.querySelector('.content__summary'),\n\t\tbtnRemoveVoucher: document.querySelector('.js-remove-discount'),\n\t\tdiscountField: document.querySelector('.content__summary-discount'),\n\t\tsubtotalField: document.querySelector('.content__summary-subtotal'),\n\t\tcontainerFinalPrice: document.querySelector('.js-reservation-final-price'),\n\t\tvoucherErrorMessage: document.querySelector('.js-voucher-code-error-message'),\n\t\tsubTotalPrice: document.querySelector('.js-reservation-subtotal')\n\t},\n\n\tfxValidateVoucher(el) {\n\n\t\t// get endpoint\n\t\tconst endpoint = el.getAttribute('data-action')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.dataset.language\n\n\t\t// set formData\n\t\tconst BookingLines = submitReservation.vars.bookingLines\n\n\t\t//-hide and reset error message\n\t\tthis.el.voucherErrorMessage.style.display = 'none'\n\t\tthis.el.voucherErrorMessage.innerHTML = ''\n\n\t\tconst formData = {\n\t\t\tBookingLines,\n\t\t\t'VoucherCode': el.previousElementSibling.value,\n\t\t\t'HotelCode': document.querySelector('.js-hotel-code').value,\n\t\t\t'NumberOfGuests': document.querySelector('.js-hosts').value\n\t\t}\n\n\t\t// callback function \n\t\tconst callback = (response, data) => response.status === 200 && this.fxUpdateData(el, data)\n\n\t\t// call api\n\t\thttp.fxPost(endpoint, formData, callback, languageParameter)\n\t},\n\n\tfxUpdateData(el, data) {\n\t\tconst discountName = this.el.containerSummary.querySelector('.js-discount-voucher-name'),\n\t\t\tbutton = document.querySelector('[data-section-next=\"3\"]'),\n\t\t\tbuttonCopy = button.firstElementChild\n\n\t\tif (data.isVoucherApplied) {\n\t\t\t// update inputs\n\t\t\tthis.el.inputVoucherCode.value = el.previousElementSibling.value\n\t\t\tthis.el.inputAmount.value = data.totalAmountAfterTax\n\n\t\t\t//- update styles and sidepanel\n\t\t\tthis.el.discountField.style.display = 'flex'\n\t\t\tthis.el.subtotalField.style.display = 'block'\n\t\t\tdiscountName.innerHTML = data.voucherDescription\n\t\t\tthis.el.containerFinalPrice.innerHTML = data.totalAmountAfterTax\n\t\t\tthis.el.voucherErrorMessage.style.display = 'none'\n\n\t\t\tbutton.firstElementChild.textContent = data.totalAmountAfterTax === '0,00' ? buttonCopy.dataset.copyConfirm : buttonCopy.dataset.copyPayment\n\t\t}\n\t\telse {\n\t\t\tlet message\n\n\t\t\tswitch (data.errorCode) {\n\t\t\t\tcase 1:\n\t\t\t\t\tmessage = el.dataset.voucherNotApplied\n\t\t\t\t\tbreak\n\t\t\t\tcase 2:\n\t\t\t\t\tmessage = el.dataset.voucherInvalid\n\t\t\t\t\tbreak\n\t\t\t\tcase 3:\n\t\t\t\t\tmessage = el.dataset.voucherSoldOut\n\t\t\t\t\tbreak\n\t\t\t\tcase 4:\n\t\t\t\t\tmessage = el.dataset.voucherExpired\n\t\t\t\t\tbreak\n\t\t\t\tcase 5:\n\t\t\t\t\tmessage = el.dataset.voucherInactive\n\t\t\t\t\tbreak\n\t\t\t\tcase 6:\n\t\t\t\t\tmessage = el.dataset.voucherInvalidHostel\n\t\t\t\t\tbreak\n\t\t\t\tcase 7:\n\t\t\t\t\tmessage = el.dataset.voucherInvalidTypology\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tthis.el.voucherErrorMessage.style.display = 'flex'\n\t\t\tthis.el.voucherErrorMessage.innerHTML = message\n\t\t}\n\t},\n\n\tfxRemoveVoucher() {\n\t\tthis.el.discountField.style.display = 'none'\n\t\tthis.el.subtotalField.style.display = 'none'\n\t\tthis.el.inputVoucherCode.value = ''\n\t\tthis.el.btnSubmitVoucher.previousElementSibling.value = ''\n\t\tthis.el.containerFinalPrice.textContent = this.el.subTotalPrice.textContent\n\t\tthis.el.inputAmount.value = this.el.subTotalPrice.textContent\n\t},\n\n\tevents() {\n\t\t// check if element exists\n\t\tif (!this.el.btnSubmitVoucher) return\n\n\t\tthis.el.btnSubmitVoucher.addEventListener('click', e => this.fxValidateVoucher(e.currentTarget))\n\t\tthis.el.btnRemoveVoucher.addEventListener('click', () => this.fxRemoveVoucher())\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nvalidateVoucher.init()","/* global http preloader */\nconst submitFileUploader = {\n\tel: {\n\t\tinputFile: document.querySelectorAll('input[type=file]')\n\t},\n\n\tvars: {\n\t\tinvalidMessage: document.querySelectorAll('.js-form')[0] && document.querySelectorAll('.js-form')[0].dataset.msgInvalidFormat,\n\t\tlimitMessage: document.querySelectorAll('.js-form')[0] && document.querySelectorAll('.js-form')[0].dataset.msgLimit\n\t},\n\n\tfxFileUploader(e) {\n\t\tdocument.querySelectorAll('.js-clear-file').forEach(el => el.style.display = 'none')\n\t\te.stopPropagation()\n\n\t\tconst el = e.currentTarget,\n\t\t\tformData = new FormData(),\n\t\t\tlimitUploadSize = el.dataset.limit, //bytes\n\t\t\tfileValue = el.previousElementSibling.previousElementSibling,\n\t\t\tfileName = el.nextElementSibling,\n\t\t\tfilePlaceholder = el.previousElementSibling,\n\t\t\tfileClearBtn = el.nextElementSibling.nextElementSibling,\n\t\t\tfileError = el.closest('.form__field-upload-file').nextElementSibling\n\n\t\tformData.append('file', el.files[0])\n\n\t\tif (el.files[0].size > 0 && el.files[0].size < limitUploadSize) {\n\t\t\tconst extension = `.${el.value.toLowerCase().split('.').pop()}`\n\t\t\tlet validExtension = false\n\n\t\t\tel.getAttribute('accept').split(',').forEach(ext => ext === extension ? validExtension = true : '')\n\n\t\t\tif (validExtension) {\n\t\t\t\tpreloader.fxPreloaderAdd(el.previousElementSibling)\n\n\t\t\t\tconst callback = (response, data) => {\n\t\t\t\t\tpreloader.fxPreloaderRemove(el.previousElementSibling)\n\t\t\t\t\t\n\t\t\t\t\tif (response.status === 200) {\n\t\t\t\t\t\tel.nextElementSibling.classList.contains('field-error') && el.nextElementSibling.remove()\n\t\t\t\t\t\tfileClearBtn.style.display = 'inherit'\n\t\t\t\t\t\tfileValue.value = data\n\t\t\t\t\t\tfilePlaceholder.style.display = 'none'\n\t\t\t\t\t\tfileName.style.display = 'flex'\n\t\t\t\t\t\tfileName.textContent = ''\n\t\t\t\t\t\tfileName.textContent = el.files[0].name\n\t\t\t\t\t\tfileError.classList.remove('field-error')\n\t\t\t\t\t\tfileError.textContent = ''\n\n\t\t\t\t\t\tfileClearBtn.addEventListener('click', () => {\n\t\t\t\t\t\t\tfileClearBtn.style.display = 'none'\n\t\t\t\t\t\t\tel.value = ''\n\t\t\t\t\t\t\tfileValue.value = ''\n\t\t\t\t\t\t\tfileName.style.display = 'none'\n\t\t\t\t\t\t\tfileName.textContent = ''\n\t\t\t\t\t\t\tfilePlaceholder.style.display = 'flex'\n\t\t\t\t\t\t\tsetTimeout(() => el.style.display = 'none', 0)\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\thttp.fxUploadFile(el.dataset.endpoint, formData, callback)\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconsole.log(fileError)\n\t\t\t\tfileError.textContent = `${this.vars.invalidMessage}`\n\t\t\t\tfileError.classList.add('form__error-message')\n\t\t\t\tfileClearBtn.style.display = 'none'\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tfileClearBtn.style.display = 'none'\n\t\t\tconst bytesToMegaBytes = bytes => bytes / (1024 * 1024)\n\t\t\tfileError.textContent = `${this.vars.limitMessage} ${Math.round(bytesToMegaBytes(limitUploadSize))} MB`\n\t\t\tfileError.classList.add('form__error-message')\n\t\t}\n\t},\n\n\tevents() {\n\t\tthis.el.inputFile.forEach(el => el.addEventListener('change', e => this.fxFileUploader(e)))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nsubmitFileUploader.init()","/* global http formValidation formHelper preloader createElementToast */\nconst submitForm = {\n\tel: {\n\t\thtml: document.documentElement,\n\t\tbody: document.body,\n\t\tbtnShowForm: document.querySelector('.js-show-form'),\n\t\tregisterForm: document.querySelector('.js-form-register'),\n\t\tcontactForm: document.querySelector('.js-form-contact'),\n\t\tembassadorForm: document.querySelector('.js-form-embassador'),\n\t\tjobOffersForm: document.querySelector('.js-form-job-offers'),\n\t\tgroupReservationForm: document.querySelector('.js-form-group-reservation'),\n\t\tcandidateTourismForm: document.querySelector('.js-form-candidate-tourism')\n\t},\n\n\tfxFormEvents(selector) {\n\n\t\tconst form = document.querySelector(selector)\n\n\t\tform.addEventListener('submit', e => {\n\t\t\tconst el = e.currentTarget\n\t\t\te.preventDefault()\n\n\t\t\tconst callback = response => {\n\t\t\t\tpreloader.fxPreloaderRemove(form)\n\n\t\t\t\tswitch (response.status) {\n\t\t\t\t\tcase 409:\n\t\t\t\t\t\t// add toast\n\t\t\t\t\t\tcreateElementToast.fxCreateToastItem('warning', form.dataset.msgConflict)\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase 500:\n\t\t\t\t\t\t// add toast\n\t\t\t\t\t\tcreateElementToast.fxCreateToastItem('warning', form.dataset.msgServer)\n\t\t\t\t\t\tbreak\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// add toast\n\t\t\t\t\t\tcreateElementToast.fxCreateToastItem('success', form.dataset.toastCopySuccess)\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (formValidation.fxValidate(el)) {\n\t\t\t\tpreloader.fxPreloaderAdd(form)\n\n\t\t\t\t// get language that has to be sent to api\n\t\t\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\t\t\t\thttp.fxPost(el.getAttribute('action'), formHelper.fxFormToJson(el), callback, languageParameter)\n\t\t\t}\n\t\t})\n\t},\n\n\tfxShowForm(e) {\n\t\tlet currentSection = e.currentTarget.closest('.content'),\n\t\t\tnextSection = currentSection.nextElementSibling\n\n\t\tcurrentSection.classList.add('d-none')\n\t\tnextSection.classList.remove('d-none')\n\t},\n\n\tinit() {\n\t\tthis.el.registerForm && this.fxFormEvents('.js-form-register')\n\t\tthis.el.contactForm && this.fxFormEvents('.js-form-contact')\n\t\tthis.el.embassadorForm && this.fxFormEvents('.js-form-embassador')\n\t\tthis.el.jobOffersForm && this.fxFormEvents('.js-form-job-offers')\n\t\tthis.el.groupReservationForm && this.fxFormEvents('.js-form-group-reservation')\n\t\tthis.el.candidateTourismForm && this.fxFormEvents('.js-form-candidate-tourism')\n\n\t\tthis.el.btnShowForm && this.el.btnShowForm.addEventListener('click', e => this.fxShowForm(e))\n\n\t}\n}\n\nsubmitForm.init()","/* global formValidation ga*/\nconst submitFormSearchBox = {\n\tel: {\n\t\tbody: document.body,\n\t\tformContainer: document.querySelector('.js-searchbox-form'),\n\t\tmodalPreloader: document.querySelector('.modal-preloader')\n\t},\n\n\tfxPreloaderModal() {\n\t\tthis.el.body.classList.add('no-scroll-fixed')\n\t\tthis.el.modalPreloader.style.display = 'flex'\n\t},\n\n\tfxSubmitFormSearchBox() {\n\t\tthis.el.formContainer.addEventListener('submit', e => {\n\t\t\te.preventDefault()\n\t\t\tconst el = e.currentTarget\n\n\t\t\tif (formValidation.fxValidate(el)) {\n\t\t\t\tconst data = new FormData(el)\n\n\t\t\t\tdata.set('arrivaldate', data.get('arrivaldate').replaceAll('-', ''))\n\t\t\t\tdata.set('departuredate', data.get('departuredate').replaceAll('-', ''))\n\n\t\t\t\tconst formValues = new URLSearchParams(data).toString()\n\n\t\t\t\twindow.open(`${el.action}?${formValues}`, '_blank')\n\n\t\t\t\tif (window.ga && ga.loaded)\n\t\t\t\t\tga('send', 'event', { 'eventCategory': 'booking', 'eventAction': 'click', 'eventLabel': 'step1', 'eventValue': 1 })\n\t\t\t}\n\t\t})\n\t},\n\n\tevents() {\n\t\tthis.el.formContainer && this.fxSubmitFormSearchBox()\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\nsubmitFormSearchBox.init()\n","/* global http formHelper reservationHelper ga preloader scrollOnEvent */\nconst submitReservation = {\n\tel: {\n\t\thtml: document.documentElement,\n\t\tbody: document.body,\n\t\tformReservation: document.querySelector('.js-form-reservation'),\n\t\tselects: document.querySelectorAll('.form-table__select select'),\n\t\tinputBookingId: document.querySelector('.js-booking-id')\n\t},\n\n\tvars: {\n\t\tbookingLines: [],\n\t\textraLargeAndUp: window.matchMedia('(min-width: 75em)')\n\t},\n\n\tfxSubmitReservation(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// get endpoint\n\t\tconst endpoint = el.getAttribute('data-action'),\n\t\t\tsection = el.closest('.form')\n\n\t\t// get language that has to be sent to api\n\t\tconst languageParameter = this.el.body.getAttribute('data-language')\n\n\t\t//add bookingLines to data\n\t\tconst BookingLines = this.vars.bookingLines\n\t\tconst formData = formHelper.fxFormToJson(section),\n\t\t\tdata = {\n\t\t\t\tBookingLines,\n\t\t\t\t...formData\n\t\t\t}\n\n\t\tif (this.vars.extraLargeAndUp.matches === false) {\n\t\t\tdata.ratePlan = '0'\n\t\t}\n\n\t\tconst callback = (response, data) => {\n\t\t\tpreloader.fxPreloaderRemove(section)\n\t\t\tscrollOnEvent.fxScrollOnEvent(document.querySelector('.content-aside'))\n\n\t\t\t//update input booking ID\n\t\t\tconst bookingId = this.el.inputBookingId.value = data.bookingId\n\n\t\t\tif (response.status === 200) {\n\t\t\t\t//events google analytics\n\t\t\t\tif (window.ga && ga.loaded)\n\t\t\t\t\tga('send', 'event', { 'eventCategory': 'booking', 'eventAction': 'click', 'eventLabel': 'step3', 'eventValue': 1 })\n\n\t\t\t\tif (data.isError) {\n\t\t\t\t\tswitch (data.statusCode) {\n\t\t\t\t\t\t// cartao jovem invalid\n\t\t\t\t\t\tcase 222: {\n\t\t\t\t\t\t\tconst form = document.querySelector('[name=\"numCartaoJovemReservations\"]') && document.querySelector('[name=\"numCartaoJovemReservations\"]').parentElement,\n\t\t\t\t\t\t\t\tdiv = document.createElement('div')\n\n\t\t\t\t\t\t\tdiv.classList.add('form__error-message', 'form__error-message-card-invalid')\n\t\t\t\t\t\t\tform.appendChild(div)\n\t\t\t\t\t\t\tdocument.querySelector('.form__error-message-card-invalid').textContent = ''\n\t\t\t\t\t\t\tdocument.querySelector('.form__error-message-card-invalid').textContent = data.message\n\t\t\t\t\t\t\tdocument.querySelectorAll('.form__error-message-card-invalid').length > 1 && document.querySelectorAll('.form__error-message-card-invalid:not(:first-of-type)').forEach(el => el.remove())\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telse {\n\t\t\t\t\tswitch (data.statusCode) {\n\t\t\t\t\t\t// if free voucher\n\t\t\t\t\t\tcase 201: {\n\t\t\t\t\t\t\tconst confirmReservationUrl = el.closest('.js-form-reservation').dataset.actionConfirmReservation,\n\t\t\t\t\t\t\t\treservationUrlWithParameters = `${confirmReservationUrl}?id=${bookingId}`\n\n\t\t\t\t\t\t\tlocation.href = reservationUrlWithParameters\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if no error, go to section 3 of reservation form\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\treservationHelper.fxLoopElements(document.querySelectorAll('.form__tab'), 'section', el.dataset.sectionNext)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tpreloader.fxPreloaderAdd(section)\n\t\thttp.fxPost(endpoint, data, callback, languageParameter)\n\t},\n\n\t//fx to update bookings\n\tfxTriggerEvents() {\n\t\tconst selects = document.querySelectorAll('.form-table__select select'),\n\t\t\tinputRateplan = document.querySelectorAll('.form-table__radio-input')\n\n\t\tselects.forEach(el => el.addEventListener('change', () => this.fxUpdateBookingLines()))\n\t\tinputRateplan.forEach(el => el.addEventListener('change', () => this.fxUpdateBookingLines()))\n\t},\n\n\tfxUpdateBookingLines() {\n\t\tconst selects = document.querySelectorAll('.form-table__select select')\n\n\t\tlet bookingLines = [],\n\t\t\tratePlanValue = null,\n\t\t\tfield = {}\n\n\t\t//get rateplan\n\t\tif (this.vars.extraLargeAndUp.matches) {\n\t\t\tdocument.querySelectorAll('.form-table--desktop .form-table__radio-input').forEach(input => input.checked ? ratePlanValue = input.value : '')\n\t\t}\n\t\t\n\t\telse {\n\t\t\tdocument.querySelectorAll('.form-table--mobile .form-table__radio-input').forEach(input => input.checked ? ratePlanValue = input.value : '')\n\t\t}\n\n\t\tdocument.querySelector('.js-rateplan').value = ratePlanValue\n\t\tconsole.log(ratePlanValue, document.querySelector('.js-rateplan').value)\n\t\t\n\t\t//loop selects/inputs\n\t\tselects.forEach(item => {\n\t\t\tif (item.value !== '0') {\n\n\t\t\t\tconst wrapper = item.closest('.js-room-info')\n\n\t\t\t\twrapper.querySelectorAll('.js-rateplan-value').forEach(el => {\n\t\t\t\t\tif (ratePlanValue === el.dataset.rateplan) {\n\t\t\t\t\t\tfield = {\n\t\t\t\t\t\t\t'RoomID': Number(wrapper.dataset.roomId),\n\t\t\t\t\t\t\t'RoomDescription': wrapper.dataset.roomDescription,\n\t\t\t\t\t\t\t'CodTipologia': wrapper.dataset.roomTypology,\n\t\t\t\t\t\t\t'NumberOfUnits': Number(item.value),\n\t\t\t\t\t\t\t'GuestCount': Number(wrapper.dataset.roomCapacity),\n\t\t\t\t\t\t\t'StartDate': this.el.formReservation.querySelector('.js-start-date').value,\n\t\t\t\t\t\t\t'EndDate': this.el.formReservation.querySelector('.js-end-date').value,\n\t\t\t\t\t\t\t'ResourceAmountAfterTax': item.value * el.dataset.price\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tbookingLines.push(field)\n\t\t\t}\n\t\t})\n\t\tthis.vars.bookingLines = bookingLines\n\t},\n\n\tinit() {\n\t\tthis.el.formReservation && this.fxTriggerEvents()\n\t}\n}\n\nsubmitReservation.init()\n","const toggleEventsAccordion = {\n\tel: {\n\t\taccordionElement: document.querySelectorAll('.js-accordion-toggle')\n\t},\n\n\tvars: {\n\t\textraLargeAndUp: window.matchMedia('(min-width: 75em)')\n\t},\n\n\tfxToggleClasses(el) {\n\t\t// add/remove open class on current target\n\t\tif (el.currentTarget.parentElement.classList.contains('open')) {\n\t\t\tif (el.currentTarget.classList.contains('content-columns__header')) {\n\t\t\t\t!this.vars.extraLargeAndUp.matches && (el.currentTarget.parentElement.classList.remove('open'), this.fxCloseAccordion(el.currentTarget))\n\t\t\t}\n\t\t\telse {\n\t\t\t\tel.currentTarget.parentElement.classList.remove('open')\n\t\t\t\tthis.fxCloseAccordion(el.currentTarget)\n\t\t\t}\n\n\t\t}\n\t\telse {\n\t\t\tif (el.currentTarget.classList.contains('content-columns__header')) {\n\t\t\t\t!this.vars.extraLargeAndUp.matches && (el.currentTarget.parentElement.classList.add('open'), this.fxOpenAccordion(el.currentTarget), this.fxCloseSiblings(el.currentTarget.parentElement, el.currentTarget.closest('.js-accordion')))\n\t\t\t}\n\t\t\telse {\n\t\t\t\tel.currentTarget.parentElement.classList.add('open')\n\t\t\t\tthis.fxOpenAccordion(el.currentTarget)\n\t\t\t\tthis.fxCloseSiblings(el.currentTarget.parentElement, el.currentTarget.closest('.js-accordion'))\n\t\t\t}\n\t\t}\n\t},\n\n\tfxCloseSiblings(element, parent) {\n\t\tconst children = [...parent.children]\n\t\t// loop through siblings and remove open class\n\t\tchildren.filter(child => child !== element && child.classList.contains('open') && (child.classList.remove('open'), this.fxCloseAccordion(child.querySelector('.js-accordion-toggle'))))\n\t},\n\n\tfxOpenAccordion(el) {\n\t\tconst content = el.nextElementSibling\n\t\tcontent.style.maxHeight = content.scrollHeight + 'px'\n\t},\n\n\tfxCloseAccordion(el) {\n\t\tconst content = el.nextElementSibling\n\t\tcontent.style.maxHeight = null\n\t},\n\n\tevents(el) {\n\t\tel.forEach(el => el.addEventListener('click', e => this.fxToggleClasses(e)))\n\t},\n\n\tinit() {\n\t\tthis.events(this.el.accordionElement)\n\t}\n}\n\ntoggleEventsAccordion.init()","const toggleEventsAsideFilterMap = {\n\tel: {\n\t\tasideFilterMapContainer: document.querySelector('.aside-filter-map'),\n\t\ttoggleButton: document.querySelector('.js-aside-filter-toggle')\n\t},\n\n\tvars: {\n\t\textraLargeAndUp: window.matchMedia('(min-width: 75em)')\n\t},\n\n\tfxHandleToggleAsideFilter(el) {\n\t\t// check if element exists\n\t\tif (!el) return\n\n\t\t// prevent page reload\n\t\tel.preventDefault()\n\n\t\t// toggle aside filter\n\t\tthis.el.asideFilterMapContainer.classList.toggle('aside-filter--hidden')\n\t},\n\n\tfxWatchModalOnResize() {\n\t\t// Condition that make sure when user is resizing the screen the page will not be locked with scroll hidden\n\t\tif (!this.vars.extraLargeAndUp.matches && this.el.asideFilterMapContainer.classList.contains('aside-filter--hidden')) {\n\t\t\tthis.el.asideFilterMapContainer.classList.remove('aside-filter--hidden')\n\t\t}\n\t},\n\n\tevents() {\n\t\t// check if there is the container\n\t\tif (!this.el.asideFilterMapContainer) return\n\n\t\t// Responsible for Toggle Aside Filter \n\t\tthis.el.toggleButton.addEventListener('click', el => this.fxHandleToggleAsideFilter(el))\n\n\t\t// resize event for window - Responsible for check if the modal is active and if it is, then it will remove the active class\n\t\twindow.addEventListener('resize', () => this.fxWatchModalOnResize())\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\ntoggleEventsAsideFilterMap.init()","const toggleEventsFilterModal = {\n\tel: {\n\t\tbody: document.querySelector('body'),\n\t\tfilterContainer: document.querySelector('.filter'),\n\t\tfilterInputAndSelectListener: document.querySelectorAll('.js-filter-change-listener'),\n\t\ttoggleModalButton: document.querySelectorAll('.js-filter-toggle-modal'),\n\t\tfilterTabs: document.querySelectorAll('[data-filter-tab]')\n\t},\n\n\tvars: {\n\t\textraLargeAndUp: window.matchMedia('(min-width: 75em)')\n\t},\n\n\tfxHideSelectionsOnTwoFieldset(valueSelected, filterTypeSelected, firstFieldsetName, secondFieldsetName, firstOptionSelectOnSecondFieldset, dataAttributeName) {\n\t\t// Check if selected filter is category that might filter subCategories on next select\n\t\tif (filterTypeSelected === firstFieldsetName) {\n\n\t\t\t// reset data filter type on subCategories containers\n\t\t\tdocument.querySelectorAll(`[data-filter-type=\"${secondFieldsetName}\"]`).forEach(el => {\n\t\t\t\t// reset value on atribute data-filter-id\n\t\t\t\tel.setAttribute('data-filter-id', '')\n\n\t\t\t\t// reset input checked to allSubCategories\n\t\t\t\tdocument.querySelector(`input[value=\"${firstOptionSelectOnSecondFieldset}\"]`).checked = true\n\t\t\t\t// reset select option to allSubCategories\n\t\t\t\tdocument.querySelector(`[value=\"${firstOptionSelectOnSecondFieldset}\"`).selected = true\n\t\t\t})\n\n\t\t\t// set hidden to every subCategory SELECTS\n\t\t\tdocument.querySelectorAll(`option[${dataAttributeName}]`).forEach(el => el.setAttribute('hidden', 'hidden'))\n\n\t\t\t// remove hidden to subCategory SELECTED\n\t\t\tdocument.querySelectorAll(`option[${dataAttributeName}=\"${valueSelected}\"]`).forEach(el => el.removeAttribute('hidden'))\n\n\t\t\t// set hidden to every subCategory RADIO BUTTONS\n\t\t\tdocument.querySelectorAll(`div[${dataAttributeName}]`).forEach(el => el.style.display = 'none')\n\n\t\t\t// remove hidden to subCategory RADIO BUTTONS\n\t\t\tdocument.querySelectorAll(`div[${dataAttributeName}=\"${valueSelected}\"]`).forEach(el => el.style.display = 'block')\n\t\t}\n\t},\n\n\tfxHandleSelectAndInputValue(el) {\n\t\t// Check if the element exists\n\t\tif (!el) return\n\n\t\t// Get the value of the element\n\t\tconst valueSelected = el.currentTarget.value\n\t\t// Get filter type of element selected\n\t\tconst getFilterTypeSelected = el.currentTarget.closest('[data-filter-type]').getAttribute('data-filter-type')\n\n\t\t// find filter type of element selected and set atribute to filter id\n\t\tdocument.querySelectorAll(`[data-filter-type=\"${getFilterTypeSelected}\"]`).forEach(el => {\n\t\t\tel.setAttribute('data-filter-id', valueSelected)\n\t\t})\n\n\t\tthis.fxHideSelectionsOnTwoFieldset(valueSelected, getFilterTypeSelected, 'category', 'subCategory', 'allSubCategories', 'data-category')\n\n\t\tthis.fxHideSelectionsOnTwoFieldset(valueSelected, getFilterTypeSelected, 'regionEvents', 'locationEvents', 'allLocations', 'data-region')\n\n\t\t// find input element and set value as value selected\n\t\tdocument.querySelector(`input[value=\"${valueSelected}\"]`).checked = valueSelected\n\t\t// find select element and set value as value selected\n\t\tdocument.querySelector(`[value=\"${valueSelected}\"`).parentElement.value = valueSelected\n\t},\n\n\tfxHandleToggleModal(el) {\n\t\tif (!el) return\n\t\t// Check if the modal is open\n\t\tif (el.currentTarget.closest('.filter').classList.contains('filter-modal-active')) {\n\t\t\tthis.el.body.classList.remove('no-scroll-hidden')\n\t\t\tel.currentTarget.closest('.filter').classList.remove('filter-modal-active')\n\t\t} else {\n\t\t\tthis.el.body.classList.add('no-scroll-hidden')\n\t\t\tel.currentTarget.closest('.filter').classList.add('filter-modal-active')\n\t\t}\n\t},\n\n\tfxWatchResizeForCloseModal() {\n\t\tif (!this.el.filterContainer) return\n\n\t\t// Condition that make sure when user is resizing the screen the page will not be locked with scroll hidden\n\t\tif (this.vars.extraLargeAndUp.matches && this.el.filterContainer.classList.contains('filter-modal-active')) {\n\t\t\tthis.el.filterContainer.classList.remove('filter-modal-active')\n\t\t\tthis.el.body.classList.remove('no-scroll-hidden')\n\t\t}\n\t},\n\n\tinit() {\n\t\t// Responsible for toggling the filter modal\n\t\tthis.el.toggleModalButton.forEach(el => el.addEventListener('click', e => this.fxHandleToggleModal(e)))\n\n\t\t// Responsible for set values of radio buttons and select elements on data attribute called \"data filter id\" and make sure that when user select mobile version, the desktop version is selected as well\n\t\tthis.el.filterInputAndSelectListener.forEach(el => el.addEventListener('change', e => this.fxHandleSelectAndInputValue(e)))\n\n\t\t// resize event for window - Responsible for check if the modal is active and if it is, then it will remove the active class\n\t\twindow.addEventListener('resize', () => this.fxWatchResizeForCloseModal())\n\t}\n}\n\ntoggleEventsFilterModal.init()","const toggleEventsLanguageSelect = {\n\tel: {\n\t\tbody: document.querySelector('body'),\n\t\tmodalLanguageSelect: document.querySelector('.js-modal-language'),\n\t\tbuttonModalLanguageSelect: document.querySelectorAll('.js-toggle-modal-language')\n\t},\n\n\tfxToggleModalLanguageSelect(el) {\n\t\tthis.el.body.classList.toggle('no-scroll-hidden')\n\t\tel.classList.toggle('header__modal--open')\n\t},\n\n\tevents() {\n\t\t// Event for open and close modal\n\t\tthis.el.buttonModalLanguageSelect.forEach(el => el.addEventListener('click', () => this.fxToggleModalLanguageSelect(this.el.modalLanguageSelect)))\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\ntoggleEventsLanguageSelect.init()","const toggleEventsNav = {\n\tel: {\n\t\thtml: document.documentElement,\n\t\tbody: document.querySelector('body'),\n\t\theader: document.querySelector('.header'),\n\t\thamburger: document.querySelector('.js-toggle-hamburger'),\n\t\tnavLink: document.querySelectorAll('.js-nav-link'),\n\t\tmainWrapper: document.querySelector('main')\n\t},\n\n\tvars: {\n\t\textraLargeAndUp: window.matchMedia('(min-width: 75em)')\n\t},\n\n\tfxWatchScrollOnHeaderForRemoveTransparency() {\n\t\tif (this.el.header.classList.contains('js-header-transparent')) {\n\t\t\t// when page is scrolled and value is bigger than 1, we remove transparent class \n\t\t\tif (this.el.html.scrollTop > 1) {\n\t\t\t\tthis.el.header.classList.remove('transparent')\n\t\t\t\tthis.el.mainWrapper.style.paddingTop = 0\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.el.header.classList.add('transparent')\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\treturn\n\t\t}\n\t},\n\n\tfxToggleNavLinkActive(el) {\n\t\t// remove visited class in all links\n\t\tthis.el.navLink.forEach(el => el.classList.remove('visited'))\n\n\t\t// add visited class on current clicked link\n\t\tel.currentTarget.classList.add('visited')\n\n\t\t// Check if header is open, if yes close it after few seconds\n\t\tif (this.el.header.classList.contains('header--open')) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.el.header.classList.remove('header--open')\n\t\t\t\tthis.el.body.classList.remove('no-scroll-hidden')\n\t\t\t}, 500)\n\t\t}\n\t},\n\n\tfxToggleHamburger(el) {\n\t\t// Toggle classes for open and close menu\n\t\tthis.el.body.classList.toggle('no-scroll-hidden')\n\t\tel.classList.toggle('header--open')\n\n\t\t// if user is in homepage and page scroll is equal 0, than we remove transparent class\n\t\tif (this.el.header.classList.contains('transparent')) {\n\t\t\tthis.el.header.classList.remove('transparent')\n\t\t}\n\t},\n\n\tfxWatchResizeForScrollHidden() {\n\t\t// Condition that make sure when user is resizing the screen the page will not be locked with scroll hidden\n\t\tif (this.vars.extraLargeAndUp.matches && this.el.header.classList.contains('header--open')) {\n\t\t\tthis.el.header.classList.remove('header--open')\n\t\t\tthis.el.body.classList.remove('no-scroll-hidden')\n\t\t}\n\t},\n\n\tevents() {\n\t\t// click event for open menu\n\t\tthis.el.hamburger.addEventListener('click', () => this.fxToggleHamburger(this.el.header))\n\n\t\t// click event for links on menu\n\t\tthis.el.navLink.forEach(el => el.addEventListener('click', e => this.fxToggleNavLinkActive(e)))\n\n\t\t// call this function when load page in order to start header transparent - only Homepage is used\n\t\tthis.fxWatchScrollOnHeaderForRemoveTransparency()\n\n\t\t// scroll for change transparency on header - only Homepage is used\n\t\twindow.addEventListener('scroll', () => this.fxWatchScrollOnHeaderForRemoveTransparency())\n\n\t\t// resize event for window\n\t\twindow.addEventListener('resize', () => this.fxWatchResizeForScrollHidden())\n\t},\n\n\tinit() {\n\t\tthis.events()\n\t}\n}\n\ntoggleEventsNav.init()"]}