1(function () { 2 'use strict'; 3 4 var selector = '[data-ccc-home-countdown]'; 5 var timer = null; 6 var resizeTimer = null; 7 8 function pad(value) { 9 return String(Math.max(0, value)).padStart(2, '0'); 10 } 11 12 function setValue(root, key, value) { 13 var element = root.querySelector('[data-countdown-value="' + key + '"]'); 14 var next = pad(value); 15 16 if (!element || element.textContent === next) { 17 return; 18 } 19 20 element.textContent = next; 21 element.classList.remove('is-ticking'); 22 void element.offsetWidth; 23 element.classList.add('is-ticking'); 24 } 25 26 function render(root) { 27 var target = Date.parse(root.getAttribute('data-target')); 28 var remaining = target - Date.now(); 29 var clock = root.querySelector('.ccc-home-countdown__clock'); 30 var date = root.querySelector('.ccc-home-countdown__date'); 31 var open = root.querySelector('.ccc-home-countdown__open'); 32 var totalSeconds; 33 var days; 34 var hours; 35 var minutes; 36 var seconds; 37 38 if (!Number.isFinite(target)) { 39 return; 40 } 41 42 if (remaining <= 0) { 43 root.classList.add('is-open'); 44 clock.hidden = true; 45 date.hidden = true; 46 open.hidden = false; 47 root.querySelector('.ccc-home-countdown__heading span:last-child').textContent = 'Cyprus Comic Con 2026'; 48 root.setAttribute('aria-label', 'Cyprus Comic Con 2026 is now open'); 49 if (timer) { 50 window.clearInterval(timer); 51 timer = null; 52 } 53 return; 54 } 55 56 totalSeconds = Math.floor(remaining / 1000); 57 days = Math.floor(totalSeconds / 86400); 58 hours = Math.floor((totalSeconds % 86400) / 3600); 59 minutes = Math.floor((totalSeconds % 3600) / 60); 60 seconds = totalSeconds % 60; 61 62 setValue(root, 'days', days); 63 setValue(root, 'hours', hours); 64 setValue(root, 'minutes', minutes); 65 setValue(root, 'seconds', seconds); 66 67 clock.setAttribute( 68 'aria-label', 69 days + ' days, ' + hours + ' hours and ' + minutes + ' minutes until Cyprus Comic Con 2026 Opening Night' 70 ); 71 } 72 73 function start(root) { 74 if (root.getAttribute('data-countdown-started') === 'true') { 75 return; 76 } 77 78 root.setAttribute('data-countdown-started', 'true'); 79 render(root); 80 timer = window.setInterval(function () { 81 render(root); 82 }, 1000); 83 } 84 85 function mount() { 86 var slider = document.getElementById('SR7_13_1'); 87 var template = document.getElementById('ccc-home-countdown-template'); 88 var mobileHero = slider && slider.querySelector('.ccc-mobile-home-hero'); 89 var actions; 90 var root; 91 92 if (!slider || !template || !template.content) { 93 return false; 94 } 95 96 // The native phone hero is mounted by a separate legacy compatibility 97 // layer. Wait for it so the countdown never ends up loose behind it. 98 if (window.matchMedia('(max-width: 768px)').matches && !mobileHero) { 99 return false; 100 } 101 102 root = slider.querySelector(selector); 103 if (!root) { 104 root = template.content.firstElementChild.cloneNode(true); 105 slider.appendChild(root); 106 } 107 108 if (window.matchMedia('(max-width: 768px)').matches && mobileHero) { 109 actions = mobileHero.querySelector('.ccc-mobile-home-hero__actions'); 110 if (actions && root.parentNode !== mobileHero) { 111 mobileHero.insertBefore(root, actions); 112 } 113 } else if (root.parentNode !== slider) { 114 slider.appendChild(root); 115 } 116 117 start(root); 118 return true; 119 } 120 121 function reposition() { 122 var slider = document.getElementById('SR7_13_1'); 123 var root = slider && slider.querySelector(selector); 124 var mobileHero = slider && slider.querySelector('.ccc-mobile-home-hero'); 125 var actions; 126 127 if (!slider || !root) { 128 return; 129 } 130 131 if (window.matchMedia('(max-width: 768px)').matches && mobileHero) { 132 actions = mobileHero.querySelector('.ccc-mobile-home-hero__actions'); 133 if (actions && root.parentNode !== mobileHero) { 134 mobileHero.insertBefore(root, actions); 135 } 136 } else if (root.parentNode !== slider) { 137 slider.appendChild(root); 138 } 139 } 140 141 function boot() { 142 var attempts = 0; 143 144 if (mount()) { 145 return; 146 } 147 148 var mountTimer = window.setInterval(function () { 149 attempts += 1; 150 if (mount() || attempts >= 60) { 151 window.clearInterval(mountTimer); 152 } 153 }, 250); 154 } 155 156 if (document.readyState === 'loading') { 157 document.addEventListener('DOMContentLoaded', boot, { once: true }); 158 } else { 159 boot(); 160 } 161 162 window.addEventListener('resize', function () { 163 window.clearTimeout(resizeTimer); 164 resizeTimer = window.setTimeout(reposition, 120); 165 }); 166}());
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.