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, '"') + '" />' + 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.