PageSourceSearch

https://allcoolthings.net/wp-content/plugins/jet-tricks/assets/js/jet-tricks-frontend.js?ver=1.5.2

js allcoolthings.net collected 2026-10-04 14:16:37 UTC 36,987 bytes, 1,264 lines download raw bytes

1( function( $, elementor ) {
2
3	'use strict';
4
5	var JetTricks = {
6
7		init: function() {
8			elementor.hooks.addAction( 'frontend/element_ready/section', JetTricks.elementorSection );
9			elementor.hooks.addAction( 'frontend/element_ready/section', JetTricks.elementorColumn );
10			elementor.hooks.addAction( 'frontend/element_ready/container', JetTricks.elementorSection );
11			elementor.hooks.addAction( 'frontend/element_ready/container', JetTricks.elementorColumn );
12			elementor.hooks.addAction( 'frontend/element_ready/column', JetTricks.elementorColumn );
13			elementor.hooks.addAction( 'frontend/element_ready/widget', JetTricks.elementorWidget );
14
15			var widgets = {
16				'jet-view-more.default' : JetTricks.widgetViewMore,
17				'jet-unfold.default' : JetTricks.widgetUnfold,
18				'jet-hotspots.default' : JetTricks.widgetHotspots
19			};
20
21			$.each( widgets, function( widget, callback ) {
22				elementor.hooks.addAction( 'frontend/element_ready/' + widget, callback );
23			});
24
25			// Re-init widgets in nested tabs
26			window.elementorFrontend.elements.$window.on(
27				'elementor/nested-tabs/activate',
28				( event, content ) => {
29
30					const $content = $( content );
31
32					var $button  = $content.find( '.jet-unfold__button' );
33
34					$button.off( 'click.jetUnfold' );
35
36					JetTricks.initWidgetsHandlers( $content );
37					JetTricks.elementorSection( $content );
38
39				}
40			);
41
42			// Add an action when the Swiper Loop Carousel widget is ready on the frontend
43			var loopCarouselTypes = [
44				'loop-carousel.post',
45				'loop-carousel.product',
46				'loop-carousel.post_taxonomy',
47				'loop-carousel.product_taxonomy'
48			];
49			
50			loopCarouselTypes.forEach( function( carouselType ) {
51				elementorFrontend.hooks.addAction( 'frontend/element_ready/' + carouselType, function( $scope, $ ) {
52					
53					$( window ).on( 'load', function() {
54						var loopCarousel = $scope.find( '.swiper' ),
55							swiperInstance = loopCarousel.data( 'swiper' ),
56							$button = $scope.find( '.jet-unfold__button' );
57						
58						if ( swiperInstance && $button ) {
59				
60							$button.off( 'click.jetUnfold' );
61							JetTricks.initLoopCarouselHandlers( $scope );
62				
63							swiperInstance.on( 'slideChange', function() {
64								$button.off( 'click.jetUnfold' );
65								JetTricks.initLoopCarouselHandlers( $scope );
66							});
67						}
68					});
69				});
70			});
71		},
72
73		initLoopCarouselHandlers: function( $selector ) {
74			$selector.find( '.elementor-widget-jet-unfold' ).each( function() {
75
76				var $this  = $( this ),
77
78				elementType = $this.data( 'element_type' );
79
80				if ( !elementType ) {
81					return;
82				}
83
84				if ( 'widget' === elementType ) {
85					elementType = $this.data( 'widget_type' );
86					window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ );
87				}
88
89				window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ );
90				window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ );
91
92
93			} );
94		},
95
96		initWidgetsHandlers: function( $selector ) {
97
98				$selector.find( '[data-element_type]' ).each( function() {
99
100					var excludeWidgets = [
101						'jet-woo-product-gallery-slider.default',
102						'accordion.default' 
103					];
104
105					var $this  = $( this ),
106
107					elementType = $this.data( 'element_type' );
108
109					if ( !elementType ) {
110						return;
111					}
112
113					if ( 'widget' === elementType ) {
114
115						elementType = $this.data( 'widget_type' );
116						
117						if ( excludeWidgets.includes( elementType ) ) {
118							return;
119						}
120						
121						window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ );
122					}
123
124					window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ );
125					window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ );
126
127
128				} );
129		},
130
131		elementorSection: function( $scope ) {
132			var $target        = $scope,
133				sectionId      = $scope.data( 'id' ),
134				editMode       = Boolean( elementor.isEditMode() ),
135				jetListing     = $target.parents( '.elementor-widget-jet-listing-grid' ).data( 'id' ),
136				settings       = {};
137
138			if ( window.JetTricksSettings && window.JetTricksSettings.elements_data.sections.hasOwnProperty( sectionId ) ) {
139				settings = window.JetTricksSettings.elements_data.sections[ sectionId ];
140			}
141
142			if ( editMode ) {
143				settings = JetTricks.sectionEditorSettings( $scope );
144			}
145
146			if ( ! settings ) {
147				return false;
148			}
149
150			if ( jQuery.isEmptyObject( settings ) ) {
151				return false;
152			}
153
154			if ( 'false' === settings.particles || '' === settings.particles_json ) {
155				return false;
156			}
157
158			// Compatibility jet tricks particles with jet listing
159
160			if ( jetListing && $target.parent().data( 'elementor-type' ) === 'jet-listing-items' ){
161				sectionId += jetListing + $target.parents( '.jet-listing-grid__item' ).data( 'post-id' );
162			} 
163
164			var particlesId   = 'jet-tricks-particles-instance-' + sectionId,
165				particlesJson = JSON.parse( settings.particles_json );
166
167			$scope.prepend( '<div id="' + particlesId + '" class="jet-tricks-particles-section__instance"></div>' );
168
169			// Initialize particles based on library version
170
171			if ( typeof tsParticles !== 'undefined' && tsParticles.load && tsParticles.version && tsParticles.version.startsWith('3.') ) {
172				tsParticles.load({
173					id: particlesId,
174					options: particlesJson
175				});
176			} else if ( typeof tsParticles !== 'undefined' && tsParticles.load ) {
177				tsParticles.load( particlesId, particlesJson );
178			}
179
180		},
181
182		elementorColumn: function( $scope ) {
183			var $target  = $scope,
184				$parentSection = $scope.closest( '.elementor-section' ),
185				isLegacyModeActive = !!$target.find( '> .elementor-column-wrap' ).length,
186				$window  = $( window ),
187				columnId = $target.data( 'id' ),
188				editMode = Boolean( elementor.isEditMode() ),
189				settings = {},
190				stickyInstance = null,
191				stickyInstanceOptions = {
192					topSpacing: 50,
193					bottomSpacing: 50,
194					containerSelector: isLegacyModeActive ? '.elementor-row' : '.elementor-container, .e-con-inner',
195					innerWrapperSelector: isLegacyModeActive ? '.elementor-column-wrap' : '.elementor-widget-wrap',
196				},
197				$observerTarget = $target.find('.elementor-element');
198
199			if ( ! editMode ) {
200				settings = $target.data( 'jet-settings' );
201
202				if ( $target.hasClass( 'jet-sticky-column' ) ) {
203					if ( -1 !== settings['stickyOn'].indexOf( elementorFrontend.getCurrentDeviceMode() ) ) {
204						$target.each( function() {
205							var $this  = $( this ),
206								elementType = $this.data( 'element_type' );
207		
208							if ( settings['behavior'] === 'fixed' ) {
209								initFixedSticky( $this, settings );
210							} else if ( elementType !== 'container' && elementType !== 'section' ) {
211								initSidebarSticky( $this, settings, stickyInstanceOptions );
212							} else if ( settings['behavior'] === 'scroll_until_end' ) {
213								initScrollUntilEndSticky( $this, settings );
214							} else {
215								initDefaultSticky( $this, settings );
216							}
217						});
218					}
219				}
220			}
221
222			function initFixedSticky($element, settings) {
223				var offsetTop = parseInt(settings['topSpacing']) || 0;
224				var bottomSpacing = parseInt(settings['bottomSpacing']) || 0;
225				var $window = $(window);
226				var elementId = $element.data('id');
227				var originalOffsetTop = $element.offset().top;
228				var originalHeight = $element.outerHeight();
229			
230				var $allStickyElements = $('.jet-sticky-column').filter(function() {
231					var $this = $(this);
232					var elementSettings = $this.data('jet-settings');
233
234					return elementSettings && elementSettings.stickyOn.indexOf(elementorFrontend.getCurrentDeviceMode()) !== -1;
235				});
236
237				var currentIndex = $allStickyElements.index($element);
238				var $nextSticky = currentIndex + 1 < $allStickyElements.length ? $allStickyElements.eq(currentIndex + 1) : null;
239				var $stopper = null;
240				if ($nextSticky) {
241					$stopper = $nextSticky.closest('.elementor-top-section, .e-parent');
242					if (!$stopper.length) {
243						$stopper = $nextSticky;
244					}
245				}
246			
247				const $placeholder = $('<div></div>')
248					.addClass('jet-sticky-placeholder')
249					.css({
250						display: 'none',
251						height: originalHeight,
252						width: $element.outerWidth(),
253						visibility: 'hidden'
254					});
255			
256				$element.before($placeholder);				
257			
258				function enableSticky() {
259					$placeholder.show();
260					$element.addClass('jet-sticky-container--stuck');
261			
262					var stopperTop = $stopper?.offset()?.top;
263					var stopPoint = stopperTop ? (stopperTop - $element.outerHeight() - offsetTop - bottomSpacing) : null;
264					var diff = 0;
265			
266					if (stopPoint && stopPoint < $window.scrollTop()) {
267						diff = (stopPoint - $window.scrollTop());
268					}
269			
270					$element.css({
271						position: 'fixed',
272						top: diff + 'px',
273						transform: `translateY(${offsetTop}px)`,
274						left: $placeholder.offset().left + 'px',
275						width: $placeholder.outerWidth() + 'px'
276					});
277				}
278			
279				function disableSticky() {
280					$placeholder.hide();
281					$element.removeClass('jet-sticky-container--stuck');
282			
283					$element.css({
284						position: '',
285						top: '',
286						transform: '',
287						left: '',
288						width: ''
289					});
290				}
291			
292				function onScroll() {
293					var scrollTop = $window.scrollTop();
294					if (scrollTop >= originalOffsetTop) {
295						enableSticky();
296					} else {
297						disableSticky();
298					}
299				}
300			
301				function onResize() {
302					originalOffsetTop = $placeholder.offset().top;
303					originalHeight = $element.outerHeight();
304			
305					$placeholder.css({
306						height: originalHeight,
307						width: $element.outerWidth()
308					});
309			
310					onScroll();
311				}
312			
313				let ticking = false;
314				$window.on('scroll.jetStickyHeader-' + elementId, function() {
315					if (!ticking) {
316						requestAnimationFrame(function() {
317							onScroll();
318							ticking = false;
319						});
320						ticking = true;
321					}
322				});
323			
324				$window.on('resize.jetStickyHeader-' + elementId, JetTricksTools.debounce(100, onResize));
325				onScroll();
326			
327				$window.on('resize.jetStickyHeader-' + elementId, JetTricksTools.debounce(100, function() {
328					if (-1 === settings['stickyOn'].indexOf(elementorFrontend.getCurrentDeviceMode())) {
329						cleanupSticky($element, $placeholder, elementId);
330					}
331				}));
332			}
333			
334			function cleanupSticky( $element, $placeholder, elementId ) {
335				$placeholder.remove();
336				$element.css({
337					position: '',
338					top: '',
339					transform: '',
340					left: '',
341					width: '',
342					zIndex: '',
343					transition: '',
344					willChange: ''
345				});
346				$element.removeClass('jet-sticky-container--stuck');
347				$window.off('scroll.jetStickyHeader-' + elementId);
348				$window.off('resize.jetStickyHeader-' + elementId);
349			}
350
351			function initSidebarSticky( $element, settings, options ) {
352				options.topSpacing = settings['topSpacing'];
353				options.bottomSpacing = settings['bottomSpacing'];
354
355				imagesLoaded( $parentSection, function() {
356					$target.data( 'stickyColumnInit', true );
357					stickyInstance = new StickySidebar( $target[0], options );
358				});
359
360				var targetMutation = $target[0],
361					config = { attributes: true, childList: true, subtree: true };
362
363				var observer = new MutationObserver( function( mutations ) {
364					for( var mutation of mutations ) {
365						if ( 'attributes' === mutation.type ) {
366							$target[0].style.height = 'auto';
367						}
368					}
369				});
370
371				observer.observe( targetMutation, config );
372
373				$window.on( 'resize.JetTricksStickyColumn orientationchange.JetTricksStickyColumn', 
374					JetTricksTools.debounce( 50, resizeDebounce ) );
375
376				var observer = new MutationObserver( function( mutations ) {
377					if ( stickyInstance ) {
378						mutations.forEach( function(mutation){
379							if (mutation.attributeName === 'class') {
380								setTimeout( function() {
381									stickyInstance.destroy();
382									stickyInstance = new StickySidebar( $target[0], options );
383								}, 100 );
384							}
385						});
386					}
387				});
388
389				$observerTarget.each( function(){
390					observer.observe( $( this )[0], {
391						attributes: true
392					});
393				});
394			}
395
396			function initScrollUntilEndSticky( $element, settings ) {
397				const stickyHeight = $element.outerHeight();
398				const stickyContentBottom = $element.offset().top + stickyHeight;
399				const stickyViewportOffset = $window.height() - stickyHeight - settings['bottomSpacing'];
400
401				$('body').addClass('jet-sticky-container');
402
403				$window.on( 'scroll.jetSticky', function () {
404					const scrollPosition = $window.scrollTop();
405
406					if ( scrollPosition + $window.height() >= stickyContentBottom ) {
407						$element.css({
408							position: 'sticky',
409							top: stickyViewportOffset + 'px',
410							bottom: 'auto',
411							left: 'auto',
412							zIndex: settings['zIndex'],
413						});
414					}
415				});
416
417				$observerTarget.on( 'destroy.jetSticky', function () {
418					$window.off( 'scroll.jetSticky' );
419					$('body').removeClass('jet-sticky-container');
420				});
421			}
422
423			function initDefaultSticky( $element, settings ) {
424				$('body').addClass('jet-sticky-container');
425				$element.addClass( 'jet-sticky-container-sticky' );
426				$element.css({ 
427					'top': settings['topSpacing'], 
428					'bottom': settings['bottomSpacing']
429				});
430			}
431
432			function resizeDebounce() {
433				var currentDeviceMode = elementorFrontend.getCurrentDeviceMode(),
434					availableDevices  = settings['stickyOn'] || [],
435					isInit            = $target.data( 'stickyColumnInit' );
436
437				if ( -1 !== availableDevices.indexOf( currentDeviceMode ) ) {
438					if ( ! isInit ) {
439						$target.data( 'stickyColumnInit', true );
440						stickyInstance = new StickySidebar( $target[0], stickyInstanceOptions );
441						stickyInstance.updateSticky();
442					}
443				} else {
444					$target.data( 'stickyColumnInit', false );
445					stickyInstance.destroy();
446				}
447			}
448		},
449
450		elementorWidget: function( $scope ) {
451			var parallaxInstance = null,
452				satelliteInstance = null,
453				tooltipInstance = null;
454
455			parallaxInstance = new jetWidgetParallax( $scope );
456			parallaxInstance.init();
457
458			satelliteInstance = new jetWidgetSatellite( $scope );
459			satelliteInstance.init();
460
461			tooltipInstance = new jetWidgetTooltip( $scope );
462			tooltipInstance.init();
463
464		},
465
466		getElementorElementSettings: function( $scope ) {
467
468			if ( window.elementorFrontend && window.elementorFrontend.isEditMode() && $scope.hasClass( 'elementor-element-edit-mode' ) ) {
469				return JetTricks.getEditorElementSettings( $scope );
470			}
471
472			return $scope.data( 'settings' ) || {};
473		},
474
475		getEditorElementSettings: function( $scope ) {
476			var modelCID = $scope.data( 'model-cid' ),
477				elementData;
478
479			if ( ! modelCID ) {
480				return {};
481			}
482
483			if ( ! elementor.hasOwnProperty( 'config' ) ) {
484				return {};
485			}
486
487			if ( ! elementor.config.hasOwnProperty( 'elements' ) ) {
488				return {};
489			}
490
491			if ( ! elementor.config.elements.hasOwnProperty( 'data' ) ) {
492				return {};
493			}
494
495			elementData = elementor.config.elements.data[ modelCID ];
496
497			if ( ! elementData ) {
498				return {};
499			}
500
501			return elementData.toJSON();
502		},
503
504		widgetViewMore: function( $scope ) {
505			var $target         = $scope.find( '.jet-view-more' ),
506				instance        = null,
507				settings        = $target.data( 'settings' );
508
509			instance = new jetViewMore( $target, settings );
510			instance.init();
511		},
512
513		widgetUnfold: function( $scope ) {
514			var $target                = $scope.find( '.jet-unfold' ),
515				$button                = $( '.jet-unfold__button', $target ),
516				$mask                  = $( '.jet-unfold__mask', $target ),
517				$content               = $( '.jet-unfold__content', $target ),
518				$contentInner          = $( '.jet-unfold__content-inner', $target),
519				$trigger               = $( '.jet-unfold__trigger', $target),
520				$separator             = $( '.jet-unfold__separator', $target ),
521				settings               = $.extend( {}, $target.data( 'settings' ), JetTricks.getElementorElementSettings( $scope ) ),
522				maskBreakpointsHeights = [],
523				prevBreakpoint         = '',
524				unfoldDuration         = settings['unfoldDuration'] || settings['unfold_duration'],
525				foldDuration           = settings['foldDuration'] || settings['fold_duration'],
526				unfoldEasing           = settings['unfoldEasing'] || settings['unfold_easing'],
527				foldEasing             = settings['foldEasing'] || settings['fold_easing'],
528				maskHeightAdv          = 20,
529				heightCalc             = '',
530				autoHide               = settings['autoHide'] || false,
531				autoHideTime           = settings['autoHideTime'] && 0 != settings['autoHideTime']['size'] ? settings['autoHideTime']['size'] : 5,
532				hideOutsideClick       = settings['hideOutsideClick'] || false,
533				autoHideTrigger,
534				activeBreakpoints      = elementor.config.responsive.activeBreakpoints,
535				initialLoaded          = false;
536
537			maskBreakpointsHeights['desktop']    = [];
538			maskBreakpointsHeights['widescreen'] = [];
539
540			maskBreakpointsHeights['desktop']['maskHeight'] = '' != settings['mask_height']['size'] ? settings['mask_height']['size'] : 50;
541
542			prevBreakpoint = 'desktop';
543
544			Object.keys(  activeBreakpoints ).reverse().forEach(  function( breakpointName ) {
545
546				if ( 'widescreen' === breakpointName ) {
547					maskBreakpointsHeights['widescreen']['maskHeight'] = '' != settings['mask_height_widescreen']['size'] ? settings['mask_height_widescreen']['size'] : maskBreakpointsHeights['desktop']['maskHeight'];
548				} else {
549					maskBreakpointsHeights[breakpointName] = [];
550
551					maskBreakpointsHeights[breakpointName]['maskHeight'] = '' != settings['mask_height_' + breakpointName]['size'] ? settings['mask_height_' + breakpointName]['size'] : maskBreakpointsHeights[prevBreakpoint]['maskHeight'];
552
553					prevBreakpoint = breakpointName;
554				}
555			} );
556
557			onLoaded();
558
559			if ( 'true' === hideOutsideClick ) {
560				$( window ).on( 'mouseup', function( event ) {
561					let container = $target;
562					if ( !container.is( event.target ) && 0 === container.has( event.target ).length && $target.hasClass( 'jet-unfold-state' ) ) {
563						$button.trigger( 'click' );
564					}
565				} )
566			}
567
568			$target.one('transitionend webkitTransitionEnd oTransitionEnd', function() {
569				if ( !initialLoaded ) {
570					onLoaded();
571					initialLoaded = true;
572				}
573			});
574
575			function onLoaded() {
576				initialLoaded = true;
577
578				var deviceHeight = getDeviceHeight();
579
580				heightCalc = +deviceHeight + maskHeightAdv;
581
582				if ( heightCalc < $contentInner.height() ) {
583
584					if ( ! $target.hasClass( 'jet-unfold-state' ) ) {
585						$separator.css( {
586							'opacity': '1'
587						} );
588					}
589
590					if ( ! $target.hasClass( 'jet-unfold-state' ) ) {
591						$mask.css( {
592							'height': deviceHeight
593						} );
594					} else {
595						$mask.css( {
596							'height': $contentInner.outerHeight()
597						} );
598					}
599					$trigger.css( 'display', 'flex' );
600				} else {
601					$trigger.hide();
602					$mask.css( {
603						'height': '100%'
604					} );
605					$content.css( {
606						'max-height': 'none'
607					} );
608					$separator.css( {
609						'opacity': '0'
610					} );
611				}
612			}
613
614			$( window ).on( 'resize.jetWidgetUnfold orientationchange.jetWidgetUnfold', JetTricksTools.debounce( 50, function(){
615				initialLoaded = false;
616				onLoaded();
617			} ) );
618
619			$button.keypress( function( e ) {
620				if ( e.which == 13 ) {
621					$button.click();
622					return false;
623				}
624			} );
625
626			$button.on( 'click.jetUnfold', function(e) {
627				var $this         = $( this ),
628					$buttonText   = $( '.jet-unfold__button-text', $this ),
629					unfoldText    = $this.data( 'unfold-text' ),
630					foldText      = $this.data( 'fold-text' ),
631					$buttonIcon   = $( '.jet-unfold__button-icon', $this ),
632					unfoldIcon    = $this.data( 'unfold-icon' ),
633					foldIcon      = $this.data( 'fold-icon' ),
634					contentHeight = $contentInner.outerHeight(),
635					deviceHeight  = getDeviceHeight();
636
637				e.preventDefault();
638
639				if ( ! $target.hasClass( 'jet-unfold-state' ) ) {
640					$target.addClass( 'jet-unfold-state' );
641
642					$separator.css( {
643						'opacity': '0'
644					} );
645
646					$buttonIcon.html( foldIcon );
647					$buttonText.html( foldText );
648
649					anime( {
650						targets: $mask[0],
651						height: contentHeight,
652						duration: unfoldDuration['size'],
653						easing: unfoldEasing,
654						complete: function( anim ) {
655							// Recalculate listing masonry.
656							$( document ).trigger( 'jet-engine/listing/recalculate-masonry' );
657						}
658					} );
659
660					if ( 'true' === autoHide ) {
661						autoHideTrigger = setTimeout( function() {
662							$button.trigger( 'click' );
663						}, autoHideTime * 1000 );
664					}
665				} else {
666					clearTimeout( autoHideTrigger );
667
668					$target.removeClass( 'jet-unfold-state' );
669
670					$separator.css( {
671						'opacity': '1'
672					} );
673
674					$buttonIcon.html( unfoldIcon );
675					$buttonText.html( unfoldText );
676
677					anime( {
678						targets: $mask[0],
679						height: deviceHeight,
680						duration: foldDuration['size'],
681						easing: foldEasing,
682						complete: function( anim ) {
683							if ( 'true' === settings['foldScrolling'] ) {
684								$( 'html, body' ).animate( {
685									scrollTop: $target.offset().top - settings['foldScrollOffset']['size']
686								}, 'slow' );
687							}
688
689							// Recalculate listing masonry.
690							$( document ).trigger( 'jet-engine/listing/recalculate-masonry' );
691						}
692					} );
693				}
694			} );
695
696			function getDeviceHeight() {
697				let device = elementorFrontend.getCurrentDeviceMode();
698				let heightSettings;
699
700				switch ( device ) {
701
702					case 'mobile':
703						heightSettings = settings.mask_height_mobile;
704						break;
705
706					case 'tablet':
707						heightSettings = settings.mask_height_tablet;
708						break;
709
710					default:
711						heightSettings = settings.mask_height;
712
713				}
714
715				if ( ! heightSettings || ! heightSettings.size || ! heightSettings.unit ) {
716					heightSettings = settings.mask_height;
717				}
718
719				switch ( heightSettings.unit ) {
720
721					case 'vh':
722						return ( window.innerHeight * heightSettings.size ) / 100;
723
724					case '%':
725						let parentHeight = $contentInner.parent().height();
726						return ( parentHeight * heightSettings.size ) / 100;
727
728					default:
729						return heightSettings.size;
730				}
731			}
732		},
733
734		widgetHotspots: function( $scope ) {
735			var $target   = $scope.find( '.jet-hotspots' ),
736				$hotspots = $( '.jet-hotspots__item', $target),
737				settings  = $target.data( 'settings' ),
738				editMode  = Boolean( elementor.isEditMode() ),
739				itemActiveClass = 'jet-hotspots__item--active';
740
741			$target.imagesLoaded().progress( function() {
742				$target.addClass( 'image-loaded' );
743			} );
744
745			$hotspots.each( function( index ) {
746				var $this          = $( this ),
747					horizontal     = $this.data( 'horizontal-position' ),
748					vertical       = $this.data( 'vertical-position' ),
749					tooltipWidth   = $this.data( 'tooltip-width' ) || null,
750					itemSelector   = $this[0],
751					options        = {};
752
753				$this.css( {
754					'left': horizontal + '%',
755					'top': vertical + '%'
756				} );
757
758				if ( itemSelector._tippy ) {
759					itemSelector._tippy.destroy();
760				}
761
762				options = {
763					content: $this.data('tippy-content'),
764					arrow: settings['tooltipArrow'] ? true : false,
765					placement: settings['tooltipPlacement'],
766					trigger: settings['tooltipTrigger'],
767					appendTo: $target[0],
768					hideOnClick: 'manual' !== settings['tooltipTrigger'],
769					maxWidth: 'none',
770					offset: [0, settings['tooltipDistance']['size']],
771					allowHTML: true,
772					onShow( instance ) {
773						$( itemSelector ).addClass( itemActiveClass );
774
775						if ( tooltipWidth ) {
776							instance.popper.querySelector( '.tippy-box' ).style.width = tooltipWidth;
777						}
778
779					},
780					onHidden( instance ) {
781						$( itemSelector ).removeClass( itemActiveClass );
782					}
783				}
784
785				if ( 'manual' != settings['tooltipTrigger'] ) {
786					options['duration']  = [ settings['tooltipShowDuration']['size'], settings['tooltipHideDuration']['size'] ];
787					options['animation'] = settings['tooltipAnimation'];
788					options['delay']     = settings['tooltipDelay'];
789				}
790
791				tippy( [ itemSelector ], options );
792
793				if ( 'manual' === settings['tooltipTrigger'] && itemSelector._tippy ) {
794					itemSelector._tippy.show();
795				}
796
797				if ( settings['tooltipShowOnInit'] && itemSelector._tippy ) {
798					itemSelector._tippy.show();
799				}
800
801			} );
802		},
803
804		columnEditorSettings: function( columnId ) {
805			var editorElements = null,
806				columnData     = {};
807
808			if ( ! window.elementor.hasOwnProperty( 'elements' ) ) {
809				return false;
810			}
811
812			editorElements = window.elementor.elements;
813
814			if ( ! editorElements.models ) {
815				return false;
816			}
817
818			$.each( editorElements.models, function( index, obj ) {
819
820				$.each( obj.attributes.elements.models, function( index, obj ) {
821					if ( columnId == obj.id ) {
822						columnData = obj.attributes.settings.attributes;
823					}
824				} );
825
826			} );
827
828			return {
829				'sticky': columnData['jet_tricks_column_sticky'] || false,
830				'topSpacing': columnData['jet_tricks_top_spacing'] || 50,
831				'bottomSpacing': columnData['jet_tricks_bottom_spacing'] || 50,
832				'stickyOn': columnData['jet_tricks_column_sticky_on'] || [ 'desktop', 'tablet', 'mobile']
833			}
834
835		},
836
837		sectionEditorSettings: function( $scope ) {
838			var editorElements = null,
839				sectionData     = {};
840
841			if ( ! window.elementor.hasOwnProperty( 'elements' ) ) {
842				return false;
843			}
844
845			sectionData = JetTricks.getElementorElementSettings( $scope );
846
847			return {
848				'particles': sectionData['section_jet_tricks_particles'] || 'false',
849				'particles_json': sectionData['section_jet_tricks_particles_json'] || '',
850			}
851
852		}
853
854	};
855
856	$( window ).on( 'elementor/frontend/init', JetTricks.init );
857
858	var JetTricksTools = {
859		debounce: function( threshold, callback ) {
860			var timeout;
861
862			return function debounced( $event ) {
863				function delayed() {
864					callback.call( this, $event );
865					timeout = null;
866				}
867
868				if ( timeout ) {
869					clearTimeout( timeout );
870				}
871
872				timeout = setTimeout( delayed, threshold );
873			};
874		},
875
876		widgetEditorSettings: function( widgetId ) {
877			var editorElements = null,
878				widgetData = {};
879		
880			if ( !window.elementor.hasOwnProperty( 'elements' ) || !window.elementor.elements.models ) {
881				return false;
882			}
883		
884			editorElements = window.elementor.elements;
885		
886			function findWidgetById( models, widgetId ) {
887				let foundData = null;
888		
889				$.each( models, function( index, obj ) {
890					if ( obj.id === widgetId ) {
891						foundData = obj.attributes.settings.attributes;
892						return false;
893					}
894					if ( obj.attributes.elements && obj.attributes.elements.models ) {
895						foundData = findWidgetById( obj.attributes.elements.models, widgetId );
896						if ( foundData ) {
897							return false;
898						}
899					}
900				});
901		
902				return foundData;
903			}
904		
905			widgetData = findWidgetById( editorElements.models, widgetId ) || {};
906
907			return {
908				'speed': widgetData['jet_tricks_widget_parallax_speed'] || { 'size': 50, 'unit': '%'},
909				'parallax': widgetData['jet_tricks_widget_parallax'] || 'false',
910				'invert': widgetData['jet_tricks_widget_parallax_invert'] || 'false',
911				'stickyOn': widgetData['jet_tricks_widget_parallax_on'] || [ 'desktop', 'tablet', 'mobile'],
912				'satellite': widgetData['jet_tricks_widget_satellite'] || 'false',
913				'satelliteType': widgetData['jet_tricks_widget_satellite_type'] || 'text',
914				'satellitePosition': widgetData['jet_tricks_widget_satellite_position'] || 'top-center',
915				'tooltip': widgetData['jet_tricks_widget_tooltip'] || 'false',
916				'tooltipDescription': widgetData['jet_tricks_widget_tooltip_description'] || 'Lorem Ipsum',
917				'tooltipPlacement': widgetData['jet_tricks_widget_tooltip_placement'] || 'top',
918				'tooltipArrow': 'true' === widgetData['jet_tricks_widget_tooltip_arrow'] ? true : false,
919				'xOffset': widgetData['jet_tricks_widget_tooltip_x_offset'] || 0,
920				'yOffset': widgetData['jet_tricks_widget_tooltip_y_offset'] || 0,
921				'tooltipAnimation': widgetData['jet_tricks_widget_tooltip_animation'] || 'shift-toward',
922				'tooltipTrigger': widgetData['jet_tricks_widget_tooltip_trigger'] || 'mouseenter',
923				'customSelector': widgetData['jet_tricks_widget_tooltip_custom_selector'] || '',
924				'zIndex': widgetData['jet_tricks_widget_tooltip_z_index'] || '999',
925				'delay': widgetData['jet_tricks_widget_tooltip_delay'] || '0'
926			}
927		}
928	}
929
930	/**
931	 * Jet jetViewMore Class
932	 *
933	 * @return {void}
934	 */
935	window.jetViewMore = function( $selector, settings ) {
936		var self            = this,
937			$window         = $( window ),
938			$button         = $( '.jet-view-more__button', $selector ),
939			defaultSettings = {
940				sections: {},
941				effect: 'move-up',
942				showall: false
943			},
944			settings        = $.extend( {}, defaultSettings, settings ),
945			sections        = settings['sections'],
946			sectionsData    = {},
947			buttonVisible   = true,
948			editMode        = Boolean( elementor.isEditMode() );
949
950		/**
951		 * Init
952		 */
953		self.init = function() {
954			self.setSectionsData();
955
956			if ( editMode ) {
957				return false;
958			}
959
960			// Add Events
961			$button.on( 'click', function() {
962
963				for ( var section in sectionsData ) {
964					var $section = sectionsData[ section ]['selector'];
965
966					if ( ! settings.showall ) {
967						if ( ! sectionsData[ section ]['visible'] ) {
968							sectionsData[ section ]['visible'] = true;
969							$section.css('height', $section[0].scrollHeight + 'px');
970							$section.addClass( 'view-more-visible' );
971							$section.addClass( 'jet-tricks-' + settings['effect'] + '-effect' );
972
973							break;
974						}
975					} else {
976						sectionsData[ section ]['visible'] = true;
977						$section.css('height', $section[0].scrollHeight + 'px');
978						$section.addClass( 'view-more-visible' );
979						$section.addClass( 'jet-tricks-' + settings['effect'] + '-effect' );
980					}
981
982				}
983
984				for ( var section in sectionsData ) {
985					buttonVisible = true;
986
987					if ( sectionsData[ section ]['visible'] ) {
988						buttonVisible = false;
989					}
990				}
991
992				if ( ! buttonVisible ) {
993					$button.css( { 'display': 'none' } );
994				}
995
996			} );
997
998			$button.keydown( function( e ) {
999				var $which = e.which || e.keyCode;
1000
1001					if ( $which == 13 || $which == 32 ) {
1002						for ( var section in sectionsData ) {
1003							var $section = sectionsData[ section ]['selector'];
1004
1005							if ( ! settings.showall ) {
1006								if ( ! sectionsData[ section ]['visible'] ) {
1007									sectionsData[ section ]['visible'] = true;
1008									$section.css('height', $section[0].scrollHeight + 'px');
1009									$section.addClass( 'view-more-visible' );
1010									$section.addClass( 'jet-tricks-' + settings['effect'] + '-effect' );
1011
1012									break;
1013								}
1014							} else {
1015								sectionsData[ section ]['visible'] = true;
1016								$section.css('height', $section[0].scrollHeight + 'px');
1017								$section.addClass( 'view-more-visible' );
1018								$section.addClass( 'jet-tricks-' + settings['effect'] + '-effect' );
1019							}
1020
1021						}
1022
1023						for ( var section in sectionsData ) {
1024							buttonVisible = true;
1025
1026							if ( sectionsData[ section ]['visible'] ) {
1027								buttonVisible = false;
1028							}
1029						}
1030
1031						if ( ! buttonVisible ) {
1032							$button.css( { 'display': 'none' } );
1033						}
1034					}
1035			} );
1036		};
1037
1038		self.setSectionsData = function() {
1039
1040			for ( var section in sections ) {
1041				var $selector = $( '#' + sections[ section ] );
1042
1043				if ( ! editMode ) {
1044					$selector.addClass( 'jet-view-more-section' );
1045				} else {
1046					$selector.addClass( 'jet-view-more-section-edit-mode' );
1047				}
1048
1049				sectionsData[ section ] = {
1050					'section_id': sections[ section ],
1051					'selector': $selector,
1052					'visible': false,
1053				}
1054			}
1055		};
1056	};
1057
1058	/**
1059	 * [jetWidgetParallax description]
1060	 * @param  {[type]} $scope [description]
1061	 * @return {[type]}        [description]
1062	 */
1063	window.jetWidgetParallax = function( $scope ) {
1064		var self         = this,
1065			$target      = $scope,
1066			$section     = $scope.closest( '.elementor-top-section' ),
1067			widgetId     = $scope.data('id'),
1068			settings     = {},
1069			editMode     = Boolean( elementor.isEditMode() ),
1070			$window      = $( window ),
1071			isSafari     = !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/),
1072			platform     = navigator.platform,
1073			safariClass  = isSafari ? 'is-safari' : '',
1074			macClass    = 'MacIntel' == platform ? ' is-mac' : '';
1075
1076		/**
1077		 * Init
1078		 */
1079		self.init = function() {
1080
1081			$scope.addClass( macClass );
1082
1083			if ( ! editMode ) {
1084				settings = $scope.data( 'jet-tricks-settings' );
1085			} else {
1086				settings = JetTricksTools.widgetEditorSettings( widgetId );
1087			}
1088
1089			if ( ! settings ) {
1090				return false;
1091			}
1092
1093			if ( 'undefined' === typeof settings ) {
1094				return false;
1095			}
1096
1097			if ( 'false' === settings['parallax'] || 'undefined' === typeof settings['parallax'] ) {
1098				return false;
1099			}
1100
1101			$window.on( 'scroll.jetWidgetParallax resize.jetWidgetParallax', self.scrollHandler ).trigger( 'resize.jetWidgetParallax' );
1102		};
1103
1104		self.scrollHandler = function( event ) {
1105			var speed             = +settings['speed']['size'] * 0.01,
1106				invert            = 'true' == settings['invert'] ? -1 : 1,
1107				winHeight         = $window.height(),
1108				winScrollTop      = $window.scrollTop(),
1109				offsetTop         = $scope.offset().top,
1110				thisHeight        = $scope.outerHeight(),
1111				sectionHeight     = $section.outerHeight(),
1112				positionDelta     = winScrollTop - offsetTop + ( winHeight / 2 ),
1113				abs               = positionDelta > 0 ? 1 : -1,
1114				posY              = abs * Math.pow( Math.abs( positionDelta ), 0.85 ),
1115				availableDevices  = settings['stickyOn'] || [],
1116				currentDeviceMode = elementorFrontend.getCurrentDeviceMode();
1117
1118			posY = invert * Math.ceil( speed * posY );
1119
1120			if ( -1 !== availableDevices.indexOf( currentDeviceMode ) ) {
1121				$target.css( {
1122					'transform': 'translateY(' + posY + 'px)'
1123				} );
1124			} else {
1125				$target.css( {
1126					'transform': 'translateY(0)'
1127				} );
1128			}
1129		};
1130	};
1131
1132	/**
1133	 * [jetWidgetSatellite description]
1134	 * @param  {[type]} $scope [description]
1135	 * @return {[type]}        [description]
1136	 */
1137	window.jetWidgetSatellite = function( $scope ) {
1138		var self     = this,
1139			widgetId = $scope.data('id'),
1140			settings = {},
1141			editMode = Boolean( elementor.isEditMode() );
1142
1143		/**
1144		 * Init
1145		 */
1146		self.init = function() {
1147
1148			if ( ! editMode ) {
1149				settings = $scope.data( 'jet-tricks-settings' );
1150			} else {
1151				settings = JetTricksTools.widgetEditorSettings( widgetId );
1152			}
1153
1154			if ( ! settings ) {
1155				return false;
1156			}
1157
1158			if ( 'undefined' === typeof settings ) {
1159				return false;
1160			}
1161
1162			if ( 'false' === settings['satellite'] || 'undefined' === typeof settings['satellite'] ) {
1163				return false;
1164			}
1165
1166			$scope.addClass( 'jet-satellite-widget' );
1167
1168			$( '.jet-tricks-satellite', $scope ).addClass( 'jet-tricks-satellite--' + settings['satellitePosition'] );
1169		};
1170	};
1171
1172	/**
1173	 * [jetWidgetTooltip description]
1174	 * @param  {[type]} $scope [description]
1175	 * @return {[type]}        [description]
1176	 */
1177	window.jetWidgetTooltip = function( $scope ) {
1178		var self            = this,
1179			widgetId        = $scope.data('id'),
1180			widgetSelector  = $scope[0],
1181			tooltipSelector = widgetSelector,
1182			settings        = {},
1183			editMode        = Boolean( elementor.isEditMode() ),
1184			delay,
1185			tooltipEvent    = editMode ? 'click' : 'mouseenter';
1186
1187		/**
1188		 * Init
1189		 */
1190		self.init = function() {
1191
1192			if ( ! editMode ) {
1193				settings = $scope.data( 'jet-tricks-settings' );
1194			} else {
1195				settings = JetTricksTools.widgetEditorSettings( widgetId );
1196			}
1197
1198			if ( widgetSelector._tippy ) {
1199				widgetSelector._tippy.destroy();
1200			}
1201
1202			if ( ! settings ) {
1203				return false;
1204			}
1205
1206			if ( 'undefined' === typeof settings ) {
1207				return false;
1208			}
1209
1210			if ( 'false' === settings['tooltip'] || 'undefined' === typeof settings['tooltip'] || '' === settings['tooltipDescription'] ) {
1211				return false;
1212			}
1213
1214			$scope.addClass( 'jet-tooltip-widget' );
1215
1216			if ( settings['customSelector'] ) {
1217				tooltipSelector = $( '.' + settings['customSelector'], $scope )[0];
1218			}
1219
1220			if ( editMode && ! $( '#jet-tricks-tooltip-content-' + widgetId )[0] ) {
1221				var template = $( '<div>', {
1222					id: 'jet-tricks-tooltip-content-' + widgetId,
1223					class: 'jet-tooltip-widget__content'
1224				} );
1225
1226				template.html( settings['tooltipDescription'] );
1227				$scope.append( template );
1228			}
1229
1230			tippy(
1231				[ tooltipSelector ],
1232				{
1233					content: $scope.find( '.jet-tooltip-widget__content' )[0].innerHTML,
1234					allowHTML: true,
1235					//appendTo: widgetSelector,
1236					appendTo: editMode ? document.body : widgetSelector,
1237					arrow: settings['tooltipArrow'] ? true : false,
1238					placement: settings['tooltipPlacement'],
1239					offset: [ settings['xOffset'], settings['yOffset'] ],
1240					animation: settings['tooltipAnimation'],
1241					trigger: settings['tooltipTrigger'],
1242					interactive: true,
1243					zIndex: settings['zIndex'],
1244					maxWidth: 'none',
1245					delay: settings['delay']['size'] ? settings['delay']['size'] : 0,
1246					onCreate: function (instance) {
1247						if ( editMode ) {
1248							var dataId = tooltipSelector.getAttribute('data-id');
1249							if ( dataId ) {
1250								instance.popper.classList.add( 'tippy-' + dataId );
1251							}
1252						}
1253					}
1254				}
1255			);
1256
1257			if ( editMode && widgetSelector._tippy ) {
1258				widgetSelector._tippy.show();
1259			}
1260
1261		};
1262	};
1263	
1264}( jQuery, window.elementorFrontend ) );

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.