PageSourceSearch

https://bridge.ac.ke/wp-content/themes/charifund/assets/js/custom.js?ver=1791502521

js bridge.ac.ke collected 2026-10-08 23:36:01 UTC 38,006 bytes, 1,332 lines download raw bytes

1/* ==============
2 ========= js documentation ==========================
3
4 * template name: Charifund
5 * version: 1.0
6 * description: Nonprofit NGO Fundraising HTML5 Template
7 * author: wowtheme7
8 * author-url: https://themeforest.net/user/wowtheme7
9
10    ==================================================
11
12     01. preloader
13     -------------------------------------------------
14     02. background image
15     -------------------------------------------------
16     03. custom cursor
17     -------------------------------------------------
18     04. scroll to top with progress
19     -------------------------------------------------
20     05. add active class to the current link
21     -------------------------------------------------
22     06. open search box
23     -------------------------------------------------
24     07. mobile menu
25     -------------------------------------------------
26     08. fixed header on scroll
27     -------------------------------------------------
28     09. nice select
29     -------------------------------------------------
30     10. open sidebar info
31     -------------------------------------------------
32     11. off canvas cart
33     -------------------------------------------------
34     12. banner one slider
35     -------------------------------------------------
36     13. banner two slider
37     -------------------------------------------------
38     14. banner three slider
39     -------------------------------------------------
40     15. partner slider
41     -------------------------------------------------
42     16. difference slider
43     -------------------------------------------------
44     17. video popup
45     -------------------------------------------------
46     18. cause slider
47     -------------------------------------------------
48     19. donate amount
49     -------------------------------------------------
50     20. testimonial slider
51     -------------------------------------------------
52     21. cause two slider content
53     -------------------------------------------------
54     22. difference tab
55     -------------------------------------------------
56     23. odometer counter
57     -------------------------------------------------
58     24. testimonial two slider
59     -------------------------------------------------
60     25. testimonial three slider
61     -------------------------------------------------
62     26. coming soon
63     -------------------------------------------------
64     27. countdown
65     -------------------------------------------------
66     28. product details slider
67     -------------------------------------------------
68     29. product details tab
69     -------------------------------------------------
70     30. social link active on hover
71     -------------------------------------------------
72     31. footer copyright year
73     -------------------------------------------------
74     32. aos initialization
75     -------------------------------------------------
76     33. vanilla tilt animation
77     -------------------------------------------------
78     34. register gsap
79     -------------------------------------------------
80     35. gsap null config
81     -------------------------------------------------
82     36. target section with gsap
83     -------------------------------------------------
84     37. parallax image with gsap
85     -------------------------------------------------
86     38. title animation
87     -------------------------------------------------
88     39. banner three image animation
89     -------------------------------------------------
90     40. progress bar
91     -------------------------------------------------
92     41. circular progress bar
93     -------------------------------------------------
94     42. banner animation
95
96    ==================================================
97============== */
98
99(function ($) {
100  "use strict";
101
102  jQuery(function () {
103    let device_width = window.innerWidth;
104    let initialScroll = $(window).scrollTop();
105
106    /**
107     * ======================================
108     * 01. preloader
109     * ======================================
110     */
111
112    if ($(".preloader").length) {
113      $(".preloader").delay(500).fadeOut();
114    }
115
116    /**
117     * ======================================
118     * 02. background image
119     * ======================================
120     */
121    $("[data-background]").each(function () {
122      var backgroundImages = $(this).attr("data-background").split(",");
123      var cssValue = backgroundImages
124        .map(function (image) {
125          return 'url("' + image.trim() + '")';
126        })
127        .join(",");
128
129      $(this).css("background-image", cssValue);
130    });
131
132    /**
133     * ======================================
134     * 03. custom cursor
135     * ======================================
136     */
137    if ($(".mouseCursor").length > 0) {
138      function itCursor() {
139        var myCursor = jQuery(".mouseCursor");
140        if (myCursor.length) {
141          if ($("body")) {
142            const e = document.querySelector(".cursor-inner"),
143              t = document.querySelector(".cursor-outer");
144            let n,
145              i = 0,
146              o = !1;
147            (window.onmousemove = function (s) {
148              o ||
149                (t.style.transform =
150                  "translate(" + s.clientX + "px, " + s.clientY + "px)"),
151                (e.style.transform =
152                  "translate(" + s.clientX + "px, " + s.clientY + "px)"),
153                (n = s.clientY),
154                (i = s.clientX);
155            }),
156              $("body").on( "mouseenter", "button, a, .cursor-pointer", function () {
157                  e.classList.add("cursor-hover"),
158                    t.classList.add("cursor-hover");
159                }
160              ),
161              $("body").on( "mouseleave", "button, a, .cursor-pointer",
162                function () {
163                  ($(this).is("a", "button") &&
164                    $(this).closest(".cursor-pointer").length) ||
165                    (e.classList.remove("cursor-hover"),
166                    t.classList.remove("cursor-hover"));
167                }
168              ),
169              (e.style.visibility = "visible"),
170              (t.style.visibility = "visible");
171          }
172        }
173      }
174      itCursor();
175    }
176
177    /**
178     * ======================================
179     * 04. scroll to top with progress
180     * ======================================
181     */
182    if ($(".progress-wrap").length > 0) {
183      var progressPath = document.querySelector(".progress-wrap path");
184      var pathLength = progressPath.getTotalLength();
185      progressPath.style.transition = progressPath.style.WebkitTransition =
186        "none";
187      progressPath.style.strokeDasharray = pathLength + " " + pathLength;
188      progressPath.style.strokeDashoffset = pathLength;
189      progressPath.getBoundingClientRect();
190      progressPath.style.transition = progressPath.style.WebkitTransition =
191        "stroke-dashoffset 10ms linear";
192      var updateProgress = function () {
193        var scroll = $(window).scrollTop();
194        var height = $(document).height() - $(window).height();
195        var progress = pathLength - (scroll * pathLength) / height;
196        progressPath.style.strokeDashoffset = progress;
197      };
198      updateProgress();
199      $(window).scroll(updateProgress);
200      var offset = 50;
201      var duration = 1500;
202      $(window).on("scroll", function () {
203        if ($(this).scrollTop() > offset) {
204          $(".progress-wrap").addClass("active-progress");
205        } else {
206          $(".progress-wrap").removeClass("active-progress");
207        }
208      });
209      $(".progress-wrap").on("click", function (event) {
210        event.preventDefault();
211        $("html, body")
212          .stop()
213          .css("scroll-behavior", "auto")
214          .animate(
215            {
216              scrollTop: 0,
217            },
218            {
219              duration: 1500,
220              easing: "swing",
221              complete: function () {
222                $("html, body").css("scroll-behavior", "smooth");
223              },
224            }
225          );
226        return false;
227      });
228
229      if (initialScroll >= 50) {
230        $(".progress-wrap").addClass("active-progress");
231      }
232    }
233
234    /**
235     * ======================================
236     * 05. add active class to the current link
237     * ======================================
238     */
239    function dynamicCurrentMenuClass(selector) {
240      let FileName = window.location.href.split("/").reverse()[0];
241
242      selector.find("li").removeClass("active");
243      selector
244        .find(".navbar__dropdown-label")
245        .removeClass("navbar__item-active");
246
247      selector.find("li").each(function () {
248        let anchor = $(this).find("a");
249        if ($(anchor).attr("href") === FileName) {
250          $(this).addClass("active");
251        }
252      });
253
254      const activeDropdownItem = selector.find(".navbar__sub-menu .active");
255      if (activeDropdownItem.length) {
256        activeDropdownItem.parents("li").addClass("active");
257      }
258
259      selector.find("li").each(function () {
260        if ($(this).find(".active").length) {
261          $(this).addClass("active");
262        }
263      });
264
265      if (FileName === "") {
266        selector.find('li:has(a[href="index.html"])').addClass("active");
267      }
268    }
269    if ($("header").length) {
270      dynamicCurrentMenuClass($("header"));
271    }
272
273    /**
274     * ======================================
275     * 06. open search box
276     * ======================================
277     */
278    if ($(".search-popup").length > 0) {
279      $(".open-search").on("click", function () {
280        $("body").addClass("search-active");
281      });
282
283      $(".close-search").on("click", function () {
284        $("body").removeClass("search-active");
285      });
286    }
287
288    /**
289     * ======================================
290     * 07. mobile menu
291     * ======================================
292     */
293    if ($(".mobile-menu").length > 0) {
294      var mobileMenuContent = $(".navbar__menu").html();
295      $(".mobile-menu__list").append(mobileMenuContent);
296
297      $(".mobile-menu .navbar__dropdown-label").on("click", function () {
298        $(this).parent().siblings().find(".navbar__sub-menu").slideUp(500);
299        $(this)
300          .parent()
301          .siblings()
302          .find(".navbar__dropdown-label")
303          .removeClass("navbar__item-active");
304        $(this).siblings(".navbar__sub-menu").slideToggle(500);
305        $(this).toggleClass("navbar__item-active");
306      });
307    }
308
309    $(".open-offcanvas-nav").on("click", function () {
310      $(this).addClass("open-offcanvas-nav-active");
311      $(".mobile-menu__backdrop").addClass("mobile-menu__backdrop-active");
312      $(".nav-fade").each(function (i) {
313        $(this).css("animation-delay", 0.10 * 1 * i + "s");
314      });
315
316      $(".mobile-menu").addClass("show-menu");
317      $(".mobile-menu__wrapper").removeClass("nav-fade-active");
318    });
319
320    $(".close-mobile-menu, .mobile-menu__backdrop").on("click", function () {
321      $(".open-offcanvas-nav").removeClass("open-offcanvas-nav-active");
322      $(".mobile-menu").removeClass("show-menu");
323      $(".mobile-menu__backdrop").removeClass("mobile-menu__backdrop-active");
324      $(".mobile-menu__wrapper").addClass("nav-fade-active");
325      $(".mobile-menu .navbar__dropdown-label").removeClass(
326        "navbar__item-active"
327      );
328      $(".mobile-menu .navbar__sub-menu").slideUp(0);
329    });
330
331    $(".navbar__item.navbar__item--has-children > a").on("click", function (e) {
332      e.preventDefault();
333    });
334
335    $(window).on("resize", function () {
336      // sidebar info
337      $(".off-canvas").removeClass("off-canvas-active");
338      $(".off-canvas-backdrop").removeClass("off-canvas-backdrop-active");
339
340      // mobile menu
341      $(".mobile-menu").removeClass("show-menu");
342      $(".mobile-menu__backdrop").removeClass("mobile-menu__backdrop-active");
343      $(".mobile-menu__wrapper").addClass("nav-fade-active");
344      $(".mobile-menu .navbar__dropdown-label").removeClass(
345        "navbar__item-active"
346      );
347      $(".mobile-menu .navbar__sub-menu").slideUp(0);
348      $(".open-offcanvas-nav").removeClass("open-offcanvas-nav-active");
349    });
350
351    /**
352     * ======================================
353     * 08. fixed header on scroll
354     * ======================================
355     */
356    $(window).on("scroll", function () {
357      var scroll = $(window).scrollTop();
358      if (scroll < 160) {
359        $(".header").removeClass("sticky-header");
360      } else {
361        $(".header").addClass("sticky-header");
362      }
363    });
364
365    if (initialScroll >= 100) {
366      $(".header").addClass("sticky-header");
367    }
368
369    /**
370     * ======================================
371     * 09. nice select
372     * ======================================
373     */
374    $("select").niceSelect();
375
376    /**
377     * ======================================
378     * 10. open sidebar info
379     * ======================================
380     */
381    $(".open-sidenav").on("click", function () {
382      $(".off-canvas-backdrop").toggleClass("off-canvas-backdrop-active");
383      $(".off-canvas").toggleClass("off-canvas-active");
384    });
385
386    $(".off-canvas-backdrop, .off-canvas-close").on("click", function () {
387      $(".off-canvas").removeClass("off-canvas-active");
388      $(".off-canvas-backdrop").removeClass("off-canvas-backdrop-active");
389    });
390
391    /**
392     * ======================================
393     * 12. banner one slider
394     * ======================================
395     */
396    var bannerOne = new Swiper(".banner-two__slider", {
397      loop: true,
398      speed: 2000,
399      slidesPerView: 1,
400      slidesPerGroup: 1,
401      spaceBetween: 0,
402      effect: "fade",
403      fadeEffect: {
404        crossFade: true,
405      },
406      autoplay: {
407        delay: 6000,
408        disableOnInteraction: false,
409        pauseOnMouseEnter: true,
410      },
411      navigation: {
412        nextEl: ".next-banner",
413        prevEl: ".prev-banner",
414      },
415    });
416
417    /**
418     * ======================================
419     * 13. banner two slider
420     * ======================================
421     */
422    var bannerTwo = new Swiper(".banner__slider", {
423      loop: true,
424      speed: 2000,
425      slidesPerView: 1,
426      slidesPerGroup: 1,
427      spaceBetween: 24,
428      effect: "fade",
429      fadeEffect: {
430        crossFade: true,
431      },
432      autoplay: {
433        delay: 6000,
434        disableOnInteraction: false,
435        pauseOnMouseEnter: true,
436      },
437    });
438
439    /**
440     * ======================================
441     * 14. banner three slider
442     * ======================================
443     */
444    var bannerThree = new Swiper(".banner-three__slider", {
445      loop: true,
446      speed: 2000,
447      slidesPerView: 1,
448      slidesPerGroup: 1,
449      spaceBetween: 24,
450      effect: "fade",
451      fadeEffect: {
452        crossFade: true,
453      },
454      autoplay: {
455        delay: 6000,
456        disableOnInteraction: false,
457        pauseOnMouseEnter: true,
458      },
459    });
460
461    /**
462     * ======================================
463     * 15. partner slider
464     * ======================================
465     */
466    var partners = new Swiper(".partner__slider", {
467      loop: true,
468      speed: 1000,
469      slidesPerView: 1,
470      slidesPerGroup: 1,
471      spaceBetween: 24,
472      freeMode: true,
473      centeredSlides: true,
474      autoplay: {
475        delay: 2000,
476        disableOnInteraction: false,
477        pauseOnMouseEnter: true,
478      },
479      breakpoints: {
480        420: {
481          slidesPerView: 2,
482        },
483        576: {
484          slidesPerView: 3,
485        },
486        992: {
487          slidesPerView: 5,
488        },
489      },
490    });
491
492    /**
493     * ======================================
494     * 16. difference slider
495     * ======================================
496     */
497    var differenceSlider = new Swiper(".difference__slider", {
498      loop: true,
499      speed: 1000,
500      slidesPerView: 1,
501      slidesPerGroup: 1,
502      spaceBetween: 24,
503      autoplay: {
504        delay: 3000,
505        disableOnInteraction: false,
506        pauseOnMouseEnter: true,
507      },
508      navigation: {
509        nextEl: ".next-difference",
510        prevEl: ".prev-difference",
511      },
512      breakpoints: {
513        768: {
514          slidesPerView: 2,
515        },
516        1200: {
517          slidesPerView: 3,
518        },
519      },
520    });
521
522    /**
523     * ======================================
524     * 17. video popup
525     * ======================================
526     */
527    if (document.querySelector(".open-video-popup") !== null) {
528      $(".open-video-popup").magnificPopup({
529        disableOn: 768,
530        type: "iframe",
531        mainClass: "mfp-fade",
532        removalDelay: 160,
533        preloader: false,
534        fixedContentPos: false,
535      });
536    }
537
538    /**
539     * ======================================
540     * 18. cause slider
541     * ======================================
542     */
543    var causeSlider = new Swiper(".cause__slider", {
544      loop: true,
545      speed: 1000,
546      slidesPerView: 1,
547      slidesPerGroup: 1,
548      spaceBetween: 24,
549
550      autoplay: {
551        delay: 2000,
552        disableOnInteraction: false,
553        pauseOnMouseEnter: true,
554      },
555      navigation: {
556        nextEl: ".next-cause",
557        prevEl: ".prev-cause",
558      },
559      pagination: {
560        el: ".cause-pagination",
561        clickable: true,
562      },
563      breakpoints: {
564        768: {
565          slidesPerView: 2,
566        },
567        992: {
568          slidesPerView: 3,
569        },
570        1400: {
571          slidesPerView: 4,
572        },
573      },
574    });
575
576    /**
577     * ======================================
578     * 19. donate amount
579     * ======================================
580     */
581    if ($("#donationAmount").length > 0) {
582      const activeAmount = $(".donation-amount.active").text();
583      $("#donationAmount").val(activeAmount);
584
585      $(".donation-amount").on("click", function () {
586        $(".donation-amount").removeClass("active");
587        $(this).addClass("active");
588
589        if ($(this).hasClass("custom-amount")) {
590          $("#donationAmount").val("").focus(); // Clear and focus input for custom amount
591        } else {
592          const amount = $(this).text();
593          $("#donationAmount").val(amount);
594        }
595      });
596    }
597
598    /**
599     * ======================================
600     * 20. testimonial slider
601     * ======================================
602     */
603    var testimonial = new Swiper(".testimonial__slider", {
604      loop: true,
605      speed: 1000,
606      slidesPerView: 1,
607      slidesPerGroup: 1,
608      spaceBetween: 24,
609
610      autoplay: {
611        delay: 2000,
612        disableOnInteraction: false,
613        pauseOnMouseEnter: true,
614      },
615      navigation: {
616        nextEl: ".next-testimonial",
617        prevEl: ".prev-testimonial",
618      },
619
620      breakpoints: {
621        768: {
622          slidesPerView: 2,
623        },
624        1200: {
625          slidesPerView: 3,
626        },
627      },
628    });
629
630    /**
631     * ======================================
632     * 21. cause two slider content
633     * ======================================
634     */
635    var causeTwoSliderThumb = new Swiper(".cause-two__content-slider", {
636      loop: true,
637      speed: 1000,
638      slidesPerView: 1,
639      slidesPerGroup: 1,
640      spaceBetween: 24,
641      centeredSlides: true,
642      watchSlidesProgress: true,
643      effect: "fade",
644
645      fadeEffect: {
646        crossFade: true,
647      },
648      autoplay: {
649        delay: 3000,
650        disableOnInteraction: false,
651        pauseOnMouseEnter: true,
652      },
653      navigation: {
654        nextEl: ".next-cause-two",
655        prevEl: ".prev-cause-two",
656      },
657    });
658
659    var causeTwoSlider = new Swiper(".cause-two__slider", {
660      loop: true,
661      speed: 1000,
662      slidesPerView: 1,
663      slidesPerGroup: 1,
664      spaceBetween: 24,
665      effect: "coverflow",
666      grabCursor: true,
667      centeredSlides: true,
668      loopAddBlankSlides: true,
669      loopAdditionalSlides: 1,
670      slideToClickedSlide: true,
671      roundLengths: true,
672      coverflowEffect: {
673        rotate: 40,
674        stretch: 0,
675        depth: 100,
676        modifier: 1,
677        slideShadows: false,
678      },
679      autoplay: {
680        delay: 3000,
681        disableOnInteraction: false,
682        pauseOnMouseEnter: true,
683      },
684      thumbs: {
685        swiper: causeTwoSliderThumb,
686      },
687      navigation: {
688        nextEl: ".next-cause-two",
689        prevEl: ".prev-cause-two",
690      },
691      breakpoints: {
692        768: {
693          slidesPerView: 2,
694        },
695        1400: {
696          slidesPerView: 3,
697        },
698      },
699    });
700
701    /**
702     * ======================================
703     * 22. difference tab
704     * ======================================
705     */
706
707    $(".difference-two__content-single").hide();
708    $(".difference-two__content-single:first").show();
709
710    $(".difference-two__tab-btn").on("click", function () {
711      $(".difference-two__tab-btn").removeClass("active");
712      $(this).addClass("active");
713      $(".difference-two__content-single").hide();
714      var target = $(this).data("target");
715      $(target).fadeIn(500);
716      return false;
717    });
718
719    /**
720     * ======================================
721     * 23. odometer counter
722     * ======================================
723     */
724    $(".odometer").each(function () {
725      $(this).isInViewport(function (status) {
726        if (status === "entered") {
727          for (
728            var i = 0;
729            i < document.querySelectorAll(".odometer").length;
730            i++
731          ) {
732            var el = document.querySelectorAll(".odometer")[i];
733            el.innerHTML = el.getAttribute("data-odometer-final");
734          }
735        }
736      });
737    });
738
739    /**
740     * ======================================
741     * 24. testimonial two slider
742     * ======================================
743     */
744    var testimonialTwo = new Swiper(".testimonial-two__slider", {
745      loop: true,
746      speed: 2000,
747      slidesPerView: 1,
748      slidesPerGroup: 1,
749      spaceBetween: 0,
750      effect: "fade",
751      fadeEffect: {
752        crossFade: true,
753      },
754      autoplay: {
755        delay: 6000,
756        disableOnInteraction: false,
757        pauseOnMouseEnter: true,
758      },
759      navigation: {
760        nextEl: ".next-testimonial-two",
761        prevEl: ".prev-testimonial-two",
762      },
763    });
764
765    /**
766     * ======================================
767     * 25. testimonial three slider
768     * ======================================
769     */
770    var testimonialThree = new Swiper(".testimonial-three__slider", {
771      loop: true,
772      speed: 1000,
773      slidesPerView: 1,
774      slidesPerGroup: 1,
775      spaceBetween: 24,
776
777      autoplay: {
778        delay: 2000,
779        disableOnInteraction: false,
780        pauseOnMouseEnter: true,
781      },
782      navigation: {
783        nextEl: ".next-testimonial-three",
784        prevEl: ".prev-testimonial-three",
785      },
786
787      breakpoints: {
788        1400: {
789          slidesPerView: 2,
790        },
791      },
792    });
793
794    /**
795     * ======================================
796     * 26. coming soon
797     * ======================================
798     */
799    if ($(".clock").length > 0) {
800      const hourMarkersContainer = document.querySelector('.hour-markers');
801      for (let i = 0; i < 12; i++) {
802        const marker = document.createElement('div');
803        marker.classList.add('hour-marker');
804        const rotation = i * 30;
805        marker.style.transform = `rotate(${rotation}deg) translateY(-216.25px)`;
806    
807        const hourText = document.createElement('span');
808        hourText.textContent = i === 0 ? '12' : i;
809        hourText.style.transform = `rotate(-${rotation}deg)`;
810        marker.appendChild(hourText);
811    
812        hourMarkersContainer.appendChild(marker);
813      }
814    
815      const hourHand = document.querySelector(".hour-hand");
816      const minuteHand = document.querySelector(".minute-hand");
817      const secondHand = document.querySelector(".second-hand");
818    
819      function setClock() {
820        const now = new Date();
821        const seconds = now.getSeconds() + now.getMilliseconds() / 1000;
822        const minutes = now.getMinutes() + seconds / 60;
823        const hours = now.getHours() % 12 + minutes / 60;
824    
825        const secondsDeg = (seconds / 60) * 360;
826        const minutesDeg = (minutes / 60) * 360;
827        const hoursDeg = (hours / 12) * 360;
828    
829        hourHand.style.transform = `rotate(${hoursDeg}deg)`;
830        minuteHand.style.transform = `rotate(${minutesDeg}deg)`;
831        secondHand.style.transform = `rotate(${secondsDeg}deg)`;
832      }
833    
834      setInterval(setClock, 50);
835      setClock();
836    
837      const countdownElement = document.querySelector('.time-countdown');
838      const dayElement = countdownElement.querySelector('.day');
839      const hourElement = countdownElement.querySelector('.hour');
840      const minuteElement = countdownElement.querySelector('.minute');
841      const secondElement = countdownElement.querySelector('.second');
842    
843      const endDate = new Date();
844      endDate.setDate(endDate.getDate() + 100);
845    
846      function updateCountdown() {
847        const now = new Date();
848        const timeRemaining = endDate - now;
849    
850        if (timeRemaining <= 0) {
851          endDate.setDate(endDate.getDate() + 100);
852        }
853    
854        const days = Math.floor(timeRemaining / (1000 * 60 * 60 * 24));
855        const hours = Math.floor((timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
856        const minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));
857        const seconds = Math.floor((timeRemaining % (1000 * 60)) / 1000);
858    
859        dayElement.textContent = days;
860        hourElement.textContent = hours < 10 ? `0${hours}` : hours;
861        minuteElement.textContent = minutes < 10 ? `0${minutes}` : minutes;
862        secondElement.textContent = seconds < 10 ? `0${seconds}` : seconds;
863      }
864    
865      setInterval(updateCountdown, 1000);
866      updateCountdown();
867    
868    }
869    
870
871    /**
872     * ======================================
873     * 28. product details slider
874     * ======================================
875     */
876    var productGallery = new Swiper(".product-details-slider-gallery", {
877      loop: true,
878      speed: 1000,
879      slidesPerView: 2,
880      slidesPerGroup: 1,
881      spaceBetween: 24,
882      watchSlidesProgress: true,
883      autoplay: {
884        delay: 3000,
885        disableOnInteraction: false,
886        pauseOnMouseEnter: true,
887      },
888      breakpoints: {
889        576: {
890          slidesPerView: 3,
891        },
892        768: {
893          slidesPerView: 4,
894        },
895        1400: {
896          slidesPerView: 4,
897        },
898      },
899    });
900
901    var productSlider = new Swiper(".product-details-slider", {
902      loop: true,
903      speed: 1000,
904      slidesPerView: 1,
905      slidesPerGroup: 1,
906      spaceBetween: 24,
907      centeredSlides: true,
908      slideToClickedSlide: true,
909      roundLengths: true,
910      autoplay: {
911        delay: 3000,
912        disableOnInteraction: false,
913        pauseOnMouseEnter: true,
914      },
915      thumbs: {
916        swiper: productGallery,
917      },
918    });
919
920    /**
921     * ======================================
922     * 29. product details tab
923     * ======================================
924     */
925
926    $(".product-tab-content-single").hide();
927    $(".product-tab-content-single:first").show();
928
929    $(".product-tab__btn").on("click", function () {
930      $(".product-tab__btn").removeClass("active");
931      $(this).addClass("active");
932      $(".product-tab-content-single").hide();
933      var target = $(this).data("target");
934      $(target).fadeIn(500);
935      return false;
936    });
937
938    document.querySelectorAll(".range__slider").forEach(function (el) {
939      el.oninput = function () {
940        var valPercent =
941          (el.valueAsNumber - parseInt(el.min)) /
942          (parseInt(el.max) - parseInt(el.min));
943        var style =
944          "background-image: -webkit-gradient(linear, 0% 0%, 100% 0%, color-stop(" +
945          valPercent +
946          ", #ffc107), color-stop(" +
947          valPercent +
948          ", #505D6A30));";
949        el.style = style;
950      };
951      el.oninput();
952    });
953
954    /**
955     * ======================================
956     * 30. social link active on hover
957     * ======================================
958     */
959    $(".comment-single").each(function () {
960      $(this)
961        .find(".reply-button button")
962        .on("click", function () {
963          var $currentComment = $(this).closest(".comment-single");
964          $(".comment-single .reply-comment")
965            .not($currentComment.find(".reply-comment"))
966            .slideUp();
967          $currentComment.find(".reply-comment").slideToggle();
968          $(".comment-single .reply-button button")
969            .not(this)
970            .removeClass("active");
971          $(this).toggleClass("active");
972        });
973    });
974
975
976
977
978    
979
980
981
982    /**
983     * ======================================
984     * 31. footer copyright year
985     * ======================================
986     */
987    if ($("#copyrightYear").length > 0) {
988      $("#copyrightYear").text(new Date().getFullYear());
989    }
990
991    /**
992     * ======================================
993     * 32. aos initialization
994     * ======================================
995     */
996    // AOS.init();
997
998    /**
999     * ======================================
1000     * 33. vanilla tilt animations
1001     * ======================================
1002     */
1003
1004    let Vantilt = document.querySelectorAll(".van-tilt");
1005
1006    if (Vantilt) {
1007      VanillaTilt.init(document.querySelectorAll(".van-tilt"), {
1008        max: 5,
1009        speed: 3000,
1010      });
1011    }
1012
1013    /**
1014     * ======================================
1015     * 34. register gsap
1016     * ======================================
1017     */
1018    gsap.registerPlugin(ScrollTrigger, ScrollToPlugin);
1019
1020    /**
1021     * ======================================
1022     * 35. gsap null config
1023     * ======================================
1024     */
1025    gsap.config({
1026      nullTargetWarn: false,
1027    });
1028
1029    /**
1030     * ======================================
1031     * 36. target section with gsap
1032     * ======================================
1033     */
1034    $('a[href^="#"]:not([href="#"])').on("click", function (event) {
1035      event.preventDefault();
1036
1037      var target = $(this).attr("href");
1038
1039      gsap.to(window, {
1040        scrollTo: {
1041          y: target,
1042          offsetY: 100,
1043        },
1044        duration: 1,
1045        ease: "power3.inOut",
1046      });
1047    });
1048
1049    /**
1050     * ======================================
1051     * 37. parallax image with gsap
1052     * ======================================
1053     */
1054    var imageParallax = document.querySelectorAll(".parallax-image");
1055    if (imageParallax.length > 0) {
1056      $(".parallax-image").each(function () {
1057        $(this).wrap(
1058          '<div class="parallax-image-wrap"><div class="parallax-image-inner"></div></div>'
1059        );
1060        $(".parallax-image-wrap").css({
1061          overflow: "hidden",
1062        });
1063
1064        var $animImageParallax = $(this);
1065        var $aipWrap = $animImageParallax.parents(".parallax-image-wrap");
1066        var $aipInner = $aipWrap.find(".parallax-image-inner");
1067
1068        let tl_ImageParallax = gsap.timeline({
1069          scrollTrigger: {
1070            trigger: $aipWrap,
1071            start: "top bottom",
1072            end: "bottom top",
1073            scrub: true,
1074            onEnter: () => animImgParallaxRefresh(),
1075          },
1076        });
1077        tl_ImageParallax.to($animImageParallax, {
1078          yPercent: 80,
1079          ease: "none",
1080        });
1081
1082        function animImgParallaxRefresh() {
1083          tl_ImageParallax.scrollTrigger.refresh();
1084        }
1085
1086        let tl_aipZoomIn = gsap.timeline({
1087          scrollTrigger: {
1088            trigger: $aipWrap,
1089            start: "top 99%",
1090          },
1091        });
1092        tl_aipZoomIn.from($aipInner, {
1093          duration: 1.5,
1094          autoAlpha: 0,
1095          scale: 1.3,
1096          ease: Power2.easeOut,
1097          clearProps: "all",
1098        });
1099      });
1100    }
1101
1102    /**
1103     * ======================================
1104     * 38. title animation
1105     * ======================================
1106     */
1107
1108    if ($(".title-animation").length > 0) {
1109      let char_come = gsap.utils.toArray(".title-animation");
1110      char_come.forEach((char_come) => {
1111        let split_char = new SplitText(char_come, {
1112          type: "chars, words",
1113          lineThreshold: 0.5,
1114        });
1115        const tl2 = gsap.timeline({
1116          scrollTrigger: {
1117            trigger: char_come,
1118            start: "top 90%",
1119            end: "bottom 60%",
1120            scrub: false,
1121            markers: false,
1122            toggleActions: "play none none none",
1123          },
1124        });
1125        tl2.from(split_char.chars, {
1126          duration: 0.8,
1127          x: 40,
1128          autoAlpha: 0,
1129          stagger: 0.05,
1130          ease: "back.out",
1131        });
1132      });
1133    }
1134
1135    /**
1136     * ======================================
1137     * 39. banner three image animation
1138     * ======================================
1139     */
1140    if ($(".move-image").length > 0) {
1141      let mouse = { x: 0, y: 0, moved: false };
1142
1143      $(document).mousemove(function (e) {
1144        mouse.moved = true;
1145        mouse.x = e.clientX;
1146        mouse.y = e.clientY;
1147      });
1148
1149      gsap.ticker.add(() => {
1150        if (mouse.moved) {
1151          parallaxImages(".move-image", -30);
1152          mouse.moved = false;
1153        }
1154      });
1155
1156      function parallaxImages(selector, movement) {
1157        $(selector).each(function () {
1158          const rect = this.getBoundingClientRect();
1159          const offsetX =
1160            ((mouse.x - (rect.left + rect.width / 2)) / rect.width) * movement;
1161          const offsetY =
1162            ((mouse.y - (rect.top + rect.height / 2)) / rect.height) * movement;
1163
1164          gsap.to(this, {
1165            x: offsetX,
1166            y: offsetY,
1167            duration: 0.5,
1168          });
1169        });
1170      }
1171    }
1172    /**
1173     * ======================================
1174     * 40. progress bar
1175     * ======================================
1176     */
1177
1178    if ($(".progress-bar-single").length > 0) {
1179      $("[data-percent]").each(function () {
1180        $(this)
1181          .find(".progress-bar-percent")
1182          .css("width", $(this).attr("data-percent"));
1183        $(this).find(".percent-value").text($(this).attr("data-percent"));
1184      });
1185
1186      const ax_progress_bar = document.querySelectorAll(".progress-bar-single");
1187      ax_progress_bar.forEach((element) => {
1188        const w = element.querySelector(".progress-bar-percent");
1189        const p = element.querySelector(".percent-value");
1190
1191        const target = p.textContent;
1192
1193        const ax_bartl = gsap.timeline({
1194          defaults: {
1195            duration: 2,
1196          },
1197          scrollTrigger: {
1198            trigger: element,
1199          },
1200        });
1201
1202        ax_bartl.fromTo(
1203          w,
1204          {
1205            width: 0,
1206          },
1207          {
1208            width: target,
1209          }
1210        );
1211        ax_bartl.from(
1212          p,
1213          {
1214            textContent: 0 + "%",
1215            snap: {
1216              textContent: 5,
1217            },
1218          },
1219          "<"
1220        );
1221      });
1222    }
1223
1224    /**
1225     * ======================================
1226     * 41. circular progress bar
1227     * ======================================
1228     */
1229    if ($(".difference-progress-single").length > 0) {
1230      const progressBars = document.querySelectorAll(".progress-bar-single");
1231
1232      progressBars.forEach((element) => {
1233        const percentAttr = element.getAttribute("data-percent");
1234
1235        if (percentAttr) {
1236          const progress = percentAttr.replace("%", "");
1237          const percentDisplay = element.querySelector(".percent-value");
1238          const circle = element.querySelector(".circle-progress");
1239
1240          if (percentDisplay && circle) {
1241            const radius = 15.9155;
1242            const circumference = 2 * Math.PI * radius;
1243
1244            gsap.fromTo(
1245              circle,
1246              {
1247                strokeDashoffset: circumference,
1248              },
1249              {
1250                strokeDashoffset:
1251                  circumference - (progress / 100) * circumference,
1252                duration: 2,
1253                scrollTrigger: {
1254                  trigger: element,
1255                  start: "top 80%",
1256                  end: "bottom 20%",
1257                  toggleActions: "play none none none",
1258                },
1259              }
1260            );
1261
1262            gsap.fromTo(
1263              percentDisplay,
1264              {
1265                textContent: 0,
1266              },
1267              {
1268                textContent: progress,
1269                duration: 2,
1270                snap: { textContent: 1 },
1271                ease: "power1.inOut",
1272                onUpdate: function () {
1273                  percentDisplay.textContent =
1274                    Math.round(percentDisplay.textContent) + "%";
1275                },
1276              }
1277            );
1278          }
1279        }
1280      });
1281    }
1282
1283
1284
1285
1286// Testimonial scroll gsap js
1287      let pr = gsap.matchMedia();
1288      pr.add("(min-width: 992px)", () => {
1289
1290        let tl = gsap.timeline();
1291        let projectpanels = document.querySelectorAll('.project-panel')
1292        projectpanels.forEach((section, index) => {
1293          tl.to(section, {
1294            scrollTrigger: {
1295              trigger: section,
1296              pin: section,
1297              scrub: 1,
1298              start: 'center center',
1299              end: "bottom 100%",
1300              endTrigger: '.project-panel-area',
1301              pinSpacing: false,
1302              markers: false,
1303            },
1304          })
1305        })
1306      });
1307      
1308      
1309    /**
1310     * ======================================
1311     * 42. banner animation
1312     * ======================================
1313     */
1314    if ($(".banner").length > 0) {
1315      if (device_width >= 768) {
1316        var tl = gsap.timeline({
1317          scrollTrigger: {
1318            trigger: ".banner",
1319            start: "center center",
1320            end: "+=40%",
1321            scrub: 0.5,
1322            pin: false,
1323          },
1324        });
1325        tl.to(".circle-shape", {
1326          duration: 3,
1327          scale: 1.7,
1328        });
1329      }
1330    }
1331  });
1332})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.