1(function() { 2 "use strict"; 3 4 /** 5 * Easy selector helper function 6 */ 7 const select = (el, all = false) => { 8 el = el.trim(); 9 if (el === '') { 10 return 'Selector is empty'; 11 } 12 if (all) { 13 return [...document.querySelectorAll(el)]; 14 } else { 15 return document.querySelector(el); 16 } 17} 18 19 /** 20 * Easy event listener function 21 */ 22 const on = (type, el, listener, all = false) => { 23 let selectEl = select(el, all) 24 if (selectEl) { 25 if (all) { 26 selectEl.forEach(e => e.addEventListener(type, listener)) 27 } else { 28 selectEl.addEventListener(type, listener) 29 } 30 } 31 } 32 33 /** 34 * Easy on scroll event listener 35 */ 36 const onscroll = (el, listener) => { 37 el.addEventListener('scroll', listener) 38 } 39 40 /** 41 * Navbar links active state on scroll 42 */ 43 let navbarlinks = select('#navbar .scrollto', true) 44 const navbarlinksActive = () => { 45 let position = window.scrollY + 200 46 navbarlinks.forEach(navbarlink => { 47 if (!navbarlink.hash) return 48 let section = select(navbarlink.hash) 49 if (!section) return 50 if (position >= section.offsetTop && position <= (section.offsetTop + section.offsetHeight)) { 51 navbarlink.classList.add('active') 52 } else { 53 navbarlink.classList.remove('active') 54 } 55 }) 56 } 57 window.addEventListener('load', navbarlinksActive) 58 onscroll(document, navbarlinksActive) 59 60 /** 61 * Scrolls to an element with header offset 62 */ 63 const scrollto = (el) => { 64 let header = select('#header') 65 let offset = header.offsetHeight 66 67 if (!header.classList.contains('header-scrolled')) { 68 offset -= 16 69 } 70 71 let elementPos = select(el).offsetTop 72 window.scrollTo({ 73 top: elementPos - offset, 74 behavior: 'smooth' 75 }) 76 } 77 78 /** 79 * Header fixed top on scroll 80 */ 81 let selectHeader = select('#header') 82 if (selectHeader) { 83 let headerOffset = selectHeader.offsetTop 84 let nextElement = selectHeader.nextElementSibling 85 const headerFixed = () => { 86 if ((headerOffset - window.scrollY) <= 0) { 87 selectHeader.classList.add('fixed-top') 88 nextElement.classList.add('scrolled-offset') 89 } else { 90 selectHeader.classList.remove('fixed-top') 91 nextElement.classList.remove('scrolled-offset') 92 } 93 } 94 window.addEventListener('load', headerFixed) 95 onscroll(document, headerFixed) 96 } 97 98 /** 99 * Back to top button 100 */ 101 let backtotop = select('.back-to-top') 102 if (backtotop) { 103 const toggleBacktotop = () => { 104 if (window.scrollY > 100) { 105 backtotop.classList.add('active') 106 } else { 107 backtotop.classList.remove('active') 108 } 109 } 110 window.addEventListener('load', toggleBacktotop) 111 onscroll(document, toggleBacktotop) 112 } 113 114 /** 115 * Mobile nav toggle 116 */ 117 on('click', '.mobile-nav-toggle', function(e) { 118 select('#navbar').classList.toggle('navbar-mobile') 119 this.classList.toggle('bi-list') 120 this.classList.toggle('bi-x') 121 }) 122 123 /** 124 * Mobile nav dropdowns activate 125 */ 126 on('click', '.navbar .dropdown > a', function(e) { 127 if (select('#navbar').classList.contains('navbar-mobile')) { 128 e.preventDefault() 129 this.nextElementSibling.classList.toggle('dropdown-active') 130 } 131 }, true) 132 133 /** 134 * Scrool with ofset on links with a class name .scrollto 135 */ 136 on('click', '.scrollto', function(e) { 137 if (select(this.hash)) { 138 e.preventDefault() 139 140 let navbar = select('#navbar') 141 if (navbar.classList.contains('navbar-mobile')) { 142 navbar.classList.remove('navbar-mobile') 143 let navbarToggle = select('.mobile-nav-toggle') 144 navbarToggle.classList.toggle('bi-list') 145 navbarToggle.classList.toggle('bi-x') 146 } 147 scrollto(this.hash) 148 } 149 }, true) 150 151 /** 152 * Scroll with ofset on page load with hash links in the url 153 */ 154 window.addEventListener('load', () => { 155 if (window.location.hash) { 156 if (select(window.location.hash)) { 157 scrollto(window.location.hash) 158 } 159 } 160 }); 161 162 /** 163 * Preloader 164 */ 165 let preloader = select('#preloader'); 166 if (preloader) { 167 window.addEventListener('load', () => { 168 preloader.remove() 169 });
170 } 171 172 173 // Get all the tab buttons and tabs 174 const tabButtons = document.querySelectorAll('.tab-buttons button'); 175 const tabs = document.querySelectorAll('.tab'); 176 177 // Add click event listener to tab buttons 178 tabButtons.forEach((button, index) => { 179 button.addEventListener('click', () => { 180 // Remove active class from all buttons and tabs 181 tabButtons.forEach(btn => btn.classList.remove('active')); 182 tabs.forEach(tab => tab.classList.remove('active')); 183 184 // Add active class to clicked button and corresponding tab 185 button.classList.add('active'); 186 const filter = button.dataset.filter; 187 tabs.forEach(tab => { 188 if (tab.dataset.type === filter) { 189 tab.classList.add('active'); 190 } 191 }); 192 }); 193 }); 194 195 // Make the first tab active by default 196 /* tabs[0].classList.add('active'); 197 tabButtons[0].classList.add('active'); 198 const portfolioItems = document.querySelectorAll('.portfolio-item'); 199 200 portfolioItems.forEach(item => { 201 item.addEventListener('mouseenter', () => { 202 item.querySelector('.content-hides').style.display = 'block'; 203 }); 204 205 item.addEventListener('mouseleave', () => { 206 item.querySelector('.content-hides').style.display = 'none'; 207 }); 208 });*/ 209 210 /** 211 * Initiate Pure Counter 212 */ 213 214$("a.nino-search, #nino-searchForm .nino-close").click(function(){ 215 $("#nino-searchForm").toggleClass("open"); 216 }); 217 218})()
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.