1/* Set the WPForms currency hidden field before conditional logic runs. */ 2(function () { 3 try { 4 var currency = window.localStorage.getItem('cazloyd_currency'); 5 if (currency !== 'GBP' && currency !== 'USD') { 6 var match = document.cookie.match(/(?:^|; )cazloyd_currency=([^;]*)/); 7 currency = match ? decodeURIComponent(match[1]).toUpperCase() : ''; 8 } 9 if (currency !== 'GBP' && currency !== 'USD') { 10 return; 11 } 12 var nodes = document.querySelectorAll('.currency_cls input, .currency_cls select, .currency_cls textarea'); 13 for (var i = 0; i < nodes.length; i++) { 14 nodes[i].value = currency; 15 } 16 } catch (e) {} 17})(); 18 19var $ = jQuery.noConflict(); 20$(document).ready(function () { 21 22 /* Currency selector - persist choice and swap itinerary prices */ 23 (function initCurrencySelector() { 24 var storageKey = 'cazloyd_currency'; 25 var cookieName = 'cazloyd_currency'; 26 var defaultCurrency = 'GBP'; 27 var allowed = { GBP: true, USD: true }; 28 29 function getCookie(name) { 30 var match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)')); 31 return match ? decodeURIComponent(match[1]) : ''; 32 } 33 34 function setCookie(name, value) { 35 document.cookie = name + '=' + encodeURIComponent(value) + '; path=/; max-age=31536000; SameSite=Lax'; 36 } 37 38 function normalizeCurrency(value) { 39 value = (value || '').toUpperCase(); 40 return allowed[value] ? value : defaultCurrency; 41 } 42 43 function getSavedCurrency() { 44 var stored = ''; 45 try { 46 stored = window.localStorage.getItem(storageKey) || ''; 47 } catch (e) {} 48 return normalizeCurrency(stored || getCookie(cookieName) || defaultCurrency); 49 } 50 51 function saveCurrency(currency) { 52 currency = normalizeCurrency(currency); 53 try { 54 window.localStorage.setItem(storageKey, currency); 55 } catch (e) {} 56 setCookie(cookieName, currency); 57 return currency; 58 } 59 60 function updatePriceElements(currency) { 61 $('.js-currency-price').each(function () { 62 var $el = $(this); 63 var gbp = $el.attr('data-price-gbp') || ''; 64 var usd = $el.attr('data-price-usd') || ''; 65 var text = currency === 'USD' ? (usd || gbp) : (gbp || usd); 66 if (text) { 67 $el.text(text); 68 } 69 }); 70 } 71 72 function updateCallButtons(currency) { 73 var key = currency === 'USD' ? 'usd' : 'gbp'; 74 75 $('.js-currency-call-btn').each(function () { 76 var $el = $(this); 77 var url = $el.attr('data-call-' + key + '-url') || ''; 78 var title = $el.attr('data-call-' + key + '-title') || ''; 79 var target = $el.attr('data-call-' + key + '-target') || '_self'; 80 81 if (!url) { 82 $el.hide(); 83 return; 84 } 85 86 $el.attr({ 87 href: url, 88 title: title, 89 target: target 90 }); 91 $el.find('.js-currency-call-label').text(title); 92 $el.show(); 93 }); 94 } 95 96 function choicesInstance(select) { 97 var libs = [window.jQuery, $]; 98 for (var i = 0; i < libs.length; i++) { 99 if (!libs[i] || !libs[i].fn) { 100 continue; 101 } 102 var instance = libs[i](select).data('choicesjs'); 103 if (instance) { 104 return instance; 105 } 106 } 107 return null; 108 } 109 110 function toggleConditionalField(field, show) { 111 if (show) { 112 field.style.display = ''; 113 field.classList.remove('wpforms-conditional-hide'); 114 field.classList.add('wpforms-conditional-show'); 115 var layout = field.closest('.wpforms-field-layout'); 116 if (layout) { 117 layout.style.display = ''; 118 layout.classList.remove('wpforms-conditional-hide'); 119 layout.classList.add('wpforms-conditional-show'); 120 } 121 field.querySelectorAll('select').forEach(function (select) { 122 var instance = choicesInstance(select); 123 if (instance && instance.containerOuter && instance.containerOuter.element) { 124 instance.containerOuter.element.style.width = '100%'; 125 } 126 }); 127 return; 128 } 129 130 field.style.display = 'none'; 131 field.classList.add('wpforms-conditional-hide'); 132 field.classList.remove('wpforms-conditional-show'); 133 } 134 135 function syncWpformsCurrency(currency) { 136 var showPound = currency !== 'USD'; 137 138 document.querySelectorAll('.budget_pound').forEach(function (field) { 139 toggleConditionalField(field, showPound); 140 }); 141 document.querySelectorAll('.budget_dollar').forEach(function (field) { 142 toggleConditionalField(field, !showPound); 143 }); 144 145 document.querySelectorAll('.currency_cls input, .currency_cls select, .currency_cls textarea').forEach(function (field) { 146 if (field.value === currency) { 147 field.dispatchEvent(new Event('change', { bubbles: true })); 148 return; 149 } 150 field.value = currency; 151 if (field.tagName === 'SELECT') { 152 var instance = choicesInstance(field); 153 if (instance && typeof instance.setChoiceByValue === 'function') { 154 instance.setChoiceByValue(currency); 155 } 156 } 157 field.dispatchEvent(new Event('input', { bubbles: true })); 158 field.dispatchEvent(new Event('change', { bubbles: true })); 159 }); 160 } 161 162 function applyCurrency(currency, persist) { 163 currency = normalizeCurrency(currency); 164 if (persist) { 165 saveCurrency(currency); 166 } 167 $('.js-currency-selector').val(currency); 168 updatePriceElements(currency); 169 updateCallButtons(currency); 170 syncWpformsCurrency(currency); 171 $('body') 172 .attr('data-currency', currency) 173 .removeClass('currency-gbp currency-usd') 174 .addClass('currency-' + currency.toLowerCase()); 175 } 176 177 applyCurrency(getSavedCurrency(), true); 178 179 $(document).on('change', '.js-currency-selector', function () { 180 applyCurrency($(this).val(), true); 181 }); 182 })(); 183 184 $('.content-page-section a[href^="#"]').not('[href="#"]').click(function(event) { 185 event.preventDefault(); 186 var target = $(this.hash); 187 if (target.length) { 188 $('html, body').animate({ 189 scrollTop: target.offset().top - 100 190 }, 800); 191 } 192 });
193 194 $(".filter-box__title").on("click", function(event) { 195 if ($(event.target).closest('.clear-filters').length) { 196 return; 197 } 198 $(".filter-wrap").toggle("500"); 199 }); 200 201 202 203 var mySwiper5 = new Swiper(".GallerySlider", { 204 effect: "coverflow", 205 centeredSlides: true, 206 slidesPerView: "auto", 207 loop: true, 208 speed: 800, 209 grabCursor: true, 210 211 navigation: { 212 nextEl: ".gallery-next", 213 prevEl: ".gallery-prev", 214 }, 215 216 coverflowEffect: { 217 rotate: 0, 218 stretch: 0, 219 depth: 100, 220 modifier: 5, 221 slideShadows: false, 222 }, 223 }); 224 if (mySwiper5.initialized) { 225 mySwiper5.init(); 226 } 227 228 229 230 231 /* Scroll Parallax */ 232 window.addEventListener("scroll", function(){ 233 let parallaxElements = document.querySelectorAll(".parallax-bg"); 234 parallaxElements.forEach(function(parallax){ 235 let rect = parallax.getBoundingClientRect(); 236 let speed = -0.2; 237 if(rect.top < window.innerHeight && rect.bottom > 0){ 238 let offset = rect.top * speed; 239 parallax.style.transform = "translateY(" + offset + "px)"; 240 } 241 }); 242 }); 243 /* Scroll Parallax */ 244 245 var headerHeight = 0; 246 var lastScrollTop = 0; 247 var $backToTop = $('.back-to-top'); 248 249 function updateHeaderHeight() { 250 headerHeight = $('.site-header').outerHeight() || 0; 251 } 252 253 function updateHeaderOnScroll(scrollTop) { 254 if (scrollTop > headerHeight) { 255 $('body').addClass('stickHeader'); 256 } else { 257 $('body').removeClass('stickHeader'); 258 } 259 260 if (scrollTop > lastScrollTop) { 261 $('body').removeClass('HeaderDown'); // Scrolling down 262 } else { 263 $('body').addClass('HeaderDown'); // Scrolling up 264 } 265 266 lastScrollTop = scrollTop <= 0 ? 0 : scrollTop; 267 } 268 269 function updateBackToTop(scrollTop) { 270 if (!$backToTop.length) { 271 return; 272 } 273 if (scrollTop > 500) { 274 $backToTop.addClass('is-visible'); 275 } else { 276 $backToTop.removeClass('is-visible'); 277 } 278 } 279 280 $backToTop.on('click', '.backto-top-link', function (event) { 281 event.preventDefault(); 282 $('html, body').animate({ scrollTop: 0 }, 600); 283 }); 284 285 updateHeaderHeight(); 286 updateHeaderOnScroll($(window).scrollTop()); 287 updateBackToTop($(window).scrollTop()); 288 289 $(window).on('scroll', function () { 290 var scrollTop = $(this).scrollTop(); 291 updateHeaderOnScroll(scrollTop); 292 updateBackToTop(scrollTop); 293 }); 294 295 $(window).on('resize', function () { 296 updateHeaderHeight(); 297 updateHeaderOnScroll($(window).scrollTop()); 298 updateBackToTop($(window).scrollTop()); 299 }); 300 301 var $header = $('.site-header'); 302 var $searchToggle = $('.search-toggle'); 303 var $searchBox = $('#header-search'); 304 var $searchInput = $('#header-search-input'); 305 var $mobileMenu = $('#mobile-menu'); 306 var $mobileToggle = $('.mobile-menu-toggle'); 307 308 function setSearchState(isOpen) { 309 $header.toggleClass('is-search-open', isOpen); 310 $searchToggle.attr('aria-expanded', isOpen ? 'true' : 'false'); 311 $searchBox.attr('aria-hidden', isOpen ? 'false' : 'true'); 312 if (isOpen) { 313 setTimeout(function () { 314 $searchInput.trigger('focus'); 315 }, 10); 316 } 317 } 318 319 $searchToggle.on('click', function (event) { 320 event.stopPropagation(); 321 setSearchState(!$header.hasClass('is-search-open')); 322 }); 323 324 $(document).on('click', function (event) { 325 if ($header.hasClass('is-search-open') && !$(event.target).closest('.header-search, .search-toggle').length) { 326 setSearchState(false); 327 } 328 }); 329 330 $(document).on('keyup', function (event) { 331 if (event.key === 'Escape') { 332 setSearchState(false); 333 closeMobileMenu(); 334 } 335 });
336 337 $('.mega-menu').each(function () { 338 var $menu = $(this); 339 var $tabs = $menu.find('.mega-tab'); 340 var hasNested = $tabs.find('> .mega-menu').length > 0; 341 if (hasNested) { 342 $menu.addClass('mega-menu--nested'); 343 $menu.find('.mega-tabs').addClass('has-nested'); 344 } 345 346 $tabs.on('mouseenter click', function (event) { 347 var $tab = $(this); 348 var target = $tab.data('mega-target'); 349 var $nestedMenu = $tab.children('.mega-menu'); 350 var hasTarget = !!target; 351 var hasNestedMenu = $nestedMenu.length > 0; 352 353 if ($(event.target).is('a') && $(event.target).attr('href') === '#' && (hasTarget || hasNestedMenu)) { 354 event.preventDefault(); 355 } 356 357 if (hasTarget) { 358 $menu.find('.mega-tab').removeClass('is-active'); 359 $tab.addClass('is-active'); 360 $menu.find('.mega-panel').removeClass('is-active'); 361 $menu.find('#' + target).addClass('is-active'); 362 } 363 364 if (hasNestedMenu) { 365 $menu.find('.mega-tab').removeClass('is-active'); 366 $tab.addClass('is-active'); 367 $menu.find('.mega-tab > .mega-menu').removeClass('is-active'); 368 $nestedMenu.addClass('is-active'); 369 } 370 }); 371 }); 372 373 $('.menu-item.has-mega>.menu-link').on('click', function (event) { 374 if (window.matchMedia('(min-width: 961px)').matches) { 375 event.preventDefault(); 376 $('.menu-item.has-mega').not($(this).closest('.menu-item.has-mega')).removeClass('is-open'); 377 $(this).closest('.menu-item.has-mega').toggleClass('is-open'); 378 } 379 }); 380 381 $(document).on('click', function (event) { 382 if (!$(event.target).closest('.menu-item.has-mega').length) { 383 $('.menu-item.has-mega').removeClass('is-open'); 384 } 385 }); 386 387 function openMobileMenu() { 388 $mobileMenu.toggleClass('is-open').attr('aria-hidden', 'false'); 389 $('body').toggleClass('is-mobile-menu-open'); 390 $mobileToggle.attr('aria-expanded', 'true'); 391 392 $(".is-open-submenu").removeClass('is-open-submenu'); 393 $(".is-open-child-submenu").removeClass('is-open-child-submenu'); 394 $(".is-open-normal-submenu").removeClass('is-open-normal-submenu'); 395 $(".is-open-normal-child-submenu").removeClass('is-open-normal-child-submenu'); 396 } 397 398 function closeMobileMenu() { 399 $mobileMenu.removeClass('is-open is-submenu-open').attr('aria-hidden', 'true'); 400 $('body').removeClass('is-mobile-menu-open'); 401 $mobileToggle.attr('aria-expanded', 'false'); 402 $mobileMenu.find('.mobile-submenu').removeClass('is-open').attr('aria-hidden', 'true'); 403 } 404 405 $mobileToggle.on('click', function () { 406 if ($mobileMenu.hasClass('is-open')) { 407 closeMobileMenu(); 408 } else { 409 openMobileMenu(); 410 } 411 }); 412 413 $mobileMenu.on('click', function (event) { 414 if ($(event.target).is('#mobile-menu')) { 415 closeMobileMenu(); 416 } 417 }); 418 419 $('.mobile-menu-close').on('click', function () { 420 closeMobileMenu(); 421 }); 422 423 if (window.matchMedia('(max-width: 991px)').matches) { 424 425 /* 1 Step Menu Open Submenu */ 426 $('.parent-child-menu .menu-link').on('click', function (e) { 427 e.preventDefault(); 428 $(this).next('.mega-menu--nested').addClass('is-open-submenu'); 429 $("body").addClass("is-open-menu-1step"); 430 }); 431 /* 2 Step Menu Open Submenu */ 432 $('.child-menu-tab>a').on('click', function (e) { 433 e.preventDefault(); 434 $(this).next('.mega-menu').addClass('is-open-child-submenu'); 435 $("body").addClass("is-open-menu-3step"); 436 }); 437 /* Normal Menu Open */ 438 $('.normal-menu>a').on('click', function (e) { 439 e.preventDefault(); 440 $(this).next('.mega-menu').addClass('is-open-submenu'); 441 $("body").addClass("is-open-menu-3step"); 442 }); 443 /* Normal Child Menu Open */ 444 $('.normal-childmenu>a').on('click', function (e) { 445 e.preventDefault(); 446 $(this).next('.normal-childmenu-content').addClass('is-open-child-submenu'); 447 $("body").addClass("is-open-menu-4step"); 448 }); 449 450 /* 1 Step Close Button */ 451 $('.back-btn .parent-back-btn').on('click', function (e) { 452 e.preventDefault(); 453 $(this).parent('.back-btn').closest(".mega-menu--nested").removeClass('is-open-submenu'); 454 $("body").removeClass("is-open-menu-1step"); 455 }); 456 457 /* 2 Step Close Button */ 458 $('.child-menu-tab .child-back-btn').on('click', function (e) { 459 e.preventDefault(); 460 $(this).parent('.back-btn').closest(".mega-menu").removeClass('is-open-child-submenu'); 461 $("body").removeClass("is-open-menu-3step"); 462 }); 463 464 /* 2 Step Close Button */ 465 $('.child-menu-tab .child-child-back-btn').on('click', function (e) { 466 e.preventDefault(); 467 $(this).parent('.back-btn').closest(".mega-menu").removeClass('is-open-child-submenu'); 468 $("body").removeClass("is-open-menu-4step"); 469 }); 470 471 /* Normal Child Menu Close Button */
472 $('.normal-menu-back-btn').on('click', function (e) { 473 e.preventDefault(); 474 $(this).parent('.back-btn').closest(".mega-menu").removeClass('is-open-submenu'); 475 $("body").removeClass("is-open-menu-4step"); 476 }); 477 478 /* Normal Menu Close Button */ 479 $('.normal-childmenu-back-btn').on('click', function (e) { 480 e.preventDefault(); 481 $(this).parent('.back-btn').closest(".normal-childmenu-content").removeClass('is-open-child-submenu'); 482 $("body").removeClass("is-open-menu-4step"); 483 }); 484 /* // Close Button */ 485 486 $('.mobile-submenu-back').on('click', function () { 487 $(this).closest('.mobile-submenu').removeClass('is-open').attr('aria-hidden', 'true'); 488 $mobileMenu.removeClass('is-submenu-open'); 489 }); 490 491 $('.child-menu-tab .mega-panel-columns a, .back-btn .highlight-menu').on('click', function (e) { 492 var targetLink = $(this).attr('href'); 493 window.open(targetLink, '_self'); 494 }); 495 } 496 else { 497 $('.child-menu-tab a').on('click', function (e) { 498 var targetLink = $(this).attr('href'); 499 window.open(targetLink, '_self'); 500 }); 501 } 502 503 $(".footer-links .h3, .footer-links h3").click(function () { 504 $(this).next('.footer-links-list').slideToggle(); 505 }); 506 507 var mobileBottomSticky = document.querySelector('.mobile-bottom-sticky'); 508 function updateMobileBottomStickyState() { 509 if (!mobileBottomSticky) { 510 $('body').removeClass('has-mobile-bottom-sticky'); 511 return; 512 } 513 514 var isVisible = window.getComputedStyle(mobileBottomSticky).display !== 'none'; 515 $('body').toggleClass('has-mobile-bottom-sticky', isVisible); 516 } 517 518 updateMobileBottomStickyState(); 519 window.addEventListener('resize', updateMobileBottomStickyState); 520 521 522 /* Slider */ 523 var tripSliderEl = document.querySelector('.TripSlider'); 524 if (tripSliderEl && typeof Swiper !== 'undefined') { 525 new Swiper(tripSliderEl, { 526 loop: false, 527 slidesPerView: 'auto', 528 spaceBetween: 0, 529 accessibility: false, 530 pagination: { 531 el: '.trip-pagination', 532 clickable: true, 533 }, 534 navigation: { 535 nextEl: '.TripSlider-button-next', 536 prevEl: '.TripSlider-button-prev', 537 } 538 }); 539 } 540 541 var pressSliderEl = document.querySelector('.press-slider'); 542 if (pressSliderEl && typeof Swiper !== 'undefined') { 543 new Swiper(pressSliderEl, { 544 loop: false, 545 slidesPerView: 1, 546 spaceBetween: 20, 547 pagination: { 548 el: '.press-pagination', 549 clickable: true, 550 }, 551 breakpoints: { 552 767: { 553 slidesPerView: 2, 554 spaceBetween: 20 555 }, 556 992: { 557 slidesPerView: 3, 558 spaceBetween: 20 559 }, 560 1280: { 561 slidesPerView: 4, 562 spaceBetween: 20 563 } 564 } 565 }); 566 } 567 568 var teamSliderEl = document.querySelector('.team-slider'); 569 if (teamSliderEl && typeof Swiper !== 'undefined') { 570 var teamSlides = teamSliderEl.querySelectorAll('.swiper-slide').length; 571 572 function updateTeamSliderState() { 573 var width = window.innerWidth || document.documentElement.clientWidth; 574 var slidesPerView = 1; 575 576 if (width >= 1280) { 577 slidesPerView = 4; 578 } else if (width >= 992) { 579 slidesPerView = 3; 580 } else if (width >= 767) { 581 slidesPerView = 3; 582 } 583 else if (width >= 640) { 584 slidesPerView = 2; 585 } 586 587 teamSliderEl.classList.toggle('is-few-slides', teamSlides <= slidesPerView); 588 } 589 590 updateTeamSliderState(); 591 window.addEventListener('resize', updateTeamSliderState); 592 593 new Swiper(teamSliderEl, { 594 loop: false, 595 slidesPerView: 1, 596 spaceBetween: 0, 597 pagination: { 598 el: '.team-pagination', 599 clickable: true, 600 }, 601 breakpoints: { 602 640: { 603 slidesPerView: 2, 604 }, 605 767: { 606 slidesPerView: 3, 607 }, 608 992: { 609 slidesPerView: 3, 610 }, 611 1280: { 612 slidesPerView: 4, 613 } 614 } 615 }); 616 } 617 618 619 document.querySelectorAll('.special-slider').forEach(function (specialSlider) { 620 if (typeof Swiper === 'undefined' || specialSlider.swiper) { 621 return; 622 } 623 624 var specialSlides = specialSlider.querySelectorAll('.swiper-slide').length; 625 var paginationEl = specialSlider.querySelector('.special-pagination'); 626 627 specialSlider.style.touchAction = 'pan-y'; 628 specialSlider.querySelectorAll('.swiper-wrapper, .swiper-slide, .special-card').forEach(function (node) { 629 node.style.touchAction = 'pan-y'; 630 }); 631 632 function getSpecialSlidesPerView() { 633 var width = window.innerWidth || document.documentElement.clientWidth; 634 635 if (width >= 1200) { 636 return 4; 637 } 638 if (width >= 767) { 639 return 3; 640 } 641 if (width >= 640) { 642 return 2; 643 } 644 return 1; 645 } 646 647 function updateSpecialSliderState() { 648 specialSlider.classList.toggle('is-few-slides', specialSlides <= getSpecialSlidesPerView()); 649 } 650 651 updateSpecialSliderState(); 652 window.addEventListener('resize', updateSpecialSliderState); 653 654 new Swiper(specialSlider, { 655 loop: false, 656 spaceBetween: 0, 657 slidesPerView: 1, 658 watchOverflow: true, 659 allowTouchMove: true, 660 simulateTouch: true, 661 grabCursor: true, 662 followFinger: true, 663 threshold: 8, 664 shortSwipes: true, 665 longSwipes: true, 666 passiveListeners: false, 667 touchStartPreventDefault: false, 668 touchEventsTarget: 'container', 669 pagination: paginationEl ? { 670 el: paginationEl, 671 clickable: true, 672 } : false, 673 breakpoints: { 674 640: { 675 slidesPerView: 2, 676 spaceBetween: 0, 677 }, 678 767: { 679 slidesPerView: 3, 680 spaceBetween: 0, 681 }, 682 992: { 683 slidesPerView: 3, 684 spaceBetween: 0, 685 }, 686 1200: { 687 slidesPerView: 4, 688 spaceBetween: 11, 689 } 690 } 691 }); 692 });
693 694 695 var testimonialsSliderEl = document.querySelector('.testimonials-slider'); 696 if (testimonialsSliderEl && typeof Swiper !== 'undefined') { 697 var testimonialsSlides = testimonialsSliderEl.querySelectorAll('.swiper-slide').length; 698 var testimonialsMaxVisibleDots = 2; 699 700 function updateTestimonialsSliderState() { 701 var width = window.innerWidth || document.documentElement.clientWidth; 702 var slidesPerView = 1; 703 704 if (width >= 767) { 705 slidesPerView = 2; 706 } 707 708 testimonialsSliderEl.classList.toggle('is-few-slides', testimonialsSlides <= slidesPerView); 709 } 710 711 updateTestimonialsSliderState(); 712 window.addEventListener('resize', updateTestimonialsSliderState); 713 714 var testimonialsPaginationEl = testimonialsSliderEl.querySelector('.testimonials-pagination') || 715 (testimonialsSliderEl.parentElement ? 716 testimonialsSliderEl.parentElement.querySelector('.testimonials-pagination') : 717 null); 718 719 var testimonialsSwiper = new Swiper(testimonialsSliderEl, { 720 loop: false, 721 slidesPerView: 1, 722 spaceBetween: 0, 723 pagination: false, 724 breakpoints: { 725 767: { 726 slidesPerView: 2, 727 }, 728 992: { 729 slidesPerView: 2, 730 }, 731 } 732 }); 733 734 function bindTestimonialsPagination(swiper, totalSlides, paginationEl) { 735 if (!paginationEl) { 736 return; 737 } 738 739 function getTestimonialsPaginationTrack() { 740 var viewport = paginationEl.querySelector('.testimonials-pagination__viewport'); 741 var track = paginationEl.querySelector('.testimonials-pagination__track'); 742 743 if (!viewport) { 744 paginationEl.innerHTML = ''; 745 viewport = document.createElement('div'); 746 viewport.className = 'testimonials-pagination__viewport'; 747 track = document.createElement('div'); 748 track.className = 'testimonials-pagination__track'; 749 viewport.appendChild(track); 750 paginationEl.appendChild(viewport); 751 } 752 753 return track; 754 } 755 756 function buildTestimonialsPaginationBullets(track, pageCount) { 757 track.innerHTML = ''; 758 759 for (var i = 0; i < pageCount; i++) { 760 var bullet = document.createElement('span'); 761 bullet.className = 'swiper-pagination-bullet swiper-no-swiping'; 762 bullet.setAttribute('role', 'button'); 763 bullet.setAttribute('tabindex', '0'); 764 bullet.setAttribute('data-slide-index', String(i)); 765 bullet.setAttribute('aria-label', 'Go to testimonial ' + (i + 1)); 766 track.appendChild(bullet); 767 } 768 } 769 770 function getTestimonialsDotMetrics(bullets) { 771 var bulletWidth = 12; 772 var gap = 8; 773 774 if (bullets.length) { 775 var bulletStyles = window.getComputedStyle(bullets[0]); 776 bulletWidth = parseFloat(bulletStyles.width) || 12; 777 778 if (bullets.length > 1) { 779 var measuredGap = bullets[1].offsetLeft - bullets[0].offsetLeft - bullets[0].offsetWidth; 780 781 if (measuredGap > 0) { 782 gap = measuredGap; 783 } 784 } 785 } 786 787 return { 788 bulletWidth: bulletWidth, 789 gap: gap, 790 step: bulletWidth + gap 791 }; 792 } 793 794 function updateTestimonialsPaginationTrackPosition(track, currentIndex, pageCount) { 795 if (pageCount <= testimonialsMaxVisibleDots) { 796 track.style.transform = ''; 797 return; 798 } 799 800 var bullets = track.querySelectorAll('.swiper-pagination-bullet'); 801 802 if (!bullets.length) { 803 return; 804 } 805 806 var metrics = getTestimonialsDotMetrics(bullets); 807 var windowStart = currentIndex; 808 809 if (windowStart + testimonialsMaxVisibleDots > pageCount) { 810 windowStart = pageCount - testimonialsMaxVisibleDots; 811 } 812 813 if (windowStart < 0) { 814 windowStart = 0; 815 } 816 817 track.style.transform = 'translate3d(-' + (windowStart * metrics.step) + 'px, 0, 0)'; 818 } 819 820 function syncTestimonialsPagination() { 821 var pageCount = Math.max(1, totalSlides); 822 var currentIndex = swiper.activeIndex || 0; 823 var track = getTestimonialsPaginationTrack(); 824 var storedPageCount = parseInt(paginationEl.dataset.pageCount, 10) || 0; 825 826 if (storedPageCount !== pageCount) { 827 paginationEl.dataset.pageCount = String(pageCount); 828 buildTestimonialsPaginationBullets(track, pageCount); 829 } 830 831 paginationEl.classList.toggle('is-dynamic-dots', pageCount > testimonialsMaxVisibleDots); 832 833 track.querySelectorAll('.swiper-pagination-bullet').forEach(function (bullet, index) { 834 bullet.classList.toggle('swiper-pagination-bullet-active', index === currentIndex); 835 }); 836 837 window.requestAnimationFrame(function () { 838 updateTestimonialsPaginationTrackPosition(track, currentIndex, pageCount); 839 840 window.requestAnimationFrame(function () { 841 updateTestimonialsPaginationTrackPosition(track, currentIndex, pageCount); 842 }); 843 }); 844 } 845 846 function handleTestimonialsPaginationClick(event) { 847 var bullet = event.target.closest('.swiper-pagination-bullet'); 848 849 if (!bullet || !paginationEl.contains(bullet)) { 850 return; 851 } 852 853 var slideIndex = parseInt(bullet.getAttribute('data-sli
853de-index'), 10); 854 855 if (isNaN(slideIndex)) { 856 return; 857 } 858 859 event.preventDefault(); 860 swiper.slideTo(slideIndex); 861 } 862 863 if (paginationEl.dataset.testimonialsPaginationBound !== '1') { 864 paginationEl.dataset.testimonialsPaginationBound = '1'; 865 paginationEl.classList.add('swiper-no-swiping'); 866 paginationEl.addEventListener('click', handleTestimonialsPaginationClick); 867 } 868 869 swiper.on('slideChange', syncTestimonialsPagination); 870 swiper.on('breakpoint', syncTestimonialsPagination); 871 swiper.on('resize', syncTestimonialsPagination); 872 syncTestimonialsPagination(); 873 } 874 875 bindTestimonialsPagination(testimonialsSwiper, testimonialsSlides, testimonialsPaginationEl); 876 } 877 878 879 // 4 items slider 880 var fourItemsSliderEls = document.querySelectorAll('.four-items-slider'); 881 if (fourItemsSliderEls.length && typeof Swiper !== 'undefined') { 882 function getFourItemsSlidesPerView(width) { 883 if (width >= 1280) { 884 return 4; 885 } 886 if (width >= 992) { 887 return 3; 888 } 889 if (width >= 767) { 890 return 3; 891 } 892 if (width >= 640) { 893 return 2; 894 } 895 return 1; 896 } 897 898 function getFourItemsMaxStartIndex(totalSlides, slidesPerView) { 899 return Math.max(0, totalSlides - slidesPerView); 900 } 901 902 function getFourItemsPageStartIndex(pageIndex, slidesPerView, totalSlides) { 903 return Math.min(pageIndex * slidesPerView, getFourItemsMaxStartIndex(totalSlides, slidesPerView)); 904 } 905 906 function getFourItemsPageIndex(activeIndex, slidesPerView, totalSlides) { 907 var maxStart = getFourItemsMaxStartIndex(totalSlides, slidesPerView); 908 909 if (activeIndex >= maxStart && totalSlides > slidesPerView) { 910 return Math.ceil(totalSlides / slidesPerView) - 1; 911 } 912 913 return Math.floor(activeIndex / slidesPerView); 914 } 915 916 function bindFourItemsGroupedControls(swiper, totalSlides, paginationEl, nextEl, prevEl) { 917 var fourItemsMaxVisibleDots = 3; 918 919 function getCurrentSlidesPerView() { 920 var width = window.innerWidth || document.documentElement.clientWidth; 921 return getFourItemsSlidesPerView(width); 922 } 923 924 function slideToPage(pageIndex) { 925 var slidesPerView = getCurrentSlidesPerView(); 926 swiper.slideTo(getFourItemsPageStartIndex(pageIndex, slidesPerView, totalSlides)); 927 } 928 929 function getFourItemsPaginationTrack() { 930 var viewport = paginationEl.querySelector('.four-items-pagination__viewport'); 931 var track = paginationEl.querySelector('.four-items-pagination__track'); 932 933 if (!viewport) { 934 paginationEl.innerHTML = ''; 935 viewport = document.createElement('div'); 936 viewport.className = 'four-items-pagination__viewport'; 937 track = document.createElement('div'); 938 track.className = 'four-items-pagination__track'; 939 viewport.appendChild(track); 940 paginationEl.appendChild(viewport); 941 } 942 943 return track; 944 } 945 946 function buildFourItemsPaginationBullets(track, pageCount) { 947 track.innerHTML = ''; 948 949 for (var i = 0; i < pageCount; i++) { 950 var bullet = document.createElement('span'); 951 bullet.className = 'swiper-pagination-bullet swiper-no-swiping'; 952 bullet.setAttribute('role', 'button'); 953 bullet.setAttribute('tabindex', '0'); 954 bullet.setAttribute('data-page-index', String(i)); 955 bullet.setAttribute('aria-label', 'Go to slide page ' + (i + 1)); 956 track.appendChild(bullet); 957 } 958 } 959 960 function getFourItemsDotMetrics(bullets) { 961 var bulletWidth = 12; 962 var gap = 8; 963 964 if (bullets.length) { 965 var bulletStyles = window.getComputedStyle(bullets[0]); 966 bulletWidth = parseFloat(bulletStyles.width) || 12; 967 968 if (bullets.length > 1) { 969 var measuredGap = bullets[1].offsetLeft - bullets[0].offsetLeft - bullets[0].offsetWidth; 970 971 if (measuredGap > 0) { 972 gap = measuredGap; 973 } 974 } 975 } 976 977 return { 978 bulletWidth: bulletWidth, 979 gap: gap, 980 step: bulletWidth + gap 981 }; 982 } 983 984 function updateFourItemsPaginationTrackPosition(track, currentPage, pageCount) { 985 if (pageCount <= fourItemsMaxVisibleDots) { 986 track.style.transform = ''; 987 return; 988 } 989 990 var bullets = track.querySelectorAll('.swiper-pagination-bullet'); 991 992 if (!bullets.length) { 993 return; 994 } 995 996 var metrics = getFourItemsDotMetrics(bullets); 997 var windowStart = currentPage - 1; 998 999 if (windowStart < 0) { 1000 windowStart = 0; 1001 } 1002 1003 if (windowStart + fourItemsMaxVisibleDots > pageCount) { 1004 windowStart = pageCount - fourItemsMaxVisibleDots; 1005 } 1006 1007 track.style.transform = 'translate3d(-' + (windowStart * metrics.step) + 'px, 0, 0)'; 1008 } 1009 1010 function syncFourItemsPagination() { 1011 if (!paginationEl) { 1012 return; 1013 } 1014 1015 var slidesPerView = getCurrentSlidesPerView(); 1016 var pageCount = Math.max(1, Math.ceil(totalSlides / slidesPerView)); 1017 var currentPage = getFourItemsPageIndex(swiper.activeIndex, slidesPerView, totalSlides); 1018 var track = getFourItemsPaginationTrack(); 1019 var storedPageCount = parseInt(paginationEl.dataset.pageCount, 10) || 0; 1020 1021 if (storedPageCount !== pageCount) { 1022 paginationEl.dataset.pageCount = String(pageCount); 1023 buildFourItemsPaginationBullets(track, pageCount); 1024 } 1025 1026 paginationEl.classList.toggle('is-dynamic-dots', pageCount > fourItemsMaxVisibleDots); 1027 1028 track.querySelectorAll('.swiper-pagination-bullet').forEach(function (bullet, index) { 1029 bullet.classList.toggle('swiper-pagination-bullet-active', index === currentPage); 1030 }); 1031 1032 window.requestAnimationFrame(function () { 1033 updateFourItemsPaginationTrackPosition(track, currentPage, pageCount); 1034 1035 window.requestAnimationFrame(function () { 1036 updateFourItemsPaginationTrackPosition(track, currentPage, pageCount); 1037 }); 1038 }); 1039 } 1040 1041 function handleFourItemsPaginationClick(event) { 1042 var bullet = event.target.closest('.swiper-pagination-bullet'); 1043 1044 if (!bullet || !paginationEl.contains(bullet)) { 1045 return; 1046 } 1047 1048 var pageIndex = parseInt(bullet.getAttribute('data-page-index'), 10); 1049 1050 if (isNaN(pageIndex)) { 1051 return; 1052 } 1053 1054 event.preventDefault(); 1055 slideToPage(pageIndex); 1056 } 1057 1058 function clampFourItemsActiveIndex() { 1059 var slidesPerView = getCurrentSlidesPerView(); 1060 var maxStart = getFourItemsMaxStartIndex(totalSlides, slidesPerView); 1061 1062 if (swiper.activeIndex > maxStart) { 1063 swiper.slideTo(maxStart, 0); 1064 } 1065 } 1066 1067 if (paginationEl && paginationEl.dataset.fourItemsPaginationBound !== '1') { 1068 paginationEl.dataset.fourItemsPaginationBound = '1'; 1069 paginationEl.addEventListener('click', handleFourItemsPaginationClick); 1070 } 1071 1072 if (nextEl && nextEl.dataset.fourItemsNavBound !== '1') { 1073 nextEl.dataset.fourItemsNavBound = '1'; 1074 1075 nextEl.addEventListener('click', function (event) { 1076 var slidesPerView = getCurrentSlidesPerView(); 1077 var maxStart = getFourItemsMaxStartIndex(totalSlides, slidesPerView); 1078 var nextIndex = Math.min(swiper.activeIndex + slidesPerView, maxStart); 1079 1080 if (nextIndex === swiper.activeIndex) { 1081 return; 1082 } 1083 1084 event.preventDefault(); 1085 event.stopImmediatePropagation(); 1086 swiper.slideTo(nextIndex); 1087 }, true); 1088 } 1089 1090 if (prevEl && prevEl.dataset.fourItemsNavBound !== '1') { 1091 prevEl.dataset.fourItemsNavBound = '1'; 1092 1093 prevEl.addEventListener('click', function (event) { 1094 var slidesPerView = getCurrentSlidesPerView(); 1095 var prevIndex = Math.max(swiper.activeIndex - slidesPerView, 0); 1096 1097 if (prevIndex === swiper.activeIndex) { 1098 return; 1099 } 1100 1101 event.preventDefault(); 1102 event.stopImmediatePropagation(); 1103 swiper.slideTo(prevIndex); 1104 }, true); 1105 } 1106 1107 swiper.on('slideChange', function () { 1108 clampFourItemsActiveIndex(); 1109 syncFourItemsPagination(); 1110 }); 1111 1112 swiper.on('breakpoint', syncFourItemsPagination); 1113 swiper.on('resize', syncFourItemsPagination); 1114 syncFourItemsPagination(); 1115 } 1116
1117 fourItemsSliderEls.forEach(function (fourItemsSliderEl) { 1118 var fourItemsSlides = fourItemsSliderEl.querySelectorAll('.swiper-slide').length; 1119 1120 function updateFourItemsSliderState() { 1121 var width = window.innerWidth || document.documentElement.clientWidth; 1122 var slidesPerView = getFourItemsSlidesPerView(width); 1123 1124 fourItemsSliderEl.classList.toggle('is-few-slides', fourItemsSlides <= slidesPerView); 1125 } 1126 1127 updateFourItemsSliderState(); 1128 window.addEventListener('resize', updateFourItemsSliderState); 1129 1130 var paginationEl = fourItemsSliderEl.querySelector('.four-items-pagination') || 1131 (fourItemsSliderEl.parentElement ? 1132 fourItemsSliderEl.parentElement.querySelector('.four-items-pagination') : 1133 null); 1134 1135 if (paginationEl && paginationEl.parentElement === fourItemsSliderEl) { 1136 fourItemsSliderEl.parentElement.insertBefore(paginationEl, fourItemsSliderEl.nextSibling); 1137 } 1138 1139 if (paginationEl) { 1140 paginationEl.classList.add('swiper-no-swiping'); 1141 } 1142 1143 var sliderWrap = fourItemsSliderEl.closest('.arrow-with-slider'); 1144 var nextEl = sliderWrap ? sliderWrap.querySelector('.four-items-slider-next') : null; 1145 var prevEl = sliderWrap ? sliderWrap.querySelector('.four-items-slider-prev') : null; 1146 1147 var hasHotelContentToggle = fourItemsSliderEl.querySelector('.hotel-content-toggle-btn'); 1148 1149 var fourItemsSwiperOptions = { 1150 loop: false, 1151 slidesPerView: 1, 1152 slidesPerGroup: 1, 1153 watchOverflow: true, 1154 speed: 1500, 1155 touchEventsTarget: 'wrapper', 1156 spaceBetween: 17, 1157 pagination: false, 1158 breakpoints: { 1159 640: { 1160 slidesPerView: 2, 1161 }, 1162 767: { 1163 slidesPerView: 3, 1164 }, 1165 992: { 1166 slidesPerView: 3, 1167 }, 1168 1280: { 1169 slidesPerView: 4, 1170 } 1171 } 1172 }; 1173 1174 if (hasHotelContentToggle) { 1175 fourItemsSwiperOptions.preventClicks = false; 1176 fourItemsSwiperOptions.preventClicksPropagation = false; 1177 fourItemsSwiperOptions.noSwipingClass = 'swiper-no-swiping'; 1178 } 1179 1180 if (nextEl && prevEl) { 1181 fourItemsSwiperOptions.navigation = { 1182 nextEl: nextEl, 1183 prevEl: prevEl, 1184 }; 1185 } 1186 1187 var fourItemsSwiper = new Swiper(fourItemsSliderEl, fourItemsSwiperOptions); 1188 bindFourItemsGroupedControls(fourItemsSwiper, fourItemsSlides, paginationEl, nextEl, prevEl); 1189 }); 1190 } 1191 1192 /* Hotel content - Read more / Read less (word count) */ 1193 var hotelReadMoreMaxWords = 42; 1194 1195 function getHotelWordCount(html) { 1196 var text = $('<div>').html(html).text().replace(/\s+/g, ' ').trim(); 1197 1198 if (!text) { 1199 return 0; 1200 } 1201
1202 return text.split(' ').filter(Boolean).length; 1203 } 1204 1205 function truncateHtmlByWords(html, maxWords) { 1206 var $temp = $('<div>').html(html); 1207 var wordCount = 0; 1208 var done = false; 1209 1210 function truncateNode(node) { 1211 if (done) { 1212 if (node.nodeType === 1) { 1213 $(node).remove(); 1214 } else if (node.nodeType === 3) { 1215 node.textContent = ''; 1216 } 1217 return; 1218 } 1219 1220 if (node.nodeType === 3) { 1221 var text = node.textContent; 1222 var words = text.trim().split(/\s+/).filter(Boolean); 1223 1224 if (!words.length) { 1225 return; 1226 } 1227 1228 if (wordCount + words.length <= maxWords) { 1229 wordCount += words.length; 1230 return; 1231 } 1232 1233 var remaining = maxWords - wordCount; 1234 node.textContent = (remaining > 0 ? words.slice(0, remaining).join(' ') : '') + '...'; 1235 wordCount = maxWords; 1236 done = true; 1237 return; 1238 } 1239 1240 if (node.nodeType === 1) { 1241 var childNodes = Array.prototype.slice.call(node.childNodes); 1242 1243 for (var i = 0; i < childNodes.length; i++) { 1244 truncateNode(childNodes[i]); 1245 1246 if (done) { 1247 for (var j = i + 1; j < childNodes.length; j++) { 1248 if (childNodes[j].parentNode) { 1249 childNodes[j].parentNode.removeChild(childNodes[j]); 1250 } 1251 } 1252 break; 1253 } 1254 } 1255 } 1256 } 1257 1258 var root = $temp[0]; 1259 var children = Array.prototype.slice.call(root.childNodes); 1260 1261 for (var i = 0; i < children.length; i++) { 1262 truncateNode(children[i]); 1263 1264 if (done) { 1265 for (var j = i + 1; j < children.length; j++) { 1266 if (children[j].parentNode) { 1267 children[j].parentNode.removeChild(children[j]); 1268 } 1269 } 1270 break; 1271 } 1272 } 1273 1274 return $temp.html(); 1275 } 1276 1277 function resetHotelReadMore($content) { 1278 var $card = $content.closest('.four-items-card'); 1279 var $body = $content.closest('.four-items-card__body'); 1280 var fullHtml = $content.data('hotel-full-html'); 1281 1282 if (fullHtml !== undefined) { 1283 $content.html(fullHtml); 1284 } 1285 1286 $card.removeClass('is-content-expanded'); 1287 $content 1288 .removeClass('is-truncated is-expanded is-collapsed') 1289 .removeData('hotel-read-more-init') 1290 .removeData('hotel-full-html') 1291 .removeData('hotel-truncated-html') 1292 .css({ maxHeight: '', overflow: '' }); 1293 $body.removeClass('hidebutton'); 1294 } 1295 1296 function setupHotelReadMoreItem($content) { 1297 var $body = $content.closest('.four-items-card__body'); 1298 var fullHtml = $content.html(); 1299 var wordCount = getHotelWordCount(fullHtml); 1300 1301 $content.data('hotel-full-html', fullHtml); 1302 1303 if (wordCount <= hotelReadMoreMaxWords) { 1304 $body.addClass('hidebutton'); 1305 $content.data('hotel-read-more-init', true); 1306 return; 1307 } 1308 1309 var truncatedHtml = truncateHtmlByWords(fullHtml, hotelReadMoreMaxWords); 1310 1311 $content 1312 .html(truncatedHtml) 1313 .addClass('is-truncated is-collapsed'); 1314 1315 $content.data({ 1316 'hotel-read-more-init': true, 1317 'hotel-truncated-html': truncatedHtml 1318 }); 1319 1320 $body.removeClass('hidebutton'); 1321 } 1322 1323 function collapseHotelReadMoreItem($content) { 1324 if (!$content.hasClass('is-expanded')) { 1325 return; 1326 } 1327 1328 var truncatedHtml = $content.data('hotel-truncated-html'); 1329 var $card = $content.closest('.four-items-card'); 1330 1331 $content 1332 .html(truncatedHtml) 1333 .removeClass('is-expanded') 1334 .addClass('is-collapsed'); 1335 1336 $card.removeClass('is-content-expanded'); 1337 } 1338 1339 function expandHotelReadMoreItem($content) { 1340 var fullHtml = $content.data('hotel-full-html'); 1341 var $card = $content.closest('.four-items-card'); 1342 1343 $content 1344 .html(fullHtml) 1345 .removeClass('is-collapsed') 1346 .addClass('is-expanded'); 1347 1348 $card.addClass('is-content-expanded'); 1349 } 1350 1351 function collapseExpandedHotelReadMore(container) { 1352 var $scope = container ? $(container) : $(document); 1353 1354 $scope.find('.hotel-content-all-data.is-expanded').each(function () { 1355 collapseHotelReadMoreItem($(this)); 1356 }); 1357 } 1358 1359 function bindHotelReadMoreSlideReset() { 1360 document.querySelectorAll('.four-items-slider').forEach(function (sliderEl) { 1361 if (!sliderEl.swiper || sliderEl.dataset.hotelReadMoreBound === '1') { 1362 return; 1363 } 1364 1365 sliderEl.dataset.hotelReadMoreBound = '1'; 1366 1367 sliderEl.swiper.on('slideChange', function () { 1368 collapseExpandedHotelReadMore(sliderEl); 1369 }); 1370 }); 1371 } 1372 1373 function initHotelReadMore() { 1374 $('.hotel-content-all-data').each(function () { 1375 var $content = $(this); 1376 1377 if ($content.data('hotel-read-more-init')) { 1378 return; 1379 } 1380 1381 setupHotelReadMoreItem($content); 1382 }); 1383 } 1384 1385 function refreshHotelReadMore() { 1386 $('.hotel-content-all-data').each(function () { 1387 resetHotelReadMore($(this)); 1388 }); 1389 1390 initHotelReadMore(); 1391 } 1392 1393 initHotelReadMore(); 1394 bindHotelReadMoreSlideReset(); 1395 1396 $(document).on('click', '.hotel-content-toggle-btn', function (e) { 1397 e.preventDefault(); 1398 e.stopPropagation(); 1399 1400 var $btn = $(this); 1401 var $content = $btn.closest('.four-items-card__body').find('.hotel-content-all-data'); 1402 var action = $btn.data('action'); 1403 1404 if (action === 'expand') { 1405 expandHotelReadMoreItem($content); 1406 } else if (action === 'collapse') { 1407 collapseHotelReadMoreItem($content); 1408 } 1409 });
1410 1411 $(window).on('load', function () { 1412 refreshHotelReadMore(); 1413 bindHotelReadMoreSlideReset(); 1414 }); 1415 /* // Hotel content - Read more / Read less */ 1416 1417 /* Highlights text - Read more / Read less (word count) */ 1418 var highlightsReadMoreMaxWords = 60; 1419 var highlightsReadMoreDuration = 500; 1420 1421 function resetHighlightsReadMore($text, $btn) { 1422 var fullHtml = $text.data('highlights-full-html'); 1423 1424 if (fullHtml !== undefined) { 1425 $text.html(fullHtml); 1426 } 1427 1428 $text 1429 .removeClass('is-truncated is-expanded is-collapsed') 1430 .removeData('highlights-read-more-init') 1431 .removeData('highlights-full-html') 1432 .removeData('highlights-truncated-html') 1433 .removeData('highlights-collapsed-height') 1434 .removeData('highlights-full-height') 1435 .css({ maxHeight: '', overflow: '' }); 1436 1437 $btn 1438 .attr('aria-expanded', 'false') 1439 .find('.highlights-read-more-label') 1440 .text('Read more') 1441 .show(); 1442 } 1443 1444 function setupHighlightsReadMoreItem($text, $btn) { 1445 var fullHtml = $text.html(); 1446 var wordCount = getHotelWordCount(fullHtml); 1447 1448 $text.data('highlights-full-html', fullHtml); 1449 1450 if (wordCount <= highlightsReadMoreMaxWords) { 1451 $btn.hide(); 1452 $text.data('highlights-read-more-init', true); 1453 return; 1454 } 1455 1456 var truncatedHtml = truncateHtmlByWords(fullHtml, highlightsReadMoreMaxWords); 1457 1458 $text.html(fullHtml); 1459 $text.css({ maxHeight: 'none', overflow: 'visible' }); 1460 var fullHeight = $text[0].scrollHeight; 1461 1462 $text.html(truncatedHtml); 1463 $text.css({ maxHeight: 'none', overflow: 'visible' }); 1464 var collapsedHeight = $text[0].scrollHeight; 1465 1466 $text 1467 .addClass('is-truncated is-collapsed') 1468 .css({ maxHeight: collapsedHeight, overflow: 'hidden' }); 1469 1470 $text.data({ 1471 'highlights-read-more-init': true, 1472 'highlights-truncated-html': truncatedHtml, 1473 'highlights-collapsed-height': collapsedHeight, 1474 'highlights-full-height': fullHeight 1475 }); 1476 1477 $btn 1478 .show() 1479 .attr('aria-expanded', 'false') 1480 .find('.highlights-read-more-label') 1481 .text('Read more'); 1482 } 1483 1484 function collapseHighlightsReadMoreItem($text, $btn, animate) { 1485 if (!$text.hasClass('is-expanded')) { 1486 return; 1487 } 1488 1489 var truncatedHtml = $text.data('highlights-truncated-html'); 1490 var collapsedHeight = $text.data('highlights-collapsed-height'); 1491 1492 $text.stop(true, true); 1493 1494 if (animate) { 1495 var currentHeight = $text[0].scrollHeight; 1496 1497 $text.css({ maxHeight: currentHeight, overflow: 'hidden' }); 1498 1499 $text.animate({ maxHeight: collapsedHeight }, highlightsReadMoreDuration, function () { 1500 $text 1501 .html(truncatedHtml) 1502 .removeClass('is-expanded') 1503 .addClass('is-collapsed') 1504 .css({ maxHeight: collapsedHeight, overflow: 'hidden' }); 1505 }); 1506 } else { 1507 $text 1508 .html(truncatedHtml) 1509 .removeClass('is-expanded') 1510 .addClass('is-collapsed') 1511 .css({ maxHeight: collapsedHeight, overflow: 'hidden' }); 1512 } 1513 1514 $btn 1515 .attr('aria-expanded', 'false') 1516 .find('.highlights-read-more-label') 1517 .text('Read more'); 1518 } 1519 1520 function expandHighlightsReadMoreItem($text, $btn) { 1521 var fullHtml = $text.data('highlights-full-html'); 1522 var collapsedHeight = $text.data('highlights-collapsed-height'); 1523 var fullHeight = $text.data('highlights-full-height'); 1524 1525 $text.html(fullHtml); 1526 $text 1527 .removeClass('is-collapsed') 1528 .addClass('is-expanded') 1529 .css({ maxHeight: collapsedHeight, overflow: 'hidden' }) 1530 .stop(true, false) 1531 .animate({ maxHeight: fullHeight }, highlightsReadMoreDuration, function () { 1532 $text.css({ maxHeight: 'none', overflow: 'visible' }); 1533 }); 1534 1535 $btn 1536 .attr('aria-expanded', 'true') 1537 .find('.highlights-read-more-label') 1538 .text('Read less'); 1539 } 1540 1541 function initHighlightsReadMore() { 1542 $('.highlights-content').each(function () { 1543 var $wrap = $(this); 1544 var $text = $wrap.children('.highlights-text').first(); 1545 var $btn = $wrap.children('.highlights-read-more-btn').first(); 1546 1547 if (!$text.length || !$btn.length) { 1548 return; 1549 } 1550 1551 if ($text.data('highlights-read-more-init')) { 1552 return; 1553 } 1554 1555 setupHighlightsReadMoreItem($text, $btn); 1556 }); 1557 } 1558 1559 function refreshHighlightsReadMore() { 1560 $('.highlights-content').each(function () { 1561 var $wrap = $(this); 1562 var $text = $wrap.children('.highlights-text').first(); 1563 var $btn = $wrap.children('.highlights-read-more-btn').first(); 1564 1565 if (!$text.length || !$btn.length) { 1566 return; 1567 } 1568 1569 resetHighlightsReadMore($text, $btn); 1570 }); 1571 1572 initHighlightsReadMore(); 1573 } 1574 1575 initHighlightsReadMore(); 1576 1577 $(document).on('click', '.highlights-read-more-btn', function (e) { 1578 e.preventDefault(); 1579 1580 var $btn = $(this); 1581 var $text = $btn.closest('.highlights-content').children('.highlights-text').first(); 1582 1583 if (!$text.length) { 1584 return; 1585 } 1586 1587 if ($text.hasClass('is-expanded')) { 1588 collapseHighlightsReadMoreItem($text, $btn, true); 1589 return; 1590 } 1591 1592 expandHighlightsReadMoreItem($text, $btn); 1593 });
1594 1595 $(window).on('load', function () { 1596 refreshHighlightsReadMore(); 1597 }); 1598 /* // Highlights text - Read more / Read less */ 1599 1600 // 4 items travel calendar slider 1601 var travelCalendarSliderEls = document.querySelectorAll('.travel-calendar'); 1602 if (travelCalendarSliderEls.length && typeof Swiper !== 'undefined') { 1603 travelCalendarSliderEls.forEach(function (travelCalendarSliderEl) { 1604 var travelCalendarSlides = travelCalendarSliderEl.querySelectorAll('.swiper-slide').length; 1605 1606 function updateTravelCalendarSliderState() { 1607 var width = window.innerWidth || document.documentElement.clientWidth; 1608 var slidesPerView = 1; 1609 1610 if (width >= 1280) { 1611 slidesPerView = 4; 1612 } else if (width >= 992) { 1613 slidesPerView = 3; 1614 } else if (width >= 767) { 1615 slidesPerView = 3; 1616 } 1617 else if (width >= 640) { 1618 slidesPerView = 2; 1619 } 1620 1621 travelCalendarSliderEl.classList.toggle('is-few-slides', travelCalendarSlides <= slidesPerView); 1622 } 1623 1624 updateTravelCalendarSliderState(); 1625 window.addEventListener('resize', updateTravelCalendarSliderState); 1626 1627 var travelCalendarPaginationEl = travelCalendarSliderEl.closest('.section') ? 1628 travelCalendarSliderEl.closest('.section').querySelector('.travel-calendar-pagination') : 1629 travelCalendarSliderEl.querySelector('.travel-calendar-pagination'); 1630 1631 var travelCalendarSliderWrap = travelCalendarSliderEl.closest('.arrow-with-slider'); 1632 var travelCalendarNextEl = travelCalendarSliderWrap ? travelCalendarSliderWrap.querySelector('.travel-calendar-slider-next') : null; 1633 var travelCalendarPrevEl = travelCalendarSliderWrap ? travelCalendarSliderWrap.querySelector('.travel-calendar-slider-prev') : null; 1634 1635 var travelCalendarSwiperOptions = { 1636 loop: false, 1637 slidesPerView: 1, 1638 spaceBetween: 17, 1639 breakpoints: { 1640 640: { 1641 slidesPerView: 2, 1642 }, 1643 767: { 1644 slidesPerView: 3, 1645 }, 1646 992: { 1647 slidesPerView: 3, 1648 }, 1649 1280: { 1650 slidesPerView: 4, 1651 } 1652 } 1653 }; 1654 1655 if (travelCalendarPaginationEl) { 1656 travelCalendarSwiperOptions.pagination = { 1657 el: travelCalendarPaginationEl, 1658 clickable: true, 1659 }; 1660 } 1661 1662 if (travelCalendarNextEl && travelCalendarPrevEl) { 1663 travelCalendarSwiperOptions.navigation = { 1664 nextEl: travelCalendarNextEl, 1665 prevEl: travelCalendarPrevEl, 1666 }; 1667 } 1668 1669 new Swiper(travelCalendarSliderEl, travelCalendarSwiperOptions); 1670 }); 1671 } 1672 1673 // 3 items slider 1674 var threeItemsSliderEls = document.querySelectorAll('.three-items-slider'); 1675 if (threeItemsSliderEls.length && typeof Swiper !== 'undefined') { 1676 function getThreeItemsSlidesPerView(width) { 1677 if (width >= 767) { 1678 return 3; 1679 } 1680 if (width >= 640) { 1681 return 2; 1682 } 1683 return 1; 1684 } 1685 1686 function getThreeItemsMaxStartIndex(totalSlides, slidesPerView) { 1687 return Math.max(0, totalSlides - slidesPerView); 1688 } 1689 1690 function getThreeItemsPageStartIndex(pageIndex, slidesPerView, totalSlides) { 1691 return Math.min(pageIndex * slidesPerView, getThreeItemsMaxStartIndex(totalSlides, slidesPerView)); 1692 } 1693 1694 function getThreeItemsPageIndex(activeIndex, slidesPerView, totalSlides) { 1695 var maxStart = getThreeItemsMaxStartIndex(totalSlides, slidesPerView); 1696 1697 if (activeIndex >= maxStart && totalSlides > slidesPerView) { 1698 return Math.ceil(totalSlides / slidesPerView) - 1; 1699 } 1700 1701 return Math.floor(activeIndex / slidesPerView); 1702 } 1703 1704 function bindThreeItemsGroupedControls(swiper, totalSlides, paginationEl, nextEl, prevEl) { 1705 var threeItemsMaxVisibleDots = 2; 1706 1707 function getCurrentSlidesPerView() { 1708 var width = window.innerWidth || document.documentElement.clientWidth; 1709 return getThreeItemsSlidesPerView(width); 1710 } 1711 1712 function slideToPage(pageIndex) { 1713 var slidesPerView = getCurrentSlidesPerView(); 1714 swiper.slideTo(getThreeItemsPageStartIndex(pageIndex, slidesPerView, totalSlides)); 1715 } 1716 1717 function getThreeItemsPaginationTrack() { 1718 var viewport = paginationEl.querySelector('.three-items-pagination__viewport'); 1719 var track = paginationEl.querySelector('.three-items-pagination__track'); 1720 1721 if (!viewport) { 1722 paginationEl.innerHTML = ''; 1723 viewport = document.createElement('div'); 1724 viewport.className = 'three-items-pagination__viewport'; 1725 track = document.createElement('div'); 1726 track.className = 'three-items-pagination__track'; 1727 viewport.appendChild(track); 1728 paginationEl.appendChild(viewport); 1729 } 1730 1731 return track; 1732 } 1733 1734 function buildThreeItemsPaginationBullets(track, pageCount) { 1735 track.innerHTML = ''; 1736 1737 for (var i = 0; i < pageCount; i++) { 1738 var bullet = document.createElement('span'); 1739 bullet.className = 'swiper-pagination-bullet swiper-no-swiping'; 1740 bullet.setAttribute('role', 'button'); 1741 bullet.setAttribute('tabindex', '0'); 1742 bullet.setAttribute('data-page-index', String(i)); 1743 bullet.setAttribute('aria-label', 'Go to slide page ' + (i + 1)); 1744 track.appendChild(bullet); 1745 } 1746 } 1747 1748 function getThreeItemsDotMetrics(bullets) { 1749 var bulletWidth = 12; 1750 var gap = 8; 1751 1752 if (bullets.length) { 1753 var bulletStyles = window.getComputedStyle(bullets[0]); 1754 bulletWidth = parseFloat(bulletStyles.width) || 12; 1755 1756 if (bullets.length > 1) { 1757 var measuredGap = bullets[1].offsetLeft - bullets[0].offsetLeft - bullets[0].offsetWidth; 1758 1759 if (measuredGap > 0) { 1760 gap = measuredGap; 1761 } 1762 } 1763 } 1764 1765 return { 1766 bulletWidth: bulletWidth, 1767 gap: gap, 1768 step: bulletWidth + gap 1769 }; 1770 } 1771 1772 function updateThreeItemsPaginationTrackPosition(track, currentPage, pageCount) { 1773 if (pageCount <= threeItemsMaxVisibleDots) { 1774 track.style.transform = ''; 1775 return; 1776 } 1777 1778 var bullets = track.querySelectorAll('.swiper-pagination-bullet'); 1779 1780 if (!bullets.length) { 1781 return; 1782 } 1783 1784 var metrics = getThreeItemsDotMetrics(bullets); 1785 var windowStart = currentPage; 1786 1787 if (windowStart + threeItemsMaxVisibleDots > pageCount) { 1788 windowStart = pageCount - threeItemsMaxVisibleDots; 1789 } 1790 1791 if (windowStart < 0) { 1792 windowStart = 0; 1793 } 1794 1795 track.style.transform = 'translate3d(-' + (windowStart * metrics.step) + 'px, 0, 0)'; 1796 } 1797 1798 function syncThreeItemsPagination() { 1799 if (!paginationEl) { 1800 return; 1801 } 1802 1803 var slidesPerView = getCurrentSlidesPerView(); 1804 var pageCount = Math.max(1, Math.ceil(totalSlides / slidesPerView)); 1805 var currentPage = getThreeItemsPageIndex(swiper.activeIndex, slidesPerView, totalSlides); 1806 var track = getThreeItemsPaginationTrack(); 1807 var storedPageCount = parseInt(paginationEl.dataset.pageCount, 10) || 0; 1808 1809 if (storedPageCount !== pageCount) { 1810 paginationEl.dataset.pageCount = String(pageCount); 1811 buildThreeItemsPaginationBullets(track, pageCount); 1812 } 1813 1814 paginationEl.classList.toggle('is-dynamic-dots', pageCount > threeItemsMaxVisibleDots); 1815 1816 track.querySelectorAll('.swiper-pagination-bullet').forEach(function (bullet, index) { 1817 bullet.classList.toggle('swiper-pagination-bullet-active', index === currentPage); 1818 }); 1819 1820 window.requestAnimationFrame(function () { 1821 updateThreeItemsPaginationTrackPosition(track, currentPage, pageCount); 1822 1823 window.requestAnimationFrame(function () { 1824 updateThreeItemsPaginationTrackPosition(track, currentPage, pageCount); 1825 }); 1826 }); 1827 } 1828 1829 function handleThreeItemsPaginationClick(event) { 1830 var bullet = event.target.closest('.swiper-pagination-bullet'); 1831 1832 if (!bullet || !paginationEl.contains(bullet)) { 1833 return; 1834 } 1835 1836 var pageIndex = parseInt(bullet.getAttribute('data-page-index'), 10); 1837 1838 if (isNaN(pageIndex)) { 1839 return; 1840 } 1841 1842 event.preventDefault(); 1843 slideToPage(pageIndex); 1844 } 1845 1846 function clampThreeItemsActiveIndex() { 1847 var slidesPerView = getCurrentSlidesPerView(); 1848 var maxStart = getThreeItemsMaxStartIndex(totalSlides, slidesPerView); 1849 1850 if (swiper.activeIndex > maxStart) { 1851 swiper.slideTo(maxStart, 0); 1852 } 1853 } 1854 1855 if (paginationEl && paginationEl.dataset.threeItemsPaginationBound !== '1') { 1856 paginationEl.dataset.threeItemsPaginationBound = '1'; 1857 paginationEl.addEventListener('click', handleThreeItemsPaginationClick); 1858 } 1859 1860 if (nextEl && nextEl.dataset.threeItemsNavBound !== '1') { 1861 nextEl.dataset.threeItemsNavBound = '1'; 1862 1863 nextEl.addEventListener('click', function (event) { 1864 var slidesPerView = getCurrentSlidesPerView(); 1865 var maxStart = getThreeItemsMaxStartIndex(totalSlides, slidesPerView); 1866 var nextIndex = Math.min(swiper.activeIndex + slidesPerView, maxStart); 1867 1868 if (nextIndex === swiper.activeIndex) { 1869 return; 1870 } 1871 1872 event.preventDefault(); 1873 event.stopImmediatePropagation(); 1874 swiper.slideTo(nextIndex); 1875 }, true); 1876 } 1877 1878 if (prevEl && prevEl.dataset.threeItemsNavBound !== '1') { 1879 prevEl.dataset.threeItemsNavBound = '1'; 1880 1881 prevEl.addEventListener('click', function (event) { 1882 var slidesPerView = getCurrentSlidesPerView(); 1883 var prevIndex = Math.max(swiper.activeIndex - slidesPerView, 0); 1884 1885 if (prevIndex === swiper.activeIndex) { 1886 return; 1887 } 1888 1889 event.preventDefault(); 1890 event.stopImmediatePropagation(); 1891 swiper.slideTo(prevIndex); 1892 }, true); 1893 } 1894 1895 swiper.on('slideChange', function () { 1896 clampThreeItemsActiveIndex(); 1897 syncThreeItemsPagination(); 1898 }); 1899 1900 swiper.on('breakpoint', syncThreeItemsPagination); 1901 swiper.on('resize', syncThreeItemsPagination); 1902 syncThreeItemsPagination(); 1903 } 1904
1905 threeItemsSliderEls.forEach(function (threeItemsSliderEl) { 1906 var threeItemsSlides = threeItemsSliderEl.querySelectorAll('.swiper-slide').length; 1907 1908 function updateThreeItemsSliderState() { 1909 var width = window.innerWidth || document.documentElement.clientWidth; 1910 var slidesPerView = getThreeItemsSlidesPerView(width); 1911 var isFewSlides = threeItemsSlides <= slidesPerView; 1912 1913 threeItemsSliderEl.classList.toggle('is-few-slides', isFewSlides); 1914 threeItemsSliderEl.classList.toggle('is-two-slide-items', isFewSlides && threeItemsSlides === 2); 1915 } 1916 1917 updateThreeItemsSliderState(); 1918 window.addEventListener('resize', updateThreeItemsSliderState); 1919 1920 var paginationEl = threeItemsSliderEl.querySelector('.three-items-pagination') || 1921 (threeItemsSliderEl.parentElement ? 1922 threeItemsSliderEl.parentElement.querySelector('.three-items-pagination') : 1923 null); 1924 1925 if (paginationEl && paginationEl.parentElement === threeItemsSliderEl) { 1926 threeItemsSliderEl.parentElement.insertBefore(paginationEl, threeItemsSliderEl.nextSibling); 1927 } 1928 1929 if (paginationEl) { 1930 paginationEl.classList.add('swiper-no-swiping'); 1931 } 1932 1933 var sliderWrap = threeItemsSliderEl.closest('.arrow-with-slider'); 1934 var nextEl = sliderWrap ? 1935 sliderWrap.querySelector('.three-items-slider-next') : 1936 threeItemsSliderEl.querySelector('.three-items-slider-next'); 1937 var prevEl = sliderWrap ? 1938 sliderWrap.querySelector('.three-items-slider-prev') : 1939 threeItemsSliderEl.querySelector('.three-items-slider-prev'); 1940 1941 var threeItemsSwiperOptions = { 1942 loop: false, 1943 slidesPerView: 1, 1944 slidesPerGroup: 1, 1945 watchOverflow: true, 1946 spaceBetween: 17, 1947 speed: 800, 1948 pagination: false, 1949 breakpoints: { 1950 640: { 1951 slidesPerView: 2, 1952 spaceBetween: 17, 1953 }, 1954 767: { 1955 slidesPerView: 3, 1956 spaceBetween: 17, 1957 }, 1958 992: { 1959 slidesPerView: 3, 1960 spaceBetween: 17, 1961 }, 1962 1280: { 1963 slidesPerView: 3, 1964 spaceBetween: 40, 1965 }, 1966 1500: { 1967 spaceBetween: 88, 1968 slidesPerView: 3, 1969 } 1970 } 1971 }; 1972 1973 if (nextEl && prevEl) { 1974 threeItemsSwiperOptions.navigation = { 1975 nextEl: nextEl, 1976 prevEl: prevEl, 1977 }; 1978 } 1979 1980 var threeItemsSwiper = new Swiper(threeItemsSliderEl, threeItemsSwiperOptions); 1981 bindThreeItemsGroupedControls(threeItemsSwiper, threeItemsSlides, paginationEl, nextEl, prevEl); 1982 }); 1983 } 1984 1985 1986 // 3 items slider 1987 var blogThreeItemsSliderEls = document.querySelectorAll('.blog-three-items-slider'); 1988 if (blogThreeItemsSliderEls.length && typeof Swiper !== 'undefined') { 1989 blogThreeItemsSliderEls.forEach(function (blogThreeItemsSliderEl) { 1990 var blogThreeItemsSlides = blogThreeItemsSliderEl.querySelectorAll('.swiper-slide').length; 1991 1992 function updateThreeItemsSliderState() { 1993 var width = window.innerWidth || document.documentElement.clientWidth; 1994 var slidesPerView = 1; 1995 1996 if (width >= 1280) { 1997 slidesPerView = 3; 1998 } else if (width >= 992) { 1999 slidesPerView = 3; 2000 } else if (width >= 767) { 2001 slidesPerView = 3; 2002 } 2003 else if (width >= 640) { 2004 slidesPerView = 2; 2005 } 2006 2007 blogThreeItemsSliderEl.classList.toggle('is-few-slides', blogThreeItemsSlides <= slidesPerView); 2008 } 2009 2010 updateThreeItemsSliderState(); 2011 window.addEventListener('resize', updateThreeItemsSliderState); 2012 2013 var paginationEl = blogThreeItemsSliderEl.closest('.swiper') ? 2014 blogThreeItemsSliderEl.closest('.swiper').querySelector('.blog-three-items-pagination') : 2015 blogThreeItemsSliderEl.querySelector('.blog-three-items-pagination'); 2016 2017 new Swiper(blogThreeItemsSliderEl, { 2018 loop: false, 2019 slidesPerView: 1, 2020 spaceBetween: 17, 2021 pagination: { 2022 el: paginationEl || '.blog-three-items-pagination', 2023 clickable: true, 2024 }, 2025 breakpoints: { 2026 640: { 2027 slidesPerView: 2, 2028 spaceBetween: 17, 2029 }, 2030 767: { 2031 slidesPerView: 3, 2032 spaceBetween: 17, 2033 }, 2034 992: { 2035 slidesPerView: 3, 2036 spaceBetween: 17, 2037 }, 2038 1280: { 2039 slidesPerView: 3, 2040 spaceBetween: 40, 2041 }, 2042 1500: { 2043 spaceBetween: 60, 2044 slidesPerView: 3, 2045 } 2046 } 2047 }); 2048 }); 2049 } 2050 2051 // Team members slider 2052 var teamMembersSliderEls = document.querySelectorAll('.team-members-slider'); 2053 if (teamMembersSliderEls.length && typeof Swiper !== 'undefined') {
2054 teamMembersSliderEls.forEach(function (teamMembersSliderEl) { 2055 var teamMembersSlides = teamMembersSliderEl.querySelectorAll('.swiper-slide').length; 2056 2057 function updateTeamMembersSliderState() { 2058 var width = window.innerWidth || document.documentElement.clientWidth; 2059 var slidesPerView = 3; 2060 2061 2062 2063 teamMembersSliderEl.classList.toggle('is-few-slides', teamMembersSlides <= slidesPerView); 2064 } 2065 2066 updateTeamMembersSliderState(); 2067 window.addEventListener('resize', updateTeamMembersSliderState); 2068 2069 new Swiper(teamMembersSliderEl, { 2070 loop: true, 2071 slidesPerView: 3, 2072 slidesPerGroup: 1, 2073 speed: 500, 2074 watchOverflow: true, 2075 autoplay: { 2076 delay: 2500, 2077 disableOnInteraction: false, 2078 }, 2079 }); 2080 }); 2081 } 2082 2083 // Brand pillars slider 2084 var brandPillarsSliderEls = document.querySelectorAll('.brand-pillars-slider'); 2085 if (brandPillarsSliderEls.length && typeof Swiper !== 'undefined') { 2086 brandPillarsSliderEls.forEach(function (brandPillarsSliderEl) { 2087 var brandPillarsSlides = brandPillarsSliderEl.querySelectorAll('.swiper-slide').length; 2088 var sliderWrap = brandPillarsSliderEl.closest('.brand-pillars-slider-wrap') || brandPillarsSliderEl.parentElement; 2089 var nextEl = sliderWrap ? sliderWrap.querySelector('.brand-pillars-slider_right_arrow') : null; 2090 var prevEl = sliderWrap ? sliderWrap.querySelector('.brand-pillars-slider_left_arrow') : null; 2091 2092 function updateBrandPillarsSliderState() { 2093 var width = window.innerWidth || document.documentElement.clientWidth; 2094 var slidesPerView = 1.1; 2095 2096 if (width >= 1280) { 2097 slidesPerView = 2; 2098 } else if (width >= 992) { 2099 slidesPerView = 2; 2100 } else if (width >= 767) { 2101 slidesPerView = 1.5; 2102 } else if (width >= 640) { 2103 slidesPerView = 1.2; 2104 } 2105 2106 brandPillarsSliderEl.classList.toggle('one-few-slides', brandPillarsSlides <= Math.ceil(slidesPerView)); 2107 } 2108 2109 updateBrandPillarsSliderState(); 2110 window.addEventListener('resize', updateBrandPillarsSliderState); 2111 2112 var brandPillarsSwiperOptions = { 2113 loop: false, 2114 slidesPerView: 1.1, 2115 spaceBetween: 0, 2116 grabCursor: true, 2117 watchOverflow: true, 2118 speed: 500, 2119 breakpoints: { 2120 640: { 2121 slidesPerView: 1.2, 2122 }, 2123 1500: { 2124 slidesPerView: 1.5, 2125 }, 2126 } 2127 }; 2128 2129 if (nextEl && prevEl) { 2130 brandPillarsSwiperOptions.navigation = { 2131 nextEl: nextEl, 2132 prevEl: prevEl, 2133 }; 2134 } 2135 2136 new Swiper(brandPillarsSliderEl, brandPillarsSwiperOptions); 2137 }); 2138 } 2139 2140 /* Page Links Row - Smooth Scroll + Active Class */ 2141 var $pageLinksRow = $('.page-links-row ,.continue-exploring-grid'); 2142 if ($pageLinksRow.length) { 2143 var scrollOffset = 140; 2144 2145 $pageLinksRow.find('a[href^="#"]').on('click', function (e) { 2146 var hash = $(this).attr('href'); 2147 var $target = $(hash); 2148 2149 if ($target.length) { 2150 e.preventDefault(); 2151 var targetPos = $target.offset().top - scrollOffset; 2152 $('html, body').animate({ scrollTop: targetPos }, 600); 2153 } 2154 }); 2155 2156 function updatePageLinksActive() { 2157 var scrollTop = $(window).scrollTop(); 2158 2159 $('.scroll-section').each(function () { 2160 var sectionId = $(this).attr('id'); 2161 if (!sectionId) return; 2162 2163 var sectionTop = $(this).offset().top - scrollOffset; 2164 var sectionBottom = sectionTop + $(this).outerHeight(); 2165 2166 if (scrollTop >= sectionTop && scrollTop < sectionBottom) { 2167 $pageLinksRow.find('a[href^="#"]').closest('li').removeClass('active-link'); 2168 $pageLinksRow.find('a[href="#' + sectionId + '"]').closest('li').addClass('active-link'); 2169 } 2170 }); 2171 } 2172 2173 $(window).on('scroll', updatePageLinksActive); 2174 updatePageLinksActive(); 2175 2176 if (window.location.hash) { 2177 var hash = window.location.hash; 2178 var $hashTarget = $(hash); 2179 if ($hashTarget.length) { 2180 setTimeout(function () { 2181 var targetPos = $hashTarget.offset().top - scrollOffset; 2182 $('html, body').animate({ scrollTop: targetPos }, 600); 2183 }, 300); 2184 } 2185 } 2186 } 2187 /* // Page Links Row */ 2188 2189 /* When To Visit - Month tabs */ 2190 $('.when-to-visit-section').each(function () { 2191 var $section = $(this); 2192 var $months = $section.find('.wtv-month'); 2193 var $rows = $section.find('.visit-inner-row'); 2194 2195 if (!$months.length || !$rows.length) { 2196 return; 2197 } 2198 2199 2200 2201 function scrollToBestTimeVisit() { 2202 var $target = $('#BestTimeVisit'); 2203 2204 if (!$target.length) { 2205 return; 2206 } 2207 2208 var targetPos = $target.offset().top - 80; 2209 $('html, body').animate({ scrollTop: targetPos }, 300); 2210 } 2211 2212 function setActiveMonth($month, monthId) { 2213 $months.removeClass('active'); 2214 $month.addClass('active'); 2215 $rows.removeClass('active'); 2216 $section.find('.visit-inner-row#' + monthId).addClass('active'); 2217 } 2218 2219 var $firstMonth = $months.first(); 2220 var firstHref = $firstMonth.find('a[href^="#"]').attr('href'); 2221 2222 if (firstHref) {
2223 setActiveMonth($firstMonth, firstHref.replace('#', '')); 2224 } else { 2225 $firstMonth.addClass('active'); 2226 $rows.first().addClass('active'); 2227 } 2228 2229 $section.on('click', '.wtv-month a[href^="#"]', function (e) { 2230 e.preventDefault(); 2231 2232 var monthId = $(this).attr('href').replace('#', ''); 2233 var $month = $(this).closest('.wtv-month'); 2234 var $target = $section.find('.visit-inner-row#' + monthId); 2235 2236 if ($target.length) { 2237 setActiveMonth($month, monthId); 2238 } 2239 2240 scrollToBestTimeVisit(); 2241 }); 2242 }); 2243 /* // When To Visit - Month tabs */ 2244 2245 // FAQ accordion 2246 $('.faq-accordion').each(function () { 2247 var $accordion = $(this); 2248 2249 function toggleFaqItem($toggle) { 2250 var $item = $toggle.closest('.faq-accordion__item'); 2251 var $content = $item.find('.faq-accordion__content'); 2252 2253 if ($item.hasClass('is-open')) { 2254 $item.removeClass('is-open'); 2255 $toggle.attr('aria-expanded', 'false'); 2256 $content.stop(true, true).slideUp(200); 2257 return; 2258 } 2259 2260 $accordion.find('.faq-accordion__item.is-open').each(function () { 2261 var $openItem = $(this); 2262 $openItem.removeClass('is-open'); 2263 $openItem.find('.faq-accordion__toggle').attr('aria-expanded', 'false'); 2264 $openItem.find('.faq-accordion__content').stop(true, true).slideUp(200); 2265 }); 2266 2267 $item.addClass('is-open'); 2268 $toggle.attr('aria-expanded', 'true'); 2269 $content.stop(true, true).slideDown(200); 2270 } 2271 2272 $accordion.find('.faq-accordion__toggle').on('click', function () { 2273 toggleFaqItem($(this)); 2274 }); 2275 2276 $accordion.find('.faq-accordion__toggle').on('keydown', function (e) { 2277 if (e.key === 'Enter' || e.key === ' ') { 2278 e.preventDefault(); 2279 toggleFaqItem($(this)); 2280 } 2281 }); 2282 }); 2283 2284 /* Quotes text - Read more / Read less (7 lines) */ 2285 var quotesReadMoreMaxLines = 8; 2286 var quotesReadMoreDuration = 500; 2287 var quotesReadMoreResizeTimer; 2288 2289 function getQuotesLineHeight($quotesText) { 2290 var $measureEl = $quotesText.find('p').first().length ? $quotesText.find('p').first() : $quotesText; 2291 var lineHeight = parseFloat($measureEl.css('line-height')); 2292 2293 if (isNaN(lineHeight)) { 2294 lineHeight = parseFloat($measureEl.css('font-size')) * 1.6; 2295 } 2296 2297 return lineHeight; 2298 } 2299 2300 function resetQuotesReadMore($quotesText) { 2301 var $wrap = $quotesText.closest('.quotes-text-wrap'); 2302 2303 if ($wrap.length) { 2304 $wrap.replaceWith($quotesText); 2305 } 2306 2307 $quotesText 2308 .removeClass('is-truncated is-expanded is-collapsed') 2309 .removeData('quotes-read-more-init') 2310 .removeData('quotes-collapsed-height') 2311 .removeData('quotes-full-height') 2312 .css({ maxHeight: '', overflow: '', minHeight: '' }); 2313 } 2314 2315 function setupQuotesReadMoreItem($quotesText) { 2316 var lineHeight = getQuotesLineHeight($quotesText); 2317 var collapsedHeight = Math.ceil(lineHeight * quotesReadMoreMaxLines); 2318 2319 $quotesText.css({ maxHeight: 'none', overflow: 'visible' }); 2320 var fullHeight = $quotesText[0].scrollHeight; 2321 2322 $quotesText.css({ maxHeight: collapsedHeight, overflow: 'hidden' }); 2323 var isOverflowing = $quotesText[0].scrollHeight > $quotesText[0].clientHeight + 1; 2324 2325 $quotesText.css({ maxHeight: '', overflow: '' }); 2326 2327 if (!isOverflowing) { 2328 $quotesText.data('quotes-read-more-init', true); 2329 return; 2330 } 2331 2332 $quotesText.wrap('<div class="quotes-text-wrap"></div>'); 2333 var $wrap = $quotesText.parent(); 2334 var $btn = $('<button type="button" class="btn span-btn quotes-read-more-btn" aria-expanded="false"><span class="quotes-read-more-label">Read more</span></button>'); 2335 2336 $wrap.append($btn); 2337 2338 $quotesText 2339 .addClass('is-truncated is-collapsed') 2340 .css({ maxHeight: collapsedHeight, overflow: 'hidden' }); 2341 2342 $quotesText.data({ 2343 'quotes-read-more-init': true, 2344 'quotes-collapsed-height': collapsedHeight, 2345 'quotes-full-height': fullHeight 2346 }); 2347 2348 $btn.off('click.quotesReadMore').on('click.quotesReadMore', function () { 2349 if ($quotesText.hasClass('is-expanded')) { 2350 collapseQuotesReadMoreItem($quotesText, true); 2351 return; 2352 } 2353 2354 expandQuotesReadMoreItem($quotesText, $btn); 2355 }); 2356 } 2357 2358 function collapseQuotesReadMoreItem($quotesText, animate) { 2359 if (!$quotesText.hasClass('is-expanded')) { 2360 return; 2361 } 2362 2363 var storedCollapsedHeight = $quotesText.data('quotes-collapsed-height'); 2364 var $btn = $quotesText.closest('.quotes-text-wrap').find('.quotes-read-more-btn'); 2365 2366 $quotesText.stop(true, true); 2367 2368 if (animate) { 2369 $quotesText 2370 .removeClass('is-expanded') 2371 .addClass('is-collapsed') 2372 .css('overflow', 'hidden') 2373 .animate({ maxHeight: storedCollapsedHeight }, quotesReadMoreDuration, function () { 2374 $quotesText.css('maxHeight', storedCollapsedHeight); 2375 }); 2376 } else { 2377 $quotesText 2378 .removeClass('is-expanded') 2379 .addClass('is-collapsed') 2380 .css({ maxHeight: storedCollapsedHeight, overflow: 'hidden' }); 2381 } 2382 2383 $btn.attr('aria-expanded', 'false'); 2384 $btn.find('.quotes-read-more-label').text('Read more'); 2385 } 2386 2387 function expandQuotesReadMoreItem($quotesText, $btn) { 2388 var storedFullHeight = $quotesText.data('quotes-full-height'); 2389 2390 $quotesText 2391 .removeClass('is-collapsed') 2392 .addClass('is-expanded') 2393 .css('overflow', 'hidden') 2394 .stop(true, false) 2395 .animate({ maxHeight: storedFullHeight }, quotesReadMoreDuration, function () { 2396 $quotesText.css({ maxHeight: 'none', overflow: 'visible' }); 2397 }); 2398 2399 $btn.attr('aria-expanded', 'true'); 2400 $btn.find('.quotes-read-more-label').text('Read less'); 2401 } 2402 2403 function collapseExpandedQuotesReadMore(container) { 2404 var $scope = container ? $(container) : $(document); 2405
2406 $scope.find('.quotes-text.is-expanded').each(function () { 2407 collapseQuotesReadMoreItem($(this), false); 2408 }); 2409 } 2410 2411 function bindQuotesReadMoreSlideReset() { 2412 document.querySelectorAll('.swiper').forEach(function (sliderEl) { 2413 if (!sliderEl.swiper || sliderEl.dataset.quotesReadMoreBound === '1') { 2414 return; 2415 } 2416 2417 sliderEl.dataset.quotesReadMoreBound = '1'; 2418 2419 sliderEl.swiper.on('slideChange', function () { 2420 collapseExpandedQuotesReadMore(sliderEl); 2421 }); 2422 }); 2423 } 2424 2425 function initQuotesReadMore() { 2426 $('.quotes-text').each(function () { 2427 var $quotesText = $(this); 2428 2429 if ($quotesText.data('quotes-read-more-init')) { 2430 return; 2431 } 2432 2433 setupQuotesReadMoreItem($quotesText); 2434 }); 2435 } 2436 2437 function refreshQuotesReadMore() { 2438 $('.quotes-text').each(function () { 2439 resetQuotesRead
2439More($(this)); 2440 }); 2441 2442 initQuotesReadMore(); 2443 } 2444 2445 initQuotesReadMore(); 2446 bindQuotesReadMoreSlideReset(); 2447 $(window).on('load', function () { 2448 refreshQuotesReadMore(); 2449 bindQuotesReadMoreSlideReset(); 2450 }); 2451 2452 $(window).on('resize', function () { 2453 clearTimeout(quotesReadMoreResizeTimer); 2454 quotesReadMoreResizeTimer = setTimeout(refreshQuotesReadMore, 250); 2455 }); 2456 /* // Quotes text - Read more / Read less */ 2457 2458 /* Travel Magazine - Popup */ 2459 function openTravelMagazinePopup($popup) { 2460 if (!$popup || !$popup.length) { 2461 return; 2462 } 2463 2464 closeTravelMagazinePopup(); 2465 $popup.addClass('is-active').attr('aria-hidden', 'false'); 2466 $('body').addClass('travel-magazine-popup-open'); 2467 } 2468 2469 function closeTravelMagazinePopup() { 2470 $('.travel-magazine-popup.is-active') 2471 .removeClass('is-active') 2472 .attr('aria-hidden', 'true'); 2473 $('body').removeClass('travel-magazine-popup-open'); 2474 } 2475 2476 $(document).on('click', '.travel-magazine-brochures-section .card_link[data-popup]', function (event) { 2477 event.preventDefault(); 2478 2479 var popupId = $(this).data('popup'); 2480 var $popup = popupId 2481 ? $('#' + popupId) 2482 : $(this).closest('.travel-magazine-card').find('.travel-magazine-popup'); 2483 2484 openTravelMagazinePopup($popup); 2485 }); 2486 2487 $(document).on('click', '.travel-magazine-popup__close, .travel-magazine-popup__overlay', function () { 2488 closeTravelMagazinePopup(); 2489 }); 2490 2491 $(document).on('keydown', function (event) { 2492 if (event.key === 'Escape' && $('.travel-magazine-popup.is-active').length) { 2493 closeTravelMagazinePopup(); 2494 } 2495 }); 2496 /* // Travel Magazine - Popup */ 2497 2498});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.