PageSourceSearch

https://naomiklein.org/wp-content/plugins/eventON/assets/js/eventon_script.js?ver=5.0.13

js naomiklein.org collected 2026-09-24 08:45:47 UTC 122,253 bytes, 3,416 lines download raw bytes

1/**
2 * Javascript code that is associated with the front end of the calendar
3 * @version 5.0.7
4 * @license EventON JavaScript Assets 
5 * Copyright (C) 2014-2026 Ashan Jay, AshanJay Designs LLC.
6 * 
7 * PROPRIETARY LICENSE - All Rights Reserved
8 * 
9 * Permission granted solely for personal use with valid EventON license.
10 * YOU MAY NOT: redistribute, resell, sublicense, or publish these Assets.
11 * 
12 * Trademark: "EventON" is a trademark of AshanJay Designs LLC.
13 * Contact: [email protected]
14 * 
15 * PROVIDED "AS IS" WITHOUT WARRANTY. VIOLATION MAY RESULT IN LEGAL ACTION.
16 */
17
18jQuery(document).ready(function($){
19
20	// restrict this only to frontend of the calendar
21	if ( evo_general_params != '' && evo_general_params !== undefined && evo_general_params.is_admin) return; 
22	
23	//return;
24	var BODY = $('body');
25	var BUS = ''; // initial eventon calendar data
26	var ajax_url = evo_general_params.ajaxurl;
27	var D = {'listenCall': false, 'listenInt': false};
28
29// EventON calendar main function
30	// Calendar processing 2.8.6 u 4.6
31	$.fn.evo_calendar = function (options) {
32
33		var el = this;
34		var cal = this;
35		var cal = {};
36		var calO = $.extend({
37			'SC': {},
38			'json':{},
39			'type':'init' ,
40			map_delay:0
41		}, options);
42		var SC = el.evo_shortcode_data();
43
44		
45		// load calendar eventcard and eventtop interactions
46		this.find('.eventon_list_event').each(function(){
47			evo_cal_eventcard_interactions( $(this) );
48		});
49
50		var init = function(){
51
52			// change IDs for map section for eventon widgets
53			if( $(el).hasClass('evcal_widget')){
54				$(el).find('.evcal_gmaps').each(function(){
55					var gmap_id = obj.attr('id');
56					var new_gmal_id =gmap_id+'_widget'; 
57					obj.attr({'id':new_gmal_id})
58				});
59			}
60
61			// load maps on calendar
62			_evo_run_eventcard_map_load();
63
64			// initial actions on calendar
65			$(el).evo_cal_filtering();
66
67			// localizing event time
68			$(el).evo_cal_localize_time();
69
70			// load lightbox events on page load
71			$(cal).evo_cal_oneevent_onload(calO.type);			
72			
73			el.evo_cal_hide_data();	
74
75			live_now_cal();
76			counters();
77		};
78		
79		// support	
80			var live_now_cal = function(){
81				$(el).find('.evo_img_time').each(function(){
82					if( $(this).closest('a.desc_trig').find('em.evcal_time').length ){
83						_html = $(this).closest('a.desc_trig').find('em.evcal_time')[0].outerHTML;
84						$(this).html( _html );
85					}				
86				});
87			}
88
89			var counters = function(){
90				$(el).find('.evo_countdowner').each(function(){
91					$(this).evo_countdown();
92				});
93			}
94
95		init();	
96	};
97
98      
99// Event Card handling / Bind Event Listeners --- v4.6.1 @updated 5.0
100	var EVO_EventCard_Listeners = function(){
101
102		const EVO_Card_Listeners = {
103			E: { B: $('body') },
104			init(){
105				const { E } = this;
106				// Event listeners
107	            E.B.on('click.evoCard', '.evo_et_trigger', (e) => this.evo_handle_et_sidePanel(e));
108	            E.B.on('evo_ajax_success_evo_et_trigger.evoCard', (e, OO, data, el) => this.evo_handle_et_sp_content(e, OO, data, el));
109	            E.B.on('click.evoCard', '.tzo_trig', (e) => this.localizeTime(e));
110	            E.B.on('click.evoCard', '.evo_event_more_img', (e) => this.handle_event_more_img(e));
111	            E.B.on('click.evoCard', '.evo_img_triglb', (e) => this.handle_img_triglb(e));
112	            E.B.on('click.evoCard', '.evo_repeat_series_date', (e) => this.handle_repeat_series_date(e));
113	            E.B.on('click.evoCard', '.copy.evo_ss', (e) => this.handle_copy_event_link(e));
114	            E.B.on('click.evoCard', '.evo_copy_address', (e) => this.handle_copy_event_address(e));
115	            E.B.on('click.evoCard', '.evo_openmap_trig', (e) => this.handle_open_inmaps(e));
116	            E.B.on('click.evoCard', '.evo_locimg_more', (e) => this.handle_locimg_more(e));
117	            E.B.on('click.evoCard', '.evo_gal_icon', (e) => this.handle_gal_icon(e));
118	            E.B.on('click.evoCard', '.evobtn_details_show_more', (e) => this.handle_details_show_more(e));
119	            E.B.on('click.evoCard', '.evcal_close', (e) => this.handle_close_eventcard(e));
120	            E.B.on('click.evoCard', '.evocmd_button', (e) => this.handle_evocmd_button(e));
121	            E.B.on('click.evoCard', '.evo_org_clk_link', (e) => this.handle_org_clk_link(e));
122	            E.B.on('click.evoCard', '.editEventBtnET', (e) => this.handle_edit_event_button(e));
123	            E.B.on('click.evoCard', '.evo_organizer_more_trig', (e) => this.handle_organizer_more_details(e));
124			},
125
126			handle_organizer_more_details(e){
127				const { E } = this;
128		        const $el = $(e.currentTarget);
129		        $el.parent().hide();
130		        $el.parent().siblings('.evo_org_details_full').show().removeClass('evodni');
131			},
132
133			// actions
134				// Opens a side panel for event type triggers, adding a class and setting up data
135		        evo_handle_et_sidePanel(e) {
136		            const { E } = this;
137		            const $el = $(e.currentTarget);
138		            e.preventDefault();
139		            $el.addClass('evo_sp_trig_on');
140		            const aData = $el.data('d');
141		            aData.adata.data['nonce'] = evo_general_params.n;
142		            $el.evo_open_sidepanel(aData);
143		        },
144
145		        // Populates the side panel with content from an AJAX response and removes the loading bar
146		        evo_handle_et_sp_content(e, OO, data, el) {
147		            $(el).evo_populate_sidepanel(data.html);
148		            $('#evo_sp').find('.evo_loading_bar_holder').remove();
149		        },
150
151		        // Localizes the time display for elements with the tzo_trig class
152		        localizeTime(e) {
153		            e.preventDefault();
154		            e.stopPropagation();
155		            $(e.target).evo_localize_time();
156		        },
157
158		        // Changes the main event image when a thumbnail is clicked
159		        handle_event_more_img(e) {
160		            const $el = $(e.currentTarget);
161		            const box = $el.closest('.evcal_eventcard');
162		            const gal = $el.closest('.evocard_fti_in');
163
164		            if (box.length === 0) return;
165
166		            $el.siblings('span').removeClass('select');
167		            $el.addClass('select');
168
169		            const mainIMG = box.find('.evocard_main_image');
170		            mainIMG.data({
171		                h: $el.data('h'),
172		                w: $el.data('w'),
173		                f: $el.data('f'),
174		                a: $el.data('a'),
175		            });
176
177		            if (mainIMG.hasClass('def')) {
178		                mainIMG.css('background-image', `url(${$el.data('f')})`);
179		            } else {
180		                mainIMG.html(`<span style="background-image:url(${$el.data('f')})"></span>`);
181		                mainIMG.eventon_process_main_ft_img();
182		            }
183		        },
184
185		        // Opens a lightbox to display a full-size event image when clicked
186		        handle_img_triglb(e) {
187		            const $el = $(e.currentTarget);
188
189		            if ($el.hasClass('inlb')) return;
190
191		            const __ac = parseInt($el.data('w')) >= parseInt($el.data('h')) ? 'iW' : 'iH';
192		            $el.evo_lightbox_open({
193		                uid: 'evocard_ft_img',
194		                lbc: 'evolb_ft_img',
195		                lbac: `within evocard_img ${__ac}`,
196		                content: `<img class='evocard_main_image inlb' src='${$el.data('f')}' data-w='${$el.data('w')}' data-h='${$el.data('h')}' style='max-width:100%; max-height:100%;'/>`,
197		                end: 'client',
198		                lb_padding: '',
199		                d: { event_id: $el.data('event_id'), ri: $el.data('ri') }
200		            });
201		        },
202
203		        // Navigates to a repeat event's date URL based on user interaction type
204		        handle_repeat_series_date(e) {
205		            const $el = $(e.currentTarget);
206		            if (!$el.parent().hasClass('clickable')) return;
207
208		            const ux = $el.data('ux');
209		            const URL = $el.data('l');
210		            if (ux === 'def') window.location = URL;
211		            if (ux === 'defA') window.open(URL, '_blank');
212		        },
213
214		        // Copies an event link to the clipboard and shows a temporary confirmation
215		        handle_copy_event_link(e) {
216		        	e.preventDefault();
217		            e.stopPropagation();
218		            const $el = $(e.currentTarget);
219		            const ROW = $el.closest('.evcal_evdata_row');
220		            const link = decodeURIComponent($el.data('l'));
221		            navigator.clipboard.writeText(link);
222
223		            const evo_card_socialshare_html = ROW.html();
224		            ROW.html(`<p style='display:flex'><i class='fa fa-check marr10'></i> ${$el.data('t')}</p>`);
225
226		            setTimeout(() => {
227		                ROW.html(evo_card_socialshare_html);
228		            }, 3000);
229		        },
230
231		        // copy event location address
232		        handle_copy_event_address(e){
233		        	e.preventDefault();
234		            e.stopPropagation();
235		        	const $el = $(e.currentTarget);
236		        	const content = decodeURIComponent($el.data('txt'));
237		        	const informer = $el.siblings('.evo_event_loc_link');
238
239		        	navigator.clipboard.writeText(content);
240		        	informer.html( $el.data('t'));
241
242		        	setTimeout(() => {
243		                informer.html( content );
244		            }, 3000);
245		        },
246
247		        // open event location in maps
248		        handle_open_inmaps(e){
249		        	e.preventDefault();
250		            e.stopPropagation();
251		        	const $el = $(e.currentTarget);
252
253		        	const address = $el.data('d');
254		        	const ua = navigator.userAgent;
255				    // Mobile: try to open native app first
256				    if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('ipod')) {
257				        // Force Apple Maps APP
258				        window.location = 'maps://maps.apple.com/?q=' + address;
259				        // Fallback to web in new tab after 1 second if app didn't open
260				        setTimeout(() => {
261				            window.open('https://maps.apple.com/?q=' + address, '_blank');
262				        }, 1000);
263				    }
264				    else if (ua.includes('android')) {
265				        // Force Google Maps APP
266				        window.location = 'geo:0,0?q=' + address;
267				        setTimeout(() => {
268				            window.open('https://www.google.com/maps/search/?api=1&query=' + address, '_blank');
269				        }, 1000);
270				    }
271				    else {
272				        // Desktop or unknown → always open in new tab (your requirement)
273				        window.open('https://www.google.com/maps/search/?api=1&query=' + address, '_blank', 'noopener');
274				    }
275		        },
276
277		        // Toggles visibility of additional location images
278		        handle_locimg_more(e) {
279		            e.preventDefault();
280		            e.stopPropagation();
281		            $(e.currentTarget).closest('.evo_metarow_locImg').toggleClass('vis');
282		        },
283
284		        // Updates the gallery main image when a gallery icon is clicked
285		        handle_gal_icon(e) {
286		            e.preventDefault();
287		            e.stopPropagation();
288
289		            const $el = $(e.currentTarget);
290		            if ($el.hasClass('on')) return;
291		            $el.siblings('div').removeClass('on');
292		            $el.addClass('on');
293
294		            $el.closest('.evo_gal_box').find('.evo_gal_main_img')
295		                .css('background-image', `url(${$el.data('u')})`)
296		                .data('f', $el.data('u'))
297		                .data('h', $el.data('h'))
298		                .data('w', $el.data('w'));
299		        },
300
301		        // Toggles the display of additional event details
302		        handle_details_show_more(e) {
303		            e.preventDefault();
304		            this.control_more_less($(e.currentTarget));
305		        },
306
307		        // Closes the event card by sliding it up
308		        handle_close_eventcard(e) {
309		            e.preventDefault();
310		            $(e.currentTarget).closest('.evcal_eventcard').slide
310Up().removeClass('open');
311		        },
312
313		        // Redirects to a URL when an event command button is clicked
314		        handle_evocmd_button(e) {
315		            e.preventDefault();
316		            e.stopPropagation();
317
318		            const $el = $(e.currentTarget);
319		            const href = $el.data('href');
320		            if ($el.data('target') === 'yes') {
321		                window.open(href, '_blank');
322		            } else {
323		                window.location = href;
324		            }
325		        },
326
327		        // Opens an organizer's link in a new tab
328		        handle_org_clk_link(e) {
329		            window.open($(e.currentTarget).data('link'), '_blank');
330		        },
331
332		        // Redirects to the event edit page
333		        handle_edit_event_button(e) {
334		            e.stopPropagation();
335		            const href = $(e.currentTarget).attr('href');
336		            window.open(href);
337		        },
338
339		        // Controls the more/less toggle for event details display
340		        control_more_less(obj) {
341		            const content = obj.attr('content');
342		            const current_text = obj.find('.ev_more_text').html();
343		            const changeTo_text = obj.find('.ev_more_text').attr('data-txt');
344		            const cell = obj.closest('.evcal_evdata_cell');
345
346		            if (content === 'less') {
347		                cell.removeClass('shorter_desc');
348		                obj.attr('content', 'more');
349		                obj.find('.ev_more_arrow').removeClass('ard');
350		                obj.find('.ev_more_text').attr('data-txt', current_text).html(changeTo_text);
351		            } else {
352		                cell.addClass('shorter_desc');
353		                obj.attr('content', 'less');
354		                obj.find('.ev_more_arrow').addClass('ard');
355		                obj.find('.ev_more_text').attr('data-txt', current_text).html(changeTo_text);
356		            }
357		        }
358		};
359
360		EVO_Card_Listeners.init();		
361
362	}
363	var evo_cal_eventcard_interactions = function( EC , load_maps ){
364
365		// process featured image sizes
366		EC.find(".evocard_main_image").eventon_process_main_ft_img(  );		
367
368		// process content sliders
369		EC.find('.evo_elm_HCS').each(function(){
370			$(this).evoContentSlider();
371		});	
372
373		// countdown
374		EC.find('.evo_countdowner').each(function(){
375			var obj = $(this);
376			obj.removeClass('evo_cd_on');
377			obj.evo_countdown();
378		});
379		
380		$(window).on('resize',function(){
381			BODY.find(".evocard_main_image").each(function(){
382				$(this).eventon_process_main_ft_img();		
383			});
384			//EC.find(".evocard_main_image").eventon_process_main_ft_img();		
385		});
386	}
387	$.fn._evo_cal_eventcard_interactions = function( EC, load_maps){
388		evo_cal_eventcard_interactions( EC , load_maps);
389	}
390
391	// run all map waiting map @4.6.1
392	function _evo_run_eventcard_map_load(){
393		BODY.evo_run_eventcard_map_load();
394	}
395	$.fn.evo_run_eventcard_map_load = function(){
396
397		time = 600;
398
399		BODY.find('.evo_metarow_gmap').each(function(index){	
400			O = $(this);
401			if( !(O.is(":visible")) ) return;
402			O.evo_load_gmap({
403				map_canvas_id: O.attr('id'),
404				trigger_point:'evo_calendar',
405				delay: time
406			});
407			time += 600;
408		});			
409	}
410
411// EventTop Interactions v4.6
412	var evo_cal_eventtop_interactions = function( ET ){	}
413	
414// RUN on Page load
415	EVO_Global_Init();
416
417	function EVO_Global_Init(){
418
419		EVO_Interactions();
420
421		EVO_EventCard_Listeners();
422
423		// check if calendars are present in the page
424			var run_initload = false;
425
426			if( $('body').find('.ajde_evcal_calendar').length > 0 ) run_initload = true;
427			if( $('body').find('.ajax_loading_cal').length > 0 ) run_initload = true;
428			if( $('body').find('.eventon_single_event').length > 0 ) run_initload = true;
429
430			if(run_initload == false) return false;
431
432			var data_arg = {};	
433
434			BODY.trigger('evo_global_page_run');
435
436			data_arg['global'] = $('#evo_global_data').data('d');
437			data_arg['cals'] ={};	
438			data_arg['nonce'] = evo_general_params.n;				
439
440		// run through all the calendars on page
441			BODY.find('.ajde_evcal_calendar').each(function(){
442				const CAL = $(this);
443				var SC = CAL.evo_shortcode_data();
444
445				CAL.evo_pre_cal();
446
447				if( CAL.hasClass('ajax_loading_cal')){
448					data_arg['cals'][ CAL.attr('id')] = {};
449					data_arg['cals'][ CAL.attr('id')]['sc'] = SC;
450
451					BODY.trigger('evo_global_page_run_after', CAL , SC );// @4.6.1
452				}
453			});
454
455		BODY.evo_admin_get_ajax({
456			adata:{
457				data:data_arg,
458				a:'eventon_init_load',ajax_type:'endpoint',end:'client'
459			},
460			onSuccess:function( OO, data, LB){
461				$('#evo_global_data').data('d', data);
462
463				BUS = data;
464
465				// append html to calendars if present
466				if('cals' in data){
467					var time = 300;
468					$.each(data.cals, function(i,v){
469
470						setTimeout( function(){
471
472							CAL = BODY.find('#'+ i);
473							if(CAL.length === 0) return;
474							
475							if('html' in v){						
476								CAL.find('#evcal_list').html( v.html );
477								CAL.removeClass('ajax_loading_cal');
478								CAL.find('.evo_ajax_load_events').remove();
479							}	
480
481							// load SC and JSON to calendar
482							CAL.evo_cal_functions({action:'update_shortcodes',SC: v.sc});
483							CAL.evo_cal_functions({action:'update_json',json: v.json});
484							
485							$('body').trigger('evo_init_ajax_success_each_cal', [data, i, v, CAL]);
486
487						}, time);
488						time += 300;
489					});
490				}
491
492				$('body').trigger('evo_init_ajax_success', [data]);
493
494				// after timeout based cal loading, process all cals
495				setTimeout( function(){
496					BODY.find('.ajde_evcal_calendar').each(function(){
497						if( $(this).hasClass('.ajax_loading_cal') ) return;					
498						$(this).evo_calendar({'type':'complete'});
499					});
500				}, time );
501			},
502			onComplete:function( OO, data){
503				$('body').trigger('evo_init_ajax_completed', [data]);
504			}
505		});	
506
507		handlebar_additional_arguments();
508		
509		EVO_Cal_Body_listeners();
510
511		// run basic countdown timers
512		BODY.find('.evo_countdowner').each(function(){
513			$(this).evo_countdown();
514		});
515	}
516
517
518
519// ELEMENTS u4.9
520	// tooltips
521		$('body').on('mouseover','.ajdeToolTip, .evotooltip, .evotooltipfree',function(event){
522			event.stopPropagation();
523			
524			const el = $(this);
525			if(el.hasClass('show')) return;
526
527			var free = el.hasClass('free') || el.hasClass('evotooltipfree');
528			var content =  el.data('d') || el.attr('title') || '';
529			if (!content) return;
530
531			var p = el.position();			
532			var cor = getCoords(event.target);
533
534			$('.evo_tooltip_box').removeClass('show').removeClass('L').html( content );
535			var box_height = $('.evo_tooltip_box').height();
536			var box_width = $('.evo_tooltip_box').width();
537			var top = cor.top - 55 - box_height + (free ? 20 : 0);
538
539			$('.evo_tooltip_box').css({'top': top, 'left': ( cor.left + 5 ) })
540				.addClass('show');
541
542			// left align
543			if( $(this).hasClass('L')){
544				$('.evo_tooltip_box').css({'left': (cor.left - box_width - 15) }).addClass('L');			
545			}
546		})
547		.on('mouseout','.ajdeToolTip, .evotooltip, .evotooltipfree',function(e){	
548			event.stopPropagation();
549			var relatedTarget = $(event.relatedTarget);
550			var target = $(this);
551
552			$('.evo_tooltip_box').removeClass('show');
553		});
554
555		function getCoords(elem) { // crossbrowser version
556		    var box = elem.getBoundingClientRect();
557		    //console.log(box);
558
559		    var body = document.body;
560		    var docEl = document.documentElement;
561
562		    var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
563		    var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
564
565		    var clientTop = docEl.clientTop || body.clientTop || 0;
566		    var clientLeft = docEl.clientLeft || body.clientLeft || 0;
567
568		    var top  = box.top +  scrollTop - clientTop;
569		    var left = box.left + scrollLeft - clientLeft;
570
571		    return { top: Math.round(top), left: Math.round(left) };
572		}
573	// yes no button		
574		$('body').on('click','.ajde_yn_btn ', function(event){
575
576			// stop this code from working on wp-admin
577			if($('body').hasClass('wp-admin')) return false; 
578			
579			var obj = $(this);
580			var afterstatement = obj.attr('afterstatement');
581				afterstatement = (afterstatement === undefined)? obj.attr('data-afterstatement'): afterstatement;	
582			var uid = '';
583
584			// yes
585			if(obj.hasClass('NO')){					
586				obj.removeClass('NO');
587				obj.siblings('input').val('yes');
588
589				// afterstatment
590				if(afterstatement!=''){
591					var type = (obj.attr('as_type')=='class')? '.':'#';
592					if( obj.data('uid') !== undefined) uid = obj.data('uid');
593					$(type+ afterstatement).slideDown('fast');						
594				}
595
596			}else{//no
597				obj.addClass('NO');
598				obj.siblings('input').val('no');
599				
600				if(afterstatement!=''){
601					var type = (obj.attr('as_type')=='class')? '.':'#';
602					$(type+ afterstatement ).slideUp('fast');
603				}
604			}
605		});
606
607	// content slider v4.9.13
608		// jQuery plugin for content slider
609	    $.fn.evoContentSlider = function() {
610	        return this.each(function() {
611	            const $slider = $(this);
612	            const $inner = $slider.find('.evo_elm_HCS_in');
613	            const scrollAmount = 10; // Wheel scroll speed
614	            let scrollTimeout;
615
616	            // Initial button visibility
617	            updateButtonVisibility($slider);
618
619	            $slider.data('evo-slider-initialized', true);
620
621	            // Button click handler
622	            $slider.on('click', '.evo_elmHCS_nav.content_slide_trig', function() {
623	                const $button = $(this);
624	                const scrollDistance = parseInt($slider.width()) / 2;
625	                const currentScroll = $inner.scrollLeft();
626	                let newScroll;
627
628	                if ($button.hasClass('HCSnavR')) {
629	                    newScroll = currentScroll + scrollDistance;
630	                    $slider.find('.HCSnavL')[0].classList.add('vis');
631	                } else {
632	                    newScroll = Math.max(0, currentScroll - scrollDistance);
633	                }
634
635	                $inner.animate({ scrollLeft: newScroll }, 200, () => {
636	                    updateButtonVisibility($slider);
637	                });
638	            });
639
640	            // Wheel scrolling
641	            $inner[0].addEventListener('wheel', function(e) {
642	                e.preventDefault();
643	                const delta = e.deltaY;
644	                const scrollableLength = this.scrollWidth - parseInt($slider.width());
645	                const newScroll = Math.max(0, Math.min($inner.scrollLeft() + (delta > 0 ? scrollAmount : -scrollAmount), scrollableLength));
646	                $inner.scrollLeft(newScroll);
647	                updateButtonVisibility($slider);
648	            }, { passive: false });
649
650	            // Touch scrolling
651	            $inner[0].addEventListener('scroll', function() {
652	                clearTimeout(scrollTimeout);
653	                scrollTimeout = setTimeout(() => {
654	                    updateButtonVisibility($slider);
655	                }, 100);
656	            });
657	        });
658	    };
659
660	    // Add reload method
661	    $('body').on('evo_reload_slider', function(event, $slider){
662	    	updateButtonVisibility($slider);
663	    });
664		
665
666	    // Update button visibility
667	    function updateButtonVisibility($slider) {
668	    	const $inner = $slider.find('.evo_elm_HCS_in');
669	        const scrollableLength = $inner[0].scrollWidth - parseInt($slider.width());
670	        const currentScroll = $inner.scrollLeft();
671	        const leftButton = $slider.find('.HCSnavL')[0];
672	        const rightButton = $slider.find('.HCSnavR')[0];
673
674	        if (scrollableLength <= 0) {
675	            leftButton.classList.remove('vis');
676	            rightButton.classList.remove('vis');
677	            return;
678	        }
679
680	        leftButton.classList.toggle('vis', currentScroll >= 10);
681	        rightButton.classList.toggle('vis', currentScroll < scrollableLength - 5);
682	    }
683
684	    // Debounced resize handler
685	    let resizeTimeout;
686	    $(window).on('resize', function() {
687	        clearTimeout(resizeTimeout);
688	        resizeTimeout = setTimeout(() => {
689	            $('.evo_elm_HCS').each(function() {
690	                updateButtonVisibility($(this), $(this).find('.evo_elm_HCS_in'));
691	            });
692	        }, 100);
693	    });
694
695	    BODY.find('.evo_elm_HCS').each( function(event){
696			$(this).evoContentSlider();
697		});
698
699	// dynamic select @4.8.2
700		BODY.on('click', '.evo_elm_dynamic_select_trig',function(e){
701			e.preventDefault();
702			const btn = $(this);
703		    const row = btn.closest('.evo_elm_dynamic_select');
704		    const list = btn.find('.evoelm_ds_list');
705
706		    row.toggleClass('open');
707		    btn.toggleClass('open');
708
709			if (btn.hasClass('open')) {
710		        const options = btn.siblings('div').data('d');
711		        let html = `<div class="evoelm_ds_list evobr10 evodfx evofx_dr_c evobgcw evofz14 evoff_2 evo_ofh evoposa evoleft0 " role="listbox" aria-labelledby="selected-option">`;
712
713		        $.each(options, (index, value) => {
714		            html += `<span class="evoelm_ds_list_item evopad10 evocurp evoborderb" role="option" tabindex="-1" data-index="${index}">${value}</span>`;
715		        });
716
717		        html += '</div>';
718		        btn.append(html);
719		    } else {
720		        list.remove();
721		    }
722		});
723
724		$(document).click(function(event){
725			if( !$(event.target).closest('.evo_elm_dynamic_select').length){
726				const openBox = BODY.find('.evo_elm_dynamic_select.open');
727		        openBox.removeClass('open').find('button').removeClass('open');
728		        openBox.find('.evoelm_ds_list').remove();
729			}	
730		});
731
732		// item clicked from the list
733		BODY.on('click','.evoelm_ds_list_item',function(event){
734			const item = $(this);
735		    const box = item.closest('.evo_elm_dynamic_select');
736		    const value = item.data('index');
737
738		    // update focus item name
739		    box.find('.evoelm_ds_current').html( item.html() );
740
741		    // set new value to input
742		    box.find('input').val( value );
743
744		    // plug for others
745			BODY.trigger('evoelm_dynamic_select_clicked', [ item, value, box ]);
746
747			box.removeClass('open');
748            box.find('button').removeClass('open');
749            item.parent().remove();
750
751		});
752
753
754	// Image Select @added 4.9 @updated: 5.0.3	
755		var file_frame;	
756		var __img_index;
757		var __img_obj;
758		var __img_box;
759		var __img_type;
760	  
761	    BODY.on('click','.evolm_img_select_trig',function(event) {
762	    	event.preventDefault();
763	    	//console.log('ef');
764
765	    	const $trigger = $(this);
766	    	const __img_obj = $(this);
767	    	const $row = $trigger.closest('.evo_elm_row');
768	    	const __img_box = __img_obj.closest('.evo_metafield_image');
769	    	const __img_actions = __img_obj.closest('.evolm_img_actions');
770	    	const __img_type = __img_box.hasClass('multi')? 'multi': 'single';
771	    	const uploaderId = $row.data('id');
772
773	    	if( __img_type == 'single' &&  __img_box.hasClass('has_img') ) return;
774	    	if( __img_type == 'multi'){
775	    		__img_index = __img_obj.data('index');
776
777	    		// remove image
778				if( __img_obj.hasClass('on')){
779					__img_obj.css('background-image', '').removeClass('on');
780					__img_obj.find('input').val( '' );
781					return;
782				}
783	    	}
784
785	    	// Reset file_frame to avoid stale state
786	        if (file_frame) {     file_frame.close(); file_frame = null;   }
787
788			// Get user_id (0 for non-logged-in users)
789	        var user_id = __img_actions.data('userid') ? parseInt(__img_actions.data('userid')) : 0;
790	        var library_args = { type: 'image' };
791	        if (user_id > 0) { library_args.author = user_id; }
792
793	        //console.log(library_args);
794
795			// Create the media frame
796			file_frame = wp.media.frames.downloadable_file = wp.media({
797				title: 'Choose an Image', 
798				button: {text: 'Use Image'},	
799				multiple: false,
800				library: library_args,
801			});
802
803			// Attache unique ID
804			if( uploaderId != '' || uploaderId !== undefined){
805				//console.log(uploaderId);
806				file_frame.uploaderId = uploaderId;
807			}
808
809
810			// When an image is selected, run a callback.
811			file_frame.on( 'select', function() {
812				var selection = file_frame.state().get('selection');
813        		//console.log('Selection:', selection.toJSON());
814
815        		if (selection.length > 0) {
816	                var attachment = selection.first().toJSON();
817	                //console.log('Selected attachment:', attachment);
818
819	                if (__img_type == 'single') {
820	                    __img_box.addClass('has_img');
821	                    __img_box.find('input.evo_meta_img').val(attachment.id);
822	                    __img_box.find('.evoelm_img_holder').css('background-image', 'url(' + attachment.url + ')');
823	                    //console.log('Single image updated:', __img_box.find('.evoelm_img_holder').css('background-image'));
824	                } else {
825	                    __img_obj.css('background-image', 'url(' + attachment.url + ')').addClass('on');
826	                    __img_obj.find('input').val(attachment.id);
827	                    //console.log('Multi image updated:', __img_obj.css('background-image'));
828	                }
829	            } else {
830	                console.log('No image selected');
831	            }
832
833			});
834
835			// Handle errors
836	        file_frame.on('error', function(error) {
837	            console.error('Media Uploader Error:', error); alert('Error: ' + error.message);
838	        });
839
840			// Finally, open the modal.
841			file_frame.open();
842			
843	    });  
844		// remove image
845		BODY.on('click','.evoel_img_remove_trig',function(){
846
847			const field = $(this).closest('.evo_metafield_image');
848			if( !(field.hasClass('has_img') ) ) return;
849			
850			field.removeClass('has_img');
851			field.find('input').val('');
852			field.find('button').addClass('chooseimg');
853			field.find('.evoelm_img_holder').css('background-image', '' );
854		});
855
856	// plus minus changer @updated 4.9
857		$('body').on('click','.evo_plusminus_change', function(event){
858
859			// only run on frontend
860			if( evo_general_params.cal.is_admin ) return;
861
862	        OBJ = $(this);
863
864	        QTY = parseInt(OBJ.siblings('input').val());
865	        MAX = OBJ.siblings('input').data('max');        
866	        if(!MAX) MAX = OBJ.siblings('input').attr('max');           
867
868	        NEWQTY = (OBJ.hasClass('plu'))?  QTY+1: QTY-1;
869
870	        NEWQTY =(NEWQTY <= 0)? 0: NEWQTY;
871
872	        // can not go below 1
873	        if( NEWQTY == 0 && OBJ.hasClass('min') ){    return;    }
874
875	        NEWQTY = (MAX!='' && NEWQTY > MAX)? MAX: NEWQTY;
876	        if( isNaN( NEWQTY ) ) NEWQTY = 0;
877
878	        OBJ.siblings('input').val(NEWQTY).attr('value',NEWQTY);
879
880	        if( QTY != NEWQTY) $('body').trigger('evo_plusminus_changed',[NEWQTY, MAX, OBJ]);
881	       
882	        if(NEWQTY == MAX){
883	            PLU = OBJ.parent().find('b.plu');
884	            if(!PLU.hasClass('reached')) PLU.addClass('reached');   
885
886	            if(QTY == MAX)   $('body').trigger('evo_plusminus_max_reached',[NEWQTY, MAX, OBJ]);                 
887	        }else{            
888	            OBJ.parent().find('b.plu').removeClass('reached');
889	        } 
890	    });
891
892// CAL BODY Listeners
893	function EVO_Cal_Body_listeners(){
894		BODY.evo_cal_lb_listeners();
895
896		const EVO_Listeners = {
897			E: {	
898				B: $('body')	
899			},
900			init(){
901				const { B } = this.E;
902
903				// record call
904				if( D.listenCall ) return;
905				D.listenCall = true;
906
907				// FAQ toggle
908            	B.on('click.evoCal', '.evo_faq_toggle', (e) => this.handle_faq_toggle(e));
909				
910				// General AJAX trigger
911            	B.on('click.evoCal', '.evo_trig_ajax', (e) => this.handle_general_ajax(e));
912
913	            // Event anywhere lightbox trigger
914	            B.on('click.evoCal', '.eventon_anywhere.evoajax', (e) => this.handle_event_anywhere(e));
915
916	            // No events button click
917	            B.on('click.evoCal', '.evo_no_events_btn', (e) => this.handle_no_events_btn(e));
918
919	            // Month switch arrows
920	            B.on('click.evoCal', '.evcal_arrows', (e) => this.handle_month_switch(e));
921
922	            // Show more events
923	            B.on('click.evoCal', '.evoShow_more_events', (e) => this.handle_show_more_events(e));
924
925	            // Refresh event top (placeholder)
926	            B.on('runajax_refresh_eventtop.evoCal', (e, OBJ, nonce) => this.handle_refresh_eventtop(e, OBJ, nonce));
927
928	            // Event card slide down complete
929	            B.on('evo_slidedown_eventcard_complete.evoCal', (e, event_id, obj, is_slide_down) => this.handle_slidedown_complete(e, event_id, obj, is_slide_down));
930
931	            // Jumper month/year switch
932	            B.on('calendar_month_changed.evoCal', (e, CAL) => this.handle_calendar_month_changed(e, CAL));
933
934	            // Go to today button
935	            B.on('click.evoCal', '.evo-gototoday-btn', (e) => this.handle_gototoday_btn(e));
936
937	            // Refresh now calendar
938	            B.on('runajax_refresh_now_cal.evoCal', (e, OBJ, nonce) => this.handle_refresh_now_cal(e, OBJ, nonce));
939
940	            // Calendar header buttons
941	            this.handle_cal_head_interactions();	            
942	            B.on('show_cal_head_btn.evoCal', (e, obj) => this.handle_show_cal_head_btn(e, obj));
943	            B.on('hide_cal_head_btn.evoCal', (e, obj) => this.handle_hide_cal_head_btn(e, obj));
944
945	            // Tile box style 3 click
946	            B.on('click.evoCal', '.ajde_evcal_calendar.boxstyle3 .eventon_list_event', (e) => this.handle_tile_box_click(e));
947
948	            // Event card opening
949	           	B.on('click.evoCal', '.eventon_list_event .desc_trig', (e) => this.handle_desc_trig(e));
950	           		            
951			},
952			// Toggles FAQ answer visibility and updates icon
953	        handle_faq_toggle(e) {
954	            const toggle = $(e.currentTarget);
955	            const answer = toggle.next('.evo_faq_answer');
956	            const icon = toggle.find('i.fa');
957	            answer.toggle();
958	            icon.toggleClass('fa-plus fa-minus');
959	        },
960	        // Triggers general AJAX request with data from the clicked element
961	        handle_general_ajax(e) {
962	            const obj = $(e.target);
963	            let ajax_data = obj.data();
964	            $(document).data('evo_data', ajax_data);
965	            this.E.B.trigger('evo_before_trig_ajax', [obj]);
966	            const new_ajax_data = $(document).data('evo_data');
967	            new_ajax_data['nn'] = the_ajax_script.postnonce;
968	            $.ajax({
969	                beforeSend: () => {
970	                    this.E.B.trigger('evo_beforesend_trig_ajax', [obj, new_ajax_data]);
971	                },
972	                type: 'POST',
973	                url: get_ajax_url('eventon_gen_trig_ajax'),
974	                data: new_ajax_data,
975	                dataType: 'json',
976	                success: (return_data) => {
977	                    this.E.B.trigger('evo_success_trig_ajax', [obj, new_ajax_data, return_data]);
978	                },
979	                complete: () => {
980	                    this.E.B.trigger('evo_complete_trig_ajax', [obj, new_ajax_data]);
981	                }
982	            });
983	        },
984	        // Triggers lightbox for event anywhere links
985	        handle_event_anywhere(e) {
986	            e.preventDefault();
987	            const obj = $(e.currentTarget);
988	            const data = obj.data('sc');
989	            if (data.ev_uxval == '4') return;
990	            data['evortl'] = 'no';
991	            if ('id' in data) data['event_id'] = data.id;
992	            data['ux_val'] = '3a';
993	            data['ajax_eventtop_show_content'] = false;
994	            obj.evo_cal_lightbox_trigger(data, obj, false);
995	        },
996
997	        // Handles click on no events button
998	        handle_no_events_btn(e) {
999	            this.E.B.trigger('click_on_no_event_btn', [$(e.currentTarget)]);
1000	        },
1001
1002	        // Switches calendar month on arrow click
1003	        handle_month_switch(e) {
1004	            e.preventDefault();
1005	            const CAL = $(e.currentTarget).closest('.ajde_evcal_calendar');
1006	            let dir = $(e.currentTarget).hasClass('evcal_btn_prev') ? 'prev' : 'next';
1007	            const cal_id = CAL.attr('id');
1008	            if (CAL.hasClass('evortl')) {
1009	                dir = dir == 'next' ? 'prev' : 'next';
1010	            }
1011	            if ($(e.currentTarget).closest('.evo_footer_nav').length > 0) {
1012	                const BOX = $(e.currentTarget).closest('.evo_footer_nav');
1013	                const offset = BOX.offset();
1014	                const scrolltop = $(window).scrollTop();
1015	                const viewport_top = offset.top - scrolltop;
1016	                CAL.addClass('nav_from_foot').data('viewport_top', viewport_top);
1017	            }
1018	            run_cal_ajax(cal_id, dir, 'switchmonth');
1019	        },
1020
1021	        // Shows more events in the calendar list
1022	        handle_show_more_events(e) {
1023	            const CAL = $(e.currentTarget).closest('.ajde_evcal_calendar');
1024	            const SC = CAL.evo_shortcode_data();
1025	            const OBJ = $(e.currentTarget);
1026	            if (SC.show_limit_redir !== '') {
1027	                window.location = SC.show_limit_redir;
1028	                return false;
1029	            }
1030	            if (SC.show_limit_ajax == 'yes') {
1031	                const CURRENT_PAGED = parseInt(SC.show_limit_paged);
1032	                CAL.evo_update_cal_sc({ F: 'show_limit_paged', V: CURRENT_PAGED + 1 });
1033	                run_cal_ajax(CAL.attr('id'), 'none', 'paged');
1034	            } else {
1035	                const event_count = parseInt(SC.event_count);
1036	                const eventList = OBJ.parent();
1037	                const allEvents = eventList.find('.eventon_list_event').length;
1038	                const currentShowing = eventList.find('.eventon_list_event:visible').length;
1039	                for (let x = 1; x <= event_count; x++) {
1040	                    const inde = currentShowing + x - 1;
1041	                    eventList.find(`.eventon_list_event:eq(${inde})`).slideDown();
1042	                }
1043	                if (allEvents >
1043= currentShowing && allEvents <= (currentShowing + event_count)) {
1044	                    OBJ.fadeOut();
1045	                }
1046	            }
1047	        },
1048
1049	        // Placeholder for refreshing event top
1050	        handle_refresh_eventtop(e, OBJ, nonce) {},
1051
1052	        // Processes event card interactions after slide down
1053	        handle_slidedown_complete(e, event_id, obj, is_slide_down) {
1054	            if (!is_slide_down) return;
1055	            setTimeout(() => {
1056	                const OO = obj.closest('.eventon_list_event');
1057	                evo_cal_eventcard_interactions(OO, true);
1058	            }, 300);
1059	        },
1060
1061	        // Updates jumper UI when calendar month changes
1062	        handle_calendar_month_changed(e, CAL) {
1063	            const SC = CAL.evo_shortcode_data();
1064	            const B = CAL.find('.evo-gototoday-btn');
1065	            const O = CAL.find('.evo_j_container');
1066	            O.find('.evo_j_months a').removeClass('set');
1067	            O.find(`.evo_j_months a[data-val="${SC.fixed_month}"]`).addClass('set');
1068	            O.find('.evo_j_years a').removeClass('set');
1069	            O.find(`.evo_j_years a[data-val="${SC.fixed_year}"]`).addClass('set');
1070	            if (SC.fixed_month != B.data('mo') || SC.fixed_year != B.data('yr')) {
1071	                this.E.B.trigger('show_cal_head_btn', [B]);
1072	            } else {
1073	                this.E.B.trigger('hide_cal_head_btn', [B]);
1074	            }
1075	        },
1076
1077	        // Navigates to today’s date on calendar
1078	        handle_gototoday_btn(e) {
1079	            const obj = $(e.currentTarget);
1080	            const CAL = obj.closest('.ajde_evcal_calendar');
1081	            const calid = CAL.attr('id');
1082	            CAL.evo_update_cal_sc({ F: 'fixed_month', V: obj.data('mo') });
1083	            CAL.evo_update_cal_sc({ F: 'fixed_year', V: obj.data('yr') });
1084	            run_cal_ajax(calid, 'none', 'today');
1085	            this.E.B.trigger('hide_cal_head_btn', [obj]);
1086	        },
1087
1088	        // Refreshes now calendar via AJAX
1089	        handle_refresh_now_cal(e, OBJ, nonce) {
1090	            const section = OBJ.closest('.evo_eventon_live_now_section');
1091	            const CAL = section.find('.ajde_evcal_calendar').eq(0);
1092	            const dataA = {
1093	                nonce: evo_general_params.n,
1094	                other: OBJ.data(),
1095	                SC: CAL.evo_shortcode_data()
1096	            };
1097	            $.ajax({
1098	                beforeSend: () => {
1099	                    section.addClass('evoloading');
1100	                },
1101	                type: 'POST',
1102	                url: get_ajax_url('eventon_refresh_now_cal'),
1103	                data: dataA,
1104	                dataType: 'json',
1105	                success: (data) => {
1106	                    if (data.status == 'good') {
1107	                        section.html(data.html);
1108	                        this.E.B.trigger('evo_refresh_designated_elm', [OBJ, 'evo_vir_data']);
1109	                    }
1110	                },
1111	                complete: () => {
1112	                    section.removeClass('evoloading');
1113	                    this.E.B.find('.evo_countdowner').each(function() {
1114	                        $(this).evo_countdown();
1115	                    });
1116	                }
1117	            });
1118	        },
1119
1120	        // Toggles visibility of calendar header buttons
1121	        handle_cal_head_interactions() {
1122	        	const { B } = this.E;
1123	        	B.on('click.evoCal', '.cal_head_btn', (e) => {
1124	        		const obj = $(e.currentTarget);
1125		            if (obj.hasClass('vis')) {
1126		                this.E.B.trigger('hide_cal_head_btn', [obj]);
1127		            } else {
1128		                this.E.B.trigger('show_cal_head_btn', [obj]);
1129		            }
1130	        	});
1131	        	// when a header button is clicked
1132				B.on('evo_cal_header_btn_clicked',function(event, O, CAL){
1133
1134
1135					var SC = CAL.evo_shortcode_data();	
1136
1137					// if search is open on init > return
1138					if( evo_general_params.cal.search_openoninit ) return;
1139
1140					if( O.hasClass('evo-search')){
1141						if( O.hasClass('vis')){
1142							CAL.find('.evo_search_bar').show(1, function(){
1143								$(this).find('input').focus();
1144							});
1145						}else{
1146							CAL.find('.evo_search_bar').hide();
1147						}
1148					}
1149
1150					// hide the search
1151					if( O.hasClass('evo-sort-btn') || O.hasClass('evo-filter-btn')){						
1152						CAL.find('.evo_search_bar').hide();
1153					}
1154				});
1155	            
1156	        },
1157
1158	        // Shows calendar header button
1159	        handle_show_cal_head_btn(e, obj) {
1160	            if (!obj.hasClass('evo-gototoday-btn')) {
1161	                obj.siblings(':not(.evo-gototoday-btn)').removeClass('show vis');
1162	            }
1163	            obj.addClass('show vis');
1164	            const CAL = obj.closest('.ajde_evcal_calendar');
1165	            this.E.B.trigger('evo_cal_header_btn_clicked', [obj, CAL, 'show']);
1166	        },
1167
1168	        // Hides calendar header button
1169	        handle_hide_cal_head_btn(e, obj) {
1170	            const CAL = obj.closest('.ajde_evcal_calendar');
1171	            obj.removeClass('show vis');
1172	            this.E.B.trigger('evo_cal_header_btn_clicked', [obj, CAL, 'hide']);
1173	        },
1174
1175	        // Triggers desc_trig click for tile box style 3
1176	        handle_tile_box_click(e) {
1177	            e.preventDefault();
1178	            e.stopPropagation();
1179	            $(e.currentTarget).find('.desc_trig').trigger('click');
1180	        },
1181
1182	        // Handles event card opening with various user interactions
1183	        handle_desc_trig(e) {
1184	        	e.preventDefault();
1185	            const $this = $(e.currentTarget);
1186	            const $eventBox = $this.closest('.eventon_list_event');
1187	            
1188	            const $cal = $this.closest('.evo_lightbox').data('cal_id') ?
1189	                $('#' + $this.closest('.evo_lightbox').data('cal_id')) :
1190	                $this.closest('.ajde_evcal_calendar');
1191	            const SC = $cal.evo_shortcode_data();
1192	            const ux_val = $cal.evo_cal_event_get_uxval(SC, $this);
1193	            const event_id = $eventBox.data('event_id');
1194	            const exlk = $this.data('exlk');
1195	            const isSingleEventBox = $this.closest('.eventon_single_event').length > 0 && $cal.find('.evo-data').data('exturl');
1196
1197	            const actions = {
1198	                '3': () => this.open_lightbox($this, $cal, SC, event_id, $eventBox, ux_val),
1199	                '3a': () => this.open_lightbox($this, $cal, SC, event_id, $eventBox, ux_val),
1200	                '4': () => this.open_url($this, $this.attr('href') || $this.parent().siblings('.evo_event_schema').find('a').attr('href'), '_self'),
1201	                '4a': () => this.open_url($this, $this.attr('href') || $this.parent().siblings('.evo_event_schema').find('a').attr('href'), '_blank'),
1202	                '2': () => this.handle_external_link($this, isSingleEventBox),
1203	                'X': () => false,
1204	                'none': () => false,
1205	                'default': () => exlk === '1' ? this.handle_external_link($this, isSingleEventBox) : this.slide_down_event_card($this, $eventBox, $cal, SC, event_id)
1206	            };
1207
1208	            return (actions[ux_val] || actions['default'])();
1209	        },
1210
1211	        // Opens lightbox for event content
1212	        open_lightbox($trigger, $cal, SC, event_id, $eventBox, ux_val) {
1213	        	//console.log($cal.attr('class'));
1214	            const repeat_interval = parseInt($eventBox.data('ri')) || 0;
1215	            const etttc_class = $cal.attr('class')?.split(' ').find(cls => cls.startsWith('etttc_')) || '';
1216	            const new_SC_data = {
1217	                ...SC,
1218	                repeat_interval,
1219	                event_id,
1220	                ux_val,
1221	                evortl: $trigger.closest('.eventon_events_list').hasClass('evortl') ? 'yes' : 'no',
1222	                ajax_eventtop_show_content: true,
1223	                additional_class: etttc_class
1224	            };
1225	            $cal.evo_cal_lightbox_trigger(new_SC_data, $trigger, $cal);
1226	            return false;
1227	        },
1228
1229	        // Opens a URL in specified target
1230	        open_url($this, url, target) {
1231	        	target = $this.attr('target') === '_blank' ? '_blank' : target;
1232			    if (url) window.open(url, target);
1233			    return target === '_blank';
1234	        },
1235
1236	        // Handles external link navigation
1237	        handle_external_link($trigger, isSingleEventBox) {
1238	            if (isSingleEventBox) return false;
1239	            const url = $trigger.attr('href');
1240	            if (url) {
1241	                window.open(url, $trigger.attr('target') === '_blank' ? '_blank' : '_self');
1242	            }
1243	            return !!url;
1244	        },
1245
1246	        // Slides down event card and loads map if present
1247	        slide_down_event_card($trigger, $eventBox, $cal, SC, event_id) {
1248	            const $content = $eventBox.find('.event_description');
1249	            const isOpen = $content.hasClass('open');
1250	            if (SC && SC.accord === 'yes') {
1251	                $cal.find('.eventon_list_event').removeClass('open');
1252	                $cal.find('.event_description').slideUp().removeClass('open');
1253	            }
1254	            $eventBox.toggleClass('open', !isOpen);
1255	            $content[isOpen ? 'slideUp' : 'slideDown']().toggleClass('open', !isOpen);
1256	            if ($eventBox.find('.evo_metarow_gmap').length) {
1257	                $eventBox.find('.evo_metarow_gmap').evo_load_gmap({ trigger_point: 'slideDownCard' });
1258	            }
1259	            if ($trigger.data('runjs')) {
1260	                this.E.B.trigger('evo_load_single_event_content', [event_id, $trigger]);
1261	            }
1262	            this.E.B.trigger('evo_slidedown_eventcard_complete', [event_id, $trigger, !isOpen]);
1263	            return false;
1264	        }
1265		}
1266
1267		EVO_Listeners.init();		
1268	}
1269
1270// Global Calendar Listeners and Interactions
1271	function EVO_Interactions(){
1272		const interactions_class = {
1273			E:{ B: $('body')},
1274			run(){
1275				// record call
1276				if( D.listenInt ) return;
1277				D.listenInt = true;
1278
1279				const { B } = this.E;
1280				this.evoLightboxEnd();
1281				this.evocardNavTrig();
1282				this.evoMapExpandTrig();
1283				this.handle_lightbox_processed();
1284				this.handle_calendar_interactions();
1285				this.handle_global_listners();
1286				this.handle_tabs();
1287				this.handle_aria_population();
1288				this.handle_events_list_trig();
1289			},
1290
1291			handle_events_list_trig(){
1292				this.E.B.on('evo_ajax_success_evo_new_eventslist_trig',function(event,OO, data , el){
1293					const $el = $(el);
1294					
1295					$el.siblings('.evo_trigger_ajax_run').removeClass('evofwb evobgclg6 ').addClass('evobgct');
1296					$el.addClass('evofwb evobgclg6').removeClass('evobgct');
1297				});
1298			},
1299			handle_aria_population() {
1300				const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1301			   	const gen = () => Array.from({length:9},()=>chars[Math.floor(Math.random()*62)]).join('');
1302			  	const used = new Set();
1303
1304			  	$('.evo_aria_ready').each(function() {
1305			  		const $label = $(this);
1306			  		let $unique_label = $label.text().trim();
1307
1308				    const $i = $label.siblings('.evo_aria_ready_match').first();
1309				    if (!$i.length) return;			    
1310
1311				    //$label.removeClass('evo_aria_ready');
1312				    let id;
1313				    do { id = gen(); } while (used.has(id));
1314				    used.add(id);
1315
1316				    $unique_label = $unique_label.replace(/\[[^\]]*\]/, '['+id+']');
1317				    $label.html( $unique_label );
1318				    $i.attr('aria-label', $unique_label );
1319
1320				    $(this).attr('for', id);
1321				    $i.attr('id', id).removeAttr('aria-label');
1322				});
1323			},
1324			evoLightboxEnd() {
1325		        this.E.B.on('evolightbox_end', (event, LB, CAL) => {
1326		            setTimeout(() => {
1327		                LB.find('.eventon_list_event').each(function() {
1328		                    evo_cal_eventcard_interactions($(this), true);
1329		                });
1330		                _evo_run_eventcard_map_load();
1331		                LB.evo_cal_localize_time();
1332		                this.handle_aria_population();
1333		            }, 1000);
1334		        });
1335
1336		        // eventcard lightbox event navigation @version 4.9.2
1337		        this.E.B.on('evolightbox_end', (e, LB, CAL, OO) => {
1338		            if (!evo_general_params.cal.lbnav) return;
1339		            if (evo_general_params.cal.lbnav === 'no') return;
1340		            if (OO === undefined || !('other_data' in OO)) return;
1341
1342		            const event = $(OO.other_data.obj).closest('.event');
1343		            const calId = (CAL ? CAL.attr('id') : '');
1344		            const buttons = [
1345		                { dir: 'prev', icon: 'left', sibling: event.prev('.event') },
1346		                { dir: 'next', icon: 'right', sibling: event.next('.event') }
1347		            ].filter(b => b.sibling.length)
1348		             .map(b => `
1349		                <div class='evocard_lb_navs'>
1350		                    <button class='evocard_nav_trig ${b.dir} evoposa evocurp evohoop7 evobr30 evobgcw evodfx evofxjcc evofxaic evo_transit_all evoboxbb' data-id='${b.sibling.attr('id')}' data-cid='${calId}'>
1351		                        <i class='fa fa-chevron-${b.icon}'></i>
1352		                    </button>
1353		                </div>
1354		            `).join('');
1355
1356		            LB.find('.evolb_box').append(buttons);
1357		            setTimeout(() => LB.find('.evocard_nav_trig').addClass('show'), 500);
1358		        });
1359		    },
1360		    evocardNavTrig(){
1361		    	this.E.B.on('click','.evocard_nav_trig',function(e){
1362					e.preventDefault();
1363				    const $el = $(e.currentTarget);
1364				    const CAL = $('#' + $el.data('cid'));
1365				    const SC = CAL.evo_shortcode_data();
1366				    const eventId = $el.data('id').split('_')[1];
1367				    const newEvent = CAL.find(`#${$el.data('id')}`);
1368				    const newEventTrigger = newEvent.find('.desc_trig');
1369				    const LB = $el.closest('.evo_lightbox');
1370
1371				    LB.find('.evocard_nav_trig').fadeOut().addClass('old');
1372				    setTimeout(() => LB.find('.evocard_lb_navs').has('.old').remove(), 500);
1373
1374				    LB.evo_lightbox_show_open_animation({ animation_type: 'saving' });
1375
1376				    const updatedSC = {
1377				        ...SC,
1378				        repeat_interval: parseInt(newEvent.data('ri')),
1379				        ux_val: CAL.evo_cal_event_get_uxval(SC, newEventTrigger),
1380				        event_id: eventId,
1381				        ajax_eventtop_show_content: true,
1382				        evortl: newEvent.find('.eventon_events_list').hasClass('evortl') ? 'yes' : 'no',			
1383				        additional_class: CAL.attr('class').match(/etttc_\w+/)?.[0] || '',
1384				    };
1385
1386				    const newLbClass = "evo_eventcard_"+eventId;
1387				    LB.removeClass(LB.data('lbc')).addClass(newLbClass).data('lbc', newLbClass);
1388
1389				    setTimeout(() => CAL.evo_cal_lightbox_trigger(updatedSC, newEventTrigger, CAL, LB), 1000);
1390				});
1391		    },
1392		    evoMapExpandTrig(){
1393		    	this.E.B.on('click','.evo_map_expand_trig',function(e){
1394					e.preventDefault();
1395
1396					const $gmapDiv = $(this).closest('.evo_map').find('.evo_metarow_gmap');
1397					const mapID = $gmapDiv.attr('id')+'_exp';
1398					const $newDiv = $('<div id="'+ mapID +'" class="evo_lb_map evobr15" style="min-height:calc(100vh - 120px);"></div>');
1399					const locationAdd = $gmapDiv.data('address');
1400					const locationName = $gmapDiv.data('name');
1401
1402					const extra = `<div class='evodfx evofxdrr evofxaic evogap10 evomarr50'>
1403							<input id="user-address-${mapID}" type="text" placeholder="Enter starting address"/>
1404							<button id="get-directions-${mapID}" class='evo_nonbtn'><i class='fa fa-circle-arrow-right'></i></button>
1405							<i class='fa fa-route evofz24i evocurp evoop5 evohoop7'></i>
1406							<button class='evo_nonbtn evoff_2 evocurp evohoop7 evoop5'><i class='fa fa-calendar evomarr10 evofz24i'></i>More Events</button>
1407						</div>`;
1408					const $topDiv = `<div class='evodfx evofxdrr evogap10 evofxjcsb evofxaic evomarb10'>
1409						<div class='evodfx evofxdrr evofxaic evogap10'>
1410							<p class='evoff_1i evomar0i evofz18i'>${locationName}</p>
1411							<p class='evomar0i evofz14i'>${locationAdd}</p>
1412						</div>
1413						</div>`;
1414					const $botDiv = ``;
1415
1416					// Copy only data attributes, not content
1417					$.each($gmapDiv.data(), function(key, value) {
1418					    $newDiv.data(key, value).attr('data-'+key, value);
1419					});
1420					const calID = $(this).closest('.ajde_evcal_calendar').attr('id');
1421					$(this).evo_lightbox_open({
1422						uid: 'evo_map_expand',calid: calID,
1423						lbdata:{ class:'evo_map_expand',content: $topDiv + $newDiv[0].outerHTML + $botDiv }
1424					});
1425				});
1426		    },
1427		    handle_lightbox_processed(){
1428		    	this.E.B.on('evo_lightbox_processed',function(e, OO, LB){
1429		    		if( OO.uid == 'evo_map_expand'){
1430						//console.log(OO);
1431						setTimeout(function(){
1432							LB.find('.evo_lb_map').evo_load_gmap({	cal: $('body').find('#'+ OO.calid)	});
1433						}, 500);						
1434					}
1435				}).on('evo_ajax_success_evo_open_eventcard_lightbox', function( e, OO, data, el){
1436					//console.log(OO);
1437					setTimeout(function(){
1438						LB.find('.evcal_gmaps').evo_load_gmap({	cal: $('body').find('#'+ OO.d.calid)	});
1439					}, 500);	
1440				});
1441		    },
1442
1443		    // Calendar
1444		    handle_calendar_interactions(){
1445		    	const { B } = this.E;
1446		    	B.find('.ajde_evcal_calendar').each( (index, calendar) => {
1447
1448		    		const $calendar = $(calendar);
1449		    		const $SC = $calendar.evo_shortcode_data();
1450
1451			        // Bubble tooltip for events in calendars with 'bub' class
1452			        if ($calendar.hasClass('bub')) {
1453			            $calendar.on('mouseover.evoCal', '.eventon_list_event', (e) => {
1454			                const $event = $(e.currentTarget);
1455			                const $list = $event.closest('.eventon_events_list');
1456			                const title = $event.find('.evoet_dayblock').data('bub');
1457			                const position = $event.position();
1458
1459			                $list.append(`<span class="evo_bub_box">${title}</span>`);
1460			                const $bubble = $list.find('.evo_bub_box');
1461
1462			                let left = position.left;
1463			                let top = position.top - $bubble.height() - 30;
1464
1465			                // Adjust bubble position if it exceeds list width
1466			                const listWidth = $list.width();
1467			                const totalWidth = position.left + $bubble.width() + $event.width();
1468			                if (totalWidth > listWidth) {
1469			                    left = position.left - $bubble.width() + $event.width() - 20;
1470			                }
1471
1472			                $bubble.css({ top, left }).addClass('show');
1473			            }).on('mouseout.evoCal', '.eventon_list_event', (e) => {
1474			                $(e.currentTarget).closest('.eventon_events_list').find('.evo_bub_box').remove();
1475			            });
1476			        }
1477
1478			        // Jumper button toggle
1479			        $calendar.on('click.evoCal', '.evo-jumper-btn', (e) => {
1480			            const $this = $(e.currentTarget);
1481			            $this.closest('.calendar_header').find('.evo_j_container').toggle();
1482			            $this.toggleClass('vis');
1483			        });
1484
1485			        // select a new time from jumper
1486			        $calendar.on('click','.evo_j_dates a',function(){
1487						var val = $(this).attr('data-val'),
1488							type = $(this).parent().parent().attr('data-val'),
1489							CAL = $calendar,
1490							SC = CAL.evo_shortcode_data();
1491
1492						if(type=='m'){ // change month
1493							CAL.evo_update_cal_sc({F:'fixed_month', V: val });
1494						}else{
1495							CAL.evo_update_cal_sc({F:'fixed_year', V: val });
1496						}
1497
1498						run_cal_ajax( CAL.attr('id') ,'none','jumper');
1499						
1500						// hide month jumper if not set to leave expanded
1501						if(SC.expj =='no')	container.delay(2000).slideUp();
1502					});
1503
1504					// view switcher
1505					$calendar.on('click', '.evo_vSW',function(){
1506						const O = elm = $(this);
1507						var DATA = O.data('d');
1508						if(O.hasClass('focusX')) return;
1509						CAL = $calendar;
1510
1511						// remove other additions from other views
1512						CAL.find('.evoADDS').hide().delay(200).queue(function(){
1513							$(this).remove();
1514						});
1515
1516						var SC = $SC;
1517						const cal_tz = CAL.evo_get_global({S1:'cal_def',S2:'cal_tz'});
1518						var reload_cal_data = false;
1519						
1520						// Create date object
1521							_M1 = moment().set({'year': SC.fixed_year, 'month': ( SC.fixed_month -1 ), 'date':SC.fixed_day}).tz( cal_tz );
1522							_M1.set('date',1).startOf('date');
1523							_start = _M1.unix();
1524							_M1.endOf('month').endOf('date'); // move to end of month
1525							_end = _M1.unix();
1526
1527						// DEP
1528							var DD = new Date(SC.fixed_year,SC.fixed_month -1 , SC.fixed_day, 0,0,0 );
1529							DD.setUTCHours(0);
1530							DD.setUTCFullYear( SC.fixed_year );
1531							DD.setUTCMonth( SC.fixed_month -1 );
1532							DD.setUTCDate( SC.fixed_day );
1533
1534						// switch to normal
1535							O.siblings('.evo_vSW').removeClass('focusX select');					
1536							O.addClass('focusX select');
1537							CAL.find('.evo-viewswitcher-btn em').html( O.html() );
1538							O.closest('.evo_cal_view_switcher').removeClass('show');
1539
1540						// ux_val for specific cal
1541							if( DATA && 'ux_val' in DATA)	CAL.evo_update_cal_sc({F:'ux_val', V: DATA.ux_val });
1542
1543						// calendar class toggling
1544							O.siblings('.evo_vSW').each(function(){
1545								var _d = $(this).data('d');
1546								if( _d && 'c' in _d )	CAL.removeClass( _d['c'] ); // remove other cls
1547							});
1548							if( DATA && 'c' in DATA)	CAL.addClass( DATA.c );
1549					
1550
1551						// process date times block
1552							CAL.find('.evoet_dayblock span').hide();
1553							CAL.find('.evoet_dayblock span.evo_start').show();
1554							CAL.find('.evoet_dayblock span.evo_end').show();
1555							CAL.find('.evoet_dayblock span.evo_end.only_time').hide();
1556
1557						// if current date range is not a month load those unix
1558						if( SC.focus_start_date_range != _start && SC.focus_end_date_range != _end ){
1559							reload_cal_data = true;
1560							CAL.evo_update_cal_sc({F:'focus_start_date_range',V: _start });
1561							CAL.evo_update_cal_sc({F:'focus_end_date_range', V: _end });
1562						}
1563
1564						// treating events list based on dif preferences--  vals el_visibility = hide_events, show_events
1565							if( 'el_visibility' in DATA){
1566								el_visibility = DATA.el_visibility;
1567
1568								if( el_visibility =='show_events') CAL.find('.eventon_list_event').show();
1569								if( el_visibility =='hide_events') CAL.find('.eventon_list_event').hide();
1570								if( el_visibility =='hide_list') CAL.find('#evcal_list').addClass('evo_hide').hide();
1571								if( el_visibility =='show_all'){
1572									CAL.find('#evcal_list').removeClass('evo_hide').show();
1573									CAL.find('.eventon_list_event').show();
1574								} 
1575							}				
1576
1577						CAL.evo_update_cal_sc({F:'calendar_type', V: 'default'});
1578						
1579						B.trigger('evo_vSW_clicked_before_ajax', [ O, CAL, DD, reload_cal_data ]);
1580
1581						// run ajax to load new events in the range
1582							if( reload_cal_data ){
1583								B.trigger('evo_run_cal_ajax',[CAL.attr('id'),'none','filering']);
1584							}else{
1585								B.trigger('evo_vSW_clicked_noajax', [ O, CAL ]); // @s4.6
1586							}
1587												
1588						B.trigger('evo_vSW_clicked', [ O, CAL, DD, reload_cal_data]);
1589
1590						// switching to and from tiles view
1591							if( elm.hasClass('evoti')){
1592								CAL.find('.eventon_list_event').each(function(){
1593									color = $(this).data('colr');
1594									$(this).find('a.desc_trig').css({'background-color': color});
1595								});
1596								CAL.addClass('color').removeClass('sev').data('oC', 'sev');
1597							}else{
1598								if( CAL.hasClass('esty_0') || CAL.hasClass('esty_4') ){
1599									CAL.removeClass('color');
1600									CAL.find('.eventon_list_event').each(function(){
1601										$(this).find('a.desc_trig').css({'background-color': ''});
1602									});
1603									if( CAL.data('oC') !== undefined) CAL.addClass( CAL.data('oC'));
1604								}
1605							}
1606
1607					});
1608		    	});
1609		    },		  
1610
1611		    // Global  
1612		    handle_global_listners(){
1613		    	const { B } = this.E;
1614		    	B.on('evo_trigger_cal_reset', function(event, cal){
1615					cal_resets( cal );
1616				});
1617				B.on('click', function(event) {
1618					BODY.trigger('clicked_on_page', [ $(event.target) , event ]);
1619				});
1620				B.find('.evo_location_map').each(function(){			
1621					$(this).evo_load_gmap();
1622				});
1623				// on event card lightbox load -> taxonomy details @since 4.2 u4.6				
1624				B.on('evo_ajax_complete_eventon_get_tax_card_content', function(event,  OO, el){
1625
1626					parent = $(el);
1627					setTimeout(function(){
1628						// run map load
1629						if( parent.find('.evo_trigger_map').length > 0 ){
1630							map_id_elm = parent.find('.evo_trigger_map');			
1631							map_id_elm.evo_load_gmap({check_trigger:true});
1632							console.log('Loading Event Map');
1633						}
1634						
1635						// run countdown timers
1636						parent.find('.evo_countdowner').each(function(){
1637							$(this).evo_countdown();
1638						});
1639
1640						// run calendar filtering function
1641						CAL = parent.find('.ajde_evcal_calendar');
1642						if (CAL.length) CAL.evo_cal_filtering();
1643					},500);		
1644				});
1645		    },
1646		    // Tab view switcher
1647		    handle_tabs(){
1648		    	const { B } = this.E;
1649		    	B.find('.evo_tab_container').each(function(){
1650					$(this).find('.evo_tab_section').each(function(){
1651						if(!$(this).hasClass('visible')){
1652							$(this).addClass('hidden');
1653						}
1654					});
1655				});
1656				B.on('click','.evo_tab',function(){
1657					tab = $(this).data('tab');
1658					tabsection = $(this).closest('.evo_tab_view').find('.evo_tab_container');
1659					tabsection.find('.evo_tab_section').addClass('hidden').removeClass('visible');
1660					tabsection.find('.'+tab).addClass('visible').removeClass('hidden');
1661
1662					$(this).parent().find('.evo_tab').removeClass('selected');
1663					$(this).addClass('selected');
1664
1665					B.trigger('evo_tabs_newtab_selected',[ $(this)]);
1666				});
1667		    },
1668
1669		};
1670
1671		interactions_class.run();
1672	}
1673
1674// EVO ON
1675	const EVO = {
1676
1677		E:{
1678			B: $('body')
1679		},
1680		init(){
1681			this.Tools.init();
1682			this.Interactions.init();
1683			this.Virtual_Events.init();
1684			this.Search.init();
1685			this.Elements_Interactions.init();
1686			// Global event listeners (e.g., heartbeat, resize)
1687        	this.setupGlobalListeners();
1688        	this.schedule_view();
1689        	this.ajax_triggers();
1690		},
1691
1692		setupGlobalListeners(){
1693			const { B } = this.E;
1694			// Heartbeat hooks
1695	        $(document).on('heartbeat-send', (e, data) => {
1696	            if (this.BODY && this.BODY.find('.evo_refresh_on_heartbeat').length) {
1697	                this.BODY.find('.evo_refresh_on_heartbeat').each((i, el) => {
1698	                    if ($(el).closest('.eventon_list_event').length <= 0) return;
1699	                    if ($(el).data('refresh') !== undefined && !$(el).data('refresh')) return;
1700
1701	                    data['evo_data'] = EVO.Tools.build_elm_refresh_data($(el));
1702	                });
1703	            }
1704	        });
1705
1706	        $(document).on('heartbeat-tick', (e, data) => {
1707	            EVO.Tools.evo_apply_refresh_content(data);
1708	        });
1709
1710			// Other global events
1711	        B.on('evo_refresh_elements', (e, send_data) => {
1712	            if (!send_data || send_data.length <= 0) return;
1713
1714	            send_data['nonce'] = evo_general_params.n;
1715
1716	            $.ajax({
1717	                beforeSend: () => {
1718	                    if ('evo_data' in send_data) {
1719	                        $.each(send_data.evo_data, (ekey, eclasses) => {
1720	                            $.each(eclasses, (classnm, val) => {
1721	                                if (val && 'loader' in val && val.loader && 'loader_class' in val) {
1722	                                    $('#event_' + ekey).find('.' + val.loader_class).addClass('evoloading');
1723	                                }
1724	                            });
1725	                        });
1726	                    }
1727	                },
1728	                type: 'POST',
1729	                url: EVO.Tools.get_ajax_url('eventon_refresh_elm'),
1730	                data: send_data,
1731	                dataType: 'json',
1732	                success: (data) => {
1733	                    if (data.status === 'good') {
1734	                        EVO.Tools.evo_apply_refresh_content(data);
1735	                    }
1736	                },
1737	                complete: () => {
1738	                    if ('evo_data' in send_data) {
1739	                        $.each(send_data.evo_data, (ekey, eclasses) => {
1740	                            $.each(eclasses, (classnm, val) => {
1741	                                if (val && 'loader' in val && val.loader && 'loader_class' in val) {
1742	                                    $('#event_' + ekey).find('.' + val.loader_class).removeClass('evoloading');
1743	                                }
1744	                            });
1745	                        });
1746	                    }
1747	                }
1748	            });
1749	        });
1750	        // refresh the closest hearbeat run parent
1751			B.on('evo_refresh_designated_elm', function(ee, elm, elm_class, extra_data){
1752				//get closest event object
1753				const event = $(elm).closest('.eventon_list_event');
1754	            if (!event || event.find('.' + elm_class).length === 0) return;
1755
1756	            const refresh_elm = event.find('.' + elm_class);
1757	            let send_data = {};	
1758
1759				send_data['evo_data'] = EVO.Tools.build_elm_refresh_data( refresh_elm , extra_data);				
1760				B.trigger('evo_refresh_elements',[ send_data ]);
1761			});
1762
1763		},
1764		schedule_view(){
1765			EVO.E.B.on('evo_init_ajax_success_each_cal',function(event, data, i, v, CAL){
1766				$('body').find('.ajde_evcal_calendar.evoSV').each(function(){
1767					EVO.Tools.evosv_populate( $(this) );
1768				});
1769			})
1770			.on('evo_main_ajax_before_fnc', function(event, CAL,  ajaxtype, data_arg){
1771				SC = data_arg.shortcode;
1772				if( SC.calendar_type == 'schedule'){
1773					CAL.find('#evcal_list').removeClass('evo_hide').show();
1774				}
1775			}).on('evo_main_ajax_success', function(event, CAL,  ajaxtype, data , data_arg){
1776				SC = data_arg.shortcode;
1777				if( SC.calendar_type == 'schedule'){
1778					CAL.find('#evcal_list').addClass('evo_hide').hide();
1779				}
1780			}).on('evo_main_ajax_complete', function(event, CAL,  ajaxtype, data , data_arg){
1781				SC = data_arg.shortcode;
1782				if( SC.calendar_type == 'schedule'){
1783					EVO.Tools.evosv_populate( CAL );
1784				}
1785			})
1786			// view switching
1787			.on('evo_vSW_clicked_before_ajax',function(event, O, CAL, DD, reload_cal_data){
1788				if(!(O.hasClass('evosv'))) return;
1789				var SC = CAL.evo_shortcode_data();
1790
1791				CAL.evo_update_cal_sc({F:'calendar_type', V: 'schedule'});
1792				CAL.evo_update_cal_sc({F:'fixed_day', V: SC.fixed_day });
1793
1794			})
1795			.on('evo_vSW_clicked',function(event, OBJ, CAL, DD, reload_cal_data){
1796				if(!(OBJ.hasClass('evosv'))) return;						
1797				CAL.evo_update_cal_sc({F:'calendar_type', V: 'schedule'});
1798			})
1799			.on('evo_vSW_clicked_noajax',function(event, OBJ, CAL, DD, reload_cal_data){
1800				if(!(OBJ.hasClass('evosv'))) return;						
1801				EVO.Tools.evosv_populate( CAL );		
1802			})
1803			// open events from schedule view
1804			.on('click','.evosv_items',function(event, elm){
1805				O = $(this);
1806				CAL = O.closest('.ajde_evcal_calendar');
1807				var e_cl = 'event_'+O.data('id');
1808				
1809				const clicked_event_uxval = O.data('uxval');
1810
1811				// if event is set to slide down .. switch to lightbox
1812				if( clicked_event_uxval == '1' ){
1813					CAL.find('.'+e_cl).find('.desc_trig').data('ux_val', 3);
1814				}
1815
1816				CAL.find('.'+e_cl).find('.desc_trig').trigger('click');
1817			});
1818		},
1819		Interactions:{
1820			init(){
1821				const { B } = EVO.E;
1822			},
1823
1824		},
1825		Search:{
1826			init(){
1827				const { B } = EVO.E;
1828				B.on('click.evoSearch', '.evo_do_search', (event) => {
1829		            EVO.Tools.do_search_box($(event.target));
1830		        });
1831		        B.on('keypress.evoSearch', '.evo_search_field', (ev) => {
1832	                if ((ev.keyCode || ev.which) === 13) {
1833	                    EVO.Tools.do_search_box($(ev.target).siblings('.evo_do_search'));
1834	                }
1835	            });
1836	            B.on('keypress.evoSearch', '.evo_search_bar_in_field', (ev) => {
1837	                if ((ev.keyCode || ev.which) === 13) {
1838	                    EVO.Tools.search_within_calendar( $(ev.target) );
1839	                }
1840	            });
1841	            B.on('click', '.evosr_search_clear_btn', function(e) {
1842				    e.preventDefault(); EVO.Tools.reset_search($(this).siblings('input'), $(this));
1843				});
1844				B.on('evo_main_ajax_complete', function(e, CAL, ajaxtype, responseJSON, data) {
1845					if (ajaxtype === 'search' && data.shortcode['s']) {
1846				        CAL.find('.evosr_search_clear_btn').addClass('show');
1847				    }
1848				});
1849				// Handle search input interactions
1850				B.on({
1851					'click': function() { EVO.Tools.search_within_calendar($(this).siblings('input')); },
1852				    'keyup': function(e) {
1853				        const $input = $(this), $clearBtn = $input.siblings('.evosr_search_clear_btn');
1854				        if (e.which === 27) { e.preventDefault(); EVO.Tools.reset_search($input, $clearBtn); return; }
1855				        $clearBtn.toggleClass('show', $input.val().trim() !== '');
1856				    }		    
1857				}, '.evo_search_bar_in_field, .evosr_search_btn');
1858			}			
1859		},
1860		Elements_Interactions:{
1861			init(){
1862				const { B } = EVO.E;
1863				// increase and reduce quantity
1864			    B.on('click','.evo_qty_change', function(event){
1865			        var OBJ = $(this);
1866			        var QTY = oQTY = parseInt(OBJ.siblings('em').html());
1867			        var MAX = OBJ.siblings('input').attr('max');
1868			        var BOX = OBJ.closest('.evo_purchase_box');
1869
1870			        var pfd = BOX.find('.evo_purchase_box_data').data('pfd');			        
1871
1872			        (OBJ.hasClass('plu'))?  QTY++: QTY--;
1873
1874			        QTY =(QTY==0)? 1: QTY;
1875			        QTY = (MAX!='' && QTY > MAX)? MAX: QTY;
1876
1877			        // new total price
1878			        var sin_price = OBJ.parent().data('p');
1879			        new_price = sin_price * QTY;
1880
1881			        new_price = EVO.Tools.get_format_price( new_price, pfd);
1882
1883			        BOX.find('.total .value').html( new_price);
1884
1885			        OBJ.siblings('em').html(QTY);
1886			        OBJ.siblings('input').val(QTY);
1887
1888			        B.trigger('evo_qty_changed',[QTY,oQTY, new_price,OBJ ]);
1889			    });
1890			}
1891		},
1892		Virtual_Events:{
1893			init(){
1894				const { B } = EVO.E;
1895				this.jitsi();
1896				// record sign in - virtual plus // @+3.1
1897				B.on('click','.evo_vir_signin_btn',function(){
1898								
1899					let extra_data = {};
1900					extra_data['signin'] = 'y';
1901					extra_data['refresh_main'] = 'y';
1902					extra_data['loader'] = true;
1903					extra_data['loader_class'] = 'evo_vir_main_content';
1904
1905					B.trigger('evo_refresh_designated_elm',[ $(this) , 'evo_vir_data',extra_data]);
1906				});
1907			},
1908			jitsi( mod_refresh){
1909				const { B } = EVO.E;
1910				const domain = 'meet.jit.si';
1911			    let api = [];
1912
1913			    B.find('.evo-jitsi-wrapper').each(function(index, element) {
1914			    	const O = $(this);
1915			    	const eventO = O.closest('.eventon_list_event');
1916
1917			    	if( mod_refresh != '' && mod_refresh == 'mod_refresh_no' && O.hasClass('mod')) return;
1918
1919			        const roomName = $(element).data('n');
1920		            const width = $(element).data('width');
1921		            const height = $(element).data('height');
1922		            const audioMuted = $(element).data('audiomute');
1923		            const videoMuted = $(element).data('videomute');
1924		            const screenSharing = $(element).data('screen');
1925	           
1926			        const myOverwrite =
1927					{
1928					 	'TOOLBAR_BUTTONS': $(element).data('d'),
1929					    "DEFAULT_BACKGROUND": '#494a4e',
1930					    'MOBILE_APP_PROMO': false,
1931					    'SETTINGS_SECTIONS':['devices', 'language', 'profile', 'calendar'],
1932					};
1933			        const options = {
1934			            roomName,
1935			            width,
1936			            height,
1937			            parentNode: element,	            
1938			            configOverwrite: { 
1939			            	startWithAudioMuted: audioMuted,
1940			                startWithVideoMuted: videoMuted,
1941			                startScreenSharing: false,	  
1942			                disableInviteFunctions: false,             
1943			            },
1944			            interfaceConfigOverwrite: myOverwrite,     
1945			        };
1946
1947			       	api = new JitsiMeetExternalAPI(domain, options);      
1948
1949			        api.addEventListener('participantRoleChanged', function(event){
1950
1951			        	// record moderator joined
1952			        	if (event.role === "moderator"){	        		
1953			        		this._record_moderator_join( 'yes', eventO.data('event_id'), eventO.data('ri'));
1954			        	}
1955
1956			        	const pp = jQuery(element).data('p');
1957			        	if (event.role === "moderator" && pp != '__') {
1958			        		ppp = pp.replace('_','');
1959					        api.executeCommand('password', ppp);
1960					    }	        	
1961			        });	
1962
1963			        // moderator leave	        
1964			        api.addEventListener('videoConferenceLeft', function(event){
1965			        	if( eventO.find('.evo_vir_data').data('ismod') =='y'){
1966			        		this._record_moderator_join( 'no', eventO.data('event_id'), eventO.data('ri'));
1967			        		O.siblings('.evo_vir_mod_left').show();
1968			        		O.hide();
1969			        	}
1970			        });
1971			    });
1972			},
1973			// record moderator logins for jitsi
1974			_record_moderator_join(joined, eid, ri){
1975				var data_arg = {
1976					'action': 'eventon_record_mod_joined',
1977					'eid': eid,
1978					'ri': ri,
1979					'joined': joined,
1980					'nonce': evo_general_params.n,				
1981				};
1982
1983				$.ajax({
1984					beforeSend: function(){},
1985					type: 'POST',url: ajax_url,
1986					data: data_arg,dataType:'json',
1987					success:function(data){	}
1988				});
1989			}
1990		},
1991		ajax_triggers(){
1992			const { B } = EVO.E;
1993			B.on('evo_before_trig_ajax',function(event, obj){
1994				if(!obj.hasClass('evo_trig_vir_end')) return;
1995				
1996				var new_ajax_data = $(document).data( 'evo_data');
1997				new_ajax_data['fnct'] = 'mark_event_ended';
1998				$(document).data( 'evo_data', new_ajax_data );
1999				
2000			})
2001			.on('evo_beforesend_trig_ajax',function( event, obj, new_ajax_data){
2002				if(!obj.hasClass('evo_trig_vir_end')) return;
2003
2004				obj.closest('.evo_vir_mod_box').addClass('evoloading');
2005			})
2006			.on('evo_success_trig_ajax',function( event, obj, new_ajax_data, return_data){
2007				if(!obj.hasClass('evo_trig_vir_end')) return;
2008
2009				// if virtual events were marked as ended
2010				if(!('_vir_ended' in return_data)) return;
2011
2012				// refresh the virtual main content
2013				extra_data = {};
2014				extra_data['refresh_main'] = 'yy';
2015				extra_data['loader'] = true;
2016				extra_data['loader_class'] = 'evo_vir_main_content';
2017
2018				//console.log(extra_data);
2019
2020				B.trigger('evo_refresh_designated_elm',[ obj , 'evo_vir_data',extra_data]);
2021			})
2022			.on('evo_complete_trig_ajax',function( event, obj, new_ajax_data){
2023				if(!obj.hasClass('evo_trig_vir_end')) return;
2024				obj.closest('.evo_vir_mod_box').removeClass('evoloading');
2025			});
2026		},
2027		Tools:{
2028			init() {
2029				const { B } = EVO.E;  
2030				//const { B } = EVO.E;
2031	            // Bind AJAX listeners once
2032	            B.on('evo_ajax_beforesend_evo_get_search_results', (event, OO, el) => {
2033	            	$(el).find('.evo_search_results_count').hide();
2034	                $(el).addClass('searching');
2035	            }).on('evo_ajax_complete_evo_get_search_results', (event, OO, el) => {
2036	                $(el).removeClass('searching');
2037	               	EVO_Cal_Body_listeners();
2038	               	EVO_Interactions();
2039
2040	            }).on('evo_ajax_success_evo_get_search_results', (event, OO, data, el) => {
2041	                $(el).find('.evo_search_results').html(data.content);
2042	                if ($(el).find('.no_events').length === 0) {
2043	                    const Events = $(el).find('.eventon_list_event').length;
2044	                    $(el).find('.evo_search_results_count span').html(Events);
2045	                    $(el).find('.evo_search_results_count').fadeIn();
2046
2047	                    const CAL = $(el).find('.ajde_evcal_calendar');
2048	                    
2049	                    CAL.evo_calendar();
2050	                }
2051	            });
2052			},
2053			do_search_box( OBJ ){
2054				const { B } = EVO.E;
2055				const SearchVal = OBJ.closest('.evosr_search_box').find('input').val();
2056				const Evosearch = OBJ.closest('.EVOSR_section');
2057				OBJ.closest('.evo_search_entry').find('.evosr_msg').toggle( !SearchVal );
2058
2059				if (!SearchVal) return false;			
2060
2061				var ajax_results = Evosearch.evo_admin_get_ajax({
2062					'ajaxdata': {
2063						//action: 		'eventon_search_evo_events',
2064						search: 		SearchVal,
2065						shortcode:  	Evosearch.find('span.data').data('sc'),
2066						nonce: 			evo_general_params.n				
2067					},
2068					ajax_type:'endpoint',
2069					ajax_action:'eventon_search_evo_events',
2070					uid:'evo_get_search_results',
2071					end: 'client',
2072				});
2073			},
2074			// Search function
2075			search_within_calendar($input) {
2076			    const ev_cal = $input.closest('.ajde_evcal_calendar');
2077			    ev_cal.evo_update_cal_sc({ F: 'show_limit_paged', V: '1' });
2078			    ev_cal.evo_update_cal_sc({ F: 's', V: $input.val() });
2079			    run_cal_ajax(ev_cal.attr('id'), 'none', 'search');
2080			    return false;
2081			},
2082
2083			// Reset search function
2084			reset_search($input, $clearBtn) {
2085			    const ev_cal = $input.closest('.ajde_evcal_calendar');
2086			    ev_cal.evo_update_cal_sc({ F: 's', V: '' });
2087			    run_cal_ajax(ev_cal.attr('id'), 'none', 'search');
2088			    $input.val('');
2089			    $clearBtn.removeClass('show');
2090			},
2091
2092			// Total formating
2093	        get_format_price(price, data){
2094
2095	            // price format data
2096	            PF = data;
2097	           
2098	            totalPrice = price.toFixed(PF.numDec); // number of decimals
2099	            htmlPrice = totalPrice.toString().replace('.', PF.decSep);
2100
2101	            if(PF.thoSep.length > 0) {
2102	                htmlPrice = EVO.Tools._addThousandSep(htmlPrice, PF.thoSep);
2103	            }
2104	            if(PF.curPos == 'right') {
2105	                htmlPrice = htmlPrice + PF.currencySymbol;
2106	            }
2107	            else if(PF.curPos == 'right_space') {
2108	                htmlPrice = htmlPrice + ' ' + PF.currencySymbol;
2109	            }
2110	            else if(PF.curPos == 'left_space') {
2111	                htmlPrice = PF.currencySymbol + ' ' + htmlPrice;
2112	            }
2113	            else {
2114	                htmlPrice = PF.currencySymbol + htmlPrice;
2115	            }
2116	            return htmlPrice;
2117	        },
2118	        _addThousandSep(n, thoSep){
2119	            var rx=  /(\d+)(\d{3})/;
2120	            return String(n).replace(/^\d+/, function(w){
2121	                while(rx.test(w)){
2122	                    w= w.replace(rx, '$1'+thoSep+'$2');
2123	                }
2124	                return w;
2125	            });
2126	        },
2127
2128	        // apply refresh event element content with matching data that is sent
2129			evo_apply_refresh_content(data){
2130				const { B } = EVO.E;          
2131				if (!('evo_data' in data)) return;
2132
2133				$.each(data.evo_data, function(eclass, boxes){
2134					// if event exists in the page
2135
2136					var vir_data_vals = false;
2137					if( 'evo_vir_data' in boxes) vir_data_vals = boxes.evo_vir_data.data;
2138
2139					B.find('.'+eclass).each(function(){
2140						const event_elm = $(this);
2141						$.each(boxes, (boxclass, boxdata) => {
2142							//console.log(boxdata);
2143							if( boxdata == '') return;
2144		                    if (!boxdata.html || event_elm.find('.' + boxclass).length <= 0) return;
2145		                    event_elm.find('.' + boxclass).html(boxdata.html);
2146		                });
2147
2148						// only for virtual event update
2149						if( vir_data_vals ){
2150
2151							// reload jitsi for main content - if main content html is sent it will refresh
2152								if( vir_data_vals && ('vir_type' in vir_data_vals) 
2153									&& vir_data_vals.vir_type == 'jitsi' 
2154									&& ('evo_vir_main_content' in boxes) 
2155									&& ('html' in boxes.evo_vir_main_content)  
2156									&& boxes.evo_vir_main_content.html != ''
2157								){
2158									EVO.Virtual_Events.jitsi('mod_refresh_no');
2159								}
2160
2161							// update data for sent object
2162								$.each(boxes, function(boxclass, boxdata){
2163									if( boxdata.data == '' || boxdata.data === undefined) return;
2164
2165									// for jitsi if mod left --> force refresh main
2166									if( boxdata !== undefined && vir_data_vals.vir_type == 'jitsi' && vir_data_vals.mod_joined =='left'){
2167										
2168										// force refresh main
2169										boxdata.data['refresh_main'] = 'yy';
2170									}	
2171
2172									event_elm.find( '.'+boxclass ).data( boxdata.data );
2173								});
2174						}
2175
2176					});
2177				});
2178			},
2179			// get refresh data for specified elem
2180			build_elm_refresh_data( elm , extra_data){
2181				const dataObj = {};
2182		        const event = $(elm).closest('.eventon_list_event');
2183		        const ekey = event.data('event_id') + '_' + parseInt(event.data('ri'));
2184		        dataObj[ekey] = {};
2185		        const key2 = elm.data('key');
2186		        dataObj[ekey][key2] = elm.data();
2187
2188		        if (elm.data('check_awaitmod')) {
2189		            if ((event.find('.evo_vir_jitsi_waitmod').length > 0)) dataObj[ekey][key2]['refresh_main'] = 'yy';
2190
2191		            if (event.find('.evo-jitsi-wrapper').length > 0 && dataObj[ekey][key2]['mod_joined'] !== 'left') 
2192		                dataObj[ekey][key2]['refresh_main'] = '';
2193		        }
2194
2195		        if (extra_data && extra_data !== undefined) {
2196		            $.each(extra_data, (index, val) => {
2197		                dataObj[ekey][key2][index] = val;
2198		            });
2199		        }
2200
2201		        return dataObj;
2202			},
2203
2204			// populate the schedule view data @4.5.8
2205			evosv_populate(CAL){
2206				//console.log('s');
2207				var SC = CAL.evo_shortcode_data();
2208				OD = CAL.evo_get_OD(); // calendar other data 
2209
2210				var cal_events = CAL.find('.eventon_list_event');
2211				days_in_month = CAL.evo_day_in_month({M: SC.fixed_month, Y: SC.fixed_year});
2212				time_format = CAL.evo_get_global({S1:'cal_def',S2:'wp_time_format'});
2213
2214				// text strings
2215					_txt = CAL.evo_get_txt({V:'no_events'});
2216					_txt2 = CAL.evo_get_txt({V:'until'});
2217					_txt3 = CAL.evo_get_txt({V:'from'});
2218					_txt4 = CAL.evo_get_txt({V:'all_day'});
2219				
2220				CAL.find('#evcal_list').addClass('evo_hide');
2221
2222				var has_events = false;
2223				var html = '';
2224				var template_data = {};
2225				var processed_ids = {};
2226
2227				// Set initial date - date values
2228					var SU = parseInt( SC.focus_start_date_range);	var EU = '';
2229					var M = moment.unix( SU ).tz( OD.cal_tz );
2230
2231				// go through each day in month
2232				for(var x=1; x<= days_in_month; x++){
2233					
2234					var month_name = CAL.evo_get_dms_vals({ V: (M.get('month') +1), type:'m3'});
2235					var day_name = CAL.evo_get_dms_vals({ V: M.day(), type:'d3'});
2236					
2237					// set event unix into moment
2238						SU = M.unix();	M.endOf('day');
2239						EU = M.unix();	M.startOf('day');
2240					
2241					// run through each event and get events in this date
2242						var events = {};
2243
2244						cal_events.each(function(index, elm){
2245							ED = $(elm).evo_cal_get_basic_eventdata();
2246							if( !ED) return;
2247
2248							processed_ids[ED.uID] = ED.uID;
2249							ESU = ED.unix_start; EEU = ED.unix_end;
2250
2251							// check for date range
2252								var inrange = CAL.evo_is_in_range({
2253									'S': SU,	'E': EU,	'start': ESU,	'end':EEU
2254								});
2255								if(!inrange) return; // skip if no in range
2256
2257							has_events = true;
2258
2259							// event time relative to calendar tz
2260							m = moment.unix( ESU ).tz( OD.cal_tz );
2261							me = moment.unix( end ).tz( OD.cal_tz );
2262
2263							var all_day = $(elm).find('a.desc_trig').hasClass('allday') ? true: false;
2264
2265							// get event time correct for all day
2266							if( all_day ){
2267								ED['t'] = _txt4;
2268							}else{
2269								if( ESU <= SU ){
2270									if( EEU >= EU) ED['t'] = _txt4;
2271									if( EEU < EU ) ED['t'] = _txt2+' ' + me.format( time_format);		
2272								}else if(ESU > SU){
2273									if( EEU >= EU)  ED['t'] = _txt3+' '+ m.format( time_format);
2274									if( EEU < EU ) ED['t'] = m.format( time_format) +' - '+ me.format( time_format);
2275								}	
2276							}						
2277
2278							// hide end time
2279							if( ED.hide_et == 'y')		ED['t'] = m.format( time_format);
2280
2281							events[index] = ED;
2282						});			
2283
2284					// if there are events in this date
2285						if( events && Object.keys(events).length > 0){
2286							
2287							template_data[ x ] = {};
2288							template_data[ x ]['date'] = '<b>' + M.get('date')+'</b> '+ month_name+' '+ day_name;
2289							template_data[ x ]['d'] =  M.format('YYYY-M-D');
2290							template_data[ x ]['SU'] = SU;
2291							template_data[ x ]['events'] = {}
2292
2293							$.each(events, function(index, item){		
2294
2295								location_data = organizer_data = event_tags = '';
2296
2297								// location 
2298								if( SC.show_location == 'yes' && 'location' in item){
2299									location_data = "<div class='evosv_subdata evosv_location'><i class='fa fa-location-pin marr5'></i>" +item.location+"</div>";
2300								}
2301
2302								// organizer					
2303								if( SC.show_organizer == 'yes' && 'organizer' in item){
2304									organizer_data = "<div class='evosv_subdata evosv_org'>" +item.organizer+"</div>";
2305								}
2306
2307								// event tags
2308								if( SC.show_tags == 'yes' && 'event_tags' in item){
2309									event_tags = "<div class='evosv_subdata evosv_tags'>";
2310									$.each( item.event_tags, function(index, val){
2311										event_tags += "<span class='evosv_tag " + index +"'>" + val+"</span>";
2312									});
2313									event_tags += "</div>";
2314								}
2315
2316								template_data[ x ]['events'][ item.uID ] = {
2317									'time': item.t,
2318									'ux_val': item.ux_val,
2319									'title': item.event_title,
2320									'color':item.hex_color,
2321									'tag': event_tags,
2322									'loc': location_data,
2323									'org': organizer_data,
2324									'i': item
2325								}
2326
2327							});					
2328						}
2329
2330					// next date
2331					M.add(1, 'd');
2332				}
2333
2334				var html_ = "<div class='evosv_grid evoADDS'>";
2335				
2336				// if no events
2337				if( !has_events){
2338					no_event_content = CAL.evo_get_global({S1: 'html', S2:'no_events'});			
2339					html_ += "<div class='date_row'><div class='row no_events evosv'>"+no_event_content+"</div></div>";
2340				}else{
2341					html_ += CAL.evo_HB_process_template({
2342						TD:template_data, part:'evosv_grid'
2343					});
2344				}
2345
2346				html_ += '</div>';
2347
2348				if( CAL.find('.evosv_grid').length > 0){
2349					CAL.find('.evosv_grid').replaceWith( html_ );
2350				}else{
2351					ELM = CAL.find('#eventon_loadbar_section');
2352					ELM.after( html_ );
2353				}
2354				
2355			},
2356
2357			// call ajax url
2358			get_ajax_url(action){
2359				var ajax_type = 'endpoint';
2360				if('ajax_method' in evo_general_params ) ajax_type = evo_general_params.ajax_method;
2361				return EVO.E.B.evo_get_ajax_url({a:action, type: 	ajax_type });
2362			},
2363		}
2364
2365	};
2366	EVO.init();
2367
2368
2369
2370// Other
2371	// RESET general calendar -- @U 2.8.9		
2372		function cal_resets(calOBJ){
2373			calargs = $(calOBJ).find('.cal_arguments');
2374			calargs.attr('data-show_limit_paged', 1 );
2375			calOBJ.evo_update_cal_sc({
2376				F:'show_limit_paged',V:'1'
2377			});
2378		}
2379	
2380	// layout view changer - legacy
2381		if($('body').find('.evo_layout_changer').length>0){
2382			// menu button focus adjust
2383			$('body').find('.evo_layout_changer').each(function(item){
2384				if($(this).parent().hasClass('boxy')){
2385					$(this).find('.fa-th-large').addClass('on');
2386				}else{
2387					$(this).find('.fa-reorder').addClass('on');
2388				}
2389			});
2390
2391			// interaction
2392			$('.evo_layout_changer').on('click','i',function(){
2393				const CAL = $(this).closest('.ajde_evcal_calendar');
2394				TYPE = $(this).data('type');
2395				$(this).parent().find('i').removeClass('on');
2396				$(this).addClass('on');
2397
2398				//console.log(TYPE);
2399				
2400				if(TYPE=='row'){
2401					CAL.attr('class','ajde_evcal_calendar');
2402					// set tile colors
2403					CAL.find('.eventon_list_event').each(function(){
2404						$(this).find('.desc_trig').css('background-color',  '');
2405						$(this).find('.desc_trig_outter').css('background-color',  '');
2406					});
2407				}else if(TYPE =='bar'){
2408					CAL.attr('class','ajde_evcal_calendar  box_2 sev cev');
2409					
2410					// set tile colors
2411					CAL.find('.eventon_list_event').each(function(){
2412						const color = $(this).data('colr');
2413						$(this).find('.desc_trig').css('background-color',  color);
2414					});
2415				}else{
2416
2417					// set tile colors
2418					CAL.find('.eventon_list_event').each(function(){
2419						const color = $(this).data('colr');
2420						$(this).find('.desc_trig_outter').css('background-color',  color);
2421					});
2422
2423					CAL.attr('class','ajde_evcal_calendar boxy boxstyle0 box_2');
2424				}				
2425			});
2426		}
2427	
2428	// SORTING & FILTERING		
2429		// Sorting	
2430			// update calendar based on the sorting selection
2431				$('body').on('click', '.evo_sort_option',function(){
2432					O = $(this);
2433					var CAL = O.closest('.ajde_evcal_calendar');
2434					var sort_by = O.data('val');
2435					
2436					// update new values everywhere
2437					CAL.evo_update_cal_sc({F:'sort_by',V:sort_by});
2438
2439					O.parent().find('p').removeClass('select');
2440					O.addClass('select');	
2441
2442					run_cal_ajax(CAL.attr('id'),'none','sorting');						
2443				});		
2444
2445		// close filter menus on click outside
2446			BODY.on('clicked_on_page',function( ev, obj, ee){
2447
2448				// hide filter menu when clicked outside 4.6.2
2449				if( !(obj.hasClass('eventon_filter')) && 
2450					!(obj.hasClass('filtering_set_val')) &&
2451					!(obj.hasClass('evo_filter_val')) &&
2452					!(obj.hasClass('evofp_filter_search_i')) &&
2453					obj.parents('.filtering_set_val').length == 0 
2454				){
2455					//console.log(obj);
2456					BODY.find('.evo_filter_menu').html('');
2457					BODY.find('.evo_filter_tax_box.vis').removeClass('vis');
2458				}
2459			});
2460
2461		// Filtering
2462			$.fn.evo_cal_filtering = function(O){
2463				
2464				var opt = $.extend({}, O);
2465
2466				var el = this; // cal
2467				const sortbox = el.find('.eventon_sorting_section'),
2468					filter_container = sortbox.find('.evo_filter_container_in'),
2469					filter_line = sortbox.find('.eventon_filter_line'),
2470					fmenu = sortbox.find('.evo_filter_menu'),
2471					all_cal_filter_data = el.evo_get_filter_data(),
2472					SC = el.evo_shortcode_data();
2473				var tterms = [];
2474
2475
2476				var init = function(){
2477
2478					if( SC == '' || SC === null ) return;
2479					if( el.hasClass('filters_go'))	return;
2480					el.addClass('filters_go');
2481					
2482					draw_filter_bar();
2483					filter_actions();
2484					run_filter_nav_check();
2485
2486				}
2487
2488				// draw the filter bar
2489				var draw_filter_bar = function(){
2490					//console.log(all_cal_filter_data);
2491
2492					BODY.trigger('evo_filter_before_draw', [ el ]);
2493
2494					html = '';
2495
2496					$.each( all_cal_filter_data , function( index, value){
2497
2498						// skip fast filter items
2499						if( SC && 'fast_filter' in SC && SC.fast_filter == 'yes' && SC.ff_tax != '' && SC.ff_tax !== undefined ){
2500							__t = SC.ff_tax.split(',');
2501							if( __t.includes( index ) ) return;
2502						}
2503
2504						html += "<div class='eventon_filter evo_filter_tax_box evo_hideshow_st "+index+"' data-tax='"+ value.__tax +"' data-filter_type='"+ value.__filter_type +"'>";
2505						html += "<div class='eventon_filter_selection'>";
2506							html += "<p class='filtering_set_val'><i class='fa fa-check'></i> "+ value.__name +"<em class='fa fa-caret-down'></em></p>";							
2507						html += "</div>";
2508						html += "</div>";
2509					});
2510
2511					filter_line.html( html );
2512
2513					BODY.trigger('evo_filter_drawn', [ el ]);
2514				}
2515
2516
2517				// filter all actions
2518				var filter_actions = function(){
2519
2520					el.off('click', '.evo-filter-btn');
2521
2522					// show/hide filter bar
2523						el.on('click','.evo-filter-btn',function(){
2524							const CAL = $(this).closest('.ajde_evcal_calendar');
2525							
2526							BODY.trigger('evo_filter_btn_trig', [ CAL , O ]);
2527							if( CAL.hasClass('fp_lb')) return; // PLUG 4.6.4
2528
2529							if( !( $(this).hasClass('vis') ) ){
2530								sortbox.addClass('vis');
2531								run_filter_nav_check();
2532							}else{
2533								sortbox.removeClass('vis');
2534							}
2535
2536							console.log('r');
2537
2538						});
2539
2540						// close filter when other sibling buttons clicked 4.6.4
2541						BODY.on('evo_cal_header_btn_clicked',function(event, O){	
2542							if( O.hasClass('evo-sort-btn') || O.hasClass('evo-search')  ){
2543								const CAL = O.closest('.ajde_evcal_calendar');
2544								CAL.find('.eventon_sorting_section').removeClass('vis');								
2545							}
2546						});
2547						
2548						
2549					// show hide menu
2550					el.on('click','.filtering_set_val',function(){
2551
2552						O = $(this);
2553						const filterbox = O.closest('.evo_filter_tax_box'),
2554						filter_tax = filterbox.data('tax');
2555						selected_terms = el.evo_cal_get_filter_sub_data( filter_tax , 'tterms' );
2556
2557						// close sort menu
2558							el.find('.eventon_sort_line').hide();
2559
2560						// hide already opened menus
2561							if( filterbox.hasClass('vis')){
2562								filterbox.removeClass('vis');							
2563								close_filter_menu();
2564								return;
2565							}
2566							if( fmenu.data('tax') == filter_tax ){	
2567								filterbox.removeClass('vis');							
2568								close_filter_menu();
2569								return;
2570							}else{
2571								sortbox.find('.filtering_set_val').removeClass('show');
2572								sortbox.find('.evo_filter_tax_box').removeClass('vis');
2573								filterbox.addClass('vis');	
2574							}
2575
2576						// build the filter menu from data
2577							var filter_item_data = all_cal_filter_data[ filter_tax ].__list;
2578
2579							//console.log(all_cal_filter_data);
2580							//console.log(selected_terms);
2581							
2582							var __menu_html = '<div class="evo_filter_inside evo_filter_menu_in" data-tax="'+filter_tax+'"><div class="eventon_filter_dropdown">';
2583
2584
2585							// Sort the filter list alphabetically
2586							var sorted_data = Object.values(filter_item_data);  
2587							sorted_data.sort(function(a, b) {
2588							    // Natural sort by term label (a[1] and b[1]), case-insensitive
2589							    return a[1].localeCompare(b[1], 'en', {
2590							        numeric: true,      // Treat numbers properly (e.g., 2 before 11)
2591							        sensitivity: 'base' // Ignore case and accents for case-insensitive sort
2592							    });
2593							});
2594							
2595							// each term
2596							var menuInside = '';
2597							var AllHtml = '';
2598							$.each(sorted_data, function (index, val){
2599								var icon_html = '';
2600								var _class = filter_tax+'_'+ val[0] + ' '+ val[0];
2601								
2602								// parent or child term
2603								if( val[3] !== undefined && val[3] != '' && val[3] == 'n') _class += ' np';
2604
2605								//console.log(selected_terms);
2606								// select or not
2607								if( selected_terms == 'all' )  _class += ' select';
2608								if( selected_terms.includes( val[0] ) )  _class += ' select';
2609
2610								// icon
2611								if( val[2] != '' && val[2] !== undefined ){
2612									_class += ' has_icon'; icon_html = val[2];
2613								} 
2614
2615								// tax term color
2616								var _tax_color = '';
2617								if( val[4] != '' && val[4] !== undefined ){
2618									_tax_color = `style='background-color:#${val[4]};'`;
2619								}
2620
2621								const itemHTML = `<p class="evo_filter_val ${_class}" data-id="${val[0]}" ${_tax_color}>${icon_html} ${val[1]}</p>`;
2622
2623								// save all value
2624								if( val[0]=='all'){
2625									AllHtml = itemHTML;
2626								}else{
2627									menuInside += itemHTML;
2628								} 
2629								
2630							});
2631
2632							__menu_html += AllHtml + menuInside +"</div></div>";
2633
2634							// 4.6.4
2635							BODY.trigger('evo_filter_menu_html_ready', [ el , __menu_html , O , filterbox, filter_tax]);
2636
2637
2638							if( el.hasClass('fp_side')) return; // PLUG
2639							
2640
2641							
2642						// set new menu with correct location
2643							const scrolled_width = filter_container.scrollLeft();
2644							fmenu.html( __menu_html );
2645
2646							// pluggable
2647							BODY.trigger('evo_filter_menu_built', [ el , fmenu , filter_tax ]);
2648							
2649
2650							__left_margin = filterbox.position().left + 10 - scrolled_width;
2651							__menu_width = fmenu.find('.evo_filter_inside').width();
2652
2653							__cal_left_margin = el.position().left;
2654
2655							//console.log(__cal_left_margin + ' '+ __left_margin +' '+ __menu_width + ' '+ $(window).width());
2656
2657							if( __left_margin + __menu_width + __cal_left_margin > $(window).width()  ){
2658								
2659								if(  ( __left_margin + __menu_width ) > el.width() ){
2660									new_left = el.width() - __menu_width - 10;
2661								}else{
2662									new_left = ( el.width() - __menu_width ) / 2;
2663								}								
2664								fmenu.css('left', new_left );
2665							}else{
2666								fmenu.css('left', __left_margin);
2667							}
2668					});
2669
2670					// select a static filter menu item
2671						el.on('click','p.filtering_static_val',function(){
2672
2673							BODY.trigger('evo_filter_static_clicked', [ el , $(this) ]);
2674												
2675						});
2676
2677					// select terms in filter menu
2678						el.on('click','p.evo_filter_val',function (){
2679
2680							var O = $(this);
2681							const filter_menuIN = O.closest('.evo_filter_inside'),
2682								filter_tax = filter_menuIN.data('tax'),
2683								filterbox = sortbox.find('.evo_filter_tax_box.'+ filter_tax),
2684								all_terms_obj = filter_menuIN.find('p'),
2685								new_term_id = O.data('id'),
2686								old_terms = el.evo_cal_get_filter_sub_data( filter_tax , 'terms' )
2687								;
2688							var tterms = el.evo_cal_get_filter_sub_data( filter_tax , 'nterms' );
2689
2690							var new_terms = [];
2691
2692
2693							// select filter type
2694							if( SC.filter_type == 'select' ){
2695
2696								// all value
2697								if( new_term_id == 'all' ){
2698									if( O.hasClass('select') ){
2699										all_terms_obj.removeClass('select');
2700									}else{
2701										all_terms_obj.addClass('select');
2702										new_terms.push('all');
2703									}
2704								}else{
2705									// unselect all value
2706									filter_menuIN.find('p.all').removeClass('select');
2707									O.toggleClass('select');	
2708
2709									var unselect_count = 0;
2710									all_terms_obj.each(function(){
2711										if( $(this).hasClass('select')){
2712											new_terms.push( $(this).data('id') )
2713										}else{
2714											// not select
2715											if(!$(this).hasClass('all')) unselect_count++;
2716										}
2717									});	
2718
2719									// all selected
2720									if(unselect_count == 0){
2721										filter_menuIN.find('p.all').addClass('select');
2722										new_terms.push('all');
2723									}	
2724
2725									// if all field is not visible; nothing selected = all
2726									if( new_terms.length == 0 && O.parent().find('p.all').length == 0) 
2727										new_terms.push('all');
2728								}							
2729
2730							// non select type
2731							}else{ 
2732								// all value
2733								if( new_term_id == 'all' ){
2734									// if all is already selected
2735									if( O.hasClass('select')){
2736										new_terms.push('NOT-all');
2737										all_terms_obj.removeClass('select');
2738									}else{
2739										all_terms_obj.addClass('select');
2740										new_terms.push( new_term_id );
2741									}	
2742								}else{
2743									all_terms_obj.removeClass('select');
2744									O.addClass('select');
2745									new_terms.push( new_term_id );
2746								}
2747
2748								update_filter_data( filter_tax, new_terms );
2749
2750								// process selection @4.6.6
2751									if( tterms == new_terms ){
2752										close_filter_menu();
2753									}else{					
2754										cal_resets( el );
2755												
2756										el.evo_update_sc_from_filters();					
2757
2758										run_cal_ajax( el.attr('id') ,'none','filering');
2759																								
2760										close_filter_menu();
2761										O.removeClass('show');
2762									}
2763
2764								close_filter_menu();
2765								// mark hide of menu
2766								filterbox.removeClass('vis');
2767							}
2768							
2769							// show and hide apply filter button
2770								// if new terms = temp terms
2771									if( compare_terms( new_terms, tterms) ){
2772										filterbox.removeClass('chg');										
2773									}else{
2774										filterbox.addClass('chg');			
2775									}
2776									if( compare_terms( old_terms, new_terms) ){
2777										filterbox.removeClass('set');	
2778									}else{
2779										filterbox.addClass('set');
2780									}								
2781									
2782
2783								// changed filters
2784								var chg_filters = sortbox.find('.evo_filter_tax_box.chg').length;
2785								var set_count = sortbox.find('.evo_filter_tax_box.set').length;
2786								if( SC.filter_type == 'select' ) 
2787									( chg_filters > 0 ) ? show_apply_btns() : hide_apply_btns();
2788
2789
2790							// Filter highlighted indicator 
2791								if( !( el.hasClass('flhi') ) ){
2792
2793									const filter_btn = el.find('.evo-filter-btn');	
2794
2795									if( set_count > 0){
2796										filter_btn.find('em').html( set_count ).addClass('o');	
2797									}else{
2798										filter_btn.find('em').removeClass('o');			
2799									}			
2800								}
2801
2802
2803
2804							update_filter_data( filter_tax, new_terms , 'tterms');
2805
2806							run_filter_nav_check();
2807
2808						});
2809													
2810					// apply filters button
2811						el.on('click','.evo_filter_submit',function(){
2812
2813							el.evo_filters_update_from_temp( filter_line, el );
2814							
2815							cal_resets( el);
2816
2817							close_filter_menu(); // hide filter menu
2818
2819							// update filter item button
2820							sortbox.find('.filtering_set_val').removeClass('show');
2821
2822							el.evo_update_sc_from_filters();	// update shortcode from filters
2823							
2824							run_cal_ajax( el.attr('id'),'none','filering');
2825
2826							run_filter_nav_check();
2827						});
2828
2829					// clear filters
2830						el.on('click','.evo_filter_clear',function(){
2831								
2832							el.find('.evo_filter_tax_box').each(function(){
2833								const O = $(this),
2834									tax = O.data('tax'),
2835									terms = O.data('terms');
2836
2837								O.removeClass('set');
2838								O.find('.filtering_set_val').removeClass('set show');
2839								el.find('.evo-filter-btn em').removeClass('o');
2840
2841								close_filter_menu();
2842							});
2843
2844							// update all filters with default/ onload values @4.6.1
2845							$.each( all_cal_filter_data, function( tax, tdata){
2846								update_filter_data( tax, tdata.terms );
2847							} );
2848
2849
2850							hide_apply_btns(); // hide filter action buttons
2851							
2852							// update shortcode and run new ajax for events
2853							el.evo_update_sc_from_filters();					
2854							run_cal_ajax( el.attr('id'),'none','filering');
2855
2856							run_filter_nav_check();
2857						});
2858
2859					// click on filter navs
2860						el.on('click','.evo_filter_nav',function(){
2861							O = $(this);
2862
2863							_filter_bar = O.closest('.evo_filter_bar');
2864							_filter_container = _filter_bar.find('.evo_filter_container_in');
2865							_filter_line_width = _filter_bar.find('.eventon_filter_line')[0].scrollWidth;
2866							_filter_container_width = parseInt( _filter_container.width() ) + 0;
2867							_leftPos = _filter_container.scrollLeft();
2868							_scrollable_legth = _filter_line_width - _filter_container_width;
2869
2870							const scroll_length = _filter_container_width /2;
2871							
2872							// move right
2873							if( O.hasClass('evo_filter_r') ){
2874																		
2875								_filter_container.animate({scrollLeft:_leftPos + scroll_length},200);
2876								_filter_bar.find('.evo_filter_l').addClass('vis');
2877							// move left
2878							}else{
2879								sleft = (_leftPos - scroll_length < scroll_length) ? 0 :  _leftPos - scroll_length;
2880								_filter_container.animate({scrollLeft: sleft },200);											
2881							}
2882
2883							close_filter_menu();
2884
2885							setTimeout(function(){
2886								var _leftPos = _filter_container.scrollLeft();
2887								//console.log(_leftPos);
2888								if( _leftPos < 10){
2889									_filter_bar.find('.evo_filter_l').removeClass('vis');
2890									_filter_bar.find('.evo_filter_r').addClass('vis');
2891								}
2892
2893								if( _leftPos > ( _scrollable_legth - 5 ) ){
2894									_filter_bar.find('.evo_filter_r').removeClass('vis');
2895								}
2896							},200);
2897												
2898						});
2899
2900					// on window size change
2901					$(window).on('resize',function(){
2902						run_filter_nav_check();
2903					});
2904				}
2905
2906				var compare_terms = function(a, b){
2907					if (a === b) return true;
2908					if (a == null || b == null) return false;
2909					if (a.length !== b.length) return false;
2910
2911					for (var i = 0; i < a.length; ++i) {
2912					   if (a[i] !== b[i]) return false;
2913					}
2914					return true;
2915				}
2916				var close_filter_menu = function(){
2917					fmenu.html('').data('tax','');
2918				}
2919
2920				var show_apply_btns = function(){
2921					sortbox.find('.evo_filter_aply_btns').addClass('vis');	
2922				}
2923				var hide_apply_btns = function(){
2924					sortbox.find('.evo_filter_aply_btns').removeClass('vis');		
2925				}
2926
2927				var update_filter_data = function(tax, new_val, key){
2928
2929					el.evo_cal_update_filter_data( tax , new_val , key );					
2930				}
2931
2932
2933				// adjust and position filter nav buttons
2934				var run_filter_nav_check = function(){
2935
2936					$.each( el.find('.evo_filter_bar') , function(event){
2937						_filter_bar = $(this);
2938						_filter_container = _filter_bar.find('.evo_filter_container_in');
2939						_filter_line_width = _filter_bar.find('.eventon_filter_line')[0].scrollWidth;
2940						_filter_container_width = parseInt( _filter_container.width() ) + 3;
2941						var leftPos = _filter_container.scrollLeft();
2942
2943						//console.log(_filter_line_width +' '+ _filter_container_width +' '+leftPos);
2944
2945						// filter line is not showing full
2946						if( _filter_line_width > _filter_container_width ){
2947
2948							// if some of filter line is hidden on right
2949							if( ( _filter_container_width + leftPos  ) < _filter_line_width )
2950								_filter_bar.find('.evo_filter_r').addClass('vis');
2951
2952							// if filter has been scrolled
2953							if( leftPos > 0 ){
2954								_filter_bar.find('.evo_filter_l').addClass('vis');
2955							}else{
2956								_filter_bar.find('.evo_filter_r').addClass('vis');
2957							}
2958						}else{
2959							_filter_bar.find('.evo_filter_l').removeClass('vis');
2960							_filter_bar.find('.evo_filter_r').removeClass('vis');
2961						}
2962
2963					});
2964
2965					//console.log(filter_line_width +' '+ filter_container_width +' '+leftPos);					
2966				}
2967
2968				init();
2969			}
2970
2971			// for each tax move tterms value to nterms / before sending ajax
2972			$.fn.evo_filters_update_from_temp = function(filter_line, cal){
2973				// move temp term values into new terms
2974					filter_line.find('.evo_filter_tax_box').each(function(){
2975						var taxonomy = $(this).data('tax');
2976						const tterms = cal.evo_cal_get_filter_sub_data( taxonomy , 'tterms');
2977
2978						cal.evo_cal_update_filter_data( taxonomy , tterms, 'nterms');
2979
2980						$(this).removeClass('chg');
2981					});
2982			}
2983				
2984
2985	// PRIMARY hook to get content	 
2986		// MAIN AJAX for calendar events v2.8
2987		function run_cal_ajax( cal_id, direction, ajaxtype){
2988			
2989			// identify the calendar and its elements.
2990			var CAL = ev_cal = $('#'+cal_id); 
2991
2992			// check if ajax post content should run for this calendar or not			
2993			if(CAL.attr('data-runajax')!='0'){
2994
2995				const EVENTS_LIST = CAL.find('.eventon_events_list');
2996				const $showMoreBtn = EVENTS_LIST.find('.evoShow_more_events');
2997
2998				// category filtering for the calendar
2999				var cat = CAL.find('.evcal_sort').attr('cat');
3000
3001				// reset paged values for switching months
3002				if(ajaxtype=='switchmonth'){
3003					CAL.find('.cal_arguments').attr('data-show_limit_paged',1);
3004					CAL.evo_update_cal_sc({F:'show_limit_paged', V: '1'});
3005				}	
3006
3007				SC = CAL.evo_cal_functions({action:'load_shortcodes'});
3008
3009				$('body').trigger('evo_main_ajax_before', [CAL, ajaxtype, direction, SC]);		
3010
3011				var data_arg = {
3012					//action: 		'eventon_get_events',
3013					direction: 		direction,
3014					shortcode: 		SC,
3015					ajaxtype: 		ajaxtype,
3016					nonce: 			evo_general_params.n,
3017					nonceX: 		evo_general_params.nonce
3018				};	
3019
3020				
3021
3022				$.ajax({
3023					// preload actions
3024					beforeSend: function(xhr){
3025						xhr.setRequestHeader('X-WP-Nonce', evo_general_params.nonce );
3026
3027						CAL.addClass('evo_loading');
3028
3029						// paged -- adding events to end
3030						if(ajaxtype == 'paged'){							
3031							const currentContent = $showMoreBtn.html();
3032							$showMoreBtn.data('txt',currentContent);
3033							if( SC.tiles == 'yes'){
3034								$showMoreBtn.addClass('evoloading');
3035								$showMoreBtn.find('span').html('');
3036							}else{
3037								$showMoreBtn.find('span').addClass('evobtn_loader full');
3038							}
3039							
3040						}else{
3041
3042							html = evo_general_params.html.preload_events;
3043							if( SC.tiles == 'yes') html = evo_general_params.html.preload_event_tiles;
3044
3045							EVENTS_LIST.html( html );
3046							//EVENTS_LIST.slideUp('fast');
3047						}	
3048
3049						// maintain scrolltop location 4.6
3050						if( CAL.hasClass('nav_from_foot')){
3051							
3052							//scrolltop = (CAL.find('.evo_footer_nav').offset().top) - CAL.data('viewport_top');
3053							scrolltop = CAL.offset().top;
3054							$('html, body').animate({	scrollTop: scrolltop	},20);
3055						}	
3056
3057						$('body').trigger('evo_main_ajax_before_fnc',[CAL, ajaxtype, data_arg ]);	//s4.6			
3058					},
3059					type: 'POST', url: get_ajax_url('eventon_get_events'),data: data_arg,dataType:'json',
3060					success:function(data){
3061
3062						if(!data) return false;
3063
3064						// paged calendar
3065						if(ajaxtype == 'paged'){	
3066							$showMoreBtn.remove();
3067							EVENTS_LIST.find('.clear').remove();
3068							EVENTS_LIST.append( data.html + "<div class='clear'></div>");
3069
3070							// hide show more events if all events loaded
3071							var events_in_list = EVENTS_LIST.find('.eventon_list_event').length;
3072							if( 'total_events' in data && data.total_events == events_in_list){
3073								$showMoreBtn.hide();
3074							}	
3075
3076							// for month lists duplicate headers // @+2.8.1
3077							var T = {};
3078							EVENTS_LIST.find('.evcal_month_line').each(function(){
3079								d = $(this).data('d');
3080								if( T[d]) 
3081									$(this).remove();
3082								else
3083									T[d] = true;
3084							});
3085
3086							var T = {};
3087							EVENTS_LIST.find('.sep_month_events').each(function(){
3088								d = $(this).data('d');
3089								if( T[d]){
3090									var H = $(this).html();
3091									EVENTS_LIST.find('.sep_month_events[data-d="'+d+'"]').append( H );
3092									$(this).remove();
3093								}else{T[d] = true;}
3094							});
3095							
3096						}else{
3097							EVENTS_LIST.html(data.html);
3098						}
3099
3100						
3101						// update calendar data
3102						CAL.find('.evo_month_title').html( data.cal_month_title );
3103
3104						CAL.evo_cal_functions({action:'update_shortcodes',SC: data.SC});
3105						CAL.evo_cal_functions({action:'update_json',json: data.json});
3106
3107						// run cal process code
3108						CAL.evo_calendar({
3109							SC: data.SC,
3110							json: data.json
3111						});
3112							
3113
3114						$('body').trigger('calendar_month_changed',[CAL, data]);
3115						
3116						$('body').trigger('evo_main_ajax_success', [CAL, ajaxtype, data, data_arg]);
3117															
3118					},complete:function(data){
3119
3120						// show events list events if not set to hide on load
3121						if(! EVENTS_LIST.hasClass('evo_hide')) EVENTS_LIST.delay(300).slideDown('slow');
3122						
3123						// maintain scrolltop location 4.6
3124						if( CAL.hasClass('nav_from_foot')){
3125							
3126							setTimeout(function(){
3127								//scrolltop = (CAL.find('.evo_footer_nav').offset().top) - CAL.data('viewport_top');
3128								scrolltop = CAL.offset().top;
3129								$('html, body').animate({	scrollTop: scrolltop	},20);
3130								CAL.removeClass('nav_from_foot');
3131							},302);														
3132						}					
3133
3134						// pluggable
3135						$('body').trigger('evo_main_ajax_complete', [CAL, ajaxtype, data.responseJSON , data_arg]);
3136						CAL.removeClass('evo_loading');
3137					}
3138				});
3139			}			
3140		}
3141
3142		$('body').on('evo_run_cal_ajax',function(event,cal_id, direction, ajaxtype){
3143			run_cal_ajax( cal_id, direction, ajaxtype);
3144		});
3145
3146		// deprecated bridge function for sortby value 
3147		function ajax_post_content(sortby, cal_id, direction, ajaxtype){
3148			run_cal_ajax( cal_id, direction, ajaxtype);
3149		}
3150	
3151		
3152	// SINGLE EVENTS
3153		// Loading single event json based content
3154			$('body').on('evo_load_single_event_content', function(event, eid, obj){
3155				var ajaxdataa = {};
3156				ajaxdataa['eid'] = eid;
3157				ajaxdataa['nonce'] = the_ajax_script.postnonce;	
3158
3159				// pass on other event values
3160				if(obj.data('j')){
3161					$.each(obj.data('j'), function(index,val){
3162						ajaxdataa[ index] = val;
3163					});
3164				}			
3165				
3166				$.ajax({
3167					beforeSend: function(){ 	},	
3168					url:	get_ajax_url('eventon_load_event_content'),
3169					data: 	ajaxdataa,	dataType:'json', type: 	'POST',
3170					success:function(data){
3171						$('body').trigger('evo_single_event_content_loaded', [data, obj]);
3172					},complete:function(){ 	}
3173				});
3174			});
3175	
3176		if(BODY.evo_is_mobile()){
3177			if($('body').find('.fb.evo_ss').length != 0){
3178				$('body').find('.fb.evo_ss').each(function(){
3179					obj = $(this);
3180					obj.attr({'href':'http://m.facebook.com/sharer.php?u='+obj.attr('data-url')});
3181				});
3182			}
3183		}
3184
3185		// on single event page
3186		if($('body').find('.evo_sin_page').length>0){
3187			$('.evo_sin_page').each(function(){
3188				$('body').trigger('evo_load_single_event_content',[ $(this).data('eid'), $(this)]);
3189				$(this).find('.desc_trig ').attr({'data-ux_val':'none'});
3190			});
3191		}
3192		
3193		// Single events box
3194			// Click on single event box > Handled via main function
3195			// each single event box
3196				$('body').find('.eventon_single_event').each(function(){
3197					var _this = $(this);
3198
3199					var CAL = _this.closest('.ajde_evcal_calendar');
3200					var SC = CAL.evo_shortcode_data();	
3201					var evObj = CAL.find('.eventon_list_event');									
3202
3203					// show expanded eventCard
3204					if( SC.expanded =='yes'){
3205						_this.find('.evcal_eventcard').show();
3206						var idd = _this.find('.evcal_gmaps');						
3207
3208						// close button
3209						_this.find('.evcal_close').parent().css({'padding-right':0});
3210						_this.find('.evcal_close').hide();
3211
3212						//console.log(idd);
3213						var obj = _this.find('.desc_trig');
3214
3215						// Google Map
3216						_this.find('.evo_metarow_gmap').evo_load_gmap();
3217					
3218						// mark as eventcard open @since 4.4
3219						evObj.find('.event_description').addClass('open');
3220
3221					// open eventBox and lightbox	
3222					}else if(SC.uxval =='3'){
3223
3224						var obj = _this.find('.desc_trig');
3225						// remove other attr - that cause to redirect
3226						obj.removeAttr('data-exlk').attr({'data-ux_val':'3'});
3227					}
3228
3229					// show event excerpt
3230					var ev_excerpt = CAL.find('.event_excerpt').html();
3231					
3232					if(ev_excerpt!='' && ev_excerpt!== undefined && SC.excerpt =='yes' ){
3233						var appendation = '<div class="event_excerpt_in">'+ev_excerpt+'</div>'
3234						evObj.append(appendation);
3235					}
3236
3237					// trigger support @since 4.4
3238					var obj = evObj.find('.desc_trig');
3239					var event_id = evObj.data('event_id');
3240
3241
3242					$('body').trigger('evo_slidedown_eventcard_complete',[ event_id, obj]);	
3243				});
3244
3245// supportive
3246	// ajax url function  @u 4.5.5
3247		function get_ajax_url(action){
3248			var ajax_type = 'endpoint';
3249			if('ajax_method' in evo_general_params ) ajax_type = evo_general_params.ajax_method;
3250			return $('body').evo_get_ajax_url({a:action, type: 	ajax_type });
3251		}
3252	// handlebar additions
3253		function handlebar_additional_arguments(){
3254			Handlebars.registerHelper('ifE',function(v1, options){
3255				return (v1 !== undefined && v1 != '' && v1)
3256                    ? options.fn(this)
3257                    : options.inverse(this);
3258			});
3259
3260			Handlebars.registerHelper('ifEQ',function(v1, v2, options){
3261				return ( v1 == v2)? options.fn(this): options.inverse(this);
3262			});
3263			Handlebars.registerHelper('ifNEQ',function(v1, v2, options){
3264				return ( v1 != v2)? options.fn(this): options.inverse(this);
3265			});
3266			Handlebars.registerHelper('BUStxt',function(V, options){	
3267				if( !( V in BUS.txt) ) return V;
3268				return BUS.txt[V];
3269			});
3270			Handlebars.registerHelper('GetDMnames',function(V, U, options){				
3271				return BUS.dms[U][ V ];
3272			});
3273			// get total of increments
3274			Handlebars.registerHelper('forAdds',function(count, add_val, options){	
3275				O = '';
3276				for(x=1; x<= count; x++){	O += add_val;	}			
3277				return O;
3278			});
3279			Handlebars.registerHelper('GetEvProp',function(EID, PROP, CALID){
3280				EID = EID.split('-');	
3281				EV = $('#'+ CALID).find('.evo_cal_events').data('events');
3282				
3283				var O = '';
3284				$.each(EV, function(i,d){
3285					if( d.ID == EID[0] && d.ri == EID[1]){
3286						if( !(PROP in d.event_pmv)) return;
3287						O = d.event_pmv[PROP][0];
3288					}
3289				});
3290				return O;
3291			});
3292			Handlebars.registerHelper('GetEvV',function(EID, PROP, CALID){
3293				EID = EID.split('-');	
3294				EV = $('#'+ CALID).find('.evo_cal_events').data('events');
3295				
3296				var O = '';
3297				$.each(EV, function(i,d){
3298					if( d.ID == EID[0] && d.ri == EID[1]){
3299						O = d[PROP];
3300					}
3301				});
3302				return O;
3303			});
3304			Handlebars.registerHelper('COUNT',function( V){		
3305				return Object.keys(V).length;
3306			});
3307			Handlebars.registerHelper('CountlimitLess',function( AR, C,options){		
3308				var L= Object.keys(AR).length;
3309				return ( L < C)? options.inverse(this): options.fn(this);
3310			});
3311			Handlebars.registerHelper('ifCOND',function(v1, operator, v2, options){
3312				return checkCondition(v1, operator, v2)
3313	                ? options.fn(this)
3314	                : options.inverse(this);
3315			});
3316			Handlebars.registerHelper('toJSON', function(obj) {
3317			    return new Handlebars.SafeString(JSON.stringify(obj));
3318			});
3319			Handlebars.registerHelper('Cal_def_check',function(V, options){		
3320				if( BUS.cal_def && BUS.cal_def[V] ) return options.fn(this);
3321				return options.inverse(this);
3322			});
3323			Handlebars.registerHelper('TypeCheck',function(V, options){		
3324				if( options.type == V ) return options.fn(this);
3325				return options.inverse(this);
3326			});
3327		}
3328		function checkCondition(v1, operator, v2) {
3329	        switch(operator) {
3330	            case '==':
3331	                return (v1 == v2);
3332	            case '===':
3333	                return (v1 === v2);
3334	            case '!==':
3335	                return (v1 !== v2);
3336	            case '<':
3337	                return (v1 < v2);
3338	            case '<=':
3339	                return (v1 <= v2);
3340	            case '>':
3341	                return (v1 > v2);
3342	            case '>=':
3343	                return (v1 >= v2);
3344	            case '&&':
3345	                return (v1 && v2);
3346	            case '||':
3347	                return (v1 || v2);
3348	            default:
3349	                return false;
3350	        }
3351	    }
3352
3353
3354// DEPRECATING 
3355	// LIGHTBOX		
3356		// since 4.2 moving to functions
3357		// open lightbox @2.9
3358			BODY.on('evo_open_lightbox',function(event, lb_class, content){
3359				const LIGHTBOX = $('.evo_lightbox.'+lb_class).eq(0);
3360
3361				// if already open
3362				if(LIGHTBOX.is("visible")===true) return false;
3363
3364				if( content != ''){
3365					LIGHTBOX.find('.evo_lightbox_body').html( content );
3366				}
3367				BODY.trigger('evolightbox_show', [ lb_class ]);
3368			});
3369
3370		// click outside close LB
3371			BODY.on('clicked_on_page', function(event, obj, ev ){
3372				if( obj.hasClass('evo_content_inin')){
3373					closing_lightbox( obj.closest('.evo_lightbox') );
3374				}
3375			});
3376
3377		// close popup
3378			BODY.on('click','.evolbclose', function(){	
3379				if( $(this).hasClass('evolb_close_btn')) return;
3380				LIGHTBOX = 	$(this).closest('.evo_lightbox');
3381				closing_lightbox( LIGHTBOX );				
3382			});
3383
3384		// close with click outside popup box when pop is shown						
3385			function closing_lightbox( lightboxELM){
3386				
3387				if(! lightboxELM.hasClass('show')) return false;
3388				Close = (lightboxELM.parent().find('.evo_lightbox.show').length == 1)? true: false;
3389				lightboxELM.removeClass('show');
3390
3391				$('body').trigger('lightbox_before_event_closing', [lightboxELM]);
3392
3393				setTimeout( function(){ 
3394					lightboxELM.find('.evo_lightbox_body').html('');
3395					
3396					if(Close){
3397						$('body').removeClass('evo_overflow');
3398						$('html').removeClass('evo_overflow');
3399					}
3400					
3401					// trigger action to hook in at this stage
3402						$('body').trigger('lightbox_event_closing', [lightboxELM]);
3403				}, 100);
3404			}
3405
3406		// when lightbox open triggered
3407			$('body').on('evolightbox_show',function(event, lb_class){
3408				$('.evo_lightboxes').show();
3409				$('body').addClass('evo_overflow');
3410				$('html').addClass('evo_overflow');
3411
3412				$('body').trigger('evolightbox_opened',[ lb_class ]);
3413			});
3414
3415
3416});

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.