PageSourceSearch

https://www.cloudfronts.com/wp-content/plugins/custom-elementor-widgets/assets/js/main.js?ver=1.0.0

js cloudfronts.com collected 2026-09-25 03:45:26 UTC 6,440 bytes, 139 lines download raw bytes

1(function($) {
2    'use strict';
3
4    // 1. Initialize Image Slider
5    var initImageSlider = function($scope) {
6        const carouselContainer = $scope.find('.carousel-container-unique')[0];
7        if (!carouselContainer) return;
8
9        const wrapper = carouselContainer.querySelector('.carousel-wrapper-unique');
10        const prevButton = carouselContainer.querySelector('.prev-button-unique');
11        const nextButton = carouselContainer.querySelector('.next-button-unique');
12        if (!wrapper || !prevButton || !nextButton) return;
13
14        const updateButtons = () => {
15            if (!wrapper.offsetParent) return; // a little check to avoid errors on hidden elements
16            const scrollEnd = wrapper.scrollWidth - wrapper.clientWidth;
17            prevButton.disabled = wrapper.scrollLeft <= 0;
18            nextButton.disabled = wrapper.scrollLeft >= scrollEnd - 1;
19        };
20
21        nextButton.addEventListener('click', () => {
22            const firstCard = wrapper.querySelector('.card-unique');
23            if (!firstCard) return;
24            const cardWidth = firstCard.offsetWidth;
25            const gap = parseInt(window.getComputedStyle(wrapper).gap);
26            wrapper.scrollBy({ left: cardWidth + gap, behavior: 'smooth' });
27        });
28
29        prevButton.addEventListener('click', () => {
30            const firstCard = wrapper.querySelector('.card-unique');
31            if (!firstCard) return;
32            const cardWidth = firstCard.offsetWidth;
33            const gap = parseInt(window.getComputedStyle(wrapper).gap);
34            wrapper.scrollBy({ left: -(cardWidth + gap), behavior: 'smooth' });
35        });
36
37        wrapper.addEventListener('scroll', updateButtons, { passive: true });
38        new ResizeObserver(updateButtons).observe(wrapper);
39        setTimeout(updateButtons, 100);
40    };
41
42    // 2. Initialize Testimonial Slider
43    var initTestimonialSlider = function($scope) {
44        const slider = $scope.find('.testimonial-section-tslider')[0];
45        if (!slider) return;
46
47        const wrapper = slider.querySelector('.testimonial-wrapper-tslider');
48        const prevButton = slider.querySelector('.testimonial-prev-btn-tslider');
49        const nextButton = slider.querySelector('.testimonial-next-btn-tslider');
50        if (!wrapper || !prevButton || !nextButton) return;
51
52        const updateButtons = () => {
53            if (!wrapper.offsetParent) return;
54            const scrollEnd = wrapper.scrollWidth - wrapper.clientWidth;
55            prevButton.disabled = wrapper.scrollLeft <= 0;
56            nextButton.disabled = wrapper.scrollLeft >= scrollEnd - 1;
57        };
58
59        const handleScroll = (direction) => {
60            const firstCard = wrapper.querySelector('.testimonial-card-tslider');
61            if (!firstCard) return;
62            const gap = parseInt(window.getComputedStyle(wrapper).gap) || 20;
63            const scrollAmount = firstCard.offsetWidth + gap;
64            wrapper.scrollBy({ left: scrollAmount * direction, behavior: 'smooth' });
65        };
66
67        nextButton.addEventListener('click', () => handleScroll(1));
68        prevButton.addEventListener('click', () => handleScroll(-1));
69        wrapper.addEventListener('scroll', updateButtons, { passive: true });
70        new ResizeObserver(updateButtons).observe(wrapper);
71        setTimeout(updateButtons, 50);
72    };
73
74    // 3. Initialize Case Studies Slider
75    var initCaseStudiesSlider = function($scope) {
76        const slider = $scope.find('.latest-work-wslider')[0];
77        if (!slider) return;
78
79        const wrapper = slider.querySelector('.wslider-wrapper');
80        const prevButton = slider.querySelector('.wslider-prev-btn');
81        const nextButton = slider.querySelector('.wslider-next-btn');
82        if (!wrapper || !prevButton || !nextButton) return;
83
84        const updateButtons = () => {
85            if (!wrapper.offsetParent) return;
86            const scrollEnd = wrapper.scrollWidth - wrapper.clientWidth;
87            prevButton.disabled = wrapper.scrollLeft <= 0;
88            nextButton.disabled = wrapper.scrollLeft >= scrollEnd - 1;
89        };
90
91        const handleScroll = (direction) => {
92            const firstCard = wrapper.querySelector('.wslider-card');
93            if (!firstCard) return;
94            const gap = parseInt(window.getComputedStyle(wrapper).gap) || 24;
95            const scrollAmount = firstCard.offsetWidth + gap;
96            wrapper.scrollBy({ left: scrollAmount * direction, behavior: 'smooth' });
97        };
98
99        nextButton.addEventListener('click', () => handleScroll(1));
100        prevButton.addEventListener('click', () => handleScroll(-1));
101        wrapper.addEventListener('scroll', updateButtons, { passive: true });
102        new ResizeObserver(updateButtons).observe(wrapper);
103        setTimeout(updateButtons, 50);
104    };
105
106    // 4. Initialize Insights Tabs
107    var initInsightsTabs = function($scope) {
108        const container = $scope.find('.cf-insights-container')[0];
109        if (!container) return;
110
111        const tabButtons = container.querySelectorAll('.tab-button');
112        const tabContents = container.querySelectorAll('.tab-content');
113
114        tabButtons.forEach(button => {
115            button.addEventListener('click', () => {
116                const tabName = button.getAttribute('data-tab');
117
118                tabButtons.forEach(btn => btn.classList.remove('active'));
119                button.classList.add('active');
120
121                tabContents.forEach(content => {
122                    content.classList.remove('active');
123                    if (content.id === tabName) {
124                        content.classList.add('active');
125                    }
126                });
127            });
128        });
129    };
130
131    // Elementor Frontend Hook
132    $(window).on('elementor/frontend/init', function() {
133        elementorFrontend.hooks.addAction('frontend/element_ready/image-slider-widget.default', initImageSlider);
134        elementorFrontend.hooks.addAction('frontend/element_ready/testimonial-slider-widget.default', initTestimonialSlider);
135        elementorFrontend.hooks.addAction('frontend/element_ready/case-studies-widget.default', initCaseStudiesSlider);
136        elementorFrontend.hooks.addAction('frontend/element_ready/insights-tabs-widget.default', initInsightsTabs);
137    });
138
139})(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.