1(function () { 2 'use strict'; 3 4 var measurementId = '__SHF2_GA_MEASUREMENT_ID__'; 5 6 if (!measurementId || measurementId === '__SHF2_GA_MEASUREMENT_ID__') { 7 measurementId = 'G-XWDG5MR6KK'; 8 } 9 10 function findTrackedLink(node) { 11 while (node && node !== document) { 12 if (node.tagName === 'A' && node.getAttribute('data-ga-event')) { 13 return node; 14 } 15 16 node = node.parentNode; 17 } 18 19 return null; 20 } 21 22 function isMobileLaunch() { 23 var userAgent = navigator.userAgent || ''; 24 var hasMobileUserAgent = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test( 25 userAgent 26 ); 27 var isTouchMac = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1; 28 var hasCoarsePointer = typeof window.matchMedia === 'function' && window.matchMedia('(pointer: coarse)').matches; 29 var hasSmallViewport = 30 typeof window.matchMedia === 'function' && window.matchMedia('(max-width: 1024px)').matches; 31 32 return hasMobileUserAgent || isTouchMac || (hasCoarsePointer && hasSmallViewport); 33 } 34 35 function initAnalytics() { 36 window.dataLayer = window.dataLayer || []; 37 window.gtag = function () { 38 window.dataLayer.push(arguments); 39 }; 40 41 window.gtag('js', new Date()); 42 window.gtag('config', measurementId); 43 44 function loadAnalyticsScript() { 45 var gaScript = document.createElement('script'); 46 gaScript.async = true; 47 gaScript.src = 'https://www.googletagmanager.com/gtag/js?id=' + encodeURIComponent(measurementId); 48 document.head.appendChild(gaScript); 49 } 50 51 function loadAnalyticsWhenIdle() { 52 if (typeof window.requestIdleCallback === 'function') { 53 window.requestIdleCallback(loadAnalyticsScript, { timeout: 3000 }); 54 } else { 55 window.setTimeout(loadAnalyticsScript, 1200); 56 } 57 } 58 59 if (document.readyState === 'complete') { 60 loadAnalyticsWhenIdle(); 61 } else { 62 window.addEventListener('load', loadAnalyticsWhenIdle, { once: true }); 63 } 64 } 65 66 function initTrackedLinks() { 67 document.addEventListener('click', function (event) { 68 var trackedLink = findTrackedLink(event.target); 69 70 if (!trackedLink) { 71 return; 72 } 73 74 window.gtag('event', trackedLink.getAttribute('data-ga-event'), { 75 link_url: trackedLink.href, 76 transport_type: 'beacon' 77 }); 78 79 var mobileHref = trackedLink.getAttribute('data-mobile-href'); 80 var isModifiedClick = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button !== 0; 81 82 if (!mobileHref || isModifiedClick || trackedLink.target === '_blank' || !isMobileLaunch()) { 83 return; 84 } 85 86 event.preventDefault(); 87 window.location.assign(mobileHref); 88 }); 89 } 90 91 function initHeader() { 92 var header = document.querySelector('[data-header]'); 93 94 if (!header) { 95 return; 96 } 97 98 function updateHeader() { 99 header.classList.toggle('is-scrolled', window.scrollY > 24); 100 } 101 102 updateHeader(); 103 window.addEventListener('scroll', updateHeader, { passive: true }); 104 } 105 106 function initLaunchRain() { 107 var canvas = document.querySelector('[data-launch-rain]'); 108 var reducedMotion = 109 typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 110 111 if (!canvas || reducedMotion) { 112 return; 113 } 114 115 var context = canvas.getContext('2d'); 116 117 if (!context) { 118 return; 119 } 120 121 var drops = []; 122 var width = 0; 123 var height = 0; 124 var pixelRatio = 1; 125 var lastFrameTime = 0; 126 127 function resetDrop(drop, isInitialDrop) { 128 var depth = Math.pow(Math.random(), 1.45); 129 130 drop.x = Math.random() * (width + 180) - 70; 131 drop.y = isInitialDrop ? Math.random() * height : -20 - Math.random() * height * 0.24; 132 drop.length = 13 + Math.random() * 17 + depth * 35; 133 drop.speed = 470 + Math.random() * 310 + depth * 570; 134 drop.drift = -32 - Math.random() * 40 - depth * 50; 135 drop.opacity = 0.08 + Math.random() * 0.08 + depth * 0.2; 136 drop.lineWidth = 0.55 + depth * 0.95; 137 } 138 139 function resizeRain() { 140 var bounds = canvas.getBoundingClientRect(); 141 var targetDropCount; 142 143 width = Math.max(1, bounds.width); 144 height = Math.max(1, bounds.height); 145 pixelRatio = Math.min(window.devicePixelRatio || 1, 2); 146 canvas.width = Math.round(width * pixelRatio); 147 canvas.height = Math.round(height * pixelRatio); 148 context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); 149 150 targetDropCount = Math.max(100, Math.min(320, Math.round((width * height) / 4500))); 151 drops = Array.from({ length: targetDropCount }, function () { 152 var drop = {}; 153 resetDrop(drop, true); 154 return drop; 155 }); 156 } 157 158 function drawRain(frameTime) { 159 var deltaSeconds; 160 161 if (!lastFrameTime) { 162 lastFrameTime = frameTime; 163 } 164 165 deltaSeconds = Math.min((frameTime - lastFrameTime) / 1000, 0.035); 166 lastFrameTime = frameTime; 167 context.clearRect(0, 0, width, height); 168 context.lineCap = 'round'; 169 170 drops.forEach(function (drop) { 171 var horizontalLength = (drop.drift / drop.speed) * drop.length; 172 173 context.beginPath(); 174 context.moveTo(drop.x, drop.y); 175 context.lineTo(drop.x + horizontalLength, drop.y + drop.length); 176 context.lineWidth = drop.lineWidth; 177 context.strokeStyle = 'rgba(220, 238, 243, ' + drop.opacity + ')'; 178 context.stroke(); 179 180 drop.x += drop.drift * deltaSeconds; 181 drop.y += drop.speed * deltaSeconds; 182 183 if (drop.y > height + drop.length || drop.x < -100) { 184 resetDrop(drop, false); 185 } 186 }); 187 188 window.requestAnimationFrame(drawRain); 189 } 190 191 resizeRain(); 192 193 if (typeof ResizeObserver === 'function') { 194 new ResizeObserver(resizeRain).observe(canvas.parentNode); 195 } else { 196 window.addEventListener('resize', resizeRain); 197 } 198 199 window.requestAnimationFrame(drawRain); 200 } 201 202 function initLaunchLightning() { 203 var weather = document.querySelector('.launch-weather'); 204 var reducedMotion = 205 typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 206 207 if (!weather || reducedMotion) { 208 return; 209 } 210 211 function scheduleLightning(isFirstStrike) {
212 var delay = isFirstStrike ? 1400 + Math.random() * 3200 : 3800 + Math.random() * 8200; 213 214 window.setTimeout(triggerLightning, delay); 215 } 216 217 function triggerLightning() { 218 var direction = Math.random() > 0.5 ? 1 : -1; 219 220 weather.style.setProperty('--lightning-x', 10 + Math.random() * 80 + '%'); 221 weather.style.setProperty('--lightning-y', 2 + Math.random() * 18 + '%'); 222 weather.style.setProperty('--lightning-width', 72 + Math.random() * 78 + 'px'); 223 weather.style.setProperty('--lightning-height', 42 + Math.random() * 27 + '%'); 224 weather.style.setProperty('--lightning-rotation', -11 + Math.random() * 22 + 'deg'); 225 weather.style.setProperty('--lightning-direction', direction); 226 weather.style.setProperty('--lightning-opacity', 0.72 + Math.random() * 0.26); 227 weather.classList.remove('is-lightning'); 228 229 window.requestAnimationFrame(function () { 230 weather.classList.add('is-lightning'); 231 232 window.setTimeout(function () { 233 weather.classList.remove('is-lightning'); 234 scheduleLightning(false); 235 }, 720); 236 }); 237 } 238 239 scheduleLightning(true); 240 } 241 242 function initImageViewer() { 243 var viewer = document.querySelector('[data-image-viewer]'); 244 var triggers = Array.prototype.slice.call(document.querySelectorAll('[data-image-viewer-trigger]')); 245 246 if (!viewer || !triggers.length) { 247 return; 248 } 249 250 var viewerImage = viewer.querySelector('[data-image-viewer-image]'); 251 var viewerCaption = viewer.querySelector('[data-image-viewer-caption]'); 252 var closeButton = viewer.querySelector('[data-image-viewer-close]'); 253 var previousButton = viewer.querySelector('[data-image-viewer-prev]'); 254 var nextButton = viewer.querySelector('[data-image-viewer-next]'); 255 var currentIndex = 0; 256 257 function showImage(index) { 258 currentIndex = (index + triggers.length) % triggers.length; 259 260 var trigger = triggers[currentIndex]; 261 var thumbnail = trigger.querySelector('img'); 262 var figure = trigger.closest('figure'); 263 var caption = figure ? figure.querySelector('figcaption') : null; 264 265 viewerImage.src = trigger.href; 266 viewerImage.alt = thumbnail ? thumbnail.alt : ''; 267 viewerCaption.textContent = caption ? caption.textContent : viewerImage.alt; 268 } 269 270 function openViewer(index) { 271 showImage(index); 272 273 if (typeof viewer.showModal === 'function') { 274 viewer.showModal(); 275 } else { 276 viewer.setAttribute('open', ''); 277 } 278 279 closeButton.focus(); 280 } 281 282 function closeViewer() { 283 if (typeof viewer.close === 'function') { 284 viewer.close(); 285 } else { 286 viewer.removeAttribute('open'); 287 } 288 } 289 290 triggers.forEach(function (trigger, index) { 291 trigger.addEventListener('click', function (event) { 292 event.preventDefault(); 293 openViewer(index); 294 }); 295 }); 296 297 closeButton.addEventListener('click', closeViewer); 298 previousButton.addEventListener('click', function () { 299 showImage(currentIndex - 1); 300 }); 301 nextButton.addEventListener('click', function () { 302 showImage(currentIndex + 1); 303 }); 304 305 viewer.addEventListener('click', function (event) { 306 if (event.target === viewer) { 307 closeViewer(); 308 } 309 }); 310 311 viewer.addEventListener('keydown', function (event) { 312 if (event.key === 'ArrowLeft') { 313 event.preventDefault(); 314 showImage(currentIndex - 1); 315 } else if (event.key === 'ArrowRight') { 316 event.preventDefault(); 317 showImage(currentIndex + 1); 318 } 319 }); 320 } 321 322 function initLaunchFighterAfterLoad() { 323 var fighter = document.querySelector('.launch-fighter'); 324 325 if (!fighter) { 326 return; 327 } 328 329 var image = fighter.querySelector('img[data-src]'); 330 var stillFrame = fighter.querySelector('source[data-srcset]'); 331 332 if (!image) { 333 return; 334 } 335 336 function loadFighter() { 337 image.addEventListener('load', function () { 338 fighter.classList.add('is-loaded'); 339 }, { once: true }); 340 341 if (stillFrame) { 342 stillFrame.srcset = stillFrame.getAttribute('data-srcset'); 343 } 344 345 image.src = image.getAttribute('data-src'); 346
347 if (image.complete && image.naturalWidth) { 348 fighter.classList.add('is-loaded'); 349 } 350 } 351 352 function scheduleFighter() { 353 if (typeof window.requestIdleCallback === 'function') { 354 window.requestIdleCallback(loadFighter, { timeout: 2500 }); 355 } else { 356 window.setTimeout(loadFighter, 300); 357 } 358 } 359 360 function observeFighter() { 361 if (typeof IntersectionObserver !== 'function') { 362 scheduleFighter(); 363 return; 364 } 365 366 var observer = new IntersectionObserver(function (entries) { 367 if (!entries.some(function (entry) { return entry.isIntersecting; })) { 368 return; 369 } 370 371 observer.disconnect(); 372 scheduleFighter(); 373 }, { rootMargin: '200px 0px' }); 374 375 observer.observe(fighter); 376 } 377 378 // Keep decorative animation off the critical page-load path. 379 if (document.readyState === 'complete') { 380 observeFighter(); 381 } else { 382 window.addEventListener('load', observeFighter, { once: true }); 383 } 384 } 385 386 function initLaunchEffectsAfterLoad() { 387 function startEffects() { 388 window.requestAnimationFrame(function () { 389 initLaunchRain(); 390 initLaunchLightning(); 391 }); 392 } 393 394 if (document.readyState === 'complete') { 395 startEffects(); 396 } else { 397 window.addEventListener('load', startEffects, { once: true }); 398 } 399 } 400 401 initAnalytics(); 402 initTrackedLinks(); 403 initHeader(); 404 initLaunchFighterAfterLoad(); 405 initLaunchEffectsAfterLoad(); 406 initImageViewer(); 407})();
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.