/* global React */ // ===================================================================== // Geo-aware cookie consent (GDPR/UK) — the blocking consent banner ONLY // shows for EU / UK / EEA visitors. Everyone else (NZ, AUS, rest of // world) gets Google Analytics + the Meta Pixel firing immediately, with // no banner — so ad retargeting data stays intact where the law allows. // A "Cookie settings" footer link can reopen the banner for anyone. // ===================================================================== const { useState, useEffect, useCallback } = React; const CC_KEY = "jb_cookie_consent_v1"; // "all" | "essential" // EU 27 + UK + EEA (Iceland, Liechtenstein, Norway) + Switzerland. const EU_UK = new Set([ "AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE", "IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE", "GB","IS","LI","NO","CH", ]); // ---- Consent-gated analytics loader ------------------------------------- // Runs only when consent is given (EU/UK) or auto (rest of world). Drop your // real IDs in below; until then they're inert no-ops, so nothing tracks. function loadAnalytics() { if (window.__jbAnalyticsLoaded) return; window.__jbAnalyticsLoaded = true; // --- Google Analytics 4 --- (replace G-XXXXXXXXXX with your real ID) const GA_ID = "G-XXXXXXXXXX"; if (GA_ID && !GA_ID.includes("XXXX")) { const s = document.createElement("script"); s.async = true; s.src = "https://www.googletagmanager.com/gtag/js?id=" + GA_ID; document.head.appendChild(s); window.dataLayer = window.dataLayer || []; window.gtag = function () { window.dataLayer.push(arguments); }; window.gtag("js", new Date()); window.gtag("config", GA_ID, { anonymize_ip: true }); } // --- Meta (Facebook) Pixel --- (replace 0000000000 with your real ID) const PIXEL_ID = "0000000000"; if (PIXEL_ID && !PIXEL_ID.startsWith("0000")) { /* eslint-disable */ !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n; n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)} (window,document,'script','https://connect.facebook.net/en_US/fbevents.js'); window.fbq('init', PIXEL_ID); window.fbq('track', 'PageView'); /* eslint-enable */ } } // ---- Region detection: "eu" (needs consent) vs "row" (rest of world) ----- // 1) Offline timezone fast-path — instantly clears most NZ/AUS visitors with // no network call. 2) IP lookup for everyone else. 3) On any failure we // fail SAFE and treat the visitor as EU (show the banner). async function detectRegion() { try { const tz = (Intl.DateTimeFormat().resolvedOptions().timeZone || ""); if (/^(Australia\/|Pacific\/Auckland|Pacific\/Chatham)/.test(tz)) return "row"; if (/^Europe\//.test(tz)) return "eu"; } catch (e) {} try { const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), 2500); const r = await fetch("https://get.geojs.io/v1/ip/country.json", { signal: ctrl.signal }); clearTimeout(timer); const j = await r.json(); return EU_UK.has(String(j.country || "").toUpperCase()) ? "eu" : "row"; } catch (e) {} return "eu"; // fail safe } function CookieConsent() { const [open, setOpen] = useState(false); useEffect(() => { let stored = null; try { stored = localStorage.getItem(CC_KEY); } catch (e) {} // Returning visitor with an explicit choice — honour it everywhere. if (stored === "all") { loadAnalytics(); return; } if (stored === "essential") { return; } // First visit — decide by region. let cancelled = false; detectRegion().then((region) => { if (cancelled) return; if (region === "row") { loadAnalytics(); // NZ / AUS / rest of world: fire, no banner } else { setOpen(true); // EU / UK / EEA: ask first } }); return () => { cancelled = true; }; }, []); // Let the footer "Cookie settings" link reopen the banner for anyone. useEffect(() => { window.openCookieSettings = () => setOpen(true); return () => { delete window.openCookieSettings; }; }, []); const decide = useCallback((value) => { try { localStorage.setItem(CC_KEY, value); } catch (e) {} setOpen(false); if (value === "all") loadAnalytics(); }, []); if (!open) return null; return (

I use a few cookies — some essential for the site to work, and some (Google Analytics & the Meta Pixel) that only run if you say yes. See the Privacy Policy for the details.

); } window.CookieConsent = CookieConsent;