1function startCountdown() { 2 // Find all countdown spans 3 const countdownElements = document.querySelectorAll('span[data-countdown-to]'); 4 5 // Log how many countdown elements are present 6 console.log(`Found ${countdownElements.length} countdown elements.`); 7 8 countdownElements.forEach((element) => { 9 const targetTime = new Date(element.getAttribute('data-countdown-to')); 10 11 // Update the countdown every second 12 function updateCountdown() { 13 const now = new Date(); 14 const timeDifference = targetTime - now; 15 16 if (timeDifference <= 0) { 17 // Time has passed or is exactly the target time 18 element.innerHTML = 'Countdown ended'; 19 return; 20 } 21 22 // Calculate days, hours, minutes, and seconds remaining 23 const days = Math.floor(timeDifference / (1000 * 60 * 60 * 24)); 24 const hours = Math.floor((timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 25 const minutes = Math.floor((timeDifference % (1000 * 60 * 60)) / (1000 * 60)); 26 const seconds = Math.floor(timeDifference % (1000 * 60) / 1000); 27 28 // Conditional updates if the elements exist and are not zero 29 const daysElement = element.querySelector('span[data-days]'); 30 if (daysElement) { 31 if (days > 0) { 32 daysElement.innerText = `${days} ${days === 1 ? 'day' : 'days'}`; 33 daysElement.style.display = ''; 34 } else { 35 daysElement.style.display = 'none'; 36 } 37 } 38 39 const hoursElement = element.querySelector('span[data-hours]'); 40 if (hoursElement) { 41 if (hours > 0) { 42 hoursElement.innerText = `${hours} ${hours === 1 ? 'hour' : 'hours'}`; 43 hoursElement.style.display = ''; 44 } else { 45 hoursElement.style.display = 'none'; 46 } 47 } 48 49 const minutesElement = element.querySelector('span[data-minutes]'); 50 if (minutesElement) { 51 if (minutes > 0) { 52 minutesElement.innerText = `${minutes} ${minutes === 1 ? 'minute' : 'minutes'}`; 53 minutesElement.style.display = ''; 54 } else { 55 minutesElement.style.display = 'none'; 56 } 57 } 58 59 const secondsElement = element.querySelector('span[data-seconds]'); 60 if (secondsElement) { 61 secondsElement.innerText = `${seconds} ${seconds === 1 ? 'second' : 'seconds'}`; 62 // Seconds are always shown 63 } 64 } 65 66 // Update immediately, and then every second 67 updateCountdown(); 68 setInterval(updateCountdown, 1000); 69 }); 70} 71 72// Start the countdowns 73document.addEventListener('DOMContentLoaded', startCountdown); 74 75/** 76 * Promo slider 77 */ 78 79document.addEventListener('DOMContentLoaded', function() { 80 const slideGroup = document.querySelector('.slide-group--promos'); 81 const leftArrow = document.querySelector('.left-arrow'); 82 const rightArrow = document.querySelector('.right-arrow'); 83 84 // Amount to scroll, equal to the width of one promo block 85 let scrollAmount = 10; 86 if (slideGroup) { 87 scrollAmount = slideGroup.querySelector('.promo-block').offsetWidth + 16; // 16px gap 88 } 89 90 if (leftArrow) { 91 leftArrow.addEventListener('click', () => { 92 console.log('left'); 93 slideGroup.scrollBy({ 94 left: -scrollAmount, 95 behavior: 'smooth' 96 }); 97 }); 98 } 99 100 if (rightArrow) { 101 rightArrow.addEventListener('click', () => { 102 console.log('right'); 103 slideGroup.scrollBy({ 104 left: scrollAmount, 105 behavior: 'smooth' 106 }); 107 }); 108 } 109 110}); 111 112 113/** 114 * Set arrow visibility 115 */ 116 117document.addEventListener('DOMContentLoaded', function() { 118 const slideGroup = document.querySelector('.slide-group--promos'); 119 const leftArrow = document.querySelector('.left-arrow'); 120 const rightArrow = document.querySelector('.right-arrow'); 121 122 function updateArrowVisibility() { 123 // Detect if there is overflow on the right (more content to scroll) 124 if (slideGroup) { 125 if (slideGroup.scrollWidth > slideGroup.clientWidth) { 126 // If at the start, hide left arrow 127 if (slideGroup.scrollLeft === 0) { 128 leftArrow.style.display = 'none'; 129 } else { 130 leftArrow.style.display = 'block'; 131 } 132 133 // If at the end, hide right arrow 134 if (slideGroup.scrollLeft + slideGroup.clientWidth >= slideGroup.scrollWidth) { 135 rightArrow.style.display = 'none'; 136 } else { 137 rightArrow.style.display = 'block'; 138 } 139 } else { 140 // No overflow, hide both arrows 141 leftArrow.style.display = 'none'; 142 rightArrow.style.display = 'none'; 143 } 144 } 145 } 146 147 // Attach scroll event listener to update arrow visibility on scroll 148 if (slideGroup) { 149 slideGroup.addEventListener('scroll', updateArrowVisibility); 150 } 151 152 // Initial call to set the correct state on load 153 updateArrowVisibility(); 154 155 // Arrow click handlers 156 let scrollAmount = 10; 157 if (slideGroup) { 158 scrollAmount = slideGroup.querySelector('.promo-block').offsetWidth + 16; // 16px gap 159 } 160 161 if (leftArrow) { 162 leftArrow.addEventListener('click', () => { 163 slideGroup.scrollBy({ 164 left: -scrollAmount, 165 behavior: 'smooth' 166 }); 167 }); 168 } 169 170 if (rightArrow) { 171 rightArrow.addEventListener('click', () => { 172 slideGroup.scrollBy({ 173 left: scrollAmount, 174 behavior: 'smooth' 175 }); 176 }); 177 } 178 179 // Recalculate arrow visibility when window is resized 180 window.addEventListener('resize', updateArrowVisibility); 181});
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.