1(function($) { 2 3 function heroUnit() { 4 5 function animateHeroImages(plankParents, heroImageParents, plankImages, heroLabels, heroImages) { 6 if(!$('.hero-unit').hasClass('animated')) { 7 8 // hidding non-animated/animated items ------ 9 $(plankParents).css('position', 'absolute'); 10 $(heroImageParents).css('position', 'absolute'); 11 // ------ hidding non-animated/animated items 12 13 // showing items to animate ------ 14 $(heroImages).parent().parent().css('position', 'relative'); 15 $(plankImages).parent().css('position', 'relative'); 16 // ------ showing items to animate 17 18 //prevent animation from false-start ------ 19 $('.hero-unit').addClass('animated'); 20 // ------ prevent animation from false-start 21 22 for(let i = 0; i < plankImages.length; i++) { 23 let currentPlankImage = plankImages[i]; // current plank logo 24 let currentPlankLabel = heroLabels[i]; // current plank label 25 let currentHeroImage = heroImages[i]; // current hero image 26 27 // reset max-width and scale to image 28 $(currentHeroImage).css('max-width', '33rem'); 29 $(currentHeroImage).css('transform', 'scale(1.1)'); 30 31 // set default translate to label ------ 32 $(heroLabels).each(function(labelIndex, label) { 33 $(label).css('transform', 'translateX(-100%)'); 34 }) 35 // ------ set default translate to label 36 37 setTimeout(() => { 38 // hero image start ------ 39 $(currentHeroImage).css('opacity', 1); // show the hero image 40 $(currentHeroImage).css('transform', 'scale(1)'); // show the hero image 41 // ------ hero image end 42 43 // plank image start ------ 44 $(currentPlankImage).css('opacity', 1); // show the plank image 45 // ------ plank image end 46 }, 900 * (i + 1)); 47 48 setTimeout(() => { 49 // plank label start ------ 50 $(currentPlankLabel).css('opacity', 1); // show the plank label 51 $(currentPlankLabel).css('transform', 'translateX(0)'); // show the plank label 52 // ------ plank label end 53 54 // hidding items start ------ 55 if(i == 0 && plankImages.length > 0 && $('.hero-unit .plank .plank-content').length > 1) { 56 setTimeout(() => { 57 hideHeroImages(plankImages, heroLabels, heroImages); 58 }, 2800 + 900 * (plankImages.length - 1)); 59 } 60 // ------ hidding items end 61 62 }, 2800 + 900 * i); 63 } 64 } 65 } 66 67 function hideHeroImages(plankImages, heroLabels, heroImages) { 68 for(let i = plankImages.length - 1; i >= 0; i--) { 69 let currentHeroImage = heroImages[i]; 70 71 setTimeout(() => { 72 73 // set width and opacity to image ------ 74 $(currentHeroImage).css('max-width', 0); 75 $(currentHeroImage).css('opacity', 0); 76 // ------ set width and opacity to image 77 78 if(i == 0) { 79 $(heroLabels).each(function(labelIndex, label) { 80 // set translate and opacity to label ------ 81 $(label).css('opacity', 0); 82 $(label).css('transform', 'translateX(100%)'); 83 // ------ set translate and opacity to label 84 }) 85 86 // removing animated class to remove preventer ------ 87 setTimeout(() => { 88 $('.hero-unit').removeClass('animated'); 89 }, 100) 90 // ------ removing animated class to remove preventer 91 92 // set opacity to planks ------ 93 $(plankImages).each(function(plankIndex, plank) { 94 $(plank).css('opacity', 0); 95 }) 96 // ------ set opacity to planks 97 98 } 99 }, 1000 * (plankImages.length - i - 1.7)); 100 } 101 } 102 103 if($('body.home .hero-unit').length || $('.hero-unit.content-block').length ) { 104 let hero = $('.hero-unit'), 105 planks = $(hero).find('.plank .plank-content'), 106 heroImageWrappers = $(hero).find('.hero-unit-images .images-wrapper'); 107 108 $(heroImageWrappers).each((index, imagesWrapper) => { 109 let currentPlank = $(planks)[index], // current plank wrapper 110 currentImages = $(heroImageWrappers)[index], // current images wrapper 111 plankImages = $(currentPlank).find('.image-wrapper'), // current plank 112 heroImages = $(currentImages).find('.image img'), // hero image 113 heroLabels = $(currentImages).find('.image .label'); // hero label 114 115 for(let i = 0; i < plankImages.length; i++) { 116 let currentHeroImage = heroImages[i]; // current hero image 117 let imageWrapper = $(currentHeroImage).parent(); // parent of current hero image 118 119 // set width and height to wrapper 120 $(imageWrapper).css('width', $(currentHeroImage).outerWidth()); 121 $(imageWrapper).css('height', $(currentHeroImage).outerHeight() + 50); 122 123 // set width and height to image 124 $(currentHeroImage).css('height', $(currentHeroImage).outerHeight()); 125 $(currentHeroImage).css('max-width', 'auto'); 126 } 127 128 setInterval(() => { 129 if(!$('.hero-unit').hasClass('animated')) { // checking if no animation processing 130 if(!$(imagesWrapper).hasClass('animated')) { // checking if image wrapper not animated yet 131 $(imagesWrapper).addClass('animated'); // add class to prevent false start 132 animateHeroImages(planks, heroImageWrappers, plankImages, heroLabels, heroImages); // start animation 133 134 if(index == $(heroImageWrappers).length - 1) { // checking if all elements are being processed 135 136 // start animation over ------ 137 $(heroImageWrappers).each((animatedIndex, animatedItem) => { 138 $(animatedItem).removeClass('animated'); 139 }) 140 // ------ start animation over 141 } 142 } 143 } 144 }, 100) 145 }) 146 } 147 148 function randomIntFromInterval(min, max) { 149 return Math.floor(Math.random() * (max - min + 1) + min) 150 } 151 152 153 const templates = document.querySelectorAll(".hero-unit.has-multiple-images"); 154
155 templates.forEach(template => { 156 const images = template.querySelectorAll(".isAnimated"); 157 158 addEventListener('mousemove', (e) => { 159 let xPos = e.pageX - template.getBoundingClientRect().left; 160 let yPos = e.pageY - template.getBoundingClientRect().top; 161 162 let moveX = 0, 163 moveY = 0, 164 angle = 0; 165 166 if (xPos > template.getBoundingClientRect().left) { 167 moveX = (xPos - template.offsetWidth / 2) / template.offsetWidth; 168 angle = 169 Math.atan2( 170 e.pageX - template.getBoundingClientRect().left, 171 -(e.pageY - template.getBoundingClientRect().top) 172 ) * 173 (180 / Math.PI); 174 } 175 176 if (yPos > template.getBoundingClientRect().top) { 177 moveY = (yPos - template.offsetHeight / 2) / template.offsetHeight; 178 angle = 179 Math.atan2( 180 e.pageX - template.getBoundingClientRect().left, 181 -(e.pageY - template.getBoundingClientRect().top) 182 ) * 183 (180 / Math.PI); 184 } 185 186 images.forEach((image, index) => { 187 let multiplier = 0.5; 188 189 if(index === 0 || index === 3 || index === 5) { 190 multiplier = 0.25; 191 } 192 193 gsap.to(image, { x: moveX * randomIntFromInterval(10, 20) * multiplier, y: moveY * randomIntFromInterval(10, 20) * multiplier, duration: 1.5 }); 194 }); 195 }); 196 }); 197 } // END HERO UNIT 198 199 function editableSvg(el) { 200 $(el).each(function() { 201 let $img = $(this); 202 const imgID = $img.attr('id'); 203 const imgClass = $img.attr('class'); 204 const imgURL = $img.attr('src'); 205 $.get(imgURL, function(data) { 206 // Get the SVG tag, ignore the rest 207 let $svg = $(data).find('svg'); 208 // Add replaced image's ID to the new SVG 209 if (typeof imgID !== 'undefined') { 210 $svg = $svg.attr('id', imgID); 211 } 212 // Add replaced image's classes to the new SVG 213 if (typeof imgClass !== 'undefined') { 214 $svg = $svg.attr('class', imgClass + ' replaced-svg'); 215 } 216 // Remove any invalid XML tags as per http://validator.w3.org 217 $svg = $svg.removeAttr('xmlns:a'); 218 // Check if the viewport is set, if the viewport is not set the SVG wont't scale. 219 if (!$svg.attr('viewBox') && $svg.attr('height') && $svg.attr('width')) { 220 $svg.attr('viewBox', '0 0 ' + $svg.attr('width') + ' ' + $svg.attr('height')); 221 } 222 // Replace image with new SVG 223 $img.replaceWith($svg); 224 }, 'xml'); 225 }); 226 } // END EDITABLE SVG 227 228 /* Replace all SVG images with inline SVG */ 229 editableSvg('img.editable-svg'); 230 231 // START top-menu and notif bar display scroll events 232 const scrollThreshold = 5; 233 const topMenu = document.querySelector('.top-menu'); 234 const notificationBar = document.querySelector('.notification-bar'); 235 const siteHeader = document.querySelector('.site-header'); 236 const root = document.documentElement; 237 let lastScrollTop = 0; 238 239 const setNavProperties = () => { 240 let topMenuHeight = 0; 241 let siteHeaderHeight = 0; 242 243 // Check for element existence and content before measuring heights 244 if (topMenu && topMenu.innerHTML.trim() !== '') { 245 topMenuHeight = topMenu.offsetHeight; 246 } 247 if (siteHeader) { 248 siteHeaderHeight = siteHeader.offsetHeight; 249 } 250 251 // Set the CSS variables. The CSS will use these to position the sticky elements. 252 root.style.setProperty('--top-menu-height', `${topMenuHeight}px`); 253 root.style.setProperty('--site-header-height', `${siteHeaderHeight}px`); 254 }; 255 256 setNavProperties(); 257 258 const handleScroll = () => { 259 const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop; 260 261 // Ignore minor scroll changes 262 if (Math.abs(lastScrollTop - currentScrollTop) <= scrollThreshold) { 263 return; 264 } 265 266 // Determine scroll direction 267 if (currentScrollTop > lastScrollTop && currentScrollTop > 10) { 268 // Scrolling down: Hide both bars and shift the header 269 if (topMenu) topMenu.classList.add('is-hidden'); 270 if (notificationBar) notificationBar.classList.add('is-hidden'); 271 if (siteHeader) siteHeader.classList.add('is-shifted'); 272 } else { 273 // Scrolling up: Show both bars and un-shift the header 274 if (topMenu) topMenu.classList.remove('is-hidden'); 275 if (notificationBar) notificationBar.classList.remove('is-hidden');
276 if (siteHeader) siteHeader.classList.remove('is-shifted'); 277 } 278 279 lastScrollTop = currentScrollTop; 280 }; 281 282 window.addEventListener('scroll', handleScroll); 283 window.addEventListener('resize', setNavProperties); 284 285 286 /* resource apply sticky btn mobile filter nav */ 287 // function setTopToViewportHeight() { 288 // let sidebar = document.querySelector('.aside'); 289 // let pageHero = document.querySelector('.hero-unit-content'); 290 // let applyFilterContainer = document.querySelector('.apply-filter-wrapper'); 291 // const viewportHeight = window.innerHeight; 292 // const viewportWidth = window.innerWidth; 293 294 // if (sidebar) { 295 // sidebar.style.maxHeight = `${viewportWidth + pageHero.offsetHeight + 20}px`; 296 // // sidebar.style.maxHeight = `${ viewportWidth}px`; 297 // // applyFilterContainer.style.top = `${viewportWidth}px`; 298 // } 299 // } 300 301 // // Set the top value initially 302 // setTopToViewportHeight(); 303 304 // // Update the top value on window resize 305 // window.addEventListener('resize', setTopToViewportHeight); 306 307 // function setTopToViewportHeight() { 308 // let sidebar = document.querySelector('.aside'); 309 // let pageHero = document.querySelector('.hero-unit-content'); 310 // const viewportHeight = window.innerHeight; 311 // const viewportWidth = window.innerWidth; 312 313 // if (sidebar) { 314 // sidebar.style.height = `${viewportHeight - viewportWidth + pageHero.offsetHeight}px`; 315 // } 316 // } 317 318 // // Set the top value initially 319 // setTopToViewportHeight(); 320 321 // // Update the top value on window resize 322 // window.addEventListener('resize', setTopToViewportHeight); 323 /* end resource apply sticky btn mobile filter nav */ 324 325 // START SECONDARY NAV 326 // if($('.secondary-nav-wrapper').length) { 327 // $('.secondary-nav-wrapper').find('a').each((index, item) => { 328 // $(item).on('click', function() { 329 // if($(this.hash).offset()) { 330 // $('html, body').animate({scrollTop: $(this.hash).offset().top - $(header).outerHeight() - $('.secondary-nav-wrapper').outerHeight() - 30 }, 1000); 331 // return false; 332 // } 333 // }); 334 // }) 335 // } 336 // END SECONDARY NAV 337 338 /* anchor links */ 339 let hash = window.location.hash; 340 const mainHeader = document.querySelector('.site-header'); // added July 7, 2026 11am PDT to fix a console error of header not found 341 342 if($(hash).offset()) { 343 // $('html, body').animate({scrollTop: $(hash).offset().top - $(header).outerHeight()}, 1000); 344 $('html, body').animate({scrollTop: $(hash).offset().top - $(mainHeader).outerHeight()}); // updated July 7, 2026 11am PDT from $(header) to $(mainHeader) 345 } 346 347 348 if(document.querySelector('.site-header select')) { 349 new SlimSelect({ 350 select: '.site-header select', 351 }); 352 } 353 354 $('main.content section.content-block.bg-cool-wave + section.content-block.template-cta').length ? $('.site-footer .footer-top').addClass('bg-cool-wave') : false; 355 356 heroUnit(); 357 358 window.addEventListener('DOMContentLoaded', () => { 359 360 const siteHeader = document.querySelector('.site-header'); 361 document.body.style.setProperty('--site-header-height', siteHeader.offsetHeight + 'px'); 362 363 364 window.addEventListener(('resize'), ()=> { 365 document.body.style.setProperty('--site-header-height', siteHeader.offsetHeight + 'px'); 366 }) 367 368 if(siteHeader.classList.contains('has-secondary-nav')) { 369 document.body.classList.add('with-secondary-nav'); 370 } 371 372 const notificationBar = document.querySelector('.off-canvas-content > .notification-bar'); 373 374 if(notificationBar) { 375 document.body.classList.add('with-notification-bar'); 376 document.body.style.setProperty('--notification-height', notificationBar.offsetHeight + 'px'); 377 378 window.addEventListener(('resize'), ()=> { 379 document.body.style.setProperty('--notification-height', notificationBar.offsetHeight + 'px'); 380 }) 381 } 382 383 const listItems = document.querySelectorAll('.menu.dropdown .mega-menu .submenu li:not(.headline)'); 384 385 // Loop through each list item to check its content.
386 listItems.forEach(li => { 387 // Find the direct child link within the current list item. 388 const link = li.querySelector(':scope > a'); 389 390 // Proceed only if a link is found inside the li. 391 if (link) { 392 // Check if the link contains any of the specified nested elements. 393 const hasImage = link.querySelector('img'); 394 const hasSpan = link.querySelector('span'); 395 const hasParagraph = link.querySelector('p'); 396 397 // If the link does NOT contain an image, span, or paragraph... 398 if (!hasImage && !hasSpan && !hasParagraph) { 399 // ...then add the 'hover-underline' class to that specific parent <li>. 400 li.classList.add('hover-underline'); 401 } 402 } 403 }); 404 }); 405 406})(jQuery);
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.