1(function () { 2 'use strict'; 3 4 var CONSENT_KEY = 'bv-analytics-consent'; // 'granted' | 'denied' 5 var GA_ID = 'G-Q09MJLS86E'; 6 7 function getConsent() { 8 try { 9 return localStorage.getItem(CONSENT_KEY); 10 } catch (e) { 11 return null; 12 } 13 } 14 15 function setConsent(value) { 16 try { 17 localStorage.setItem(CONSENT_KEY, value); 18 } catch (e) { 19 /* localStorage unavailable â consent choice won't persist, banner will re-show */ 20 } 21 } 22 23 // Google Analytics is only ever requested from here, and only after explicit opt-in. 24 function loadAnalytics() { 25 if (window.__bvAnalyticsLoaded) return; 26 window.__bvAnalyticsLoaded = true; 27 28 window.dataLayer = window.dataLayer || []; 29 window.gtag = function () { 30 window.dataLayer.push(arguments); 31 }; 32 window.gtag('js', new Date()); 33 window.gtag('config', GA_ID); 34 35 var script = document.createElement('script'); 36 script.async = true; 37 script.src = 'https://www.googletagmanager.com/gtag/js?id=' + GA_ID; 38 document.head.appendChild(script); 39 } 40 41 function buildBanner() { 42 var wrap = document.createElement('div'); 43 wrap.id = 'cookie-consent-banner'; 44 wrap.className = 'cookie-banner'; 45 wrap.setAttribute('role', 'dialog'); 46 wrap.setAttribute('aria-live', 'polite'); 47 wrap.setAttribute('aria-label', 'Cookie consent'); 48 wrap.innerHTML = 49 '<div class="cookie-banner-inner">' + 50 '<p class="cookie-banner-text">' + 51 'We\'d like to use Google Analytics to understand how visitors use our site. ' + 52 'It only runs if you click "Accept" â you can change your mind anytime via the ' + 53 '"Cookie Settings" link in the footer. See our ' + 54 '<a href="privacy.html">Privacy Policy</a> for details.' + 55 '</p>' + 56 '<div class="cookie-banner-actions">' + 57 '<button type="button" class="btn btn-outline cookie-btn-reject">Reject</button>' + 58 '<button type="button" class="btn btn-primary cookie-btn-accept">Accept</button>' + 59 '</div>' + 60 '</div>'; 61 return wrap; 62 } 63 64 function hideBanner() { 65 var banner = document.getElementById('cookie-consent-banner'); 66 if (!banner) return; 67 banner.classList.remove('visible'); 68 setTimeout(function () { 69 if (banner.parentNode) banner.parentNode.removeChild(banner); 70 }, 300); 71 } 72 73 function showBanner() { 74 if (document.getElementById('cookie-consent-banner')) return; 75 if (!document.body) { 76 document.addEventListener('DOMContentLoaded', showBanner); 77 return; 78 } 79 80 var banner = buildBanner(); 81 document.body.appendChild(banner); 82 requestAnimationFrame(function () { 83 banner.classList.add('visible'); 84 }); 85 86 banner.querySelector('.cookie-btn-accept').addEventListener('click', function () { 87 setConsent('granted'); 88 loadAnalytics(); 89 hideBanner(); 90 }); 91 banner.querySelector('.cookie-btn-reject').addEventListener('click', function () { 92 setConsent('denied'); 93 // If analytics was already running (consent withdrawn via "Cookie Settings"), 94 // a reload is the only way to actually stop it â an injected gtag script can't be unloaded. 95 if (window.__bvAnalyticsLoaded) { 96 location.reload(); 97 } else { 98 hideBanner(); 99 } 100 }); 101 } 102 103 function init() { 104 var consent = getConsent(); 105 if (consent === 'granted') { 106 loadAnalytics(); 107 } else if (consent !== 'denied') { 108 showBanner(); 109 } 110 } 111 112 // Lets the footer's "Cookie Settings" link reopen the banner to change consent later. 113 document.addEventListener('click', function (e) { 114 var target = e.target.closest && e.target.closest('#cookie-sett
114ings-link'); 115 if (target) { 116 e.preventDefault(); 117 showBanner(); 118 } 119 }); 120 121 if (document.readyState === 'loading') { 122 document.addEventListener('DOMContentLoaded', init); 123 } else { 124 init(); 125 } 126})();
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.