PageSourceSearch

https://www.brighthorizons.com/dist/js/corporate/corporate.js?v1.4.2

js brighthorizons.com collected 2026-10-01 08:42:14 UTC 36,361 bytes, 955 lines download raw bytes

1/* Toggles active classes based on scroll position for side-nav */
2
3const links = document.querySelectorAll(".bhc-solutions__navCategory");
4const sections = document.querySelectorAll(".bhc-solution");
5
6function initMap() {
7    var input = document.getElementById("addressInput");
8    var autocomplete = new google.maps.places.Autocomplete(input);
9    var selectedAddress = "";
10
11    // listen for user interaction with the page
12    autocomplete.addListener("place_changed",
13        async () => {
14            var place = autocomplete.getPlace();
15            if (!place.geometry) {
16                console.log('Location from Autocomplete Bar by Enter Key');
17                selectedAddress = $(".pac-container .pac-item:first").text();
18            } else {
19                console.log('Location from Autocomplete Bar Selection');
20                selectedAddress = place.formatted_address;
21            }
22            //console.log('Selected Address ' + selectedAddress)
23            location.href = "/find-a-center?address=" + encodeURIComponent(selectedAddress);
24        });
25    if (input !== null && input !== undefined) {
26        input.addEventListener('keydown', function (event) {
27            if ((event.key === 'Enter' || event.keycode === 13) && !autocomplete.getPlace()) {
28                const inputText = input.value;
29                const autocompleteService = new google.maps.places.AutocompleteService();
30                autocompleteService.getPlacePredictions({ input: inputText }, function (predictions, status) {
31                    if (status === google.maps.places.PlacesServiceStatus.OK && predictions && predictions.length > 0) {
32                        const firstPrediction = predictions[0].description;
33                        location.href = "/find-a-center?address=" + encodeURIComponent(firstPrediction);
34                    }
35                });
36            }
37        });
38    }
39}
40
41function changeNavState() {
42    let index = sections.length;
43    if (index > 0) {
44        console.log('sections length:' + sections.length);
45        while (--index && window.scrollY + 350 < sections[index].offsetTop) { }
46
47        links.forEach((link) => link.classList.remove("active"));
48        links[index].classList.add("active");
49    }
50}
51
52changeNavState();
53window.addEventListener("scroll", changeNavState);
54
55/* Toggles animation class when cicrcle chart enters viewport */
56
57(function () {
58    var elements;
59    var windowHeight;
60
61    function init() {
62        elements = document.querySelectorAll(".bhc-circle");
63        windowHeight = window.innerHeight;
64    }
65
66    function checkPosition() {
67        for (var i = 0; i < elements.length; i++) {
68            var element = elements[i];
69            var positionFromTop = elements[i].getBoundingClientRect().top;
70
71            if (positionFromTop - windowHeight <= 0) {
72                element.classList.add("bhc-drawCircle");
73            }
74        }
75    }
76    window.addEventListener("scroll", checkPosition);
77    window.addEventListener("resize", init);
78
79    init();
80    checkPosition();
81})();
82
83// Corporate Home Solutions Container JS
84$(".toggle.-onHeading").click(function () {
85    $(".bhc-solution").addClass("-showNav");
86    $(".bhc-solutions__nav").addClass("-showNav");
87    $(".-onHeading").addClass("hide");
88    $(".homeModal").addClass("-showBackground");
89    $("#closeNav").addClass("show");
90});
91$("#closeNav").click(function () {
92    $(".bhc-solution").removeClass("-showNav");
93    $(".bhc-solutions__nav").removeClass("-showNav");
94    $(".-onHeading").removeClass("hide");
95    $(".homeModal").removeClass("-showBackground");
96    $("#closeNav").removeClass("show");
97});
98$('.bhc-icon-modal-close-x').click(function () {
99    $("#subnav-search-desktop-top").addClass("hide");
100});
101$('.nav-link-search').click(function () {
102    $("#subnav-search-desktop-top").removeClass("hide");
103});
104
105/* JS for Show and Hide Feature */
106const buttons = document.querySelectorAll(".js-btn-see-more");
107buttons.forEach(button => {
108    button.addEventListener("click", function () {
109        document.querySelectorAll(".hidden-see-more").forEach(el => {
110            el.classList.remove("hidden-see-more");
111        });
112        button.style.display = "none";
113    });
114});
115
116$("#meet-our-staff .js-btn-see-less").on("click", function () {
117    scrollToElement($("#meet-our-staff"));
118})
119function scrollToElement($element) {
120    $('html, body').animate({
121        scrollTop: $element.offset().top
122    }, 0);
123    return false;
124}
125
126const showMoreBtnDesktop = document.querySelector(".js-btn-see-more-desktop");
127const showLessBtnDesktop = document.querySelector(".js-btn-see-less-desktop");
128const showMoreBtnMobile = document.querySelector(".js-btn-see-more-mobile");
129const showLessBtnMobile = document.querySelector(".js-btn-see-less-mobile");
130const desktopTiles = document.querySelectorAll(".hidden-xs-corp .js-tile-see-more.tile-see-more");
131const mobileTiles = document.querySelectorAll(".visible-xs-block-corp .panel-teacher-wrap.tile-see-more");
132
133document.addEventListener("DOMContentLoaded", function () {
134    const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
135    const isBrowserStack = navigator.userAgent.includes('BrowserStack');
136    const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
137    const isIOSBrowser = isIOS || (isBrowserStack && isSafari);
138
139    console.log("Device detection:", {
140        userAgent: navigator.userAgent,
141        isIOS: isIOS,
142        isBrowserStack: isBrowserStack,
143        isSafari: isSafari,
144        isIOSBrowser: isIOSBrowser
145    });
146
147
148    // Function to hide desktop tiles beyond the first 3
149    function hideExtraDesktopTiles() {
150        for (let i = 0; i < desktopTiles.length; i++) {
151            if (i >= 3) {
152                desktopTiles[i].classList.add("hidden-see-more");
153                if (isIOSBrowser) {
154                    desktopTiles[i].style.display = "none !important";
155                }
156            } else {
157                desktopTiles[i].classList.remove("hidden-see-more");
158                if (isIOSBrowser) {
159                    desktopTiles[i].style.display = "block !important";
160                }
161            }
162        }
163    }
164
165    // Function to show all desktop tiles
166    function showAllDesktopTiles() {
167        for (let i = 0; i < desktopTiles.length; i++) {
168            desktopTiles[i].classList.remove("hidden-see-more");
169
170            //desktopTiles[i].setAttribute('tabindex', '0'); // Ensure it's focusable
171            //desktopTiles[i].focus();
172
173            if (isIOSBrowser) {
174                desktopTiles[i].style.display = "block !important";
175            }
176            // Focus on the heading within the 4th card for better accessibility
177            const headingElement = desktopTiles[3].querySelector("h3.txt-curriculum-wheel-title");
178            if (headingElement) {
179                headingElement.setAttribute('tabindex', '0');
180                headingElement.focus();
181            } else {
182                // Fallback to focusing on the card itself
183                desktopTiles[3].setAttribute('tabindex', '0');
184                desktopTiles[3].focus();
185            }
186
187        }
188    }
189    function hideExtraMobileTiles() {
190        for (let i = 0; i < mobileTiles.length; i++) {
191            if (i >= 3) {
192                mobileTiles[i].classList.add("hidden-see-more");
193                if (isIOSBrowser) {
194                    mobileTiles[i].style.display = "none !important";
195                }
196            } else {
197                mobileTiles[i].classList.remove("hidden-see-more");
198                if (isIOSBrowser) {
199                    mobileTiles[i].style.display = "block !important";
200                }
201            }
202
203        }
204    }
205
206    // Function to show all mobile tiles
207    function showAllMobileTiles() {
208        for (let i = 0; i < mobileTiles.length; i++) {
209            mobileTiles[i].classList.remove("hidden-see-more");
210            if (isIOSBrowser) {
211                mobileTiles[i].style.display = "block !important";
212            }
213            if (mobileTiles.length >= 4) {
214                // Try to focus on the heading within the 4th mobile card
215                const headingElement = mobileTiles[3].querySelector("h3.txt-curriculum-wheel-title");
216                if (headingElement) {
217                    headingElement.setAttribute('tabindex', '0');
218                    headingElement.focus();
219                } else {
220                    // Fallback to focusing on the card itself
221                    mobileTiles[3].setAttribute('tabindex', '0');
222                    mobileTiles[3].focus();
223                }
224            }
225
226        }
227    }
228
229    // Apply iOS-specific CSS fixes
230    function applyIOSFixes() {
231        // Add iOS-specific style overrides
232        const styleEl = document.createElement('style');
233        styleEl.innerHTML = `
234           /* @media (max-width: 480px) {*/
235           @media (max-width: 745px) {
236                .visible-xs-block-corp {
237                    display: block !important;
238                }
239                .hidden-xs-corp {
240                    display: none !important;
241                }
242                .visible-xs-block-corp .panel-teacher-wrap.tile-see-more.hidden-see-more {
243                    display: none !important;
244                }
245                .panel-teacher-wrap {
246                    background-color: white;
247                    margin-bottom: 10px;
248                    border-radius: 8px;
249                    width: 100%;
250                }
251                .panel-teacher-link {
252                    display: block;
253                    padding: 15px;
254                    position: relative;
255                }
256                .panel-teacher-link .arrow-rotating {
257                    transform: rotate(0deg) !important;
258                    transition: transform 0.3s;
259                }
260                .panel-teacher-link:not(.collapsed) .arrow-rotating {
261                    transform: rotate(90deg) !important;
262                }
263                .panel-teacher-content-expandable {
264                    transition: height 0.35s ease;
265                }
266                .panel-teacher-link.collapsed + .panel-teacher-content-expandable {
267                    height: 0 !important;
268                    display: none !important;
269                    overflow: hidden;
270                }
271               .teacher-accordion-group .tile-teacher-img-wrap
272                Specificity: (0,3,0)
273                    {
274                    margin: 0;
275                    padding: 0;
276                    }
277        .teacher-accordion-group .tile-teacher-img-wrap {
278        display: inline-block;
279        vertical-align: top;
280        background-size: cover;
281        background-position: 50%;
282        background-repeat: no-repeat;
283        width: 65px;
284        height: 57px;
285        overflow: hidden;
286    }
287         .tile-teacher-img-wrap {
288            width: 67px;
289            border-radius: 8px;
290        }
291
292        .teacher-accordion-group .txt-tile-description {
293        color: #4a4a4a;
294        line-height: 1.285;
295        padding-top: 14px;
296        padding-bottom: 10px;
297    }
298        .txt-rating-notes-sm {
299        font-size: 1.4rem;
300        line-height: 1.375;
301        letter-spacing: normal;
302    }
303        .btn.btn-large {
304        padding: 10px 30px;
305        border-radius: 5px;
306    }
307        .btn-hollow {
308        border: 2px solid #f2a900;
309        background-color: transparent;
310        color: #233956;
311    }
312        .btn-large {
313        font-size: 1.6rem;
314        line-height: 1.25;
315        letter-spacing: 0;
316    }
317
318    .teacher-accordion-group .profile-text-wrap {
319        display: inline-block;
320        color: #fff;
321        padding-left: 15px;
322    }
323    .teacher-accordion-group .txt-curriculum-wheel-title {
324        color: #231f20;
325        padding-bottom: 2px;
326    }
327     .teacher-accordion-group .txt-tile-subhead {
328        color: #5d5e60;
329    }
330      .learn-more-wrap {
331            margin-top: 32px;
332        }
333 .collapse.in {
334    display: block;
335    height:auto!important;
336   }
337       .btn.btn-large {
338        display: flex;
339        width: 343px;
340        justify-content: space-between;
341        height: 60p!importantx;
342        padding: 16px 28px!important;
343        justify-content: center!important;
344        align-items: center!important;
345        gap: 12px!important;
346        border-radius: 8px!important;
347border: 2px solid var(--yellow-500, #F0BD1B)!important;
348    }
349        .module-padding {
350            padding-bottom: 56px;
351            padding-top: 56px;
352        }
353
354            .teacher-accordion-group .arrow-rotating {
355        color: #5d5e60;
356        position: absolute;
357        right: 20px;
358        top: 35px;
359    }
360            .arrow-rotating {
361            font-size: 24px;
362        }
363        .btn-back-arrow:before, .faq-module .faq-nav-question-list li a:after, .footer-module .footer-breadcrumb-link+.footer-breadcrumb-link:before, .root-page-module .panel-center-link:after, .tag-enrolling:before, .tile-events .txt-tile-subhead:after, .tiles-module-slider-wrap .slick-arrow:before, [class*=" bh-icon-"], [class^=bh-icon-] {
364    speak: none;
365    font-style: normal;
366    font-weight: 400;
367    font-variant: normal;
368    text-transform: none;
369    line-height: 1;
370    -webkit-font-smoothing: antialiased;
371    -moz-osx-font-smoothing: grayscale;
372}     }
373        `;
374        document.head.appendChild(styleEl);
375
376        // Fix mobile visibility classes
377        if (window.innerWidth < 768) {
378            document.querySelectorAll('.visible-xs-block-corp').forEach(el => {
379                el.style.display = 'block !important';
380            });
381            document.querySelectorAll('.hidden-xs-corp').forEach(el => {
382                el.style.display = 'none !important';
383            });
384           
385        }
386
387        // Fix collapsed state and click behavior for accordion items
388        fixAccordions();
389    }
390
391    function fixAccordions() {
392        const accordionLinks = document.querySelectorAll('.panel-teacher-link');
393        accordionLinks.forEach(link => {
394            // Ensure initial state
395            if (!link.classList.contains('collapsed')) {
396                link.classList.add('collapsed');
397            }
398
399            // Get associated content panel
400            const targetId = link.getAttribute('href') || link.getAttribute('data-target');
401            if (targetId) {
402                const contentPanel = document.querySelector(targetId);
403                if (contentPanel) {
404                    contentPanel.classList.remove('in');
405                    contentPanel.style.height = '0px';
406                    contentPanel.style.display = 'none';
407                }
408            }
409
410            // Replace existing click handlers
411            link.removeEventListener('click', accordionClickHandler);
412            link.addEventListener('click', accordionClickHandler);
413        });
414    }
415
416    function accordionClickHandler(e) {
417        e.preventDefault();
418        e.stopPropagation();
419
420        const link = this;
421        const wasCollapsed = link.classList.contains('collapsed');
422        const targetId = link.getAttribute('href') || link.getAttribute('data-target');
423
424        if (targetId) {
425            const contentPanel = document.querySelector(targetId);
426
427            if (wasCollapsed) {
428                // Expanding
429                link.classList.remove('collapsed');
430                if (contentPanel) {
431                    contentPanel.classList.add('in');
432                    contentPanel.style.height = contentPanel.scrollHeight + 'px';
433                    contentPanel.style.display = 'block';
434                }
435            } else {
436                // Collapsing
437                link.classList.add('collapsed');
438                if (contentPanel) {
439                    contentPanel.classList.remove('in');
440                    contentPanel.style.height = '0px';
441                    setTimeout(function () {
442                        contentPanel.style.display = 'none';
443                    }, 350);
444                }
445            }
446        }
447        return false;
448    }
449
450    // Initial setup function
451    function initialSetup() {
452
453        // Apply iOS-specific fixes if needed
454        if (isIOSBrowser) {
455            applyIOSFixes();
456        }
457
458        // Set up desktop view
459        hideExtraDesktopTiles();
460        if (showMoreBtnDesktop && showLessBtnDesktop) {
461            showLessBtnDesktop.style.display = "none";
462            showMoreBtnDesktop.style.display = "inline-block";
463        }
464
465        // Set up mobile view
466        hideExtraMobileTiles();
467        if (showMoreBtnMobile && showLessBtnMobile) {
468            showLessBtnMobile.style.display = "none";
469            showMoreBtnMobile.style.display = "inline-block";
470        }
471    }
472
473    // Run initial setup
474    initialSetup();
475
476    // Configure desktop button click handlers
477    if (showMoreBtnDesktop && showLessBtnDesktop) {
478        showMoreBtnDesktop.addEventListener("click", function () {
479            showAllDesktopTiles();
480            showMoreBtnDesktop.style.display = "none";
481            showLessBtnDesktop.style.display = "inline-block";
482        });
483
484        showLessBtnDesktop.addEventListener("click", function () {
485            hideExtraDesktopTiles();
486            showLessBtnDesktop.style.display = "none";
487            showMoreBtnDesktop.style.display = "inline-block";
488        });
489    }
490
491    // Configure mobile button click handlers
492    if (showMoreBtnMobile && showLessBtnMobile) {
493        showMoreBtnMobile.addEventListener("click", function () {
494            showAllMobileTiles();
495            showMoreBtnMobile.style.display = "none";
496            showLessBtnMobile.style.display = "inline-block";
497        });
498
499        showLessBtnMobile.addEventListener("click", function () {
500            hideExtraMobileTiles();
501            showLessBtnMobile.style.display = "none";
502            showMoreBtnMobile.style.display = "inline-block";
503        });
504    }
505
506    // Fallback for mobile buttons
507    const fallbackMoreBtn = document.querySelector(".visible-xs-block-corp .js-btn-see-more");
508    const fallbackLessBtn = document.querySelector(".visible-xs-block-corp .js-btn-see-less");
509
510    if ((!showMoreBtnMobile || !showLessBtnMobile) && fallbackMoreBtn && fallbackLessBtn) {
511
512        fallbackLessBtn.style.display = "none";
513
514        fallbackMoreBtn.addEventListener("click", function () {
515            showAllMobileTiles();
516            fallbackMoreBtn.style.display = "none";
517            fallbackLessBtn.style.display = "inline-block";
518        });
519
520        fallbackLessBtn.addEventListener("click", function () {
521            hideExtraMobileTiles();
522            fallbackLessBtn.style.display = "none";
523            fallbackMoreBtn.style.display = "inline-block";
524        });
525    }
526
527    // Handle window resize events with improved iOS support
528    window.addEventListener("resize", function () {
529        const isMobileView = window.innerWidth < 768;
530
531        // Re-apply iOS fixes on resize
532        if (isIOSBrowser) {
533            // Ensure correct display based on viewport
534            if (isMobileView) {
535                document.querySelectorAll('.visible-xs-block-corp').forEach(el => {
536                    el.style.display = 'block !important';
537                });
538                document.querySelectorAll('.hidden-xs-corp').forEach(el => {
539                    el.style.display = 'none !important';
540                });
541
542                // Re-check mobile tiles
543                const allMobileVisible = Array.from(mobileTiles).every(tile =>
544                    !tile.classList.contains('hidden-see-more'));
545
546                if (showMoreBtnMobile && showLessBtnMobile) {
547                    showMoreBtnMobile.style.display = allMobileVisible ? "none" : "inline-block";
548                    showLessBtnMobile.style.display = allMobileVisible ? "inline-block" : "none";
549                }
550            } else {
551                // Desktop view
552                document.querySelectorAll('.visible-xs-block-corp').forEach(el => {
553                    el.style.display = 'none !important';
554                });
555                document.querySelectorAll('.hidden-xs-corp').forEach(el => {
556                    el.style.display = 'block !important';
557                });
558
559                // Re-check desktop tiles
560                const allDesktopVisible = Array.from(desktopTiles).every(tile =>
561                    !tile.classList.contains('hidden-see-more'));
562
563                if (showMoreBtnDesktop && showLessBtnDesktop) {
564                    showMoreBtnDesktop.style.display = allDesktopVisible ? "none" : "inline-block";
565                    showLessBtnDesktop.style.display = allDesktopVisible ? "inline-block" : "none";
566                }
567            }
568        }
569    });
570
571    // For iOS Safari, add a slight delay to make sure everything is properly rendered
572    if (isIOSBrowser) {
573        setTimeout(function () {
574            initialSetup();
575            if (window.innerWidth < 768) {
576                document.querySelectorAll('.visible-xs-block-corp').forEach(el => {
577                    el.style.display = 'block !important';
578                });
579                document.querySelectorAll('.hidden-xs-corp').forEach(el => {
580                    el.style.display = 'none !important';
581                });
582            }
583        }, 300);
584    }
585});
586
587
588// Configure desktop button click handlers
589if (showMoreBtnDesktop && showLessBtnDesktop) {
590    showMoreBtnDesktop.addEventListener("click", function () {
591        showAllDesktopTiles();
592        showMoreBtnDesktop.style.display = "none";
593        showLessBtnDesktop.style.display = "inline-block";
594    });
595
596    showLessBtnDesktop.addEventListener("click", function () {
597        hideExtraDesktopTiles(); // This function should keep first 3 visible
598        showLessBtnDesktop.style.display = "none";
599        showMoreBtnDesktop.style.display = "inline-block";
600    });
601}
602
603// Configure mobile button click handlers
604if (showMoreBtnMobile && showLessBtnMobile) {
605    showMoreBtnMobile.addEventListener("click", function () {
606        showAllMobileTiles();
607        showMoreBtnMobile.style.display = "none";
608        showLessBtnMobile.style.display = "inline-block";
609    });
610
611    showLessBtnMobile.addEventListener("click", function () {
612        hideExtraMobileTiles(); // This function should keep first 3 visible
613        showLessBtnMobile.style.display = "none";
614        showMoreBtnMobile.style.display = "inline-block";
615    });
616}
617
618/* ========================================================================
619 * Bootstrap: transition.js v3.3.5
620 * https://getbootstrap.com/javascript/#transitions
621 * ========================================================================
622 * Copyright 2011-2015 Twitter, Inc.
623 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
624 * ======================================================================== */
625
626
627+
628
629    function ($) {
630        'use strict';
631
632        // CSS TRANSITION SUPPORT (Shoutout: https://www.modernizr.com/)
633        // ============================================================
634
635        function transitionEnd() {
636            var el = document.createElement('bootstrap')
637
638            var transEndEventNames = {
639                WebkitTransition: 'webkitTransitionEnd',
640                MozTransition: 'transitionend',
641                OTransition: 'oTransitionEnd otransitionend',
642                transition: 'transitionend'
643            }
644
645            for (var name in transEndEventNames) {
646                if (el.style[name] !== undefined) {
647                    return { end: transEndEventNames[name] }
648                }
649            }
650
651            return false // explicit for ie8 (  ._.)
652        }
653
654        // http://blog.alexmaccaw.com/css-transitions
655        $.fn.emulateTransitionEnd = function (duration) {
656            var called = false
657            var $el = this
658            $(this).one('bsTransitionEnd', function () { called = true })
659            var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
660            setTimeout(callback, duration)
661            return this
662        }
663
664        $(function () {
665            $.support.transition = transitionEnd()
666
667            if (!$.support.transition) return
668
669            $.event.special.bsTransitionEnd = {
670                bindType: $.support.transition.end,
671                delegateType: $.support.transition.end,
672                handle: function (e) {
673                    if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
674                }
675            }
676        })
677    }(jQuery);
678
679// Disables Spacebar scrolling for Solutions nav jumpLinks, 
680
681$('.bhc-solutions__jumpLink').on('keydown', function (e) {
682    return !(e.keyCode == 32);
683});         
684
685$(document).ready(function () {
686    // Global state for video tracking across all videos
687    var videoTrackingState = {};
688    var currentActiveVideo = null;
689
690    // Create the missing trackVideoEvent function
691    function trackVideoEvent(provider, videoUrl, linkText) {
692        // Initialize dataLayer if it doesn't exist
693        window.dataLayer = window.dataLayer || [];
694        
695        // Push video_start event to dataLayer
696        window.dataLayer.push({
697            event: 'video_start',
698            video_provider: provider,
699            video_url: videoUrl,
700            link_text: linkText || ''
701        });
702    }
703
704    // Make trackVideoEvent globally available
705    window.trackVideoEvent = trackVideoEvent;
706
707    // Initialize tracking for all videos on the page
708    function initializeAllVideoTracking() {
709        // Clear existing state
710        videoTrackingState = {};
711        
712        // Find all video containers - improved selector
713        var $videoContainers = $(".videoContent__iframe, .embed-responsive, .video-container, [class*='video']").filter(function() {
714            return $(this).find('iframe').length > 0 || $(this).is('iframe');
715        });
716
717        $videoContainers.each(function(index) {
718            var $videoContainer = $(this);
719            var $iframe = $videoContainer.find('iframe').first();
720            
721            // If this element is an iframe itself, use it
722            if ($videoContainer.is('iframe')) {
723                $iframe = $videoContainer;
724                $videoContainer = $videoContainer.parent();
725            }
726            
727            if ($iframe.length === 0) {
728                return;
729            }
730
731            var trackingVal = $videoContainer.data("tracking-cta");
732            var trackingArr = trackingVal ? trackingVal.split(",") : null;
733            var linkText = trackingArr && trackingArr[0] ? trackingArr[0] : "Video";
734            var linkSection = trackingArr && trackingArr[2] ? trackingArr[2] : "body";
735            var videourl = $iframe.attr("src");
736            var provider = "unknown";
737            
738            if (videourl) {
739                try {
740                    var urlObj = new URL(videourl);
741                    provider = urlObj.hostname.replace('www.', '');
742                } catch(e) {
743                    provider = 'unknown';
744                }
745            }
746
747            // Get unique identifier for this video container
748            var videoId = $videoContainer.attr('id') || 
749                         $videoContainer.closest('[id]').attr('id') || 
750                         'video-' + index + '-' + Math.random().toString(36).substr(2, 5);
751
752            // Store tracking data for this video
753            videoTrackingState[videoId] = {
754                element: $videoContainer,
755                iframe: $iframe,
756                trackingVal: trackingVal,
757                trackingArr: trackingArr,
758                linkText: linkText,
759                linkSection: linkSection,
760                videourl: videourl,
761                provider: provider,
762                overIframe: false,
763                isFirstClick: true
764            };
765        });
766    }
767
768    // Get the currently active video (visible/active one)
769    function getCurrentActiveVideo() {
770        // Check for video containers that are active/visible
771        var $activeContainer = $('.videoContainer .container.-active, .videoContainer .container[aria-hidden="false"]').first();
772        if ($activeContainer.length > 0) {
773            var activeId = $activeContainer.attr('id');
774            return videoTrackingState[activeId] || null;
775        }
776        
777        // Fallback to first video if no active one found
778        var firstVideoId = Object.keys(videoTrackingState)[0];
779        return firstVideoId ? videoTrackingState[firstVideoId] : null;
780    }
781
782    // Setup pointer tracking for all video iframes
783    function setupPointerTracking() {
784        Object.keys(videoTrackingState).forEach(function(videoId) {
785            var videoState = videoTrackingState[videoId];
786            
787            // Remove any existing handlers
788            videoState.element.off('mouseover.videotrack mouseout.videotrack click.videotrack');
789            videoState.iframe.off('mouseover.videotrack mouseout.videotrack');
790            
791            // Add hover tracking to container
792            videoState.element.on("mouseover.videotrack", function () {
793                // Reset all other video states
794                Object.keys(videoTrackingState).forEach(function(id) {
795                    videoTrackingState[id].overIframe = false;
796                });
797                
798                // Set current video as active
799                videoState.overIframe = true;
800                currentActiveVideo = videoState;
801            }).on("mouseout.videotrack", function () {
802                videoState.overIframe = false;
803                if (currentActiveVideo === videoState) {
804                    currentActiveVideo = null;
805                }
806            });
807
808            // Add direct click tracking as fallback
809            videoState.element.on("click.videotrack", function(e) {
810                // Check if click is on or near iframe
811                var $target = $(e.target);
812                if ($target.is('iframe') || $target.closest('.embed-responsive').length > 0 || 
813                    $target.closest('.videoContent__iframe').length > 0) {
814                    
815                    // Fire video_start event immediately
816                    trackVideoEvent(videoState.provider, videoState.videourl, videoState.linkText);
817                    
818                    // Mark as not first click for blur tracking
819                    videoState.isFirstClick = false;
820                }
821            });
822            
823            // Also add hover tracking to iframe itself
824            videoState.iframe.on("mouseover.videotrack", function () {
825                videoState.overIframe = true;
826                currentActiveVideo = videoState;
827            });
828        });
829    }
830
831    // Detect click via window blur while cursor is over any iframe
832    $(window).off('blur.videotrack').on("blur.videotrack", function () {
833        // Check if we have an active video under cursor
834        var activeVideo = currentActiveVideo || getCurrentActiveVideo();
835        
836        if (!activeVideo || !activeVideo.overIframe) {
837            return;
838        }
839
840        // Fire video_start event
841        trackVideoEvent(activeVideo.provider, activeVideo.videourl, activeVideo.linkText);
842
843        // Mark as not first click
844        if (activeVideo.isFirstClick) {
845            activeVideo.isFirstClick = false;
846        }
847    });
848
849    // Reinitialize when videos change (for carousel functionality)
850    function reinitializeVideoTracking() {
851        initializeAllVideoTracking();
852        setupPointerTracking();
853    }
854
855    // Watch for DOM changes to handle dynamically loaded videos
856    var observer = new MutationObserver(function(mutations) {
857        var shouldReinit = false;
858        mutations.forEach(function(mutation) {
859            if (mutation.type === 'attributes' || mutation.type === 'childList') {
860                // Check if video containers were added/modified
861                if ($(mutation.target).find('iframe').length > 0 ||
862                    $(mutation.target).is('iframe') ||
863                    $(mutation.target).hasClass('videoContent__iframe') ||
864                    $(mutation.target).hasClass('embed-responsive')) {
865                    shouldReinit = true;
866                }
867            }
868        });
869        
870        if (shouldReinit) {
871            setTimeout(reinitializeVideoTracking, 500);
872        }
873    });
874
875    // Observe the document body for changes
876    var observeTarget = $('.videoContainer')[0] || document.body;
877    observer.observe(observeTarget, {
878        childList: true,
879        subtree: true,
880        attributes: true,
881        attributeFilter: ['aria-hidden', 'class', 'src']
882    });
883
884    // Initialize everything
885    setTimeout(function() {
886        initializeAllVideoTracking();
887        setupPointerTracking();
888    }, 100);
889
890    // Periodic reinitialization to catch any missed videos
891    setInterval(function() {
892        var currentVideoCount = Object.keys(videoTrackingState).length;
893        var actualVideoCount = $('iframe').filter(function() {
894            var src = $(this).attr('src');
895            return src && (src.includes('youtube') || src.includes('vimeo') || src.includes('wistia') || src.includes('brightcove'));
896        }).length;
897        
898        if (currentVideoCount !== actualVideoCount && actualVideoCount > 0) {
899            reinitializeVideoTracking();
900        }
901    }, 3000);
902
903    // Add additional fallback - track any iframe clicks
904    $(document).on('click', 'iframe, .embed-responsive, .videoContent__iframe', function(e) {
905        var $iframe = $(this).is('iframe') ? $(this) : $(this).find('iframe').first();
906        if ($iframe.length > 0) {
907            var src = $iframe.attr('src');
908            if (src && (src.includes('youtube') || src.includes('vimeo') || src.includes('wistia') || src.includes('brightcove'))) {
909                var provider = 'unknown';
910                try {
911                    provider = new URL(src).hostname.replace('www.', '');
912                } catch(e) {
913                    provider = 'unknown';
914                }
915                
916                trackVideoEvent(provider, src, 'Video');
917            }
918        }
919    });
920
921    // Clean up on page unload
922    $(window).on('beforeunload', function() {
923        $(window).off('blur.videotrack');
924        Object.keys(videoTrackingState).forEach(function(videoId) {
925            var videoState = videoTrackingState[videoId];
926            videoState.element.off('mouseover.videotrack mouseout.videotrack click.videotrack');
927            videoState.iframe.off('mouseover.videotrack mouseout.videotrack');
928        });
929    });
930
931    // Debug function to check current state
932    window.debugVideoTracking = function() {
933        return {
934            trackedVideos: Object.keys(videoTrackingState).length,
935            currentActiveVideo: currentActiveVideo,
936            videoTrackingState: videoTrackingState
937        };
938    };
939
940    // Infinitely loop awards logos marquee
941    const root = document.documentElement;
942    const marqueeElementsDisplayed = getComputedStyle(root).getPropertyValue(
943        "--marquee-elements-displayed"
944    );
945    const marqueeContent = document.querySelector("ul.bhc-awardsMarquee__content");
946
947    if (marqueeContent) {
948        root.style.setProperty("--marquee-elements", marqueeContent.children.length);
949
950
951        for (let i = 0; i < marqueeElementsDisplayed; i++) {
952            marqueeContent.appendChild(marqueeContent.children[i].cloneNode(true));
953        }
954    }
955});

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.