1/* BroadbandSwitch.uk honest delight layer. 2 1) Counts up real numeric hero stats when they scroll into view. 3 2) Fires a small emoji burst when the USER submits the postcode form. 4 Both respect prefers-reduced-motion. No fake social proof, ever. */ 5(function () { 6 'use strict'; 7 var reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 8 9 /* 1. Count-up on real stats */ 10 function countUp(el) { 11 var raw = el.getAttribute('data-count-base'); 12 var target = parseInt(raw, 10); 13 if (!target || reduced) return; 14 var small = el.querySelector('small'); 15 var suffix = small ? small.outerHTML : ''; 16 var start = null, dur = 900; 17 function step(ts) { 18 if (!start) start = ts; 19 var p = Math.min((ts - start) / dur, 1); 20 var eased = 1 - Math.pow(1 - p, 3); 21 el.innerHTML = Math.round(target * eased).toLocaleString('en-GB') + suffix; 22 if (p < 1) requestAnimationFrame(step); 23 } 24 requestAnimationFrame(step); 25 } 26 var nums = document.querySelectorAll('.live-stat-num[data-count-base]'); 27 if ('IntersectionObserver' in window && nums.length) { 28 var seen = new WeakSet(); 29 var io = new IntersectionObserver(function (entries) { 30 entries.forEach(function (e) { 31 if (e.isIntersecting && !seen.has(e.target)) { 32 seen.add(e.target); 33 countUp(e.target); 34 io.unobserve(e.target); 35 } 36 }); 37 }, { threshold: 0.6 }); 38 nums.forEach(function (n) { io.observe(n); }); 39 } 40 41 /* 2. Emoji burst on the user's own action (postcode submit) */ 42 function burst(x, y) { 43 if (reduced) return; 44 var emojis = ['ð', 'â¡', 'ð·', 'ð¶', 'â¨']; 45 for (var i = 0; i < 7; i++) { 46 var s = document.createElement('span'); 47 s.textContent = emojis[i % emojis.length]; 48 s.style.cssText = 'position:fixed;left:' + x + 'px;top:' + y + 'px;' + 49 'font-size:18px;pointer-events:none;z-index:9999;transition:transform .8s cubic-bezier(.2,.8,.3,1),opacity .8s;opacity:1;will-change:transform,opacity;'; 50 document.body.appendChild(s); 51 (function (el, idx) { 52 requestAnimationFrame(function () { 53 var dx = (Math.random() - 0.5) * 160; 54 var dy = -60 - Math.random() * 90; 55 el.style.transform = 'translate(' + dx + 'px,' + dy + 'px) rotate(' + ((Math.random() - 0.5) * 60) + 'deg)'; 56 el.style.opacity = '0'; 57 }); 58 setTimeout(function () { el.remove(); }, 850); 59 })(s, i); 60 } 61 } 62 document.addEventListener('submit', function (ev) { 63 var form = ev.target; 64 if (form && form.querySelector && form.querySelector('input[placeholder*="postcode" i], input[name*="postcode" i]')) { 65 var btn = form.querySelector('button[type="submit"], button'); 66 var r = (btn || form).getBoundingClientRect(); 67 burst(r.left + r.width / 2, r.top); 68 } 69 }, true); 70})();
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.