1"use strict"; 2 3/* ======= Header animation ======= */ 4const header = document.getElementById('header'); 5 6window.onload=function() 7{ 8 headerAnimation(); 9 10}; 11 12window.onresize=function() 13{ 14 headerAnimation(); 15 16}; 17 18window.onscroll=function() 19{ 20 headerAnimation(); 21 22}; 23 24 25function headerAnimation () { 26 27 var scrollTop = window.scrollY; 28 29 if ( scrollTop > 100 ) { 30 header.classList.add('header-shrink'); 31 32 } else { 33 header.classList.remove('header-shrink'); 34 } 35 36}; 37 38/* ===== Sponsor links jump, never glide (Marek 2026-09-21) ===== */ 39/* "Sponsor" buttons and nav links (#sponsor on home pages, #sponsors on event pages) used to start a smooth scroll 40 while the lead form's "Email us" panel was animating open and lazy images were still arriving above: the page 41 grew under the glide and it sometimes stopped half way. They now teleport: the panel opens without its 42 transition, the page jumps in the same tick, and the landing is re-checked once shortly after and once on load 43 unless the visitor has touched the page. Every other anchor keeps its smooth scroll. Never throws. */ 44(function () { 45 try { 46 var target = document.getElementById('sponsor') || document.getElementById('sponsors'); 47 if (!target) return; 48 var hash = '#' + target.id; 49 var touched = false; 50 ['wheel', 'touchmove', 'keydown', 'pointerdown'].forEach(function (t) { 51 window.addEventListener(t, function () { touched = true; }, { passive: true, capture: true }); 52 }); 53 54 function openLeadPanel() { 55 var panel = document.getElementById('lead-panel'); 56 if (!panel || typeof window.leadOpen !== 'function') return; 57 var was = panel.style.transition; 58 panel.style.transition = 'none'; 59 window.leadOpen(); 60 void panel.offsetHeight; // apply the open state before the transition returns 61 panel.style.transition = was; 62 } 63 function land() { 64 var margin = parseFloat(getComputedStyle(target).scrollMarginTop); 65 var offset = margin > 0 ? margin : 69; // 69 = header height, same as the .scrollto handler 66 var y = Math.max(0, Math.round(target.getBoundingClientRect().top + window.pageYOffset - offset)); 67 if (Math.abs(window.pageYOffset - y) > 1) window.scrollTo({ top: y, left: 0, behavior: 'instant' }); 68 } 69 function sponsorJump() { 70 openLeadPanel(); 71 land(); 72 touched = false; 73 setTimeout(function () { if (!touched) land(); }, 300); 74 } 75 function closeMenu() { 76 if (typeof closeMobileNav === 'function') return closeMobileNav(); 77 var nav = document.getElementById('navigation'); 78 if (nav && nav.classList.contains('show')) nav.classList.remove('show'); 79 } 80 81 document.querySelectorAll('a[href="' + hash + '"]').forEach(function (a) { 82 a.addEventListener('click', function (e) { 83 e.preventDefault(); 84 e.stopImmediatePropagation(); // not the smooth .scrollto handler, not the animated leadOpen 85 if (history.pushState) history.pushState(null, '', hash); 86 sponsorJump(); 87 closeMenu(); 88 }, true); 89 }); 90 91 // arriving with the hash (talk page hero button -> ./#sponsors, navbar from a subpage, a shared link) 92 if (location.hash === hash) { 93 var arrive = function () { if (!touched) { openLeadPanel(); land(); } }; 94 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', arrive); else arrive(); 95 window.addEventListener('load', arrive); 96 } 97 } catch (e) {} 98})(); 99 100 101/* ===== Smooth scrolling ====== */ 102/* Note: You need to include smoothscroll.min.js (smooth scroll behavior polyfill) on the page to cover some browsers */ 103/* Ref: https://github.com/iamdustan/smoothscroll */ 104 105 106let scrollLinks = document.querySelectorAll('.scrollto'); 107const pageNavWrapper = document.getElementById('navigation'); 108 109scrollLinks.forEach((scrollLink) => { 110 111 scrollLink.addEventListener('click', (e) => { 112 113 e.preventDefault(); 114 115 let element = document.querySelector(scrollLink.getAttribute("href")); 116 117 const yOffset = 69; //page .header height 118 119 //console.log(yOffset); 120 121 const y = element.getBoundingClientRect().top + window.pageYOffset - yOffset; 122 123 window.scrollTo({top: y, behavior: 'smooth'}); 124 history.pushState(null, null, scrollLink.getAttribute("href")); 125 126 127 //Collapse mobile menu after clicking 128 closeMobileNav(); 129 130 131 }); 132 133}); 134 135 136/* ===== Mobile menu ===== */ 137/* Collapse the open hamburger menu. Used by the .scrollto handler above and by a delegated 138 handler below, so plain nav-link anchors (sreday home, all event pages) close it too. */ 139function closeMobileNav() { 140 if (!pageNavWrapper || !pageNavWrapper.classList.contains('show')) return; 141 if (window.bootstrap && bootstrap.Collapse) { 142 bootstrap.Collapse.getOrCreateInstance(pageNavWrapper, { toggle: false }).hide(); 143 } else { 144 pageNavWrapper.classList.remove('show'); 145 } 146} 147if (pageNavWrapper) { 148 pageNavWrapper.addEventListener('click', (e) => { if (e.target.closest('a')) closeMobileNav(); }); 149} 150 151/* ===== Navbar glow ===== */ 152// A soft vertical flare behind the glassy navbar that follows the mouse (styles: "NAVBAR GLOW" in the css). 153// Desktop pointers only; the beam eases towards the cursor so it trails a little. Never throws. 154(function () { 155 try { 156 var bar = document.getElementById('header') || document.querySelector('.navbar.fixed-top'); 157 if (!bar || !window.matchMedia || !window.requestAnimationFrame) return; 158 if (!window.matchMedia('(hover: hover) and (pointer: fine)').matches) return; 159 var still = window.matchMedia('(prefers-reduced-motion: reduce)').matches; 160 var wrap = document.createElement('div'), beam = document.createElement('i'); 161 wrap.className = 'nav-glow'; wrap.setAttribute('aria-hidden', 'true'); wrap.appendChild(beam); 162 bar.insertBefore(wrap, bar.firstChild); 163 var x = null, target = 0, raf = 0; 164 function frame() { 165 raf = 0; 166 x += (target - x) * 0.16; 167 if (Math.abs(target - x) < 0.4) x = target; 168 beam.style.transform = 'translate3d(' + x.toFixed(1) + 'px,0,0)'; 169 if (x !== target) raf = window.requestAnimationFrame(frame); 170 } 171 bar.addEventListener('mousemove', function (e) { 172 target = e.clientX - bar.getBoundingClientRect().left; 173 if (x === null || still) x = target; 174 wrap.classList.add('on'); 175 if (!raf) raf = window.requestAnimationFrame(frame); 176 }); 177 bar.addEventListener('mouseleave', function () { wrap.classList.remove('on'); }); 178 } catch (e) {} 179})(); 180 181/* ===== Gumshoe SrollSpy ===== */ 182/* Ref: https://github.com/cferdinandi/gumshoe */ 183// Get the sticky header 184 185 186// Initialize Gumshoe 187var spy = new Gumshoe('#navigation a', { 188 offset: 69 //page .header heights 189}); 190
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.