PageSourceSearch

https://www.mea.gov.in/Javascript/general.js

js mea.gov.in collected 2026-09-24 08:39:29 UTC 76,730 bytes, 2,272 lines download raw bytes

1// ============================================================
2// SWIPER REGISTRY — central store for all Swiper instances
3// ============================================================
4
5const swiperRegistry = {};
6
7function registerSwiper(name, instance) {
8    if (instance) swiperRegistry[name] = instance;
9}
10
11function toggleSwiper(instance, action) {
12    if (!instance) return;
13    if (action === 'stop') {
14        instance.autoplay.stop();
15    } else {
16        instance.autoplay.start();
17    }
18}
19
20function bindSwiperPlayPauseButton(swiperInstance, buttonSelector, labels) {
21    const btn = document.querySelector(buttonSelector);
22    if (!btn || !swiperInstance || !swiperInstance.autoplay) return;
23
24    let isPaused = false;
25    const textNode = Array.from(btn.childNodes).find(n => n.nodeType === 3 && n.textContent.trim() !== '');
26
27    function updateButtonState() {
28        const label = isPaused ? labels.play : labels.pause;
29        btn.classList.toggle('play', isPaused);
30        btn.title = label;
31        btn.setAttribute('aria-label', label);
32        if (textNode) textNode.textContent = ' ' + label;
33    }
34
35    btn.addEventListener('click', function () {
36        isPaused = !isPaused;
37        if (isPaused) {
38            swiperInstance.autoplay.stop();
39        } else {
40            swiperInstance.autoplay.start();
41        }
42        updateButtonState();
43    });
44
45    updateButtonState();
46}
47
48// ============================================================
49// DOCUMENT READY
50// ============================================================
51$(document).ready(function () {
52
53    // ----------------------------------------------------------
54    // Advanced Search Toggle
55    // ----------------------------------------------------------
56    $('.advanced-search-toggle-btn').on('click', function () {
57        $(this).toggleClass('active');
58        $('.advance-search-toggle-wrap').slideToggle(400);
59    });
60
61    // ----------------------------------------------------------
62    // Multiselect Dropdown — checkbox selection
63    // ----------------------------------------------------------
64    $('.multiselect-option input[type="checkbox"]').on('change', function () {
65        updateMultiselectText($(this).closest('.multiselect-dropdown'));
66    });
67
68    $(document).on('click', '.multiselect-button', function (e) {
69        e.stopPropagation();
70        var current = $(this).closest('.multiselect-dropdown');
71        $('.multiselect-dropdown').not(current).each(function () {
72            $(this).removeClass('active');
73            resetMultiselectSearch($(this));
74        });
75        current.toggleClass('active');
76        if (!current.hasClass('active')) {
77            resetMultiselectSearch(current);
78        } else {
79            setTimeout(function () {
80                current.find('.multiselect-search').focus();
81            }, 50);
82        }
83    });
84
85    $(document).on('click', '.multiselect-options', function (e) {
86        e.stopPropagation();
87    });
88
89    $(document).on('click', '.multiselect-group-title', function (e) {
90        e.stopPropagation();
91        $(this).toggleClass('active');
92        $(this).next('.multiselect-group-children').toggleClass('open');
93    });
94
95    function resetMultiselectSearch(dropdown) {
96        if (dropdown.closest('#TagDropdown').length > 0) return;
97        dropdown.find('.multiselect-search').val('');
98        dropdown.find('.multiselect-option').show();
99        dropdown.find('.multiselect-group').show();
100        dropdown.find('.multiselect-group-children').removeClass('open').hide();
101    }
102
103    $(document).on('click', function (e) {
104        $('.multiselect-dropdown').each(function () {
105            if (!$(e.target).closest(this).length) {
106                $(this).removeClass('active');
107                resetMultiselectSearch($(this));
108            }
109        });
110    });
111
112    let searchTimeout;
113    $(document).on('keyup', '.multiselect-search', function () {
114        clearTimeout(searchTimeout);
115        const $input = $(this);
116        searchTimeout = setTimeout(function () {
117            var term = $input.val().toLowerCase();
118            var dropdown = $input.closest('.multiselect-dropdown');
119            if (dropdown.closest('#TagDropdown').length > 0) return;
120            var hasGroups = dropdown.find('.multiselect-group').length > 0;
121            if (term.length === 0 && hasGroups) {
122                dropdown.find('.multiselect-group').show();
123                dropdown.find('.multiselect-group-children').removeClass('open').hide();
124                return;
125            }
126            if (hasGroups && term.length < 2) return;
127            dropdown.find('> .multiselect-options > .multiselect-option').each(function () {
128                var text = $(this).text().toLowerCase();
129                $(this).toggle(text.indexOf(term) > -1);
130            });
131            dropdown.find('.multiselect-group').each(function () {
132                var group = $(this);
133                var anyVisible = false;
134                group.find('.multiselect-option').each(function () {
135                    var text = $(this).text().toLowerCase();
136                    var match = text.indexOf(term) > -1;
137                    $(this).toggle(match);
138                    if (match) anyVisible = true;
139                });
140                group.toggle(anyVisible);
141                if (term.length > 0 && anyVisible) {
142                    group.find('.multiselect-group-children').addClass('open').show();
143                }
144            });
145        }, 250);
146    });
147
148    function updateMultiselectText(dropdown) {
149        const selected = [];
150        dropdown.find('input[type="checkbox"]:checked').each(function () {
151            selected.push($(this).val());
152        });
153        const button = dropdown.find('.multiselect-selected-text');
154        if (selected.length === 0) {
155            button.text('Select Sections');
156        } else if (selected.length === 1) {
157            button.text(selected[0]);
158        } else {
159            button.text(selected.length + ' sections selected');
160        }
161    }
162
163    // ----------------------------------------------------------
164    // Mobile Search Toggle (max-width: 767px)
165    // ----------------------------------------------------------
166    if ($(window).width() <= 767) {
167        if (!$('.searchToggleIcon').length) {
168            $('.headerRight .searchBox').after('<div class="searchToggleIcon d-block d-md-none"><img src="images/search.svg" alt="Search" title="Toggle Search" /></div>');
169        }
170        $('.searchToggleIcon').on('click', function (e) {
171            e.stopPropagation();
172            $('.headerRight .searchBox').toggleClass('active');
173        });
174        $(document).on('click', function (e) {
175            if (!$(e.target).closest('.headerRight .searchBox, .searchToggleIcon').length) {
176                $('.headerRight .searchBox').removeClass('active');
177            }
178        });
179    }
180
181    // ----------------------------------------------------------
182    // Marquee  (renamed isPaused → isMarqueePaused to avoid conflict)
183    // ----------------------------------------------------------
184    let isMarqueePaused = false;
185
186    if ($('ul.home-marquee').length) {
187        $('ul.home-marquee').hover(
188            function () {
189                if (!isMarqueePaused) $('ul.home-marquee').addClass('MarqueePause');
190            },
191            function () {
192                if (!isMarqueePaused) $('ul.home-marquee').removeClass('MarqueePause');
193            }
194        );
195    }
196
197    $('.home-marquee-play-pause').click(function () {
198        isMarqueePaused = !isMarqueePaused;
199        if (isMarqueePaused) {
200            $('ul.home-marquee').addClass('MarqueePause');
201            $(this).addClass('Play');
202        } else {
203            $('ul.home-marquee').removeClass('MarqueePause');
204            $(this).removeClass('Play');
205        }
206    });
207
208    // ----------------------------------------------------------
209    // Sticky Header
210    // ----------------------------------------------------------
211    if ($('header').length) {
212        $(window).on('scroll', function () {
213            if ($(this).scrollTop() > 50) {
214                $('header').addClass('stickyHeader');
215            } else {
216                $('header').removeClass('stickyHeader');
217            }
218        });
219    }
220
221    // ----------------------------------------------------------
222    // Focused Country Swiper
223    // ----------------------------------------------------------
224    if ($('.focusedCountryInner').length) {
225        const focusedSwiper = new Swiper('.focusedCountrySwiper', {
226            loop: true,
227            speed: 1000,
228            autoplay: { delay: 3000, disableOnInteraction: false },
229            // effect: 'fade',
230            // fadeEffect: { crossFade: true },
231            spaceBetween: 20,
232            pagination: { el: '.focusedCountryPagination', clickable: true },
233            observer: true,
234            observeParents: true,
235        });
236        registerSwiper('focusedCountrySwiper', focusedSwiper);
237
238        const focusedSwiper2 = new Swiper('.focusedCountrySwiper2', {
239            loop: true,
240            speed: 1000,
241            //autoplay: { delay: 3000, disableOnInteraction: false },
242            // effect: 'fade',
243            // fadeEffect: { crossFade: true },
244            spaceBetween: 20,
245            pagination: { el: '.focusedCountryPagination2', clickable: true },
246            observer: true,
247            observeParents: true,
248        });
249        registerSwiper('focusedCountrySwiper2', focusedSwiper2);
250
251        $('button[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) {
252            const targetTab = $(e.target).attr('data-bs-target');
253            if (targetTab === '#Focused-tab-pane') focusedSwiper.update(
253);
254            else if (targetTab === '#IndiaInitiatives-tab-pane') focusedSwiper2.update();
255        });
256        setTimeout(() => {
257            focusedSwiper.update();
258            focusedSwiper.autoplay.start();
259        }, 200);
260    }
261
262    // ----------------------------------------------------------
263    // Fancybox
264    // ----------------------------------------------------------
265    Fancybox.bind('[data-fancybox]', {
266        Carousel: { Video: { autoplay: false } },
267    });
268
269    // ----------------------------------------------------------
270    // Banner Slider Swiper
271    // ----------------------------------------------------------
272    if ($('.bannerSwiper').length) {
273    const bannerSwiper = new Swiper('.bannerSwiper', {
274        slidesPerView: 1,
275        spaceBetween: 25,
276        loop: true,
277        watchOverflow: true,
278        autoplay: { delay: 4000, disableOnInteraction: false, pauseOnMouseEnter: true },
279        speed: 800,
280        navigation: {
281            nextEl: '.banner-slider-button-next',
282            prevEl: '.banner-slider-button-prev',
283        },
284        breakpoints: {
285            640: { slidesPerView: 2 },
286            992: { slidesPerView: 3 },
287        }
288    });
289 
290    const el = document.querySelector('.bannerSwiper');
291    const bannerBtn = document.querySelector('.bannerPlayPauseBtn');
292    if (el) {
293        el.addEventListener('mouseenter', function () {
294            bannerSwiper.autoplay.stop();
295        });
296
297        el.addEventListener('mouseleave', function () {
298            const isPausedByButton = bannerBtn && bannerBtn.classList.contains('play');
299            if (!isPausedByButton) {
300                bannerSwiper.autoplay.start();
301            }
302        });
303    }
304 
305    registerSwiper('bannerSwiper', bannerSwiper);
306
307    bindSwiperPlayPauseButton(bannerSwiper, '.bannerPlayPauseBtn', {
308        play: 'Play Banner Slider',
309        pause: 'Pause Banner Slider',
310    });
311}
312    // ----------------------------------------------------------
313    // Logo Swiper in Footer
314    // ≤600px  → normal discrete swiper (touch-friendly, delay 3000)
315    // >600px  → continuous freemode belt (delay 0, no touch)
316    // ----------------------------------------------------------
317    if ($('.logoSection').length) {
318        let logoManuallyPaused = false;
319        let isHovered = false;
320        let logoSwiperInst = null;
321        let logoCurrentMode = null;
322
323        function initLogoSwiper() {
324            const isMobile = window.innerWidth <= 600;
325            const newMode = isMobile ? 'mobile' : 'desktop';
326
327            // Nothing to do if mode hasn't changed
328            if (logoSwiperInst && logoCurrentMode === newMode) return;
329
330            // Tear down existing instance
331            if (logoSwiperInst) {
332                logoSwiperInst.destroy(true, true);
333                logoSwiperInst = null;
334            }
335
336            logoCurrentMode = newMode;
337
338            if (isMobile) {
339                // ── MOBILE: normal step-by-step swiper ──
340                logoSwiperInst = new Swiper('.logoSwiper', {
341                    slidesPerView: 2,
342                    spaceBetween: 20,
343                    loop: true,
344                    speed: 600,
345                    autoplay: { delay: 3000, disableOnInteraction: false },
346                    breakpoints: {
347                        432: { slidesPerView: 3, spaceBetween: 20 },
348                    },
349                });
350            } else {
351                // ── DESKTOP: continuous freemode belt ──
352                logoSwiperInst = new Swiper('.logoSwiper', {
353                    slidesPerView: 6,
354                    spaceBetween: 40,
355                    loop: true,
356                    speed: 3000,
357                    autoplay: {
358                        delay: 0,
359                        disableOnInteraction: false,
360                        pauseOnMouseEnter: false,
361                    },
362                    freeMode: { enabled: true, momentum: false },
363                    allowTouchMove: false,
364                    simulateTouch: false,
365                    breakpoints: {
366                        640: { slidesPerView: 4, spaceBetween: 20 },
367                        768: { slidesPerView: 5, spaceBetween: 30 },
368                        992: { slidesPerView: 5, spaceBetween: 40 },
369                        1200: { slidesPerView: 6, spaceBetween: 40 },
370                    },
371                    on: {
372                        autoplayStop: function () {
373                            if (!logoManuallyPaused && !isHovered) {
374                                setTimeout(() => {
375                                    if (this.autoplay && typeof this.autoplay.start === 'function') {
376                                        this.autoplay.start();
377                                    }
378                                }, 0);
379                            }
380                        },
381                    },
382                });
383            }
384
385            registerSwiper('logoSwiper', logoSwiperInst);
386            window.logoSwiperRef = logoSwiperInst;
387        }
388
389        initLogoSwiper();
390
391        // Reinitialise when crossing the 600px boundary
392        let logoResizeTimer;
393        window.addEventListener('resize', function () {
394            clearTimeout(logoResizeTimer);
395            logoResizeTimer = setTimeout(initLogoSwiper, 150);
396        });
397
398        // Tab visibility resume
399        document.addEventListener('visibilitychange', function () {
400            if (!document.hidden && !logoManuallyPaused && !isHovered) {
401                if (logoSwiperInst && logoSwiperInst.autoplay && !logoSwiperInst.autoplay.running) {
402                    logoSwiperInst.autoplay.start();
403                }
404            }
405        });
406
407        // Hover: stop/start on desktop only
408        const swiperEl = document.querySelector('.logoSwiper');
409        if (swiperEl) {
410            swiperEl.addEventListener('mouseenter', function () {
411                if (window.innerWidth <= 600) return;
412                isHovered = true;
413                if (logoSwiperInst && logoSwiperInst.autoplay) logoSwiperInst.autoplay.stop();
414            });
415
416            swiperEl.addEventListener('mouseleave', function () {
417                if (window.innerWidth <= 600) return;
418                isHovered = false;
419                if (!logoManuallyPaused && logoSwiperInst && logoSwiperInst.autoplay) {
420                    logoSwiperInst.autoplay.start();
421                }
422            });
423        }
424
425        // Expose pause/play for the global accessibility button
426        window.setLogoManuallyPaused = function (val) {
427            logoManuallyPaused = val;
428            if (!logoSwiperInst) return;
429            if (!val && !isHovered) {
430                logoSwiperInst.autoplay.start();
431            } else if (val) {
432                logoSwiperInst.autoplay.stop();
433            }
434        };
435		
436		//New Added For Play Pause
437		const logoBtn = document.querySelector('.logoPlayPauseBtn');
438		if (logoBtn) {
439			const textNode = Array.from(logoBtn.childNodes).find(n => n.nodeType === 3 && n.textContent.trim() !== '');
440			logoBtn.addEventListener('click', function () {
441			logoManuallyPaused = !logoManuallyPaused;
442			window.setLogoManuallyPaused(logoManuallyPaused);
443 
444			const label = logoManuallyPaused ? 'Play Logo Slider' : 'Pause Logo Slider';
445			logoBtn.classList.toggle('play', logoManuallyPaused);
446			logoBtn.title = label;
447			logoBtn.setAttribute('aria-label', label);
448			if (textNode) textNode.textContent = ' ' + label;
449			});
450		}
451    }
452	
453	
454
455    // ----------------------------------------------------------
456    // Back to Top Button
457    // ----------------------------------------------------------
458    const backToTopButton = document.getElementById('backToTop');
459    if (backToTopButton) {
460        window.addEventListener('scroll', function () {
461            if (window.pageYOffset > 300) {
462                backToTopButton.classList.add('show');
463            } else {
464                backToTopButton.classList.remove('show');
465            }
466        });
467        backToTopButton.addEventListener('click', function (e) {
468            e.preventDefault();
469            window.scrollTo({ top: 0, behavior: 'smooth' });
470        });
471    }
472
473    // ----------------------------------------------------------
474    // Dynamic Sidebar Height
475    // ----------------------------------------------------------
476    function setSidebarHeight() {
477        if ($(window).width() >= 1200) {
478            const viewportHeight = $(window).height();
479            const header = $('header');
480            if (header.length && $('.sideBar').length) {
481                const headerHeight = header.outerHeight();
482                const bottomSpacing = 20;
483                const availableHeight = viewportHeight - headerHeight - bottomSpacing;
484                $('.sideBar').css({ 'max-height': availableHeight + 'px' });
485            }
486        } else {
487            $('.sideBar').css('max-height', '');
488        }
489    }
490
491    setSidebarHeight();
492    $(window).on('resize', function () { setSidebarHeight(); });
493    $(window).on('scroll', function () {
494        if ($(window).width() >= 1200) setSidebarHeight();
495    });
496
497
498
499    // ----------------------------------------------------------
500    // Incoming Visit Swiper
501    // ----------------------------------------------------------
502    if ($('.incomingVisitSwiper').length) {
503        const incomingVisitSwiper = new Swiper('.incomingVisitSwiper', {
504            slidesPerView: 1,
505            spaceBetween: 25,
506            autoplay: { delay: 4000, disableOnInteraction: false },
507            speed: 800,
508            navigation: {
509                nextEl: '.incomingSwiper-next',
510                prevEl: '.incomingSwiper-prev',
511            },
512            breakpoints: {
513                480: { slidesPerView: 1, spaceBetween: 25 },
514                640: { slidesPerView: 2, spaceBetween: 25 },
515                992: { slidesPerView: 3, spaceBetween: 25 },
516                1280: { slidesPerView: 3, spaceBetween: 25 },
517            }
518        });
519        registerSwiper('incomingVisitSwiper', incomingVisitSwiper);
520    }
521
522    // ----------------------------------------------------------
523    // Outgoing Visit Swiper
524    // ----------------------------------------------------------
525    if ($('.outgoingVisitSwiper').length) {
526        const outgoingVisitSwiper = new Swiper('.outgoingVisitSwiper', {
527            slidesPerView: 1,
528            spaceBetween: 25,
529            autoplay: { delay: 4000, disableOnInteraction: false },
530            speed: 800,
531            navigation: {
532                nextEl: '.outgoingSwiper-next',
533                prevEl: '.outgoingSwiper-prev',
534            },
535            breakpoints: {
536                480: { slidesPerView: 1, spaceBetween: 25 },
537                640: { slidesPerView: 2, spaceBetween: 25 },
538                992: { slidesPerView: 3, spaceBetween: 25 },
539                1280: { slidesPerView: 3, spaceBetween: 25 },
540            }
541        });
542        registerSwiper('outgoingVisitSwiper', outgoingVisitSwiper);
543    }
544
545    // ----------------------------------------------------------
546    // Incoming/Outgoing nav visibility toggle
547    // ----------------------------------------------------------
548    if ($('#incomingVisitTab').length) {
549        $('#incomingVisitTab button[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) {
550            var target = $(e.target).attr('data-bs-target');
551            if (target === '#incomingVisit-tab-pane') {
552                $('.incomingNav').css('display', 'flex');
553                $('.outgoingNav').css('display', 'none');
554            } else if (target === '#outgoingVisit-tab-pane') {
555                $('.incomingNav').css('display', 'none');
556                $('.outgoingNav').css('display', 'flex');
557            }
558        });
559    }
560
561    // ----------------------------------------------------------
562    // Focus Country List Toggle
563    // ----------------------------------------------------------
564    if ($('.focusCountryList').length) {
565        $('.focusCountryInner').on('click', function (e) {
566            e.stopPropagation();
567            $('.focusCountryList').toggleClass('focusCountryListActive');
568        });
569        $('body').on('click', function (e) {
570            if (!$(e.target).closest('.focusCountryList').length) {
571                $('.focusCountryList').removeClass('focusCountryListActive');
572            }
573        });
574    }
575
576    // ----------------------------------------------------------
577    // Video Swiper
578    // ----------------------------------------------------------
579    if ($('.videoSwiper').length) {
580        const videoSwiper = new Swiper('.videoSwiper', {
581            slidesPerView: 3,
582            spaceBetween: 60,
583            navigation: {
584                nextEl: '.video-briefing-next',
585                prevEl: '.video-briefing-prev',
586            },
587            breakpoints: {
588                320: { slidesPerView: 1, spaceBetween: 20 },
589                600: { slidesPerView: 2, spaceBetween: 40 },
590                991: { slidesPerView: 3, spaceBetween: 60 },
591            },
592        });
593        // No autoplay on videoSwiper — no need to register
594    }
595
596    // ----------------------------------------------------------
597    // Sidebar active link toggle
598    // ----------------------------------------------------------
599    if ($('.sideBar').length) {
600        $('.sideBar ul li a').on('click', function () {
601            $('.sideBar ul li a').removeClass('active');
602            $(this).addClass('active');
603        });
604    }
605
606    // ----------------------------------------------------------
607    // Date Range Picker
608    // ----------------------------------------------------------
609    if ($('input[name="daterange"]').length) {
610        var financialYearStartMonth = 4;
611        var today = moment();
612        var financialYearStart = moment().startOf('year').month(financialYearStartMonth - 1);
613        if (today.month() < financialYearStartMonth - 1) financialYearStart.subtract(1, 'year');
614        var financialYearEnd = financialYearStart.clone().add(1, 'year').subtract(1, 'days');
615
616        $('input[name="daterange"]').daterangepicker({
617            autoUpdateInput: false,
618            alwaysShowCalendars: true,
619            opens: 'left',
620            autoApply: false,
621            showDropdowns: true,
622            minYear: 1990,
623            maxYear: 2050,
624            ranges: {
625                'Today': [moment(), moment()],
626                'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
627                'Last 7 Days': [moment().subtract(6, 'days'), moment()],
628                'Last 30 Days': [moment().subtract(29, 'days'), moment()],
629                'This Month': [moment().startOf('month'), moment().endOf('month')],
630                'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
631                'This Year': [financialYearStart, financialYearEnd],
632                'Last Year': [financialYearStart.clone().subtract(1, 'year'), financialYearEnd.clone().subtract(1, 'year')],
633            },
634            locale: { format: 'DD/MM/YYYY', cancelLabel: 'Clear' }
635        });
636
637        $('input[name="daterange"]').on('apply.daterangepicker', function (ev, picker) {
638            $(this).val(picker.startDate.format('DD/MM/YYYY') + ' - ' + picker.endDate.format('DD/MM/YYYY'));
639        });
640        $('input[name="daterange"]').on('cancel.daterangepicker', function () {
641            $(this).val('');
642        });
643    }
644
645    // ----------------------------------------------------------
646    // Single Date Picker — Date of Birth (.singledatePicker)
647    // ----------------------------------------------------------
648    if ($('.singledatePicker').length) {
649        $('.singledatePicker').daterangepicker({
650            singleDatePicker: true,
651            autoUpdateInput: false,
652            showDropdowns: true,
653            autoApply: false,
654            opens: 'right',
655            maxDate: moment(),
656            minYear: 1900,
657            maxYear: parseInt(moment().format('YYYY'), 10),
658            locale: { format: 'DD/MM/YYYY', cancelLabel: 'Clear' }
659        });
660
661        $('.singledatePicker').on('apply.daterangepicker', function (ev, picker) {
662            $(this).val(picker.startDate.format('DD/MM/YYYY'));
663        });
664        $('.singledatePicker').on('cancel.daterangepicker', function () {
665            $(this).val('');
666        });
667    }
668
669    // ----------------------------------------------------------
670    // PAUSE / PLAY ALL ANIMATIONS  (PauseAnimationAcc button)
671    // AOS is intentionally excluded — it continues independently
672    // ----------------------------------------------------------
673    $('.PauseAnimationAcc').on('click', function () {
674        const isPaused = $(this).toggleClass('paused').hasClass('paused');
675        const action = isPaused ? 'stop' : 'start';
676
677        // Set logo flag BEFORE stopping so autoplayStop doesn't restart it
678        if (typeof window.setLogoManuallyPaused === 'function') {
679            window.setLogoManuallyPaused(isPaused);
680        }
681
682        // Toggle all registered Swipers
683        Object.values(swiperRegistry).forEach(instance => toggleSwiper(instance, action));
684
685        // Toggle Marquee
686        if (isPaused) {
687            $('ul.home-marquee').addClass('MarqueePause');
688            isMarqueePaused = true;
689        } else {
690            $('ul.home-marquee').removeClass('MarqueePause');
691            isMarqueePaused = false;
692        }
693
694        // Toggle heroThumb manual autoplay timer
695        if (isPaused) {
696            if (typeof clearHeroAutoPlay === 'function') clearHeroAutoPlay();
697        } else {
698            if (typeof startHeroAutoPlay === 'function') startHeroAutoPlay();
699        }
700
701        // Update button title
702        $(this).attr('title', isPaused ? 'Play All' : 'Pause All');
703    });
704
705    // ----------------------------------------------------------
706    // Accessibility Menu — Ctrl + F2 keyboard toggle
707    // ----------------------------------------------------------
708    /*$(document).on('keydown', function (e) {
709        if (e.ctrlKey && e.key === 'F2') {
710            e.preventDefault();
711            $('body').toggleClass('AccessibilityOpen');
712        }
713    });*/
714
715    var ROWS_PER_CLICK = 5;
716
717    // Initialize each table
718    $('.table-wrapper').each(function () {
719        updateRowCount($(this));
720    });
721
722    // View More button click
723    $(document).on('click', '.toggle-btn', function () {
724        var $btn = $(this);
725        var $wrapper = $btn.closest('.profileTable');
726        var $hidden = $wrapper.find('.hidden-row:hidden');
727
728        // Show next 5 hidden rows
729        $hidden.slice(0, ROWS_PER_CLICK).show();
730
731        updateRowCount($wrapper);
732    });
733
734    // Update counter label and disable button when all rows are visible
735    function updateRowCount($wrapper) {
736        var $btn = $wrapper.find('.toggle-btn');
737        var $countLabel = $wrapper.find('.row-count');
738        var totalRows = $wrapper.find('tbody tr').length;
739        var visibleRows = $wrapper.find('tbody tr:visible').length;
740        var remaining = totalRows - visibleRows;
741
742        $countLabel.text('Showing ' + visibleRows + ' of ' + totalRows);
743
744        if (remaining <= 0) {
745            $btn.prop('disabled', true).text('All records shown');
746        }
747    }
748	
749	$("#uw-widget-custom-trigger").click(function(e){
750		e.preventDefault();
751	});
752
753
754}); // end $(document).ready
755
756
757// ============================================================
758// DOMContentLoaded — View More / View Less toggle
759// ============================================================
760document.addEventListener('DOMContentLoaded', function () {
761    const btn = document.getElementById('toggleListBtn');
762    const list = document.getElementById('morePointsList');
763    if (btn && list) {
764        btn.addEventListener('click', function () {
765            const isHidden = list.style.display === 'none' || list.style.display === '';
766            if (isHidden) {
767                list.style.display = 'block';
768                btn.textContent = 'View Less';
769                btn.setAttribute('data-hover', 'View Less');
770            } else {
771                list.style.display = 'none';
772                btn.textContent = 'View More';
773                btn.setAttribute('data-hover', 'View More');
774            }
775        });
776    }
777});
778
779
780// ============================================================
781// External Link Confirmation Dialog
782// ============================================================
783$(document).on('click', 'a', function (e) {
784    var $this = $(this);
785
786    // Skip fancybox
787    if ($this.is('[data-fancybox], [data-fancybox="VideoGallery"], [data-fancybox="PhotoGallery"]')) return;
788
789    var href = $this.attr('href');
790    if (!href || href === '#' || href.toLowerCase().startsWith('javascript:')) return; // ✅ Fixed
791
792    try {
793        var url = new URL(href, location.href);
794        if (url.hostname === location.hostname) return;
795    } catch (err) { return; }
796
797    e.preventDefault();
798    smoke.confirm(
799        'You are about to proceed to an external website. Click YES to proceed.',
800        function (confirmed) {
801            if (confirmed) window.open(href, '_blank');
802        },
803        { ok: 'Yes', cancel: 'No', classname: 'custom-class', reverseButtons: true }
804    );
805
806});
807
808// ============================================================
809// Organogram — horizontal scroll
810// ============================================================
811function scrollOrganogramChart(direction) {
812    var chartWrapper = document.querySelector('.organogram-chart-wrapper');
813    if (chartWrapper) {
814        var scrollAmount = direction === 'left' ? -500 : 500;
815        chartWrapper.scrollBy({ left: scrollAmount, behavior: 'smooth' });
816    }
817}
818
819
820// ============================================================
821// Organogram — mobile collapsible nodes
822// ============================================================
823function initMobileOrganogram() {
824    if (window.innerWidth > 767) return;
825
826    document.querySelectorAll('.organogram-node:not(.division-group)').forEach(node => {
827        const parentLi = node.closest('li');
828        const childUl = parentLi?.querySelector(':scope > ul');
829        if (!childUl) return;
830        node.classList.add('has-children');
831        node.setAttribute('role', 'button');
832        node.setAttribute('aria-expanded', 'false');
833        childUl.classList.add('mobile-collapsible', 'collapsed');
834        childUl.style.maxHeight = '0';
835        childUl.style.opacity = '0';
836        childUl.style.pointerEvents = 'none';
837    });
838
839    document.querySelectorAll('.has-children').forEach(node => {
840        const parentLi = node.closest('li');
841        const childUl = parentLi?.querySelector(':scope > ul.mobile-collapsible');
842        if (!childUl) return;
843
844        const toggleBtn = document.createElement('button');
845        toggleBtn.className = 'organogram-toggle-btn';
846        toggleBtn.setAttribute('aria-label', 'Toggle');
847        toggleBtn.innerHTML = '<span class="toggle-arrow"><span class="fa-solid fa-angle-down"></span></span>';
848        node.appendChild(toggleBtn);
849
850        toggleBtn.addEventListener('click', (e) => {
851            e.stopPropagation();
852            const isOpen = node.getAttribute('aria-expanded') === 'true';
853
854            const ancestors = new Set();
855            let current = parentLi.parentElement;
856            while (current) {
857                const ancestorNode = current.closest('li')?.querySelector(':scope > .has-children');
858                if (ancestorNode) ancestors.add(ancestorNode);
859                current = current.closest('li')?.parentElement;
860            }
861
862            document.querySelectorAll('.has-children[aria-expanded="true"]').forEach(openNode => {
863                if (openNode !== node && !ancestors.has(openNode)) {
864                    openNode.setAttribute('aria-expanded', 'false');
865                    const openUl = openNode.closest('li')?.querySelector(':scope > ul.mobile-collapsible');
866                    if (openUl) {
867                        openUl.classList.add('collapsed');
868                        openUl.style.maxHeight = '0';
869                        openUl.style.opacity = '0';
870                        openUl.style.pointerEvents = 'none';
871                    }
872                }
873            });
874
875            node.setAttribute('aria-expanded', String(!isOpen));
876            if (isOpen) {
877                childUl.classList.add('collapsed');
878                childUl.style.maxHeight = '0';
879                childUl.style.opacity = '0';
880                childUl.style.pointerEvents = 'none';
881            } else {
882                childUl.classList.remove('collapsed');
883                childUl.style.maxHeight = '3000px';
884                childUl.style.opacity = '1';
885                childUl.style.pointerEvents = '';
886            }
887        });
888    });
889}
890
891document.addEventListener('DOMContentLoaded', initMobileOrganogram);
892
893if ($('.perfomanceBox.demoPerfomanceBox').length) {
894
895    const demoPerfSwiper = new Swiper('.demoPerformanceSwiper', {
896        direction: 'horizontal',
897        slidesPerView: 4,
898        spaceBetween: 40,
899        loop: true,
900        speed: 700,
901        autoplay: { delay: 3100, disableOnInteraction: false },
902        navigation: {
903            nextEl: '.demoPerfomanceInner .performance-next',
904            prevEl: '.demoPerfomanceInner .performance-prev',
905        },
906        watchSlidesProgress: true,
907        watchSlidesVisibility: true,
908        breakpoints: {
909            320: { slidesPerView: 1 },
910            576: { slidesPerView: 2 },
911            992: { slidesPerView: 3 },
912            1200: { slidesPerView: 4 },
913        },
914        on: {
915            slideChange: function () { /* runCounterForVisible(); */ },
916        },
917    });
918    registerSwiper('demoPerfSwiper', demoPerfSwiper);
919
920    bindSwiperPlayPauseButton(demoPerfSwiper, '.performancePlayPauseBtn', {
921        play: 'Play Performance Slider',
922        pause: 'Pause Performance Slider',
923    });
924
925    const performanceSwiperEl = document.querySelector('.demoPerformanceSwiper');
926    const performanceBtn = document.querySelector('.performancePlayPauseBtn');
927
928    if (performanceSwiperEl) {
929        performanceSwiperEl.addEventListener('mouseenter', function () {
930            demoPerfSwiper.autoplay.stop();
931        });
932
933        performanceSwiperEl.addEventListener('mouseleave', function () {
934            const isPausedByButton = performanceBtn && performanceBtn.classList.contains('play');
935            if (!isPausedByButton) {
936                demoPerfSwiper.autoplay.start();
937            }
938        });
939    }
940
941    const perfObserver = new IntersectionObserver(function (entries) {
942        entries.forEach(function (entry) {
943            if (entry.isIntersecting) {
944                // runCounterForVisible();
945                perfObserver.unobserve(entry.target);
946            }
947        });
948    }, { threshold: 0.3 });
949
950    perfObserver.observe(document.querySelector('.perfomanceBox'));
951}
952
953
954
955// ============================================================
956// Hero Thumb Swiper — thumb strip only (featured pane is server-rendered)
957// ============================================================
958function ensureHeroScrollbar(heroThumbEl) {
959    if (!heroThumbEl) return null;
960
961    let scrollbar = heroThumbEl.querySelector('.swiper-scrollbar');
962
963    if (!scrollbar) {
964        scrollbar = document.createElement('div');
965        scrollbar.className = 'swiper-scrollbar';
966        heroThumbEl.appendChild(scrollbar);
967    }
968
969    return scrollbar;
970}
971//if ($('.heroThumbSwiper').length) {
972
973var heroSwiperInst = null;
974var heroCurrentMode = null;
975let isHeroInitRunning = false;
976let heroInitVersion = 0;
977let isHovered = false;
978let isManuallyPaused = false;
979
980function updateHeroPauseButtonState() {
981    var pauseBtn = document.querySelector('.heroThumbSwiper .heroThumb-pause');
982    if (!pauseBtn) return;
983
984    var label = isManuallyPaused ? 'Play Hero Highlights Slider' : 'Pause Hero Highlights Slider';
985    pauseBtn.classList.toggle('play', isManuallyPaused);
986    pauseBtn.setAttribute('aria-label', label);
987    pauseBtn.setAttribute('title', label);
988}
989
990function bindHeroPauseButton(heroThumbEl) {
991    if (!heroThumbEl) return;
992
993    var pauseBtn = heroThumbEl.querySelector('.heroThumb-pause');
994    if (!pauseBtn || pauseBtn.dataset.bound === '1') return;
995
996    pauseBtn.dataset.bound = '1';
997    pauseBtn.addEventListener('click', function () {
998        isManuallyPaused = !isManuallyPaused;
999
1000        if (isManuallyPaused) {
1001            if (heroSwiperInst?.autoplay) {
1002                heroSwiperInst.autoplay.stop();
1003            }
1004        } else if (heroSwiperInst?.autoplay) {
1005            heroSwiperInst.autoplay.start();
1006        }
1007
1008        updateHeroPauseButtonState();
1009    });
1010
1011    updateHeroPauseButtonState();
1012}
1013
1014// Cache injected slide HTML
1015var featuredSlideHTML = null;
1016
1017
1018
1019// ============================================================
1020// Build Featured Slide For Mobile
1021// ============================================================
1022function buildFeaturedSlide() {
1023
1024    featuredSlideHTML = null;
1025
1026    var pane = document.querySelector('#heroFeaturedPane');//document.getElementById('heroFeaturedPane');
1027
1028    if (!pane) return null;
1029
1030    var img = pane.querySelector('#heroFeatImg');
1031    var date = pane.querySelector('#heroFeatDate');
1032    var title = pane.querySelector('#heroFeatTitle');
1033
1034    var imgSrc = img ? img.getAttribute('src') : '';
1035    var imgAlt = img ? img.getAttribute('alt') : '';
1036    var dateText = date ? date.textContent.trim() : '';
1037    var titleHTML = title ? title.innerHTML : '';
1038
1039    // listing page url
1040    var listingHref = window.location.origin + '/news';
1041
1042    featuredSlideHTML =
1043        '<div class="hero-small-card">' +
1044
1045        '<div class="hero-small-img">' +
1046        '<img class="hero-sc-img" src="' + imgSrc + '" alt="' + imgAlt.replace(/"/g, '&quot;') + '" />' +
1047        '</div>' +
1048
1049        '<div class="hero-sc-body">' +
1050
1051        '<span class="hero-sc-date">' + dateText + '</span>' +
1052
1053        // keep original detail page link
1054        '<p class="hero-sc-title">' + titleHTML + '</p>' +
1055
1056        // listing page link
1057        '<a href="' + listingHref + '" class="view-all linkText hero-small-link" data-hover="View All Highlights">View All Highlights</a>' +
1058
1059        '</div>' +
1060        '</div>';
1061
1062    return featuredSlideHTML;
1063}
1064
1065// ============================================================
1066// Ensure Injected Slide Exists
1067// ============================================================
1068function ensureInjectedSlide() {
1069
1070    var wrapper = document.querySelector('.heroThumbSwiper .swiper-wrapper');
1071
1072    if (!wrapper) return;
1073
1074    // remove old injected slide if exists
1075    var existingInjected = wrapper.querySelector('.swiper-slide[data-injected="true"]');
1076
1077    if (existingInjected) {
1078        existingInjected.remove();
1079    }
1080
1081    var firstSlide = document.createElement('div');
1082
1083    firstSlide.className = 'swiper-slide';
1084    firstSlide.setAttribute('data-injected', 'true');
1085
1086    firstSlide.innerHTML = buildFeaturedSlide();
1087
1088    // always insert at first position
1089    wrapper.insertBefore(firstSlide, wrapper.firstChild);
1090}
1091
1092// ============================================================
1093// Remove Injected Slide
1094// ============================================================
1095function removeInjectedSlide() {
1096
1097    var wrapper = document.querySelector('.heroThumbSwiper .swiper-wrapper');
1098
1099    if (!wrapper) return;
1100
1101    var injected = wrapper.querySelector('.swiper-slide[data-injected="true"]');
1102
1103    if (injected) {
1104        injected.remove();
1105    }
1106}
1107
1108// ============================================================
1109// Destroy Swiper
1110// ============================================================
1111function destroyHeroSwiper() {
1112
1113    if (heroSwiperInst) {
1114
1115        heroSwiperInst.destroy(false, true);
1116
1117        heroSwiperInst = null;
1118    }
1119    const el = document.querySelector('.heroThumbSwiper .swiper-wrapper');
1120    if (el) {
1121        el.removeAttribute('style');
1122        //el.innerHTML = el.innerHTML; // forces DOM repaint cleanup
1123        //el.innerHTML = '';
1124        //el.removeAttribute('style');
1125
1126        //el.style.display = "block";
1127
1128    }
1129    document.querySelectorAll('.heroThumbSwiper .swiper-slide').forEach(function (slide) {
1130        slide.removeAttribute('style');
1131    });
1132}
1133
1134// ============================================================
1135// Init Swiper
1136// ============================================================
1137function initHeroSwiper() {
1138
1139    clearTimeout(window.heroInitInternalTimer);
1140
1141    window.heroInitInternalTimer = setTimeout(function () {
1142
1143        console.log('hero init:', document.querySelector('.heroThumbSwiper'));
1144
1145        var isDesktop = window.innerWidth > 991;
1146        var newMode = isDesktop ? 'desktop' : 'mobile';
1147
1148        // ============================================================
1149        // Skip rebuild if mode unchanged
1150        // ============================================================
1151        if (heroSwiperInst && heroCurrentMode === newMode) {
1152
1153            heroSwiperInst.update();
1154
1155            if (heroSwiperInst.scrollbar) {
1156                heroSwiperInst.scrollbar.updateSize();
1157            }
1158
1159            return;
1160        }
1161
1162        // ============================================================
1163        // Full Cleanup
1164        // ============================================================
1165        destroyHeroSwiper();
1166
1167        removeInjectedSlide();
1168
1169        heroCurrentMode = newMode;
1170
1171        var heroThumbEl = document.querySelector('.heroThumbSwiper');
1172
1173        if (!heroThumbEl) return;
1174
1175        // ============================================================
1176        // Inject Navigation
1177        // ============================================================
1178        if (!heroThumbEl.querySelector('.heroThumb-prev')) {
1179
1180            var prevBtn = document.createElement('button');
1181
1182            prevBtn.className = 'heroThumb-prev';
1183
1184            heroThumbEl.appendChild(prevBtn);
1185
1186            var nextBtn = document.createElement('button');
1187
1188            nextBtn.className = 'heroThumb-next';
1189
1190            heroThumbEl.appendChild(nextBtn);
1191        }
1192
1193        // ============================================================
1194        // Inject Play / Pause
1195        // ============================================================
1196        if (!heroThumbEl.querySelector('.heroThumb-pause')) {
1197            var pauseBtn = document.createElement('button');
1198            pauseBtn.className = 'heroThumb-pause';
1199            heroThumbEl.appendChild(pauseBtn);
1200        }
1201
1202        bindHeroPauseButton(heroThumbEl);
1203
1204        // ============================================================
1205        // Inject Scrollbar
1206        // ============================================================
1207        ensureHeroScrollbar(heroThumbEl);
1208
1209        var prevEl = heroThumbEl.querySelector('.heroThumb-prev');
1210        var nextEl = heroThumbEl.querySelector('.heroThumb-next');
1211
1212        if (prevEl) {
1213
1214            prevEl.innerHTML = isDesktop
1215                ? '<span class="fa-solid fa-angle-up"></span>'
1216                : '<span class="fa-solid fa-angle-left"></span>';
1217        }
1218
1219        if (nextEl) {
1220
1221            nextEl.innerHTML = isDesktop
1222                ? '<span class="fa-solid fa-angle-down"></span>'
1223                : '<span class="fa-solid fa-angle-right"></span>';
1224        }
1225
1226        // ============================================================
1227        // DESKTOP MODE
1228        // ============================================================
1229        if (isDesktop) {
1230
1231            removeInjectedSlide();
1232
1233            var scrollbar = ensureHeroScrollbar(heroThumbEl);
1234
1235            if (scrollbar) {
1236                scrollbar.style.display = 'block';
1237            }
1238
1239            // remove mobile pagination if exists
1240            var paginationEl = heroThumbEl.querySelector('.swiper-pagination');
1241
1242            if (paginationEl) {
1243                paginationEl.remove();
1244            }
1245
1246            heroSwiperInst = new Swiper('.heroThumbSwiper', {
1247
1248                direction: 'vertical',
1249
1250                slidesPerView: 2,
1251
1252                spaceBetween: 24,
1253
1254                loop: false,
1255
1256                speed: 600,
1257
1258                observer: true,
1259                observeParents: true,
1260                observeSlideChildren: true,
1261
1262                mousewheel: {
1263                    releaseOnEdges: true
1264                },
1265
1266                scrollbar: {
1267                    el: '.heroThumbSwiper .swiper-scrollbar',
1268                    draggable: true,
1269                    hide: false,
1270                },
1271
1272                navigation: {
1273                    nextEl: '.heroThumb-next',
1274                    prevEl: '.heroThumb-prev',
1275                },
1276
1277                autoplay: {
1278                    delay: 3000,
1279                    disableOnInteraction: false
1280                },
1281
1282                on: {
1283
1284                    init: function () {
1285
1286                        const swiper = this;
1287
1288                        setTimeout(function () {
1289
1290                            swiper.update();
1291
1292                            if (swiper.scrollbar) {
1293                                swiper.scrollbar.updateSize();
1294                            }
1295
1296                            if (!isManuallyPaused) {
1297                                swiper.autoplay.start();
1298                            }
1299
1300                        }, 100);
1301                    }
1302                }
1303            });
1304        }
1305
1306        // ============================================================
1307        // MOBILE MODE
1308        // ============================================================
1309        else {
1310
1311            var scrollbar = heroThumbEl.querySelector('.swiper-scrollbar');
1312
1313            if (scrollbar) {
1314                scrollbar.style.display = 'none';
1315            }
1316
1317            // inject pagination
1318            if (!heroThumbEl.querySelector('.swiper-pagination')) {
1319
1320                var mobilePagination = document.createElement('div');
1321
1322                mobilePagination.className = 'swiper-pagination';
1323
1324                heroThumbEl.appendChild(mobilePagination);
1325            }
1326
1327            // inject featured slide
1328            ensureInjectedSlide();
1329
1330            // force reflow
1331            heroThumbEl.offsetHeight;
1332
1333            heroSwiperInst = new Swiper('.heroThumbSwiper', {
1334
1335                direction: 'horizontal',
1336
1337                slidesPerView: 1,
1338
1339                spaceBetween: 0,
1340
1341                loop: false,
1342
1343                speed: 750,
1344
1345                initialSlide: 0,
1346
1347                observer: true,
1348                observeParents: true,
1349                observeSlideChildren: true,
1350
1351                autoplay: {
1352                    delay: 3000,
1353                    disableOnInteraction: false
1354                },
1355
1356                navigation: {
1357                    nextEl: '.heroThumb-next',
1358                    prevEl: '.heroThumb-prev',
1359                },
1360
1361                pagination: {
1362                    el: '.heroThumbSwiper .swiper-pagination',
1363                    clickable: true
1364                },
1365
1366                on: {
1367
1368                    init: function () {
1369
1370                        const swiper = this;
1371
1372                        setTimeout(function () {
1373
1374                            swiper.update();
1375
1376                            swiper.slideTo(0, 0);
1377
1378                            if (!isManuallyPaused) {
1379                                swiper.autoplay.start();
1380                            }
1381
1382                        }, 100);
1383                    }
1384                }
1385            });
1386
1387            // extra update after mobile render
1388            setTimeout(function () {
1389
1390                if (heroSwiperInst) {
1391
1392                    heroSwiperInst.update();
1393
1394                    if (heroSwiperInst.pagination) {
1395                        heroSwiperInst.pagination.render();
1396                        heroSwiperInst.pagination.update();
1397                    }
1398                }
1399
1400            }, 300);
1401        }
1402
1403        // ============================================================
1404        // Hover Pause / Resume
1405        // ============================================================
1406        heroThumbEl.onmouseenter = function () {
1407
1408            isHovered = true;
1409
1410            if (heroSwiperInst?.autoplay) {
1411                heroSwiperInst.autoplay.stop();
1412            }
1413        };
1414
1415        heroThumbEl.onmouseleave = function () {
1416
1417            isHovered = false;
1418
1419            if (!isManuallyPaused && heroSwiperInst?.autoplay) {
1420                heroSwiperInst.autoplay.start();
1421            }
1422        };
1423
1424        // ============================================================
1425        // Register Global Swiper
1426        // ============================================================
1427        if (typeof registerSwiper === 'function') {
1428            registerSwiper('heroThumbSwiper', heroSwiperInst);
1429        }
1430
1431        updateHeroPauseButtonState();
1432
1433    }, 100);
1434}
1435function initHeroSwiperold() {
1436
1437    clearTimeout(window.heroInitInternalTimer);
1438
1439    console.log('hero init:', document.querySelector('.heroThumbSwiper'));
1440    const version = ++heroInitVersion;
1441    if (isHeroInitRunning) return;
1442        isHeroInitRunning = true;
1443
1444   
1445
1446    var isDesktop = window.innerWidth > 991;
1447
1448    var newMode = isDesktop ? 'desktop' : 'mobile';
1449    // stale call guard (IMPORTANT)
1450    const myVersion = version;
1451
1452    if (heroSwiperInst && heroCurrentMode === newMode) {
1453        isHeroInitRunning = false;
1454        return;
1455    }
1456
1457    //isHeroInitRunning = true;
1458
1459
1460    // FORCE FULL RESET (important fix)
1461    destroyHeroSwiper();
1462    removeInjectedSlide();
1463    if (myVersion !== heroInitVersion) {
1464        isHeroInitRunning = false;
1465        return;
1466    }
1467
1468    heroCurrentMode = newMode;
1469
1470    //var featPane = document.getElementById('heroFeaturedPane');
1471    var heroThumbEl = document.querySelector('.heroThumbSwiper');
1472
1473    // ============================================================
1474    // Inject Navigation
1475    // ============================================================
1476    if (heroThumbEl && !heroThumbEl.querySelector('.heroThumb-prev')) {
1477
1478        var prevBtn = document.createElement('button');
1479
1480        prevBtn.className = 'heroThumb-prev';
1481
1482        heroThumbEl.appendChild(prevBtn);
1483
1484        var nextBtn = document.createElement('button');
1485
1486        nextBtn.className = 'heroThumb-next';
1487
1488        heroThumbEl.appendChild(nextBtn);
1489    }
1490
1491    // ============================================================
1492    // Inject Scrollbar
1493    // ============================================================
1494    //if (heroThumbEl && !heroThumbEl.querySelector('.swiper-scrollbar')) {
1495
1496    //    var scrollbarEl = document.createElement('div');
1497
1498    //    scrollbarEl.className = 'swiper-scrollbar';
1499
1500    //    heroThumbEl.appendChild(scrollbarEl);
1501    //}
1502    ensureHeroScrollbar(heroThumbEl);
1503
1504    var prevEl = heroThumbEl?.querySelector('.heroThumb-prev');
1505    var nextEl = heroThumbEl?.querySelector('.heroThumb-next');
1506
1507    if (prevEl) {
1508
1509        prevEl.innerHTML = isDesktop
1510            ? '<span class="fa-solid fa-angle-up"></span>'
1511            : '<span class="fa-solid fa-angle-left"></span>';
1512    }
1513
1514    if (nextEl) {
1515
1516        nextEl.innerHTML = isDesktop
1517            ? '<span class="fa-solid fa-angle-down"></span>'
1518            : '<span class="fa-solid fa-angle-right"></span>';
1519    }
1520
1521    // ============================================================
1522    // DESKTOP
1523    // ============================================================
1524    if (isDesktop) {
1525
1526        removeInjectedSlide();
1527
1528        //if (featPane) {
1529        //    featPane.style.display = '';
1530        //}
1531
1532        //var scrollbar = heroThumbEl.querySelector('.swiper-scrollbar');
1533        var scrollbar = ensureHeroScrollbar(heroThumbEl);//heroThumbEl ? heroThumbEl.querySelector('.swiper-scrollbar') : null;
1534
1535        if (scrollbar) {
1536            scrollbar.style.display = 'block';
1537        }
1538
1539        heroSwiperInst = new Swiper('.heroThumbSwiper', {
1540
1541            direction: 'vertical',
1542            slidesPerView: 2,
1543            spaceBetween: 24,
1544            loop: false,
1545            speed: 600,
1546
1547            mousewheel: {
1548                releaseOnEdges: true
1549            },
1550
1551            scrollbar: {
1552                el: '.heroThumbSwiper .swiper-scrollbar',
1553                draggable: true,
1554                hide: false,
1555            },
1556
1557            navigation: {
1558                nextEl: '.heroThumb-next',
1559                prevEl: '.heroThumb-prev',
1560            },
1561
1562            autoplay: {
1563                delay: 3000,
1564                disableOnInteraction: false
1565            }
1566        });
1567    }
1568
1569    // ============================================================
1570    // MOBILE
1571    // ============================================================
1572    else {
1573
1574        var heroThumbEl = document.querySelector('.heroThumbSwiper');
1575
1576        //if (featPane) {
1577        //    featPane.style.display = 'none';
1578        //}
1579
1580        var scrollbar = heroThumbEl?.querySelector('.swiper-scrollbar');
1581
1582        if (scrollbar) {
1583            scrollbar.style.display = 'none';
1584        }
1585
1586
1587        if (heroThumbEl && !heroThumbEl.querySelector('.swiper-pagination')) {
1588            var paginationEl = document.createElement('div');
1589            paginationEl.className = 'swiper-pagination';
1590            heroThumbEl.appendChild(paginationEl);
1591        }
1592
1593        // inject BEFORE swiper init
1594        ensureInjectedSlide();
1595        heroThumbEl.offsetHeight;
1596
1597        heroSwiperInst = new Swiper('.heroThumbSwiper', {
1598
1599            direction: 'horizontal',
1600            slidesPerView: 1,
1601            spaceBetween: 0,
1602            loop: false,
1603            speed: 750,
1604            initialSlide: 0,
1605
1606            observer: true,
1607            observeParents: true,
1608            observeSlideChildren: true,
1609
1610            autoplay: {
1611                delay: 3000,
1612                disableOnInteraction: false
1613            },
1614
1615            navigation: {
1616                nextEl: '.heroThumb-next',
1617                prevEl: '.heroThumb-prev',
1618            },
1619
1620            pagination: {
1621                el: '.heroThumbSwiper .swiper-pagination',
1622                clickable: true
1623            },
1624
1625            on: {
1626
1627                init: function () {
1628
1629                    // force start from injected slide
1630                    //this.slideToLoop(0, 0);
1631
1632                    //// autoplay fix after resize / zoom
1633                    //if (!isManuallyPaused) {
1634
1635                    //    this.autoplay.stop();
1636                    //    this.autoplay.start();
1637                    //}
1638                    const swiper = this;
1639
1640                    // force start from injected slide
1641                    //swiper.slideToLoop(0, 0);
1642
1643                    // IMPORTANT FIX FOR INITIAL MOBILE LOAD
1644                    setTimeout(function () {
1645
1646                        swiper.update();
1647
1648                        swiper.slideTo(0, 0);
1648   // ❗ use 0 NOT loop index
1649
1650                        if (!isManuallyPaused) {
1651                            swiper.autoplay.start();
1652                        }
1653
1654                    }, 50);
1655                }
1656            }
1657        });
1658
1659        setTimeout(function () {
1660            if (heroSwiperInst) {
1661                heroSwiperInst.update();
1662            }
1663        }, 300);
1664    }
1665
1666    // ============================================================
1667    // Hover Pause / Resume
1668    // ============================================================
1669    if (heroThumbEl) {
1670
1671        heroThumbEl.onmouseenter = function () {
1672
1673            isHovered = true;
1674
1675            if (heroSwiperInst?.autoplay) {
1676                heroSwiperInst.autoplay.stop();
1677            }
1678        };
1679
1680        heroThumbEl.onmouseleave = function () {
1681
1682            isHovered = false;
1683
1684            if (!isManuallyPaused && heroSwiperInst?.autoplay) {
1685                heroSwiperInst.autoplay.start();
1686            }
1687        };
1688    }
1689
1690    // ============================================================
1691    // Global Register
1692    // ============================================================
1693    if (typeof registerSwiper === 'function') {
1694        registerSwiper('heroThumbSwiper', heroSwiperInst);
1695    }
1696    isHeroInitRunning = false;
1697}
1698
1699// ============================================================
1700// External Pause
1701// ============================================================
1702window.clearHeroAutoPlay = function () {
1703
1704    isManuallyPaused = true;
1705
1706    if (heroSwiperInst?.autoplay) {
1707        heroSwiperInst.autoplay.stop();
1708    }
1709
1710    updateHeroPauseButtonState();
1711};
1712
1713// ============================================================
1714// External Resume
1715// ============================================================
1716window.startHeroAutoPlay = function () {
1717
1718    isManuallyPaused = false;
1719
1720    if (isHovered) return;
1721
1722    if (heroSwiperInst?.autoplay) {
1723        heroSwiperInst.autoplay.start();
1724    }
1725
1726    updateHeroPauseButtonState();
1727};
1728
1729// ============================================================
1730// Init
1731// ============================================================
1732document.addEventListener('DOMContentLoaded', function () {
1733
1734    // inject BEFORE first mobile swiper init
1735    //if (window.innerWidth <= 991) {
1736    //    ensureInjectedSlide();
1737    //}
1738
1739    initHeroSwiper();
1740
1741    // responsive rebuild
1742    let heroResizeTimer;
1743
1744    window.addEventListener('resize', function () {
1745
1746        clearTimeout(heroResizeTimer);
1747
1748        heroResizeTimer = setTimeout(function () {
1749
1750            //if (window.innerWidth <= 991) {
1751            //    ensureInjectedSlide();
1752            //}
1753
1754            initHeroSwiper();
1755
1756        }, 150);
1757    });
1758});
1759//}
1760
1761
1762// ============================================================
1763// AOS — Robust init with permanent animation lock
1764// (PauseAnimationAcc never touches AOS)
1765// ============================================================
1766(function () {
1767    // Disable AOS animations in specific sections for ≤431px
1768    if (window.innerWidth <= 431) {
1769        document.querySelectorAll('.minister-section.latest-minister-section [data-aos], .home-marquee-updates[data-aos], .home-marquee-updates [data-aos]').forEach(function (el) {
1770            el.removeAttribute('data-aos');
1771            el.removeAttribute('data-aos-delay');
1772            el.removeAttribute('data-aos-duration');
1773            el.removeAttribute('data-aos-easing');
1774            el.removeAttribute('data-aos-offset');
1775            el.removeAttribute('data-aos-anchor');
1776            el.removeAttribute('data-aos-anchor-placement');
1777            el.removeAttribute('data-aos-once');
1778        });
1779    }
1780
1781    function initAOS() {
1782        AOS.init({ duration: 800, once: true, mirror: false });
1783
1784        var aosObserver = new MutationObserver(function (mutations) {
1785            mutations.forEach(function (mutation) {
1786                if (mutation.attributeName === 'class') {
1787                    var el = mutation.target;
1788                    if (el.classList.contains('aos-animate')) el.dataset.aosLocked 
1788= '1';
1789                    if (el.dataset.aosLocked && !el.classList.contains('aos-animate')) {
1790                        el.classList.add('aos-animate');
1791                    }
1792                }
1793            });
1794        });
1795
1796        function observeAll() {
1797            document.querySelectorAll('[data-aos]').forEach(function (el) {
1798                aosObserver.observe(el, { attributes: true, attributeFilter: ['class'] });
1799            });
1800        }
1801
1802        observeAll();
1803
1804        var domWatcher = new MutationObserver(function (mutations) {
1805            var needsReObserve = false;
1806            mutations.forEach(function (mutation) {
1807                mutation.addedNodes.forEach(function (node) {
1808                    if (node.nodeType === 1) {
1809                        if (node.dataset && node.dataset.aos !== undefined) needsReObserve = true;
1810                        if (node.querySelector && node.querySelector('[data-aos]')) needsReObserve = true;
1811                    }
1812                });
1813            });
1814            if (needsReObserve) observeAll();
1815        });
1816
1817        domWatcher.observe(document.body, { childList: true, subtree: true });
1818
1819        window.addEventListener('load', function () {
1820            setTimeout(function () {
1821                document.querySelectorAll('[data-aos][data-aos-locked]').forEach(function (el) {
1822                    el.classList.add('aos-animate');
1823                });
1824                AOS.refresh();
1825            }, 300);
1826        });
1827    }
1828
1829    if (document.readyState === 'loading') {
1830        document.addEventListener('DOMContentLoaded', initAOS);
1831    } else {
1832        initAOS();
1833    }
1834})();
1835
1836//Accordion in small screen of tabbing
1837(function () {
1838    const BREAKPOINT = 767;
1839
1840    function initTabsToAccordion(wrapper) {
1841        if (wrapper._accInit) return;
1842        wrapper._accInit = true;
1843
1844        const tabButtons = [...wrapper.querySelectorAll('.nav-tabs .nav-item .nav-link')];
1845        const tabPanes = [...wrapper.querySelectorAll('.tab-content .tab-pane')];
1846        if (!tabButtons.length) return;
1847
1848        const accHeaders = [];
1849        const accPanes = [];
1850
1851        tabPanes.forEach((pane, i) => {
1852            const btn = tabButtons[i];
1853            const label = btn ? btn.textContent.trim() : 'Tab ' + (i + 1);
1854            const isActive = pane.classList.contains('active');
1855
1856            const header = document.createElement('div');
1857            header.className = 'acc-header' + (isActive ? ' open' : '');
1858            header.innerHTML = label + '<span class="acc-icon"><span class="fa-solid fa-angle-down"></span></span>';
1859
1860            const accPane = document.createElement('div');
1861            accPane.className = 'acc-pane';
1862            accPane._origPane = pane; // store reference for teardown
1863
1864            // MOVE actual child nodes instead of cloning innerHTML so Swiper
1865            // instances stay attached to their original DOM elements
1866            while (pane.firstChild) accPane.appendChild(pane.firstChild);
1867
1868            // Set initial state — visible if active, hidden if not
1869            if (isActive) {
1870                $(accPane).show();
1871            } else {
1872                $(accPane).hide();
1873            }
1874
1875            header.addEventListener('click', () => {
1876                const isOpen = header.classList.contains('open');
1877
1878                // Close all
1879                accHeaders.forEach(h => h.classList.remove('open'));
1880                accPanes.forEach(p => $(p).slideUp(500));
1881
1882                // If it wasn't open, open this one
1883                if (!isOpen) {
1884                    header.classList.add('open');
1885
1886                    // ── NEW: fire shown.bs.tab so all existing listeners trigger automatically ──
1887                    const tabBtn = tabButtons[accPanes.indexOf(accPane)];
1888                    if (tabBtn) {
1889                        $(tabBtn).trigger('shown.bs.tab');
1890                    }
1891                    // ── END NEW ──
1892
1893                    $(accPane).slideDown(500, function () {
1894                        accPane.querySelectorAll('.swiper').forEach(function (el) {
1895                            if (el.swiper) {
1896                                el.swiper.update();
1897                                if (!el.swiper.autoplay.running) el.swiper.autoplay.start();
1898                            }
1899                        });
1900                    });
1901                }
1902            });
1903
1904            pane.after(header);
1905            header.after(accPane);
1906            accHeaders.push(header);
1907            accPanes.push(accPane);
1908        });
1909
1910        // Move sliderNav elements into their corresponding acc-panes
1911        const sliderNavs = [...wrapper.querySelectorAll('.titleBox .sliderNav')];
1912        wrapper._savedNavDisplays = sliderNavs.map(function (nav) { return nav.style.display; });
1913        wrapper._sliderNavs = sliderNavs;
1914        sliderNavs.forEach(function (nav, i) {
1915            if (accPanes[i]) {
1916                nav.style.display = 'flex';
1917                accPanes[i].insertBefore(nav, accPanes[i].firstChild);
1918            }
1919        });
1920
1921        // On first init, update swipers already visible in the active pane
1922        accPanes.forEach(function (ap) {
1923            if ($(ap).is(':visible')) {
1924                setTimeout(function () {
1925                    ap.querySelectorAll('.swiper').forEach(function (el) {
1926                        if (el.swiper) {
1927                            el.swiper.update();
1928                            if (!el.swiper.autoplay.running) el.swiper.autoplay.start();
1929                        }
1930                    });
1931                }, 0);
1932            }
1933        });
1934
1935        wrapper._accHeaders = accHeaders;
1936        wrapper._accPanes = accPanes;
1937    }
1938
1939    function destroyAccordion(wrapper) {
1940        if (!wrapper._accInit) return;
1941
1942        // Move sliderNav elements back to titleBox before tearing down acc-panes
1943        const titleBox = wrapper.querySelector('.titleBox');
1944        if (titleBox && wrapper._sliderNavs) {
1945            wrapper._sliderNavs.forEach(function (nav, i) {
1946                nav.style.display = (wrapper._savedNavDisplays && wrapper._savedNavDisplays[i] != null)
1947                    ? wrapper._savedNavDisplays[i]
1948                    : '';
1949                titleBox.appendChild(nav);
1950            });
1951            wrapper._sliderNavs = null;
1952            wrapper._savedNavDisplays = null;
1953        }
1954
1955        // Move content back to original tab panes before removing acc-panes
1956        (wrapper._accPanes || []).forEach(function (accPane) {
1957            const origPane = accPane._origPane;
1958            if (origPane) {
1959                while (accPane.firstChild) origPane.appendChild(accPane.firstChild);
1960            }
1961            accPane.remove();
1962        });
1963
1964        (wrapper._accHeaders || []).forEach(el => el.remove());
1965
1966        // Refresh any swipers now back in their (possibly visible) tab panes
1967        wrapper.querySelectorAll('.tab-pane.show.active .swiper').forEach(function (el) {
1968            if (el.swiper) el.swiper.update();
1969        });
1970
1971        wrapper._accInit = false;
1972        wrapper._accHeaders = [];
1973        wrapper._accPanes = [];
1974
1975        wrapper.classList.remove('accordion-mode');
1976    }
1977
1978    let currentlySmall = null;
1979
1980    function checkAll() {
1981        const small = window.innerWidth <= BREAKPOINT;
1982        if (small === currentlySmall) return;
1983        currentlySmall = small;
1984
1985        document.querySelectorAll('.pressReleaseInner').forEach(wrapper => {
1986            // if (wrapper.querySelector('#incomingVisitTabContent')) return;
1987            if (small) {
1988                initTabsToAccordion(wrapper);
1989                wrapper.classList.add('accordion-mode');
1990            } else {
1991                destroyAccordion(wrapper);
1992            }
1993        });
1994    }
1995
1996    checkAll();
1997    window.addEventListener('resize', checkAll);
1998
1999})();
2000document.addEventListener('DOMContentLoaded', function () {
2001    var currentPath = window.location.pathname.toLowerCase();
2002
2003    document.querySelectorAll('.left-sidebar-list li a').forEach(function (el) {
2004        var href = el.getAttribute('href');
2005        if (!href || href === '#') return;
2006
2007        var linkPath = href.toLowerCase();
2008        try { linkPath = new URL(href, window.location.origin).pathname.toLowerCase(); } catch (e) { }
2009
2010        if (currentPath === linkPath || currentPath.indexOf(linkPath + '/') === 0) {
2011            el.classList.add('active');
2012        }
2013    });
2014});
2015
2016
2017
2018
2019function initTagsCollapse() {
2020    if (window.innerWidth < 768) return;
2021    document.querySelectorAll('.d-flex.tags').forEach(function (tagWrapper) {
2022        if (tagWrapper.dataset.tagsInit) return;
2023        tagWrapper.dataset.tagsInit = '1';
2024        var tags = Array.from(tagWrapper.querySelectorAll('a.btnHover'));
2025        if (tags.length <= 7) return;
2026        tags.forEach(function (tag, i) {
2027            if (i >= 7) tag.style.display = 'none';
2028        });
2029        var btn = document.createElement('a');
2030        btn.className = 'btnHover tags-more-btn';
2031        btn.href = 'javascript:void(0);';
2032        btn.innerHTML = 'more <span class="fa-solid fa-angle-down"></span>';
2033        tagWrapper.appendChild(btn);
2034        var expanded = false;
2035        btn.addEventListener('click', function () {
2036            expanded = !expanded;
2037            tags.forEach(function (tag, i) {
2038                if (i >= 7) tag.style.display = expanded ? 'inline-block' : 'none';
2039            });
2040            btn.innerHTML = expanded
2041                ? 'less <span class="fa-solid fa-angle-up"></span>'
2042                : 'more <span class="fa-solid fa-angle-down"></span>';
2043        });
2044    });
2045}
2046
2047document.addEventListener('DOMContentLoaded', initTagsCollapse);
2048
2049var tagsObserver = new MutationObserver(function () {
2050    if (document.querySelector('.d-flex.tags:not([data-tags-init])')) {
2051        initTagsCollapse();
2052    }
2053});
2054tagsObserver.observe(document.body, { childList: true, subtree: true });
2055
2056
2057$(document).ready(function () {
2058    const lang1 = localStorage.getItem('preferredLanguage') || 'en';
2059    document.body.classList.add('lang-' + lang1);
2060});
2061$(document).on('click', '.page-link', function () {
2062    window.scrollTo({ top: 0, behavior: 'smooth' });
2063});
2064
2065
2066$(document).ready(function () {
2067    if ($("body").hasClass("lang-hi")) {
2068        $(".eng-content").hide();
2069        $(".hi-content").show();
2070    } else {
2071        $(".eng-content").show();
2072        $(".hi-content").hide();
2073    }
2074});
2075
2076
2077$(document).ready(function () {
2078
2079    const wrap = document.querySelector('.home-marquee-wrap');
2080    const ul = document.querySelector('.home-marquee');
2081
2082    if (!wrap || !ul) return;
2083
2084    let position = wrap.offsetWidth;
2085    let animationId;
2086    let lastTime = 0;
2087
2088    function animate(timestamp) {
2089
2090        if (!lastTime)
2091            lastTime = timestamp;
2092
2093        const delta = (timestamp - lastTime) / 1000;
2094        lastTime = timestamp;
2095
2096        const speed = window.innerWidth <= 600 ? 35 : 75;
2097
2098        if (!ul.classList.contains("MarqueePause")) {
2099
2100            position -= speed * delta;
2101
2102            if (position <= -ul.scrollWidth) {
2103                position = wrap.offsetWidth;
2104            }
2105
2106            ul.style.transform = `translateX(${position}px)`;
2107        }
2108
2109        animationId = requestAnimationFrame(animate);
2110    }
2111
2112    function reset() {
2113        position = wrap.offsetWidth;
2114    }
2115
2116    requestAnimationFrame(animate);
2117
2118    window.addEventListener("resize", reset);
2119
2120});
2121
2122
2123/*AOS.init({
2124  disable: true
2125});*/
2126
2127
2128
2129var HERO_INIT_TIMER_MS   = 100;
2130var HERO_MOBILE_EXTRA_MS = 300;
2131var HERO_SWIPER_READY_MS = HERO_INIT_TIMER_MS + HERO_MOBILE_EXTRA_MS; // 400ms
2132
2133document.addEventListener("DOMContentLoaded", () => {
2134    // Reveal hero content immediately so the browser can paint it for LCP.
2135    // The loader overlay stays until the swiper finishes initialising.
2136    showContent();
2137
2138    setTimeout(() => {
2139        hideLoader();
2140    }, HERO_SWIPER_READY_MS);
2141
2142    function hideLoader() {
2143        const loader = document.getElementById("hero-loader");
2144        if (loader) loader.style.display = "none";
2145    }
2146
2147    function showContent() {
2148        const content = document.getElementById("hero-section");
2149        if (content) content.style.display = "block";
2150    }
2151});
2152
2153
2154// Print — expand all accordions
2155(function () {
2156    var s = null;
2157    window.addEventListener('beforeprint', function () {
2158        s = document.createElement('style');
2159        s.textContent = '.accordion-collapse, .acc-pane { display: block !important; }';
2160        document.head.appendChild(s);
2161    });
2162    window.addEventListener('afterprint', function () {
2163        if (s) { s.remove(); s = null; }
2164    });
2165})();
2166
2167
2168$('.headerMenu > ul > li.megaMenu > ul > li > ul > li > a[target="_blank"]').append('<span class="mainNavExtLink"><img src="Content/images/ext-arrow.svg" alt="External Link Arrow" /></span>');
2169
2170
2171document.addEventListener("DOMContentLoaded", async function () {
2172    const lang = localStorage.getItem("preferredLanguage");
2173    if (!lang)
2174        return;
2175
2176    try {
2177        await fetch('/FrontEnd/SetSiteLanguage', {
2178            method: 'POST',
2179            headers: {
2180                'Content-Type': 'application/x-www-form-urlencoded'
2181            },
2182            body: 'language=' + encodeURIComponent(lang)
2183        });
2184
2185        // Reload only if cookie differs
2186        if (document.documentElement.lang !== lang) {
2187            location.reload();
2188        }
2189
2190    } catch (e) {
2191        console.error(e);
2192    }
2193});
2194
2195// ============================================================
2196// Feedback Textarea Labels (injected via JS)
2197// ============================================================
2198(function () {
2199    const labelConfig = {
2200        'feedback-textarea': 'Feedback details',
2201        'feedback-suggested-feedback': 'Suggested feedback',
2202    };
2203
2204    function ensureTextareaId(textarea, className) {
2205        if (textarea.id) return textarea.id;
2206        const unique = Math.random().toString(36).slice(2, 8);
2207        const id = className + '-' + unique;
2208        textarea.id = id;
2209        return id;
2210    }
2211
2212    function syncLabelVisibility(textarea, label) {
2213        const isHidden = window.getComputedStyle(textarea).display === 'none';
2214        label.style.display = isHidden ? 'none' : '';
2215    }
2216
2217    function ensureLabelForTextarea(textarea, className, labelText) {
2218        if (!textarea) return;
2219
2220        const id = ensureTextareaId(textarea, className);
2221        let label = textarea.previousElementSibling;
2222        const expectedClass = 'sr-only';
2223
2224        if (!label || label.tagName !== 'LABEL' || !label.classList.contains(expectedClass)) {
2225            label = document.createElement('label');
2226            label.className = expectedClass;
2227            label.setAttribute('for', id);
2228            label.textContent = labelText;
2229            textarea.parentNode.insertBefore(label, textarea);
2230        } else if (label.className !== 'sr-only') {
2231            label.className = 'sr-only';
2232        }
2233
2234        syncLabelVisibility(textarea, label);
2235
2236        if (!textarea.dataset.labelObserverAttached) {
2237            const textareaObserver = new MutationObserver(function () {
2238                syncLabelVisibility(textarea, label);
2239            });
2240
2241            textareaObserver.observe(textarea, {
2242                attributes: true,
2243                attributeFilter: ['style', 'class'],
2244            });
2245
2246            textarea.dataset.labelObserverAttached = '1';
2247        }
2248    }
2249
2250    function injectFeedbackLabels() {
2251        Object.keys(labelConfig).forEach(function (className) {
2252            document.querySelectorAll('textarea.' + className).forEach(function (textarea) {
2253                ensureLabelForTextarea(textarea, className, labelConfig[className]);
2254            });
2255        });
2256    }
2257
2258    if (document.readyState === 'loading') {
2259        document.addEventListener('DOMContentLoaded', injectFeedbackLabels);
2260    } else {
2261        injectFeedbackLabels();
2262    }
2263
2264    const pageObserver = new MutationObserver(function () {
2265        injectFeedbackLabels();
2266    });
2267
2268    pageObserver.observe(document.body, {
2269        childList: true,
2270        subtree: true,
2271    });
2272})();

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.