PageSourceSearch

https://topfmsp.com.br/concursos/wp-content/plugins/jet-engine/assets/js/frontend.js?ver=3.5.4

js topfmsp.com.br collected 2026-10-02 20:06:23 UTC 61,000 bytes, 2,337 lines download raw bytes

1( function( $ ) {
2
3	"use strict";
4
5	var JetEngineRegisteredStores = window.JetEngineRegisteredStores || {};
6	var JetEngineStores           = window.JetEngineStores || {};
7
8	var JetEngine = {
9
10		currentMonth: null,
11		currentRequest: {},
12		activeCalendarDay: null,
13		lazyLoading: false,
14		addedScripts: [],
15		addedStyles: [],
16		addedPostCSS: [],
17		assetsPromises: [],
18
19		initDone: false,
20
21		commonInit: function() {
22
23			JetEngine.commonEvents();
24
25			$( window ).on( 'jet-popup/render-content/ajax/success', JetEngine.initStores );
26
27			window.JetPlugins.hooks.addFilter(
28				'jet-popup.show-popup.data',
29				'JetEngine.popupData',
30				( popupData, $popup, $triggeredBy ) => {
31
32					if ( ! $triggeredBy ) {
33						return popupData;
34					}
35
36					if ( $triggeredBy.data( 'popupIsJetEngine' ) ) {
37						popupData = JetEngine.prepareJetPopup( popupData, { 'is-jet-engine': true }, $triggeredBy );
38					}
39
40					return popupData;
41				}
42			);
43
44			JetEngine.initStores();
45			JetEngine.customUrlActions.init();
46
47		},
48
49		commonEvents: function( $scope ) {
50			$scope = $scope || $( document );
51
52			$scope
53				.on( 'click.JetEngine', '.jet-calendar-nav__link', JetEngine.switchCalendarMonth )
54				.on( 'click.JetEngine', '.jet-calendar-week__day-mobile-overlay', JetEngine.showCalendarEvent )
55				.on( 'click.JetEngine', '.jet-listing-dynamic-link__link[data-delete-link="1"]', JetEngine.showConfirmDeleteDialog )
56				.on( 'jet-filter-content-rendered', JetEngine.maybeReinitSlider )
57				.on( 'click.JetEngine', '.jet-add-to-store', JetEngine.addToStore )
58				.on( 'click.JetEngine', '.jet-remove-from-store', JetEngine.removeFromStore )
59				.on( 'click.JetEngine', '.jet-engine-listing-overlay-wrap:not([data-url*="event=hover"])', JetEngine.handleListingItemClick )
60				.on( 'jet-filter-content-rendered', JetEngine.filtersCompatibility )
61				.on( 'click.JetEngine', '.jet-container[data-url]', JetEngine.handleContainerURL )
62				.on( 'change.JetEngine', '.jet-listing-dynamic-link .qty', JetEngine.handleProductQuantityChange );
63		},
64
65		handleProductQuantityChange: function ( event ) {
66			event.preventDefault();
67			event.stopPropagation();
68
69			const $this = $( this );
70
71			$this.closest( ".jet-listing-dynamic-link" ).find( ".jet-woo-add-to-cart" ).data( "quantity", $this.val() ).attr( "data-quantity", $this.val() );
72		},
73
74		handleContainerURL: function() {
75			var $this  = $( this ),
76				url    = $this.data( 'url' ),
77				target = $this.data( 'target' );
78
79			if ( ! target ) {
80				window.location = url;
81			} else {
82				window.open( url, '_blank' ).focus();
83			}
84
85		},
86
87		filtersCompatibility: function( event, $provider, filtersInstance, providerType ) {
88
89			if ( 'jet-engine' !== providerType ) {
90				return;
91			}
92
93			/*
94			No need anymore to manually re-init the block.
95			JetSmartFilters automatically re-init blocks.
96
97			var $blocksListing = $provider.closest( '.jet-listing-grid--blocks' );
98
99			if ( $blocksListing.length ) {
100				JetEngine.widgetListingGrid( $blocksListing );
101			}
102			*/
103
104			if ( window.JetPopupFrontend && window.JetPopupFrontend.initAttachedPopups ) {
105				window.JetPopupFrontend.initAttachedPopups( $provider );
106			}
107		},
108
109		init: function() {
110
111			var widgets = {
112				'jet-listing-dynamic-field.default' : JetEngine.widgetDynamicField,
113				'jet-listing-grid.default': JetEngine.widgetListingGrid,
114			};
115
116			$.each( widgets, function( widget, callback ) {
117				window.elementorFrontend.hooks.addAction( 'frontend/element_ready/' + widget, callback );
118			});
119
120			// Re-init sliders in nested tabs
121			window.elementorFrontend.elements.$window.on(
122				'elementor/nested-tabs/activate',
123				( event, content ) => {
124					const $content = $( content );
125
126					setTimeout( () => {
127						JetEngine.maybeReinitSlider( event, $content );
128						JetEngine.widgetDynamicField( $content );
129					} );
130				}
131			);
132
133			window.elementorFrontend.hooks.addFilter(
134				'jet-popup/widget-extensions/popup-data',
135				JetEngine.prepareJetPopup
136			);
137
138			window.JetPlugins.hooks.addFilter(
139				'jet-popup.show-popup.data',
140				'JetEngine.popupData',
141				( popupData, $popup, $triggeredBy ) => {
142
143					if ( ! $triggeredBy ) {
144						return popupData;
145					}
146
147					if ( $triggeredBy.data( 'popupIsJetEngine' ) ) {
148						popupData = JetEngine.prepareJetPopup( popupData, { 'is-jet-engine': true }, $triggeredBy );
149					}
150
151					return popupData;
152				}
153			);
154
155			JetEngine.updateAddedStyles();
156		},
157
158		initBricks: function( $scope ) {
159
160			if ( window.bricksIsFrontend ) {
161				return;
162			}
163
164			$scope = $scope || $( 'body' );
165			JetEngine.initBlocks( $scope );
166
167		},
168
169		initBlocks: function( $scope ) {
170
171			$scope = $scope || $( 'body' );
172
173			window.JetPlugins.init( $scope, [
174				{
175					block: 'jet-engine/listing-grid',
176					callback: JetEngine.widgetListingGrid
177				},
178				{
179					block: 'jet-engine/dynamic-field',
180					callback: JetEngine.widgetDynamicField
181				}
182			] );
183		},
184
185		initFrontStores: function( $scope ) {
186
187			$scope = $scope || $( 'body' );
188
189			$( '.jet-add-to-store.is-front-store', $scope ).each( function() {
190
191				var $this = $( this ),
192					args  = $this.data( 'args' ),
193					store = JetEngineStores[ args.store.type ],
194					count = 0;
195
196				args = JetEngine.ensureJSON( args );
197
198				if ( ! store ) {
199					return;
200				}
201
202				if ( store.inStore( args.store.slug, '' + args.post_id ) ) {
203					JetEngine.switchDataStoreStatus( $this );
204				}
205
206			} );
207
208			$( '.jet-remove-from-store.is-front-store', $scope ).each( function() {
209
210				var $this = $( this ),
211					args  = $this.data( 'args' ),
212					store = JetEngineStores[ args.store.type ],
213					count = 0;
214
215				args = JetEngine.ensureJSON( args );
216
217				if ( ! store ) {
218					return;
219				}
220
221				if ( ! store.inStore( args.store.slug, '' + args.post_id ) ) {
222					$this.addClass( 'is-hidden' );
223				} else {
224					$this.removeClass( 'is-hidden' );
225				}
226
227			} );
228
229		},
230
231		initStores: function() {
232
233			JetEngine.initFrontStores();
234
235			$.each( JetEngineRegisteredStores, function( storeSlug, storeType ) {
236
237				var store = JetEngineStores[ storeType ],
238					storeData = null,
239					count = 0;
240
241				if ( ! store ) {
242					return;
243				}
244
245				storeData = store.getStore( storeSlug );
246
247				if ( storeData && storeData.length ) {
248					count = storeData.length;
249				}
250
251				$( 'span.jet-engine-data-store-count[data-store="' + storeSlug + '"]' ).text( count );
252
253			} );
254
255			JetEngine.loadFrontStoresItems();
256
257		},
258
259		loadFrontStoresItems: function( $scope ) {
260
261			$scope = $scope || $( 'body' );
262
263			$( '.jet-listing-not-found.jet-listing-grid__items', $scope ).each( function() {
264
265				var $this   = $( this ),
266					nav     = $this.data( 'nav' ),
267					isStore = $this.data( 'is-store-listing' ),
268					query   = nav.query;
269
270				nav = JetEngine.ensureJSON( nav );
271
272				if ( query && query.post__in && query.post__in.length && 0 >= query.post__in.indexOf( 'is-front' ) ) {
273
274					var storeType  = query.post__in[1],
275						storeSlug  = query.post__in[2],
276						store      = JetEngineStores[ storeType ],
277						posts      = [],
278						$container = $this.closest( '.elementor-widget-container' );
279
280					if ( ! $container.length ) {
281						$container = $this.closest( '.jet-listing-grid--blocks' );
282					}
283
284					if ( ! store ) {
285						return;
286					}
287
288					posts = store.getStore( storeSlug );
289
290					if ( ! posts.length ) {
291						return;
292					}
293
294					query.post__in = posts;
295					query.is_front_store = true;
296
297					JetEngine.ajaxGetListing( {
298						handler: 'get_listing',
299						container: $container,
300						masonry: false,
301						slider: false,
302						append: false,
303						query: query,
304						widgetSettings: nav.widget_settings,
305					}, function( response ) {
306						JetEngine.widgetListingGrid( $container );
307					} );
308
309				} else if ( isStore ) {
310					$( document ).trigger( 'jet-listing-grid-init-store', $this );
311				}
312
313			} );
314		},
315
316		removeFromStore: function( event ) {
317
318			event.preventDefault();
319			event.stopPropagation();
320
321			var $this = $( this ),
322				args  = $this.data( 'args' ),
323				isDataStoreBtn = $this.hasClass( 'jet-data-store-link' );
324
325			args = JetEngine.ensureJSON( args );
326
327			if ( args.store.is_front ) {
328
329				var store = JetEngineStores[ args.store.type ],
330					count = 0;
331
332				if ( ! store ) {
333					return;
334				}
335
336				if ( ! store.inStore( args.store.slug, '' + args.post_id ) ) {
337					var storePosts = store.getStore( args.store.slug );
338					count = storePosts.length;
339				} else {
340					count = store.remove( args.store.slug, args.post_id );
341				}
342
343				$( '.jet-add-to-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).each( function() {
344					JetEngine.switchDataStoreStatus( $( this ), true );
345				} );
346
347				$( '.jet-data-store-link.jet-remove-from-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).each( function() {
348					JetEngine.switchDataStoreStatus( $( this ), true );
349				} );
350
351				$( 'span.jet-engine-data-store-count[data-store="' + args.store.slug + '"]' ).text( count );
352
353				if ( args.remove_from_listing ) {
354					$this.closest( '.jet-listing-dynamic-post-' + args.post_id ).remove();
355				}
356
357				if ( args.synch_id ) {
358					var $container     = $( '#' + args.synch_id ),
359						$elemContainer = $container.find( '> .elementor-widget-container' ),
360						$items         = $container.find( '.jet-listing-grid__items' ),
361						posts          = [],
362						nav            = $items.data( 'nav' ) || {},
363						query          = nav.query || {};
364
365					nav = JetEngine.ensureJSON( nav );
366
367					posts = store.getStore( args.store.slug );
368
369					if ( ! posts.length ) {
370						posts = [ 'is-front', args.store.type, args.store.slug ];
371					}
372
373					query.post__in = posts;
374					query.is_front_store = true;
375
376					JetEngine.ajaxGetListing( {
377						handler: 'get_listing',
378						container: $elemContainer.length ? $elemContainer : $container,
379						masonry: false,
380						slider: false,
381						append: false,
382						query: query,
383						widgetSettings: nav.widget_settings,
384						postID: window.elementorFrontendConfig.post.id,
385						elementID: $container.data( 'id' ),
386					}, function( response ) {
387						JetEngine.widgetListingGrid( $container );
388					} );
389				}
390
391				$( document ).trigger( 'jet-engine-data-stores-on-remove', args );
392
393				return;
394
395			}
396
397			if ( $this.hasClass( 'jet-store-processing' ) ) {
398				return;
399			}
400
401			$this.css( 'opacity', 0.3 );
402			$this.addClass( 'jet-store-processing' );
403
404			$.ajax({
405				url: JetEngineSettings.ajaxurl,
406				type: 'POST',
407				dataType: 'json',
408				data: {
409					action: 'jet_engine_remove_from_store_' + args.store.slug,
410					store: args.store.slug,
411					post_id: args.post_id,
412				},
413			}).done( function( response ) {
414
415				$this.css( 'opacity', 1 );
416				$this.removeClass( 'jet-store-processing' );
417
418				if ( response.success ) {
419
420					if ( ! isDataStoreBtn ) {
421						$this.addClass( 'is-hidden' );
422					}
423
424					$( '.jet-add-to-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).each( function() {
425						JetEngine.switchDataStoreStatus( $( this ), true );
426					} );
427
428					$( '.jet-data-store-link.jet-remove-from-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).each( function() {
429						JetEngine.switchDataStoreStatus( $( this ), true );
430					} );
431
432					if ( args.synch_id ) {
433						var $container     = $( '#' + args.synch_id ),
434							$elemContainer = $container.find( '> .elementor-widget-container' ),
435							$items         = $container.find( '.jet-listing-grid__items' ),
436							nav            = $items.data( 'nav' ),
437							query          = nav.query,
438							postID         = window.elementorFrontend ? window.elementorFrontendConfig.post.id : 0;
439
440						nav = JetEngine.ensureJSON( nav );
441
442						// Context Bricks
443						if ( $container.hasClass( 'brxe-jet-engine-listing-grid' ) ) {
444							postID = window.bricksData.postId;
445						}
446
447						JetEngine.ajaxGetListing( {
448							handler: 'get_listing',
449							container: $elemContainer.length ? $elemContainer : $container,
450							masonry: false,
451							slider: false,
452							append: false,
453							query: query,
454							widgetSettings: nav.widget_settings,
455							postID,
456							elementID: $container.data( 'id' ),
457						}, function( response ) {
458							JetEngine.widgetListingGrid( $container );
459						} );
460
461					}
462
463					if ( args.remove_from_listing ) {
464						$this.closest( '.jet-listing-grid__item[data-post="' + args.post_id + '"]' ).remove();
465					}
466
467					if ( response.data.fragments ) {
468						$.each( response.data.fragments, function( selector, value ) {
469							$( selector ).html( value );
470						} );
471					}
472
473					$( document ).trigger( 'jet-engine-data-stores-on-remove', args );
474
475				} else {
476					alert( response.data.message );
477				}
478
479				return response;
480
481			} ).done( function( response ) {
482
483				if ( args.remove_from_listing ) {
484					$this.closest( '.jet-listing-grid__item' ).remove();
485				}
486
487				if ( response.success ) {
488					$( 'span.jet-engine-data-store-count[data-store="' + args.store.slug + '"]' ).text( response.data.count );
489				}
490
491			} ).fail( function( jqXHR, textStatus, errorThrown ) {
492				$this.css( 'opacity', 1 );
493				$this.removeClass( 'jet-store-processing' );
494				alert( errorThrown );
495			} );
496
497		},
498
499		triggerPopup: function( popupID, isJetEngine, postID ) {
500
501			if ( ! popupID ) {
502				return;
503			}
504
505			var popupData = {
506				popupId: 'jet-popup-' + popupID,
507			};
508
509			if ( isJetEngine ) {
510				popupData.isJetEngine = true;
511				popupData.postId      = postID;
512			}
513
514			$( window ).trigger( {
515				type: 'jet-popup-open-trigger',
516				popupData: popupData
517			} );
518
519		},
520
521		addToStore: function( event ) {
522
523			event.preventDefault();
524			event.stopPropagation();
525
526			var $this = $( this ),
527				args  = $this.data( 'args' );
528
529			args = JetEngine.ensureJSON( args );
530
531			if ( $this.hasClass( 'in-store' ) ) {
532				if ( args.popup ) {
533					JetEngine.triggerPopup( args.popup, args.isJetEngine, args.post_id );
534				} else if ( '_blank' === $this.attr( 'target' ) ) {
535					window.open( $this.attr( 'href' ) );
536				} else {
537					window.location = $this.attr( 'href' );
538				}
539				return;
540			}
541
542			if ( args.store.is_front ) {
543
544				var store = JetEngineStores[ args.store.type ],
545					count = 0;
546
547				if ( ! store ) {
548					return;
549				}
550
551				if ( store.inStore( args.store.slug, '' + args.post_id ) ) {
552					var storePosts = store.getStore( args.store.slug );
553					count = storePosts.length;
554				} else {
555
556					count = store.addToStore( args.store.slug, args.post_id, args.store.size );
557
558					if ( false === count ) {
559						return;
560					}
561
562				}
563
564				if ( args.popup ) {
565					JetEngine.triggerPopup( args.popup, args.isJetEngine, args.post_id );
566				}
567
568				JetEngine.switchDataStoreStatus( $this );
569				$( 'span.jet-engine-data-store-count[data-store="' + args.store.slug + '"]' ).text( count );
570				$( '.jet-remove-from-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).removeClass( 'is-hidden' );
571
572				if ( args.synch_id ) {
573					var $container     = $( '#' + args.synch_id ),
574						$elemContainer = $container.find( '> .elementor-widget-container' ),
575						$items         = $container.find( '.jet-listing-grid__items' ),
576						posts          = [],
577						nav            = $items.data( 'nav' ) || {},
578						query          = nav.query || {};
579
580					nav = JetEngine.ensureJSON( nav );
581					posts = store.getStore( args.store.slug );
582
583					query.post__in = posts;
584					query.is_front_store = true;
585
586					JetEngine.ajaxGetListing( {
587						handler: 'get_listing',
588						container: $elemContainer.length ? $elemContainer : $container,
589						masonry: false,
590						slider: false,
591						append: false,
592						query: query,
593						widgetSettings: nav.widget_settings,
594						postID: window.elementorFrontendConfig.post.id,
595						elementID: $container.data( 'id' ),
596					}, function( response ) {
597						JetEngine.widgetListingGrid( $container );
598					} );
599				}
600
601				$( document ).trigger( 'jet-engine-data-stores-on-add', args );
602
603				return;
604			}
605
606			if ( $this.hasClass( 'jet-store-processing' ) ) {
607				return;
608			}
609
610			$this.css( 'opacity', 0.3 );
611			$this.addClass( 'jet-store-processing' );
612
613			$( document ).trigger( 'jet-engine-on-add-to-store', [ $this, args ] );
614
615			$.ajax({
616				url: JetEngineSettings.ajaxurl,
617				type: 'POST',
618				dataType: 'json',
619				data: {
620					action: 'jet_engine_add_to_store_' + args.store.slug,
621					store: args.store.slug,
622					post_id: args.post_id,
623				},
624			}).done( function( response ) {
625
626				$this.css( 'opacity', 1 );
627				$this.removeClass( 'jet-store-processing' );
628
629				if ( response.success ) {
630
631					JetEngine.switchDataStoreStatus( $this );
632					$( '.jet-remove-from-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).removeClass( 'is-hidden' );
633
634					if ( response.data.fragments ) {
635						$.each( response.data.fragments, function( selector, value ) {
636							$( selector ).html( value );
637						} );
638					}
639
640					if ( args.synch_id ) {
641
642						var $container     = $( '#' + args.synch_id ),
643							$elemContainer = $container.find( '> .elementor-widget-container' ),
644							$items         = $container.find( '.jet-listing-grid__items' ),
645							nav            = $items.data( 'nav' ),
646							query          = nav.query,
647							postID         = window.elementorFrontend ? window.elementorFrontendConfig.post.id : 0;
648
649						nav = JetEngine.ensureJSON( nav );
650
651						// Context Bricks
652						if ( $container.hasClass( 'brxe-jet-engine-listing-grid' ) ) {
653							postID = window.bricksData.postId;
654						}
655
656						JetEngine.ajaxGetListing( {
657							handler: 'get_listing',
658							container: $elemContainer.length ? $elemContainer : $container,
659							masonry: false,
660							slider: false,
661							append: false,
662							query: query,
663							widgetSettings: nav.widget_settings,
664							postID,
665							elementID: $container.data( 'id' ),
666						}, function( response ) {
667							JetEngine.widgetListingGrid( $container );
668						} );
669
670					}
671
672					if ( args.popup ) {
673						JetEngine.triggerPopup( args.popup, args.isJetEngine, args.post_id );
674					}
675
676				} else {
677					alert( response.data.message );
678				}
679
680				$( document ).trigger( 'jet-engine-data-stores-on-add', args );
681
682				return response;
683
684			} ).done( function( response ) {
685
686				if ( response.success ) {
687					$( 'span.jet-engine-data-store-count[data-store="' + args.store.slug + '"]' ).text( response.data.count );
688				}
689
690			} ).fail( function( jqXHR, textStatus, errorThrown ) {
691				$this.css( 'opacity', 1 );
692				$this.removeClass( 'jet-store-processing' );
693				alert( errorThrown );
694			} );
695
696		},
697
698		switchDataStoreStatus: function( $item, toInitial ) {
699
700			var isDataStoreLink = $item.hasClass( 'jet-data-store-link' ),
701				$label = $item.find( '.jet-listing-dynamic-link__label, .jet-data-store-link__label' ),
702				$icon  = $item.find( '.jet-listing-dynamic-link__icon, .jet-data-store-link__icon' ),
703				args   = $item.data( 'args' ),
704				replaceLabel,
705				replaceURL,
706				replaceIcon;
707
708			args = JetEngine.ensureJSON( args );
709
710			toInitial = toInitial || false;
711
712			if ( isDataStoreLink ) {
713
714				switch ( args.action_after_added ) {
715					case 'remove_from_store':
716
717						if ( toInitial ) {
718							$item.addClass( 'jet-add-to-store' );
719							$item.removeClass( 'jet-remove-from-store' );
720
721							$item.removeClass( 'in-store' );
722						} else {
723							$item.addClass( 'jet-remove-from-store' );
724							$item.removeClass( 'jet-add-to-store' );
725
726							$item.addClass( 'in-store' );
727
728						}
729
730						break;
731
732					case 'hide':
733
734						if ( toInitial ) {
735							$item.removeClass( 'is-hidden' );
736						} else {
737							$item.addClass( 'is-hidden' );
738						}
739
740						return;
741				}
742
743			}
744
745			if ( toInitial ) {
746				replaceLabel = args.label;
747				replaceIcon  = args.icon;
748				replaceURL   = '#';
749			} else {
750				replaceLabel = args.added_label;
751				replaceIcon  = args.added_icon;
752				replaceURL   = args.added_url;
753			}
754
755			if ( $label.length ) {
756				$label.replaceWith( replaceLabel );
757			} else {
758				$item.append( replaceLabel );
759			}
760
761			if ( $icon.length ) {
762				$icon.replaceWith( replaceIcon );
763			} else {
764				$item.prepend( replaceIcon );
765			}
766
767			if ( isDataStoreLink && 'remove_from_store' === args.action_after_added ) {
768				return;
769			}
770
771			$item.attr( 'href', replaceURL );
772
773			if ( toInitial ) {
774				$item.removeClass( 'in-store' );
775			} else if ( ! $item.hasClass( 'in-store' ) ) {
776				$item.addClass( 'in-store' );
777			}
778
779
780		},
781
782		showConfirmDeleteDialog: function( event ) {
783			event.preventDefault();
784			event.stopPropagation();
785
786			var $this = $( this );
787
788			if ( window.confirm( $this.data( 'delete-message' ) ) ) {
789				window.location = $this.attr( 'href' );
790			}
791
792		},
793
794		handleListingItemClick: function( event ) {
795
796			var url    = $( this ).data( 'url' ),
797				target = $( this ).data( 'target' ) || false;
798
799			if ( url ) {
800
801				event.preventDefault();
802
803				if ( window.elementorFrontend && window.elementorFrontend.isEditMode() ) {
804					return;
805				}
806
807				if ( -1 !== url.indexOf( '#jet-engine-action' ) ) {
808
809					JetEngine.customUrlActions.runAction( url );
810
811				} else {
812
813					if ( '_blank' === target ) {
814						window.open( url );
815						return;
816					}
817
818					window.location = url;
819				}
820			}
821
822		},
823
824		customUrlActions: {
825			selectorOnClick: 'a[href^="#jet-engine-action"][href*="event=click"]',
826			selectorOnHover: 'a[href^="#jet-engine-action"][href*="event=hover"], [data-url^="#jet-engine-action"][data-url*="event=hover"]',
827
828			init: function() {
829				var timeout = null;
830
831				$( document ).on( 'click.JetEngine', this.selectorOnClick, function( event ) {
832					event.preventDefault();
833					JetEngine.customUrlActions.actionHandler( event )
834				} );
835
836				$( document ).on( 'click.JetEngine', this.selectorOnHover, function( event ) {
837					if ( 'A' === event.currentTarget.nodeName ) {
838						event.preventDefault();
839					}
840				} );
841
842				$( document ).on( {
843					'mouseenter.JetEngine': function( event ) {
844
845						if ( timeout ) {
846							clearTimeout( timeout );
847						}
848
849						timeout = setTimeout( function() {
850							JetEngine.customUrlActions.actionHandler( event )
851						}, window.JetEngineSettings.hoverActionTimeout );
852					},
853					'mouseleave.JetEngine': function() {
854						if ( timeout ) {
855							clearTimeout( timeout );
856							timeout = null;
857						}
858					},
859				}, this.selectorOnHover );
860			},
861
862			actions: {},
863
864			addAction: function( name, callback ) {
865				this.actions[ name ] = callback;
866			},
867
868			actionHandler: function( event ) {
869				var url = $( event.currentTarget ).attr( 'href' ) || $( event.currentTarget ).attr( 'data-url' );
870
871				this.runAction( url );
872			},
873
874			runAction: function( url ) {
875				var queryParts = url.split( '&' ),
876					settings = {};
877
878				queryParts.forEach( function( item ) {
879					if ( -1 !== item.indexOf( '=' ) ) {
880						var pair = item.split( '=' );
881
882						settings[ pair[0] ] = decodeURIComponent( pair[1] );
883					}
884				} );
885
886				if ( ! settings.action ) {
887					return;
888				}
889
890				var actionCb = this.actions[ settings.action ];
891
892				if ( ! actionCb ) {
893					return;
894				}
895
896				actionCb( settings );
897			}
898		},
899
900		prepareJetPopup: function( popupData, widgetData, $scope ) {
901
902			var postId = null;
903
904			if ( widgetData['is-jet-engine'] ) {
905				popupData['isJetEngine'] = true;
906
907				var $gridItems     = $scope.closest( '.jet-listing-grid__items' ),
908					$gridItem      = $scope.closest( '.jet-listing-grid__item' ),
909					$calendarItem  = $scope.closest( '.jet-calendar-week__day-event' ),
910					$itemObject    = $scope.closest( '[data-item-object]' ),
911					filterProvider = false,
912					filterQueryId  = 'default';
913
914				if ( $gridItems.length ) {
915					popupData['listingSource'] = $gridItems.data( 'listing-source' );
916					popupData['listingId']     = $gridItems.data( 'listing-id' );
917					popupData['queryId']       = $gridItems.data( 'query-id' );
918				} else {
919
920					var $queryItems    = $scope.closest( '[data-query-id]' ),
921						$listingSource = $scope.closest( '[data-listing-source]' );
922
923					if ( $queryItems.length ) {
924						popupData['queryId'] = $queryItems.data( 'query-id' );
925					}
926
927					if ( $listingSource.length ) {
928						popupData['listingSource'] = $listingSource.data( 'listing-source' );
929					}
930				}
931
932				if ( $gridItem.length ) {
933					popupData['postId'] = $gridItem.data( 'post-id' );
934					filterProvider = 'jet-engine';
935				} else if ( $calendarItem.length ) {
936					popupData['postId'] = $calendarItem.data( 'post-id' );
937					filterProvider = 'jet-engine-calendar';
938				} else if ( $itemObject ) {
939					popupData['postId'] = $itemObject.data( 'item-object' );
940				} else if ( window.elementorFrontendConfig && window.elementorFrontendConfig.post ) {
941					popupData['postId'] = window.elementorFrontendConfig.post.id;
942				}
943
944				if ( window.JetEngineFormsEditor && window.JetEngineFormsEditor.hasEditor ) {
945					popupData['hasEditor'] = true;
946				}
947
948				// Add the filtered query to the popup data
949				if ( window.JetSmartFilters ) {
950
951					switch ( filterProvider ) {
952						case 'jet-engine':
953							var nav = $gridItems.data( 'nav' );
954
955							if ( nav.widget_settings?._element_id ) {
956								filterQueryId = nav.widget_settings._element_id;
957							}
958							break;
959
960						case 'jet-engine-calendar':
961							var settings = $calendarItem.closest( '.jet-listing-calendar' ).data( 'settings' );
962
963							if ( settings._element_id ) {
964								filterQueryId = settings._element_id;
965							}
966							break;
967					}
968
969					filterProvider = window.JetPlugins.hooks.applyFilters( 'jet-engine.prepareJetPopupData.filterProvider', filterProvider, $scope, widgetData );
970					filterQueryId  = window.JetPlugins.hooks.applyFilters( 'jet-engine.prepareJetPopupData.filterQueryId', filterQueryId, $scope, widgetData );
971
972					if ( popupData.queryId && filterProvider
973						&& window.JetSmartFilters?.filterGroups?.[ filterProvider + '/' + filterQueryId ]?.currentQuery
974					) {
975						popupData['filtered_query'] = window.JetSmartFilters.filterGroups[ filterProvider + '/' + filterQueryId ].currentQuery;
976					}
977				}
978
979			}
980
981			return popupData;
982
983		},
984
985		showCalendarEvent: function( event ) {
986
987			var $this       = $( this ),
988				$day        = $this.closest( '.jet-calendar-week__day' ),
989				$week       = $day.closest( '.jet-calendar-week' ),
990				$events     = $day.find( '.jet-calendar-week__day-content' ),
991				activeClass = 'calendar-event-active';
992
993			if ( $day.hasClass( activeClass ) ) {
994				$day.removeClass( activeClass );
995				JetEngine.activeCalendarDay.remove();
996				JetEngine.activeCalendarDay = null;
997				return;
998			}
999
1000			if ( JetEngine.activeCalendarDay ) {
1001				JetEngine.activeCalendarDay.remove();
1002				$( '.' + activeClass ).removeClass( activeClass );
1003				JetEngine.activeCalendarDay = null;
1004			}
1005
1006			$day.addClass( 'calendar-event-active' );
1007
1008			JetEngine.activeCalendarDay = $( '<tr class="jet-calendar-week"><td colspan="7" class="jet-calendar-week__day jet-calendar-week__day-mobile"><div class="jet-calendar-week__day-mobile-event">' + $events.html() + '</div></td></tr>' );
1009
1010			// Need for re-init popup events
1011			JetEngine.activeCalendarDay.find( '.jet-popup-attach-event-inited' ).removeClass( 'jet-popup-attach-event-inited' );
1012			JetEngine.initElementsHandlers( JetEngine.activeCalendarDay );
1013
1014			JetEngine.activeCalendarDay.insertAfter( $week );
1015
1016		},
1017
1018		widgetListingGrid: function( $scope ) {
1019
1020			var widgetID    = $scope.closest( '.elementor-widget' ).data( 'id' ),
1021				$wrapper    = $scope.find( '.jet-listing-grid' ).first(),
1022				hasLazyLoad = $wrapper.hasClass( 'jet-listing-grid--lazy-load' ),
1023				$listing    = $scope.find( '.jet-listing-grid__items' ).first(),
1024				$slider     = $listing.parent( '.jet-listing-grid__slider' ),
1025				$masonry    = $listing.hasClass( 'jet-listing-grid__masonry' ) ? $listing : false,
1026				navSettings = $listing.data( 'nav' ),
1027				masonryGrid = false,
1028				listingType = 'elementor';
1029
1030			navSettings = JetEngine.ensureJSON( navSettings );
1031
1032			if ( hasLazyLoad ) {
1033
1034				var lazyLoadOptions = $wrapper.data( 'lazy-load' ),
1035					widgetSettings = {},
1036					$container = $scope.find( '.elementor-widget-container' );
1037
1038				// Get widget settings from `elementorFrontend` in Editor.
1039				if ( window.elementorFrontend && window.elementorFrontend.isEditMode()
1040					&& $wrapper.closest( '.elementor[data-elementor-type]' ).hasClass( 'elementor-edit-mode' )
1041				) {
1042					widgetSettings = JetEngine.getEditorElementSettings( $scope.closest( '.elementor-widget' ) );
1043					widgetID       = false; // for avoid get widget settings from document in editor
1044				}
1045
1046				if ( ! $container.length ) {
1047					$container = $scope;
1048					widgetSettings = $scope.data( 'widget-settings' );
1049				}
1050
1051				if ( ! widgetID ) {
1052					widgetID    = $scope.data( 'element-id' );
1053					listingType = $scope.data( 'listing-type' );
1054				}
1055
1056				JetEngine.lazyLoadListing( {
1057					container:      $container,
1058					elementID:      widgetID,
1059					postID:         lazyLoadOptions.post_id,
1060					queriedID:      lazyLoadOptions.queried_id || false,
1061					offset:         lazyLoadOptions.offset || '0px',
1062					query:          lazyLoadOptions.query || {},
1063					listingType:    listingType,
1064					widgetSettings: widgetSettings,
1065					extraProps:     lazyLoadOptions.extra_props || false,
1066				} );
1067
1068				return;
1069			}
1070
1071			if ( $slider.length ) {
1072				JetEngine.initSlider( $slider );
1073			}
1074
1075			if ( $masonry && $masonry.length ) {
1076
1077				JetEngine.initMasonry( $masonry );
1078
1079				/* Keep masonry re-init for Bricks */
1080				if ( $scope.hasClass( 'brxe-jet-engine-listing-grid' ) ) {
1081					$( window ).on( 'load', function() {
1082						JetEngine.runMasonry( $masonry );
1083					} );
1084				}
1085
1086			}
1087
1088			if ( navSettings && navSettings.enabled ) {
1089
1090				JetEngine.loadMoreListing( {
1091					container: $listing,
1092					settings:  navSettings,
1093					masonry:   $masonry,
1094					slider:    $slider,
1095				} );
1096
1097			}
1098
1099			// Init elements handlers in editor.
1100			if ( window.elementorFrontend && window.elementorFrontend.isEditMode()
1101				&& $wrapper.closest( '.elementor-element-edit-mode' ).length
1102			) {
1103				JetEngine.initElementsHandlers( $wrapper );
1104			}
1105
1106		},
1107
1108		initMasonry: function( $masonry, masonrySettings ) {
1109			imagesLoaded( $masonry, function() {
1110				JetEngine.runMasonry( $masonry, masonrySettings );
1111			} );
1112		},
1113
1114		runMasonry: function( $masonry, masonrySettings ) {
1115			var defaultSettings = {
1116				itemSelector: '> .jet-listing-grid__item',
1117				columnsKey:   'columns',
1118			};
1119
1120			masonrySettings = masonrySettings || {};
1121			masonrySettings = $.extend( {}, defaultSettings, masonrySettings );
1122
1123			var $eWidget     = $masonry.closest( '.elementor-widget' ),
1124				$items       = $( masonrySettings.itemSelector, $masonry ),
1125				options      = $masonry.data( 'masonry-grid-options' ) || {};
1126
1127			options = JetEngine.ensureJSON( options );
1128
1129			// Reset masonry
1130			$items.css( {
1131				marginTop: ''
1132			} );
1133
1134			// Bricks margin
1135			const { gap } = options;
1136			let margin = null;
1137
1138			if ( gap ) {
1139				margin = {
1140					x: +gap.horizontal,
1141					y: +gap.vertical,
1142				};
1143			}
1144
1145			var args = {
1146				container: $masonry[0],
1147				margin: margin ? margin : 0,
1148			};
1149
1150			if ( $eWidget.length ) {
1151				var settings     = JetEngine.getElementorElementSettings( $eWidget ),
1152					breakpoints  = {},
1153					eBreakpoints = window.elementorFrontend.config.responsive.activeBreakpoints,
1154					columnsKey   = masonrySettings.columnsKey;
1155
1156				args.columns = settings[columnsKey + '_widescreen'] ? +settings[columnsKey + '_widescreen'] : +settings[columnsKey];
1157
1158				Object.keys( eBreakpoints ).reverse().forEach( function( breakpointName ) {
1159
1160					if ( settings[columnsKey + '_' + breakpointName] ) {
1161						if ( 'widescreen' === breakpointName ) {
1162							breakpoints[eBreakpoints[breakpointName].value - 1] = +settings[columnsKey];
1163						} else {
1164							breakpoints[eBreakpoints[breakpointName].value] = +settings[columnsKey + '_' + breakpointName];
1165						}
1166					}
1167
1168				} );
1169
1170				args.breakAt = breakpoints;
1171
1172			} else {
1173				args.columns = options.columns.desktop;
1174				args.breakAt = {
1175					1025: options.columns.tablet,
1176					768:  options.columns.mobile,
1177				};
1178			}
1179
1180			var masonryInstance = Macy( args );
1181
1182			masonryInstance.runOnImageLoad( function () {
1183				masonryInstance.recalculate( true );
1184			}, true );
1185
1186			// Event to recalculate current masonry listings.
1187			$masonry.on( 'jet-engine/listing/recalculate-masonry-listing', function() {
1188				masonryInstance.runOnImageLoad( function () {
1189					masonryInstance.recalculate( true );
1190				}, true );
1191			} );
1192
1193			// Event to recalculate all masonry listings.
1194			$( document ).on( 'jet-engine/listing/recalculate-masonry', function() {
1195				masonryInstance.recalculate( true );
1196			} );
1197
1198		},
1199
1200		ajaxGetListing: function( options, doneCallback, failCallback ) {
1201
1202			var container = options.container || false,
1203				handler = options.handler || false,
1204				masonry = options.masonry || false,
1205				slider = options.slider || false,
1206				append = options.append || false,
1207				query = options.query || {},
1208				widgetSettings = options.widgetSettings || {},
1209				postID = options.postID || false,
1210				queriedID = options.queriedID || false,
1211				elementID = options.elementID || false,
1212				page = options.page || 1,
1213				preventCSS = options.preventCSS || false,
1214				listingType = options.listingType || false,
1215				extraProps = options.extraProps || false,
1216				isEditMode = window.elementorFrontend && window.elementorFrontend.isEditMode();
1217
1218			doneCallback = doneCallback || function( response ) {};
1219
1220			if ( ! container|| ! handler ) {
1221				return;
1222			}
1223
1224			if ( ! preventCSS ) {
1225				container.css({
1226					pointerEvents: 'none',
1227					opacity: '0.5',
1228					cursor: 'default',
1229				});
1230			}
1231
1232			var requestData = {
1233					action: 'jet_engine_ajax',
1234					handler: handler,
1235					query: query,
1236					widget_settings: widgetSettings,
1237					page_settings: {
1238						post_id: postID,
1239						queried_id: queriedID,
1240						element_id: elementID,
1241						page: page,
1242					},
1243					listing_type: listingType,
1244					isEditMode: isEditMode,
1245					addedPostCSS: JetEngine.addedPostCSS
1246				};
1247
1248			if ( extraProps ) {
1249				Object.assign( requestData, extraProps );
1250			}
1251
1252			$.ajax({
1253				url: JetEngineSettings.ajaxlisting,
1254				type: 'POST',
1255				dataType: 'json',
1256				data: requestData,
1257			}).done( function( response ) {
1258
1259				// container.removeAttr( 'style' );
1260
1261				// Manual reset container style to prevent removal of masonry styles.
1262				if ( !preventCSS ) {
1263					container.css( {
1264						pointerEvents: '',
1265						opacity: '',
1266						cursor: '',
1267					} );
1268				}
1269
1270				if ( response.success ) {
1271
1272					JetEngine.enqueueAssetsFromResponse( response );
1273
1274					container.data( 'page', page );
1275
1276					var $html = $( response.data.html );
1277
1278					JetEngine.initFrontStores( $html );
1279
1280					if ( slider && slider.length ) {
1281
1282						var $slider = slider.find( '> .jet-listing-grid__items' );
1283
1284						if ( ! $slider.hasClass( 'slick-initialized' ) ) {
1285
1286							if ( append ) {
1287								container.append( $html );
1288							} else {
1289								container.html( $html );
1290							}
1291
1292							var itemsCount = container.find( '> .jet-listing-grid__item' ).length;
1293
1294							slider.addClass( 'jet-listing-grid__slider' );
1295							JetEngine.initSlider( slider, { itemsCount: itemsCount } );
1296
1297						} else {
1298							$html.each( function( index, el ) {
1299								$slider.slick( 'slickAdd', el );
1300							});
1301						}
1302
1303					} else {
1304
1305						if ( append ) {
1306							container.append( $html );
1307						} else {
1308							container.html( $html );
1309						}
1310
1311						if ( masonry && masonry.length ) {
1312							//JetEngine.initMasonry( masonry );
1313							masonry.trigger( 'jet-engine/listing/recalculate-masonry-listing' );
1314						}
1315
1316					}
1317
1318					// Re-init Bricks scripts
1319					if ( window.bricksIsFrontend ) {
1320						document.dispatchEvent(
1321							new CustomEvent("bricks/ajax/query_result/displayed")
1322						);
1323					}
1324
1325					Promise.all( JetEngine.assetsPromises ).then( function() {
1326						JetEngine.initElementsHandlers( $html );
1327						JetEngine.assetsPromises = [];
1328					} );
1329
1330					if ( response.data.fragments ) {
1331						for ( var selector in response.data.fragments ) {
1332							var $selector = $( selector );
1333
1334							if ( $selector.length ) {
1335								$selector.html( response.data.fragments[ selector ] );
1336							}
1337						}
1338					}
1339				}
1340
1341				$( document ).trigger( 'jet-engine/listing/ajax-get-listing/done', [ $html, options ] );
1342
1343			} ).done( doneCallback ).fail( function() {
1344				container.removeAttr( 'style' );
1345				if ( failCallback ) {
1346					failCallback.call();
1347				}
1348
1349			} );
1350
1351		},
1352
1353		loadMoreListing: function( args ) {
1354
1355			var instance = {
1356
1357				setup: function() {
1358					this.container = args.container;
1359					this.masonry   = args.masonry;
1360					this.slider    = args.slider;
1361					this.settings  = args.settings;
1362
1363					this.wrapper = this.container.closest( '.jet-listing-grid' );
1364
1365					this.type      = this.settings.type || 'click';
1366					this.page      = parseInt( this.container.data( 'page' ), 10 ) || 0;
1367					this.pages     = parseInt( this.container.data( 'pages' ), 10 ) || 0;
1368					this.queriedID = this.container.data( 'queried-id' ) || false;
1369				},
1370
1371				init: function() {
1372
1373					this.setup();
1374
1375					switch ( this.type ) {
1376						case 'click':
1377
1378							this.handleMore();
1379
1380							break;
1381
1382						case 'scroll':
1383
1384							if ( ( ! window.elementorFrontend || ! window.elementorFrontend.isEditMode() ) && ! this.slider.length ) {
1385								this.handleInfiniteScroll();
1386							}
1387
1388							break;
1389					}
1390				},
1391
1392				handleMore: function() {
1393
1394					if ( ! this.settings.more_el ) {
1395						return;
1396					}
1397
1398					var self    = this,
1399						$button = $( this.settings.more_el );
1400
1401					if ( ! $button.length ) {
1402						return;
1403					}
1404
1405					if ( this.page === this.pages && ! window.elementor ) {
1406						$button.css( 'display', 'none' );
1407					} else {
1408						$button.removeAttr( 'style' );
1409					}
1410
1411					$( document )
1412						.off( 'click', this.settings.more_el )
1413						.on( 'click', this.settings.more_el, function( event ) {
1414							event.preventDefault();
1415
1416							$button.css( {
1417								pointerEvents: 'none',
1418								opacity: '0.5',
1419								cursor: 'default',
1420							} );
1421
1422							self.ajaxGetItems( function( response ) {
1423									$button.removeAttr( 'style' );
1424
1425									if ( response.success && self.page === self.pages ) {
1426										$button.css( 'display', 'none' );
1427									}
1428								}, function() {
1429									$button.button.removeAttr( 'style' );
1430								}
1431							);
1432						} );
1433				},
1434
1435				handleInfiniteScroll: function() {
1436
1437					if ( this.container.hasClass( 'jet-listing-not-found' ) ) {
1438						return;
1439					}
1440
1441					if ( this.page === this.pages ) {
1442						return;
1443					}
1444
1445					var self     = this,
1446						$trigger = this.wrapper.find( '.jet-listing-grid__loader' ),
1447						offset   = '0%';
1448
1449					if ( ! $trigger.length ) {
1450						$trigger = $( '<div>', {
1451							class: 'jet-listing-grid__loading-trigger'
1452						} );
1453
1454						this.wrapper.append( $trigger );
1455					}
1456
1457					// Prepare offset value.
1458					if ( this.settings.widget_settings && this.settings.widget_settings.load_more_offset ) {
1459						var offsetValue = this.settings.widget_settings.load_more_offset;
1460
1461						switch ( typeof offsetValue ) {
1462							case 'object':
1463								var size = offsetValue.size ? offsetValue.size : '0',
1464									unit = offsetValue.unit ? offsetValue.unit : 'px';
1465
1466								offset = size + unit;
1467								break;
1468
1469							case 'number':
1470							case 'string':
1471								offset = offsetValue + 'px';
1472								break;
1473						}
1474					}
1475
1476					var observer = new IntersectionObserver(
1477						function( entries, observer ) {
1478
1479							if ( entries[0].isIntersecting ) {
1480
1481								self.ajaxGetItems( function() {
1482
1483									// Re-init observer if the last page is not loaded
1484									if ( self.page !== self.pages ) {
1485										setTimeout( function() {
1486											observer.observe( entries[0].target );
1487										}, 250 );
1488									}
1489
1490								} );
1491
1492								// Detach observer
1493								observer.unobserve( entries[0].target );
1494							}
1495						},
1496						{
1497							rootMargin: '0% 0% ' + offset + ' 0%',
1498						}
1499					);
1500
1501					observer.observe( $trigger[0] );
1502				},
1503
1504				ajaxGetItems: function( doneCallback, failCallback ) {
1505					var self = this;
1506
1507					this.page++;
1508
1509					this.wrapper.addClass( 'jet-listing-grid-loading' );
1510
1511					JetEngine.ajaxGetListing( {
1512							handler:        'listing_load_more',
1513							container:      this.container,
1514							masonry:        this.masonry,
1515							slider:         this.slider,
1516							append:         true,
1517							query:          this.settings.query,
1518							widgetSettings: this.settings.widget_settings,
1519							page:           this.page,
1520							queriedID:      this.queriedID,
1521							preventCSS:     !! this.wrapper.find( '.jet-listing-grid__loader' ).length, // Prevent CSS if listing has the loader.
1522						}, function( response ) {
1523
1524							JetEngine.lazyLoading = false;
1525							self.wrapper.removeClass( 'jet-listing-grid-loading' );
1526
1527							if ( doneCallback ) {
1528								doneCallback( response );
1529							}
1530
1531							$( document ).trigger( 'jet-engine/listing-grid/after-load-more', [args, response] );
1532
1533						}, function() {
1534
1535							JetEngine.lazyLoading = false;
1536							self.wrapper.removeClass( 'jet-listing-grid-loading' );
1537
1538							if ( failCallback ) {
1539								failCallback();
1540							}
1541
1542					} );
1543				},
1544			};
1545
1546			instance.init();
1547		},
1548
1549		lazyLoadListing: function( args ) {
1550
1551			var $wrapper = args.container.find( '.jet-listing-grid' ),
1552				observer = new IntersectionObserver(
1553					function( entries, observer ) {
1554
1555						if ( entries[0].isIntersecting ) {
1556
1557							JetEngine.lazyLoading = true;
1558
1559							if ( ! $wrapper.length ) {
1560								$wrapper = args.container;
1561							}
1562
1563							$wrapper.addClass( 'jet-listing-grid-loading' );
1564
1565							JetEngine.ajaxGetListing( {
1566								handler: 'get_listing',
1567								container: args.container,
1568								masonry: false,
1569								slider: false,
1570								append: false,
1571								elementID: args.elementID,
1572								postID: args.postID,
1573								queriedID: args.queriedID,
1574								query: args.query,
1575								widgetSettings: args.widgetSettings,
1576								listingType: args.listingType,
1577								preventCSS: true,
1578								extraProps: args.extraProps,
1579							}, function( response ) {
1580
1581								$wrapper.removeClass( 'jet-listing-grid-loading' );
1582
1583								var $widget = args.container.closest( '.elementor-widget' );
1584
1585								if ( ! $widget.length ) {
1586									$widget = args.container.closest( '.jet-listing-grid--blocks' );
1587								}
1588
1589								if ( ! $widget.length ) {
1590									$widget = args.container;
1591								}
1592
1593								if ( $widget.length ) {
1594									$widget.find( '.jet-listing-grid' ).first().removeClass( 'jet-listing-grid--lazy-load' );
1595								}
1596
1597								JetEngine.widgetListingGrid( $widget );
1598								JetEngine.loadFrontStoresItems( $widget );
1599								JetEngine.lazyLoading = false;
1600
1601								let needReInitFilters = false;
1602								let isFrontend = JetEngine.isFrontend();
1603
1604								if ( isFrontend && window.JetSmartFilterSettings ) {
1605
1606									if ( response.data.filters_data ) {
1607										$.each( response.data.filters_data, function( param, data ) {
1608											if ( 'extra_props' === param ) {
1609												window.JetSmartFilterSettings[ param ] = $.extend(
1610													{},
1611													window.JetSmartFilterSettings[ param ],
1612													data
1613												);
1614											} else {
1615												if ( window.JetSmartFilterSettings[ param ]['jet-engine'] ) {
1616													window.JetSmartFilterSettings[ param ]['jet-engine'] = $.extend(
1617														{},
1618														window.JetSmartFilterSettings[ param ]['jet-engine'],
1619														data
1620													);
1621												} else {
1622													window.JetSmartFilterSettings[ param ]['jet-engine'] = data;
1623												}
1624											}
1625										});
1626
1627										needReInitFilters = true;
1628									}
1629
1630									if ( response.data.indexer_data ) {
1631										const {
1632											provider = false,
1633											query = {}
1634										} = response.data.indexer_data;
1635
1636										window.JetSmartFilters.setIndexedData( provider, query );
1637									}
1638								}
1639
1640								// ReInit filters
1641								if ( needReInitFilters && window.JetSmartFilters ) {
1642									window.JetSmartFilters.reinitFilters();
1643								}
1644
1645								$( document ).trigger( 'jet-engine/listing-grid/after-lazy-load', [ args, response ] );
1646
1647							}, function() {
1648								JetEngine.lazyLoading = false;
1649
1650								if ( ! $wrapper.length ) {
1651									$wrapper = args.container;
1652								}
1653
1654								$wrapper.removeClass( 'jet-listing-grid-loading' );
1655							} );
1656
1657							// Detach observer after the first load the listing
1658							observer.unobserve( entries[0].target );
1659						}
1660					},
1661					{
1662						rootMargin: '0% 0% ' + args.offset + ' 0%'
1663					}
1664				);
1665
1666			observer.observe( args.container[0] );
1667		},
1668
1669		ensureJSON: function( maybeJSON ) {
1670
1671			if ( ! maybeJSON ) {
1672				return maybeJSON;
1673			}
1674
1675			if ( 'string' === typeof maybeJSON ) {
1676				console.log( maybeJSON );
1677				//maybeJSON = JSON.parse( maybeJSON );
1678			}
1679
1680			return maybeJSON;
1681
1682		},
1683
1684		initSlider: function( $slider, customOptions ) {
1685			var $eWidget    = $slider.closest( '.elementor-widget' ),
1686				options     = $slider.data( 'slider_options' ),
1687				windowWidth = $( window ).width(),
1688				tabletBP    = 1025,
1689				mobileBP    = 768,
1690				tabletSlides, mobileSlides, defaultOptions, slickOptions;
1691
1692			options = JetEngine.ensureJSON( options );
1693
1694			customOptions = customOptions || {};
1695
1696			options = $.extend( {}, options, customOptions );
1697
1698			if ( $eWidget.length ) {
1699
1700				var settings     = JetEngine.getElementorElementSettings( $eWidget ),
1701					responsive   = [],
1702					deviceMode   = elementorFrontend.getCurrentDeviceMode(),
1703					eBreakpoints = window.elementorFrontend.config.responsive.activeBreakpoints;
1704
1705				options.slidesToShow = settings.columns_widescreen ? +settings.columns_widescreen : +settings.columns;
1706
1707				Object.keys( eBreakpoints ).reverse().forEach( function( breakpointName ) {
1708
1709					if ( settings['columns_' + breakpointName] ) {
1710
1711						if ( 'widescreen' === breakpointName ) {
1712
1713							responsive.push( {
1714								breakpoint: eBreakpoints[breakpointName].value,
1715								settings: {
1716									slidesToShow: +settings['columns'],
1717								}
1718							} );
1719
1720						} else {
1721							var breakpointSettings = {
1722									breakpoint: eBreakpoints[breakpointName].value + 1,
1723									settings:   {
1724										slidesToShow: +settings['columns_' + breakpointName],
1725									}
1726								};
1727
1728							if ( options.slidesToScroll > breakpointSettings.settings.slidesToShow ) {
1729								breakpointSettings.settings.slidesToScroll = breakpointSettings.settings.slidesToShow;
1730							}
1731
1732							// if ( 'mobile' === breakpointName ) {
1733							// 	breakpointSettings.settings.slidesToScroll = 1;
1734							// }
1735
1736							responsive.push( breakpointSettings );
1737						}
1738					}
1739
1740				} );
1741
1742				options.responsive = responsive;
1743
1744			} else {
1745
1746				// Ensure we have at least some options to avoid errors
1747				if ( ! options.slidesToShow ) {
1748					options.slidesToShow = {
1749						desktop: 3,
1750						tablet: 1,
1751						mobile: 1,
1752					}
1753				}
1754
1755				if ( options.itemsCount <= options.slidesToShow.desktop && windowWidth >= tabletBP ) { // 1025 - ...
1756					$slider.removeClass( 'jet-listing-grid__slider' );
1757					return;
1758				} else if ( options.itemsCount <= options.slidesToShow.tablet && tabletBP > windowWidth && windowWidth >= mobileBP ) { // 768 - 1024
1759					$slider.removeClass( 'jet-listing-grid__slider' );
1760					return;
1761				} else if ( options.itemsCount <= options.slidesToShow.mobile && windowWidth < mobileBP ) { // 0 - 767
1762					$slider.removeClass( 'jet-listing-grid__slider' );
1763					return;
1764				}
1765
1766				if ( options.slidesToShow.tablet ) {
1767					tabletSlides = options.slidesToShow.tablet;
1768				} else {
1769					tabletSlides = 1 === options.slidesToShow.desktop ? 1 : 2;
1770				}
1771
1772				if ( options.slidesToShow.mobile ) {
1773					mobileSlides = options.slidesToShow.mobile;
1774				} else {
1775					mobileSlides = 1;
1776				}
1777
1778				options.slidesToShow = options.slidesToShow.desktop;
1779
1780				options.responsive = [
1781					{
1782						breakpoint: 1025,
1783						settings: {
1784							slidesToShow: tabletSlides,
1785							slidesToScroll: options.slidesToScroll > tabletSlides ? tabletSlides : options.slidesToScroll
1786						}
1787					},
1788					{
1789						breakpoint: 768,
1790						settings: {
1791							slidesToShow: mobileSlides,
1792							slidesToScroll: 1
1793						}
1794					}
1795				];
1796			}
1797
1798			defaultOptions = {
1799				customPaging: function( slider, i ) {
1800					return $( '<span />' ).text( i + 1 ).attr( 'role', 'tab' );
1801				},
1802				slide: '.jet-listing-grid__item',
1803				dotsClass: 'jet-slick-dots',
1804			};
1805
1806			slickOptions = $.extend( {}, defaultOptions, options );
1807
1808			var $sliderItems = $slider.find( '> .jet-listing-grid__items' );
1809
1810			if ( slickOptions.infinite ) {
1811				$sliderItems.on( 'init', function() {
1812					var $items        = $( this ),
1813						$clonedSlides = $( '> .slick-list > .slick-track > .slick-cloned.jet-listing-grid__item', $items );
1814
1815					if ( !$clonedSlides.length ) {
1816						return;
1817					}
1818
1819					JetEngine.initElementsHandlers( $clonedSlides );
1820
1821					if ( $slider.find('.bricks-lazy-hidden').length ) {
1822						bricksLazyLoad();
1823					}
1824				} );
1825			}
1826
1827			// Temporary solution issue with Lazy Load images + RTL on Chrome.
1828			// Remove after fix in Chrome.
1829			// See: https://github.com/Crocoblock/issues-tracker/issues/7552
1830			if ( slickOptions.rtl ) {
1831				$sliderItems.on( 'init', function() {
1832					var $items      = $( this ),
1833						$lazyImages = $( 'img[loading=lazy]', $items ),
1834						lazyImageObserver = new IntersectionObserver(
1835							function( entries, observer ) {
1836								entries.forEach( function( entry ) {
1837									if ( entry.isIntersecting ) {
1838										// If an image does not load, need to remove the `loading` attribute.
1839										if ( ! entry.target.complete ) {
1840											entry.target.removeAttribute( 'loading' );
1841										}
1842
1843										// Detach observer
1844										observer.unobserve( entry.target );
1845									}
1846								} );
1847							}
1848						);
1849
1850					$lazyImages.each( function() {
1851						const $img = $( this );
1852						lazyImageObserver.observe( $img[0] );
1853					} );
1854				} );
1855			}
1856
1857			if ( $sliderItems.hasClass( 'slick-initialized' ) ) {
1858				$sliderItems.slick( 'refresh', true );
1859				return;
1860			}
1861
1862			if ( slickOptions.variableWidth ) {
1863				slickOptions.slidesToShow = 1;
1864				slickOptions.slidesToScroll = 1;
1865				slickOptions.responsive = null;
1866			}
1867
1868			$sliderItems.slick( slickOptions );
1869		},
1870
1871		maybeReinitSlider: function( event, $scope ) {
1872			var $slider = $scope.find( '.jet-listing-grid__slider' );
1873
1874			if ( $slider.length ) {
1875				$slider.each( function() {
1876					JetEngine.initSlider( $( this ) );
1877				} );
1878			}
1879		},
1880
1881		widgetDynamicField: function( $scope ) {
1882
1883			var $slider = $scope.find( '.jet-engine-gallery-slider' );
1884
1885			if ( $slider.length ) {
1886				if ( $.isFunction( $.fn.imagesLoaded ) ) {
1887					$slider.imagesLoaded().always( function( instance ) {
1888
1889						var $eWidget = $slider.closest( '.elementor-widget' );
1890
1891						if ( $slider.hasClass( 'slick-initialized' ) ) {
1892							$slider.slick( 'refresh', true );
1893						} else {
1894							var atts = $slider.data( 'atts' );
1895
1896							atts = JetEngine.ensureJSON( atts );
1897
1898							if ( $eWidget.length ) {
1899								var settings     = JetEngine.getElementorElementSettings( $scope ),
1900									eBreakpoints = window.elementorFrontend.config.responsive.activeBreakpoints,
1901									responsive   = [];
1902
1903								if ( settings.img_slider_cols || settings.img_slider_cols_widescreen ) {
1904									atts.slidesToShow = settings.img_slider_cols_widescreen ? +settings.img_slider_cols_widescreen : +settings.img_slider_cols;
1905								}
1906
1907								Object.keys( eBreakpoints ).reverse().forEach( function( breakpointName ) {
1908
1909									if ( settings['img_slider_cols_' + breakpointName] ) {
1910
1911										if ( 'widescreen' === breakpointName ) {
1912
1913											responsive.push( {
1914												breakpoint: eBreakpoints[breakpointName].value,
1915												settings:   {
1916													slidesToShow: +settings['img_slider_cols'],
1917												}
1918											} );
1919
1920										} else {
1921											var breakpointSettings = {
1922												breakpoint: eBreakpoints[breakpointName].value + 1,
1923												settings:   {
1924													slidesToShow: +settings['img_slider_cols_' + breakpointName],
1925												}
1926											};
1927
1928											responsive.push( breakpointSettings );
1929										}
1930									}
1931
1932								} );
1933
1934								atts.responsive = responsive;
1935							}
1936
1937							$slider.slick( atts );
1938						}
1939					} );
1940				}
1941			}
1942
1943			$slider.on('init', function (event, slick) {
1944
1945				const slider = event.target;
1946
1947				if (!slider.classList.contains('jet-engine-gallery-lightbox')) {
1948					return;
1949				}
1950
1951				let lightbox = new PhotoSwipeLightbox({
1952					mainClass: 'brx',
1953					gallery: slider,
1954					children: 'a',
1955					showHideAnimationType: 'none',
1956					zoomAnimationDuration: false,
1957					pswpModule: PhotoSwipe5,
1958				});
1959
1960				lightbox.addFilter('numItems', numItems => slick.slideCount);
1961
1962				lightbox.addFilter('clickedIndex', function (clickedIndex, e) {
1963					const slide = e.target.closest('.slick-slide');
1964
1965					if (!slide) {
1966						return clickedIndex;
1967					}
1968
1969					if (clickedIndex >= slick.slideCount) {
1970						return clickedIndex % slick.slideCount;
1971					}
1972
1973					return clickedIndex;
1974				});
1975
1976				lightbox.addFilter('thumbEl', (thumbnail, itemData, index) => {
1977					return thumbnail;
1978				});
1979
1980				lightbox.addFilter('thumbBounds', (thumbBounds, itemData, index) => {
1981					return thumbBounds;
1982				});
1983
1984				lightbox.init();
1985			});
1986
1987			// Masonry init
1988			var $masonry = $scope.find( '.jet-engine-gallery-grid--masonry' );
1989
1990			if ( $masonry.length ) {
1991				JetEngine.initMasonry( $masonry, {
1992					columnsKey: 'img_columns',
1993					itemSelector: '> .jet-engine-gallery-grid__item',
1994				} );
1995			}
1996
1997		},
1998
1999		switchCalendarMonth: function( $event ) {
2000
2001			var $this     = $( this ),
2002				$calendar = $this.closest( '.jet-calendar' ),
2003				$widget   = $calendar.closest( '.elementor-widget-container' ),
2004				settings  = $calendar.data( 'settings' ),
2005				post      = $calendar.data( 'post' ),
2006				month     = $this.data( 'month' );
2007
2008			settings = JetEngine.ensureJSON( settings );
2009
2010			// Context Gutenberg
2011			if ( ! $widget.length ) {
2012				$widget = $calendar.closest( '.jet-listing-calendar-block' )
2013			}
2014
2015			// Context Bricks
2016			if ( ! $widget.length ) {
2017				$widget = $calendar.closest( '.brxe-jet-listing-calendar' )
2018			}
2019
2020			$calendar.addClass( 'jet-calendar-loading' );
2021
2022			JetEngine.currentRequest = {
2023				jet_engine_action: 'jet_engine_calendar_get_month',
2024				month: month,
2025				settings: settings,
2026				post: post,
2027			};
2028
2029			$( document ).trigger( 'jet-engine-request-calendar' );
2030
2031			$.ajax({
2032				url: JetEngineSettings.ajaxlisting,
2033				type: 'POST',
2034				dataType: 'json',
2035				data: JetEngine.currentRequest,
2036			}).done( function( response ) {
2037				if ( response.success ) {
2038					$calendar.replaceWith( response.data.content );
2039					JetEngine.initElementsHandlers( $widget );
2040				}
2041				$calendar.removeClass( 'jet-calendar-loading' );
2042			} );
2043		},
2044
2045		initElementsHandlers: function( $selector ) {
2046
2047			// Actual init
2048			window.JetPlugins.init( $selector );
2049
2050			// Legacy Elementor-only init
2051			$selector.find( '[data-element_type]' ).each( function() {
2052
2053				var $this       = $( this ),
2054					elementType = $this.data( 'element_type' );
2055
2056				if ( !elementType ) {
2057					return;
2058				}
2059
2060				if ( ! window?.elementorFrontend?.hooks?.doAction ) {
2061					return;
2062				}
2063
2064				if ( 'widget' === elementType ) {
2065					elementType = $this.data( 'widget_type' );
2066					window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ );
2067				}
2068
2069				window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ );
2070				window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ );
2071
2072			} );
2073
2074			if ( window.elementorFrontend ) {
2075				const elementorLazyLoad = new Event( "elementor/lazyload/observe" );
2076				document.dispatchEvent( elementorLazyLoad );
2077			}
2078
2079			if ( window.JetPopupFrontend && window.JetPopupFrontend.initAttachedPopups ) {
2080				window.JetPopupFrontend.initAttachedPopups( $selector );
2081			}
2082
2083		},
2084
2085		getElementorElementSettings: function( $scope ) {
2086
2087			if ( window.elementorFrontend && window.elementorFrontend.isEditMode() && $scope.hasClass( 'elementor-element-edit-mode' ) ) {
2088				return JetEngine.getEditorElementSettings( $scope );
2089			}
2090
2091			return $scope.data( 'settings' ) || {};
2092		},
2093
2094		getEditorElementSettings: function( $scope ) {
2095			var modelCID = $scope.data( 'model-cid' ),
2096				elementData;
2097
2098			if ( ! modelCID ) {
2099				return {};
2100			}
2101
2102			if ( ! window.elementorFrontend.hasOwnProperty( 'config' ) ) {
2103				return {};
2104			}
2105
2106			if ( ! window.elementorFrontend.config.hasOwnProperty( 'elements' ) ) {
2107				return {};
2108			}
2109
2110			if ( ! window.elementorFrontend.config.elements.hasOwnProperty( 'data' ) ) {
2111				return {};
2112			}
2113
2114			elementData = window.elementorFrontend.config.elements.data[ modelCID ];
2115
2116			if ( ! elementData ) {
2117				return {};
2118			}
2119
2120			return elementData.toJSON();
2121		},
2122
2123		debounce: function( threshold, callback ) {
2124			var timeout;
2125
2126			return function debounced( $event ) {
2127				function delayed() {
2128					callback.call( this, $event );
2129					timeout = null;
2130				}
2131
2132				if ( timeout ) {
2133					clearTimeout( timeout );
2134				}
2135
2136				timeout = setTimeout( delayed, threshold );
2137			};
2138		},
2139
2140		updateAddedStyles: function() {
2141			if ( window.JetEngineSettings && window.JetEngineSettings.addedPostCSS ) {
2142				$.each( window.JetEngineSettings.addedPostCSS, function( ind, cssID ) {
2143					JetEngine.addedStyles.push( 'elementor-post-' + cssID );
2144					JetEngine.addedPostCSS.push( cssID );
2145				} );
2146			}
2147		},
2148
2149		enqueueAssetsFromResponse: function( response ) {
2150			if ( response.data.scripts ) {
2151				JetEngine.enqueueScripts( response.data.scripts );
2152			}
2153
2154			if ( response.data.styles ) {
2155				JetEngine.enqueueStyles( response.data.styles );
2156			}
2157		},
2158
2159		enqueueScripts: function( scripts ) {
2160			$.each( scripts, function( handle, scriptHtml ) {
2161				JetEngine.enqueueScript( handle, scriptHtml )
2162			} );
2163		},
2164
2165		enqueueStyles: function( styles ) {
2166			$.each( styles, function( handle, styleHtml ) {
2167				JetEngine.enqueueStyle( handle, styleHtml )
2168			} );
2169		},
2170
2171		enqueueScript: function( handle, scriptHtml ) {
2172
2173			if ( -1 !== JetEngine.addedScripts.indexOf( handle ) ) {
2174				return;
2175			}
2176
2177			if ( ! scriptHtml ) {
2178				return;
2179			}
2180
2181			var selector = 'script[id="' + handle + '-js"]';
2182
2183			if ( $( selector ).length ) {
2184				return;
2185			}
2186
2187			//$( 'body' ).append( scriptHtml );
2188
2189			var scriptsTags = scriptHtml.match( /<script[\s\S]*?<\/script>/gm );
2190			
2191			if ( scriptsTags.length ) {
2192
2193				for ( var i = 0; i < scriptsTags.length; i++ ) {
2194
2195					JetEngine.assetsPromises.push(
2196						new Promise( function( resolve, reject ) {
2197
2198							var $tag = $( scriptsTags[i] );
2199
2200							if ( $tag[0].src ) {
2201
2202								var tag = document.createElement( 'script' );
2203
2204								tag.type   = $tag[0].type;
2205								tag.src    = $tag[0].src;
2206								tag.id     = $tag[0].id;
2207								tag.async  = false;
2208								tag.onload = function() {
2209									resolve();
2210								};
2211
2212								document.body.append( tag );
2213							} else {
2214								$( 'body' ).append( scriptsTags[i] );
2215								resolve();
2216							}
2217						} )
2218					);
2219				}
2220			}
2221
2222			JetEngine.addedScripts.push( handle );
2223		},
2224
2225		enqueueStyle: function( handle, styleHtml ) {
2226
2227			if ( -1 !== handle.indexOf( 'google-fonts' ) ) {
2228				JetEngine.enqueueGoogleFonts( handle, styleHtml );
2229				return;
2230			}
2231
2232			if ( -1 !== JetEngine.addedStyles.indexOf( handle ) ) {
2233				return;
2234			}
2235
2236			var selector = 'link[id="' + handle + '-css"],style[id="' + handle + '"]';
2237
2238			if ( $( selector ).length ) {
2239				return;
2240			}
2241
2242			$( 'head' ).append( styleHtml );
2243
2244			JetEngine.addedStyles.push( handle );
2245
2246			if ( -1 !== handle.indexOf( 'elementor-post' ) ) {
2247				var postID = handle.replace( 'elementor-post-', '' );
2248				JetEngine.addedPostCSS.push( postID );
2249			}
2250		},
2251
2252		enqueueGoogleFonts: function( handle, styleHtml ) {
2253
2254			var selector = 'link[id="' + handle + '-css"]';
2255
2256			if ( $( selector ).length ) {}
2257
2258			$( 'head' ).append( styleHtml );
2259		},
2260
2261		isFrontend: function () {
2262			// Check the Elementor
2263			if (typeof window.elementorFrontend !== 'undefined') {
2264				return !window.elementorFrontend.isEditMode();
2265			}
2266
2267			// Check the Bricks
2268			if (typeof window.bricksIsFrontend !== 'undefined') {
2269				return window.bricksIsFrontend;
2270			}
2271
2272			// If no builders are found, we assume it is frontend.
2273			return true;
2274		},
2275
2276		filters: ( function() {
2277
2278			var callbacks = {};
2279
2280			return {
2281
2282				addFilter: function( name, callback ) {
2283
2284					if ( ! callbacks.hasOwnProperty( name ) ) {
2285						callbacks[name] = [];
2286					}
2287
2288					callbacks[name].push(callback);
2289
2290				},
2291
2292				applyFilters: function( name, value, args ) {
2293
2294					if ( ! callbacks.hasOwnProperty( name ) ) {
2295						return value;
2296					}
2297
2298					if ( args === undefined ) {
2299						args = [];
2300					}
2301
2302					var container = callbacks[ name ];
2303					var cbLen     = container.length;
2304
2305					for (var i = 0; i < cbLen; i++) {
2306						if (typeof container[i] === 'function') {
2307							value = container[i](value, args);
2308						}
2309					}
2310
2311					return value;
2312				}
2313
2314			};
2315
2316		})()
2317
2318	};
2319
2320	$( window ).on( 'elementor/frontend/init', JetEngine.init );
2321
2322	window.JetEngine = JetEngine;
2323
2324	JetEngine.commonInit();
2325
2326	window.addEventListener( 'DOMContentLoaded', function() {
2327		JetEngine.initBlocks();
2328		JetEngine.initDone = true;
2329	} );
2330
2331	window.jetEngineBricks = function() {
2332		JetEngine.initBricks();
2333	}
2334
2335	$( window ).trigger( 'jet-engine/frontend/loaded' );
2336
2337}( 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.