1document.addEventListener('DOMContentLoaded', () => { 2 const items = document.querySelectorAll('[data-service]'); 3 if (!items.length) return; 4 5 const open = (item) => { 6 const desc = item.querySelector('[data-service-description]'); 7 if (desc) desc.style.maxHeight = desc.scrollHeight + 'px'; 8 item.classList.add('is-open'); 9 }; 10 11 const close = (item) => { 12 const desc = item.querySelector('[data-service-description]'); 13 if (desc) desc.style.maxHeight = ''; 14 item.classList.remove('is-open'); 15 }; 16 17 const closeAll = () => items.forEach(close); 18 19 // Hover: open on enter, close on leave 20 items.forEach((item) => { 21 item.addEventListener('mouseenter', () => { 22 closeAll(); 23 open(item); 24 }); 25 item.addEventListener('mouseleave', () => { 26 close(item); 27 }); 28 }); 29 30 // Touch: toggle on tap only (not mouse clicks â hover handles desktop) 31 items.forEach((item) => { 32 item.addEventListener('pointerup', (e) => { 33 if (e.pointerType !== 'touch') return; 34 if (e.target.closest('a')) return; 35 const wasOpen = item.classList.contains('is-open'); 36 closeAll(); 37 if (!wasOpen) open(item); 38 }); 39 }); 40});
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.