PageSourceSearch

https://gardenerd.com/wp-content/plugins/mage-eventpress/assets/frontend/mpwem_script.js?ver=5.7.3

js gardenerd.com collected 2026-09-24 21:17:52 UTC 94,154 bytes, 2,141 lines download raw bytes

1function mpwem_qty_inperson(parent) {
2    let total_qty = 0;
3    parent.find('[name="option_qty[]"]').each(function () {
4        const $item = jQuery(this).closest('.mep_ticket_item');
5        if (!$item.find('.mep-ticket-mode-badge--online').length) {
6            total_qty += parseInt(jQuery(this).val()) || 0;
7        }
8    });
9    return total_qty;
10}
11function mpwem_price_calculation(parent) {
12    // alert(123);
13    try {
14        const total_qty = mpwem_qty(parent);
15        mpwem_attendee_management(parent, total_qty);
16        const target_summary = parent.find('.mpwem_total');
17        let total = mpwem_price(parent);
18        if (total_qty > 0) {
19            parent.find('.mpwem_form_submit_area button').removeAttr('disabled');
20            // For hybrid events, only show extra service when at least one in-person ticket is selected
21            const isHybrid = parent.find('.mep-ticket-mode-badge--online, .mep-ticket-mode-badge--inperson').length > 0;
22            const inPersonQty = isHybrid ? mpwem_qty_inperson(parent) : total_qty;
23            if (inPersonQty > 0) {
24                parent.find('.mpwem_ex_service').slideDown('fast');
25                total += mpwem_ex_price(parent);
26            } else {
27                parent.find('.mpwem_ex_service').slideUp('fast');
28            }
29        } else {
30            parent.find('.mpwem_ex_service').slideUp('fast');
31            parent.find('.mpwem_form_submit_area button').attr('disabled', 'disabled');
32        }
33        target_summary.html(mpwem_price_format(total));
34    } catch (error) {
35        console.error('Error in price calculation:', error);
36    }
37}
38function mpwem_qty(parent) {
39    let total_qty = 0;
40    if (parent.find('.mpwem_seat_plan_area').length > 0) {
41        // Count selected seats
42        total_qty = parent.find('.mpwem_seat_available.mage_seat_selected').length;
43    } else {
44        // Sum up ticket quantities
45        parent.find('[name="option_qty[]"]').each(function () {
46            const qty = parseInt(jQuery(this).val()) || 0;
47            total_qty += qty;
48        });
49    }
50    return total_qty;
51}
52function mpwem_qty_ex(parent) {
53    let total_qty = 0;
54    parent.find('[name="event_extra_service_qty[]"]').each(function () {
55        const qty = parseInt(jQuery(this).val()) || 0;
56        total_qty += qty;
57    });
58    return total_qty;
59}
60function mpwem_price(parent) {
61    let total = 0;
62    if (parent.find('.mpwem_seat_plan_area').length > 0) {
63        parent.find('.mpwem_seat_available.mage_seat_selected').each(function () {
64            const seatPrice = parseFloat(jQuery(this).attr('data-seat_price')) || 0;
65            total += seatPrice;
66        });
67    } else {
68        // Calculate from ticket quantities and prices
69        parent.find('[name="option_qty[]"]').each(function () {
70            const qty = parseInt(jQuery(this).val()) || 0;
71            const price = parseFloat(jQuery(this).attr('data-price')) || 0;
72            total += price * qty;
73        });
74    }
75    return total;
76}
77function mpwem_ex_price(parent) {
78    let total = 0;
79    parent.find('[name="event_extra_service_qty[]"]').each(function () {
80        const ex_qty = parseInt(jQuery(this).val()) || 0;
81        const ex_price = parseFloat(jQuery(this).attr('data-price')) || 0;
82        total += ex_price * ex_qty;
83    });
84    return total;
85}
86/**
87 * Attendee blocks with more than 4 fields get a 2-column layout class.
88 */
89function mpwem_mark_attendee_form_columns(parent) {
90    const $scope = parent && parent.length ? parent : jQuery('.mpwem_registration_area');
91    $scope.find('.mep_attendee_info .mep_form_item, .mep_attendee_info_hidden .mep_form_item').each(function () {
92        const $card = jQuery(this);
93        const fieldCount = $card.children('.mp_form_item').length;
94        $card.toggleClass('mep-form--cols-2', fieldCount > 4);
95    });
96}
97/**
98 * Turn a freshly cloned attendee block back into real, submittable inputs.
99 *
100 * The blocks are cloned from .mep_attendee_info_hidden, whose controls are kept
101 * disabled (see mpwem_attendee_management), so every copy inherits that flag and
102 * has to be re-enabled once it lands in a real attendee container.
103 */
104function mpwem_enable_attendee_clone(target) {
105    if (!target || !target.length) {
106        return;
107    }
108    target.find('.mep-template-disabled')
109        .removeClass('mep-template-disabled')
110        .prop('disabled', false)
111        .removeAttr('disabled');
112}
113/**
114 * Make the booking form validatable, immediately before the browser validates it.
115 *
116 * Constraint validation runs *before* the submit event, so the submit handler further
117 * down cannot help here: when a required control sits in a display:none block the
118 * browser has nowhere to show the error, so it refuses to submit and tells the visitor
119 * nothing at all. The booking button just goes dead and only the console says why
120 * ("An invalid form control with name='user_name[]' is not focusable").
121 *
122 * The two blocks that can hold such a control are both ones the plugin itself marks as
123 * inert - the clone source and a conditional field whose condition is not met - so only
124 * those are touched, and only when the control is still empty. A value the visitor
125 * typed is never disabled, because disabled controls are left out of the posted data.
126 * Anything that becomes visible later is re-enabled by the code that reveals it.
127 */
128function mpwem_prepare_form_for_validation(parent) {
129    if (!parent || !parent.length) {
130        return;
131    }
132    parent.find('.mep_attendee_info_hidden').find('input, select, textarea').each(function () {
133        if (!jQuery(this).prop('disabled')) {
134            jQuery(this).addClass('mep-template-disabled').prop('disabled', true);
135        }
136    });
137    parent.find('.dNone').find('input, select, textarea').each(function () {
138        if (!this.required || this.disabled || this.type === 'hidden') {
139            return;
140        }
141        if (jQuery.trim(this.value || '') !== '') {
142            return;
143        }
144        jQuery(this).prop('disabled', true);
145    });
146}
147function mpwem_attendee_management(parent, total_qty) {
148    let form_target = parent.find('.mep_attendee_info');
149    let same_attendee = parent.find('[name="mep_same_attendee"]').val();
150
151    // Strip required attributes from hidden template inputs to avoid "invali
151d form control is not focusable" error
152    parent.find('.mep_attendee_info_hidden').find('input, select, textarea').each(function () {
153        if (jQuery(this).prop('required')) {
154            jQuery(this).removeAttr('required').addClass('mep-originally-required');
155        }
156        // The hidden block is only a clone source, never something the visitor fills in,
157        // but it lives inside the registration form so its empty controls are posted
158        // alongside the real ones. Themes that move the attendee blocks further down the
159        // document - Horizon puts them in a drawer after </form> and re-attaches them with
160        // the form attribute, and form data is built in document order - then get that
161        // blank value at index 0 of every attendee array, which shifts every answer onto
162        // the wrong attendee and drops the last one's answers entirely. Disabled controls
163        // are left out of the submitted form data, so the template stops interfering.
164        if (!jQuery(this).prop('disabled')) {
165            jQuery(this).addClass('mep-template-disabled').attr('disabled', 'disabled');
166        }
167    });
168
169    if (form_target.length > 0 && total_qty > 0) {
170        if (same_attendee === 'yes' || same_attendee === 'must') {
171            form_target.slideDown('fast');
172        } else {
173            let hidden_target = parent.find('.mep_attendee_info_hidden');
174            if (parent.find('.mpwem_seat_plan_area').length > 0) {
175                let current_parent = parent.find('.mpwem_seat_plan_area');
176                let form_length = current_parent.find('.mep_form_item').length;
177                form_target = current_parent.find('.mep_attendee_info');
178                form_target.slideDown('fast');
179                if (form_length !== total_qty) {
180                    parent.find('.mpwem_seat_available.mage_seat_selected').each(function () {
181                        let seat_name = jQuery(this).attr('data-seat-name');
182                        let ticket_name = jQuery(this).attr('data-seat-type');
183                        if (form_target.find('[data-seat_name="' + seat_name + '"]').length === 0) {
184                            hidden_target.find('.mpwem_ticket_name').html(ticket_name);
185                            hidden_target.find('.mep_form_item').attr('data-seat_name', seat_name);
186                            hidden_target.find('.mpwem_ticket_count').html(seat_name).promise().done(function () {
187                                form_target.append(hidden_target.html());
188                                mpwem_enable_attendee_clone(form_target);
189                                form_target.find('.mep-originally-required').attr('required', 'required');
190                            }).promise().done(function () {
191                                mpwem_load_date_picker(parent);
192                                mpwem_mark_attendee_form_columns(parent);
193                            });
194                        }
195                    }).promise().done(function () {
196                        form_length = form_target.find('.mep_form_item').length;
197                        if (form_length !== total_qty) {
198                            form_target.find('.mep_form_item').each(function () {
199                                let seat_name = jQuery(this).attr('data-seat_name');
200                                if (parent.find('.mpwem_seat_available.mage_seat_selected[data-seat-name="' + seat_name + '"]').length === 0) {
201                                    jQuery(this).remove();
202                                }
203                            });
204                        }
205                        mpwem_mark_attendee_form_columns(parent);
206                    });
207                } else {
208                    mpwem_mark_attendee_form_columns(parent);
209                }
210            } else {
211                parent.find('[name="option_qty[]"]').each(function () {
212                    let current_parent = jQuery(this).closest('.mep_ticket_item');
213                    let qty = parseInt(jQuery(this).val());
214                    if (current_parent.find('[name="ticket_group_qty"]').length > 0) {
215                        qty = qty * parseInt(current_parent.find('[name="ticket_group_qty"]').val());
216                    }
217                    if (current_parent.find('[name="mep_group_qty"]').length > 0) {
218                        qty = qty * parseInt(current_parent.find('[name="mep_group_qty"]').val());
219                    }
220                    let form_length = current_parent.find('.mep_form_item').length;
221                    form_target = current_parent.find('.mep_attendee_info');
222                    form_target.slideDown('fast');
223                    if (form_length !== qty) {
224                        if (form_length > qty) {
225                            for (let i = form_length; i > qty; i--) {
226                                form_target.find('.mep_form_item:last-child').slide
226Up(250).remove();
227                            }
228                        } else {
229                            for (let i = form_length; i < qty; i++) {
230                                let ticket_name = current_parent.find('[name="option_name[]"]').val();
231                                hidden_target.find('.mpwem_ticket_name').html(ticket_name);
232                                hidden_target.find('.mpwem_ticket_count').html(i + 1).promise().done(function () {
233                                    form_target.append(hidden_target.html()).promise().done(function () {
234                                        mpwem_enable_attendee_clone(jQuery(this));
235                                        jQuery(this).find('.mep-originally-required').attr('required', 'required');
236                                        jQuery(this).find('.mp_form_item').each(function () {
237                                            let condition_type = jQuery(this).attr('data-depend');
238                                            let current_ticket_name = jQuery(this).attr('data-condition-value');
239                                            if (condition_type === 'mep_ticket_type' && current_ticket_name === ticket_name) {
240                                                jQuery(this).slideDown('fast').removeClass('dNone');
241                                            }
242                                        });
243                                        mpwem_mark_attendee_form_columns(parent);
244                                    });
245                                }).promise().done(function () {
246                                    mpwem_load_date_picker(parent);
247                                    mpwem_mark_attendee_form_columns(parent);
248                                });
249                            }
250                        }
251                    }
252                });
253                mpwem_mark_attendee_form_columns(parent);
254            }
255        }
256        mpwem_mark_attendee_form_columns(parent);
257    } else {
258        if (same_attendee === 'yes' || same_attendee === 'must') {
259            form_target.slideUp(250);
260        } else {
261            form_target.html('').slideUp(250);
262        }
263    }
264}
265(function ($) {
266    "use strict";
267    $(document).ready(function () {
268        $('body').find('.mpwem_registration_area').each(function () {
269            mpwem_price_calculation($(this));
270            mpwem_mark_attendee_form_columns($(this));
271        });
272    });
273    $(document).on('change', '.mpwem_registration_area [name="mpwem_date_time"]', function () {
274        const parent = $(this).closest('.mpwem_registration_area');
275        const time_slot = parent.find('#mpwem_time');
276        if (time_slot.length > 0) {
277            const post_id = parent.find('[name="mpwem_post_id"]').val();
278            const dates = parent.find('[name="mpwem_date_time"]').val();
279            const target = parent.find('.mpwem_time_area');
280            jQuery.ajax({
281                type: 'POST',
282                url: mpwem_ajax_url,
283                data: {
284                    action: "get_mpwem_time",
285                    post_id: post_id,
286                    dates: dates,
287                },
288                beforeSend: function () {
289                    mpwem_loader_xs(target);
290                },
291                success: function (data) {
292                    target.html(data).slideDown('fast').promise().done(function () {
293                        const date = parent.find('[name="mpwem_time"]').val();
294                        get_mpwem_ticket(target, date);
295                    });
296                },
297                error: function (xhr, status, error) {
298                    console.error('Error loading time slots:', error);
299                    target.html('<p class="error">Error loading time slots. Please try again.</p>');
300                },
301                complete: function () {
302                    mpwem_loader_remove(target);
303                }
304            });
305        } else {
306            get_mpwem_ticket($(this));
307        }
308    });
309    $(document).on('change', '.mpwem_registration_area [name="mpwem_time"]', function () {
310        let parent = $(this).closest('.mpwem_registration_area');
311        let date = parent.find('[name="mpwem_time"]').val();
312        get_mpwem_ticket($(this), date);
313    });
314    function get_mpwem_ticket(current, date = '') {
315        let parent = current.closest('.mpwem_registration_area');
316        let post_id = parent.find('[name="mpwem_post_id"]').val();
317        let dates = date ? date : parent.find('[name="mpwem_date_time"]').val();
318        let target = parent.find('.mpwem_booking_panel');
319        jQuery.ajax({
320            type: 'POST',
321            url: mpwem_ajax_url,
322            data: {
323                "action": "get_mpwem_ticket",
324                "post_id": post_id,
325                "dates": dates,
326                "backend_order": window.location.href.search("backend_order"),
327            },
328            beforeSend: function () {
329                mpwem_loader_xs(target);
330            },
331            success: function (data) {
332                // alert(dates);
333                target.html(data).slideDown('fast').promise().done(function () {
334                    mpwem_load_seat_status(parent.closest('.mpwem_wrapper'),dates);
335                    mep_change_date_status(parent.closest('.mpwem_wrapper'),dates);
336                    mep_change_time_status(parent.closest('.mpwem_wrapper'),dates);
337                    mpwem_price_calculation(parent);
338                });
339            }
340        });
341    }
342    function mpwem_load_seat_status(parent,dates) {
343        let target = parent.find('.mpwem_seat_status');
344        if (target.length > 0) {
345            let post_id = parent.find('[name="mpwem_post_id"]').val();
346            let dates = parent.find('[name="mpwem_date_time"]').val();
347            jQuery.ajax({
348                type: 'POST',
349                url: mpwem_script_var.url,
350                data: {
351                    "action": "mpwem_load_seat_status",
352                    "post_id": post_id,
353                    "dates": dates,
354                    "nonce": mpwem_script_var.nonce
355                },
356                beforeSend: function () {
357                    mpwem_loader_xs(target);
358                },
359                success: function (data) {
360                    target.html(data);
361                }
362            });
363        }
364    }
365    function mep_change_date_status(parent,dates) {
366        let target = parent.find('.mep_date_status');
367
368            let post_id = parent.find('[name="mpwem_post_id"]').val();
369            //let dates = parent.find('[name="mpwem_date_time"]').val();
370            jQuery.ajax({
371                type: 'POST',
372                url: mpwem_script_var.url,
373                data: {
374                    "action": "mep_change_date_status",
375                    "post_id": post_id,
376                    "dates": dates,
377                    "nonce": mpwem_script_var.nonce
378                },
379                beforeSend: function () {
380                    mpwem_loader_xs(target);
381                },
382                success: function (data) {
383                    target.html(data);
384                }
385            });
386
387    }
388    function mep_change_time_status(parent,dates) {
389        let target = parent.find('.mep_time_status');
390
391        let post_id = parent.find('[name="mpwem_post_id"]').val();
392        //let dates = parent.find('[name="mpwem_date_time"]').val();
393        jQuery.ajax({
394            type: 'POST',
395            url: mpwem_script_var.url,
396            data: {
397                "action": "mep_change_time_status",
398                "post_id": post_id,
399                "dates": dates,
400                "nonce": mpwem_script_var.nonce
401            },
402            beforeSend: function () {
403                mpwem_loader_xs(target);
404            },
405            success: function (data) {
406                target.html(data);
407            }
408        });
409
410    }
411    $(document).on("click", "div.mpwem_style .decQty, div.mpwem_style .incQty", function () {
412        let parent = $(this).closest('.mpwem_registration_area');
413        let current = $(this);
414        if (!current.hasClass('mpDisabled')) {
415            let target = current.closest('.qtyIncDec').find('input');
416            let newValue = parseInt(target.val()) || 0;
417            let min = parseInt(target.attr('min')) || 0;
418            let max = parseInt(target.attr('max')) || Infinity;
419            let minQty = parseInt(target.attr('data-min-qty')) || 0;
420            if (current.hasClass('incQty')) {
421                newValue = newValue + 1;
422                if (newValue < min) {
423                    newValue = min;
424                }
425            } else {
426                newValue = newValue - 1;
427                if (newValue < min) {
428                    newValue = 0;
429                }
430            }
431            if (minQty > 0) {
432                newValue = Math.max(newValue, min);
433            }
434            newValue = Math.min(newValue, max);
435            target.val(newValue);
436            parent.find('.qtyIncDec').each(function () {
437                let $this = $(this);
438                $this.find('.incQty, .decQty').removeClass('mpDisabled');
439                let loop_target = $(this).find('input');
440                let loop_value = parseInt(loop_target.val()) || 0;
441                //let loop_min = parseInt(loop_target.attr('min')) || 0;
442                let loop_max = parseInt(loop_target.attr('max')) || Infinity;
443                let loop_minQty = parseInt(loop_target.attr('data-min-qty')) || 0;
444                if (loop_value >= loop_max) {
445                    $this.find('.incQty').addClass('mpDisabled');
446                }
447                if (loop_value <= loop_minQty) {
448                    $this.find('.decQty').addClass('mpDisabled');
449                }
450            }).promise().done(function () {
451                target.trigger('change').trigger('input');
452            });
453        }
454    });
455    $(document).on('change', '.mpwem_registration_area [name="option_qty[]"]', function () {
456        let parent = $(this).closest('.mpwem_registration_area');
457        let qty = $(this).val();
458        let total_qty = mpwem_qty(parent);
459        if (parent.find('[name="mepgq_max_qty"]').length > 0) {
460            let max_qty_gq = parseInt(parent.find('[name="mepgq_max_qty"]').val());
461            if (max_qty_gq > 0 && total_qty > max_qty_gq) {
462                qty = qty - total_qty + max_qty_gq;
463                $(this).val(qty);
464                mpwem_price_calculation(parent);
465            } else {
466                mpwem_price_calculation(parent);
467            }
468        } else if (parent.find('[name="mepmm_min_qty"]').length > 0) {
469            let max_qty = parseInt(parent.find('[name="mepmm_max_qty"]').val());
470            if (max_qty > 0 && total_qty > max_qty) {
471                qty = qty - total_qty + max_qty;
472                $(this).val(qty);
473                mpwem_price_calculation(parent);
474            } else {
475                mpwem_price_calculation(parent);
476            }
477        } else {
478            mpwem_price_calculation(parent);
479        }
480    });
481    $(document).on("click", ".mpwem_book_now", function (e) {
482        e.preventDefault();
483
484        const $wrap = $(this).closest('.mpwem_summery');
485        const alreadyInCart = 0;
486        if (alreadyInCart === 1 || alreadyInCart === '1') {
487            alert('This product is already in your cart.');
488            return false;
489        }else {
490            let parent = $(this).closest('.mpwem_registration_area');
491            let total_qty = mpwem_qty(parent);
492            if (total_qty > 0) {
493                if (parent.find('[name="mepmm_min_qty"]').length > 0) {
494                    let min_qty = parseInt(parent.find('[name="mepmm_min_qty"]').val());
495                    if (total_qty < min_qty) {
496                        alert('must buy minimum number of ticket : ' + min_qty);
497                    } else {
498                        mpwem_prepare_form_for_validation(parent);
499                        parent.find('.mpwem_add_to_cart').trigger('click');
500                    }
501                } else {
502                    mpwem_prepare_form_for_validation(parent);
503                    parent.find('.mpwem_add_to_cart').trigger('click');
504                }
505            } else {
506                alert('Please Select Ticket Type');
507                let currentTarget = $(this).closest('.mpwem_registration_area').find('[name="option_qty[]"]');
508                currentTarget.addClass('error');
509                return false;
510            }
511        }
512    });
513    /**
514     * Last line of defence before the booking is posted: whichever code path cloned the
515     * attendee blocks, the clone source must not reach the server and every real attendee
516     * control must. Without this the attendee answers can be posted one index out of step
517     * (see mpwem_attendee_management), which silently files each answer against the wrong
518     * attendee and loses the last attendee's answers altogether.
519     */
520    $(document).on('submit', 'form#mpwem_registration', function () {
521        $(this).find('.mep_attendee_info_hidden').find('input, select, textarea').prop('disabled', true);
522        mpwem_enable_attendee_clone($('.mep_attendee_info'));
523    });
524    $(document).on('change', '.mpwem_registration_area [name="event_extra_service_qty[]"]', function () {
525        let parent = $(this).closest('.mpwem_registration_area');
526        if (parent.find('[name="mepgq_max_ex_qty"]').length > 0) {
527            let qty = $(this).val();
528            let total_qty = mpwem_qty_ex(parent);
529            let max_qty_gq = parseInt(parent.find('[name="mepgq_max_ex_qty"]').val());
530            if (total_qty > max_qty_gq) {
531                qty = qty - total_qty + max_qty_gq;
532                $(this).val(qty);
533                mpwem_price_calculation(parent);
534            } else {
535                mpwem_price_calculation(parent);
536            }
537        } else {
538            mpwem_price_calculation(parent);
539        }
540    });
541    /************File Upload*************/
542    $(document).on('change', '.mep_form_item .mep_file_item input[type="file"]', function (e) {
543        let parent = $(this).closest('.mep_file_item');
544        let input = this;
545        let url = input.value;
546        let ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
547        if (input.files && input.files[0] && (ext === "gif" || ext === "png" || ext === "jpg" || ext === "pdf")) {
548            if (input.files[0].size <= 1024000) {
549                let reader = new FileReader();
550                reader.onload = function (e) {
551                    if (ext === "pdf") {
552                        parent.find('.attach_file_view img').slideUp(250);
553                        parent.find('.attach_file_view span').slide
553Up(250);
554                        parent.find('.attach_file_view iframe').attr('src', e.target.result).slideDown(250);
555                    } else {
556                        parent.find('.attach_file_view iframe').slideUp(250);
557                        parent.find('.attach_file_view span').slideUp(250);
558                        parent.find('.attach_file_view img').attr('src', e.target.result).slideDown(250);
559                    }
560                }
561                reader.readAsDataURL(input.files[0]);
562            } else {
563                alert('Maximum size 1MB');
564                parent.find('.attach_file_view img').slideUp(250);
565                parent.find('.attach_file_view span').slideDown(250);
566                parent.find('.attach_file_view iframe').slideUp(250);
567                $(this).val('');
568            }
569        } else {
570            parent.find('.attach_file_view img').slideUp(250);
571            parent.find('.attach_file_view span').slideDown(250);
572            parent.find('.attach_file_view iframe').slideUp(250);
573            $(this).val('');
574        }
575    });
576    /************conditional form*************/
577    function mep_get_condition_trigger_value($el) {
578        if ($el.is('select')) {
579            let $opt = $el.find('option:selected');
580            return ($opt.attr('data-target-child-id') || $el.val() || '').toString();
581        }
582        return ($el.val() || '').toString();
583    }
584
585    function mep_condition_value_matches(selected, expected) {
586        selected = (selected || '').toString().trim();
587        expected = (expected || '').toString().trim();
588        if (!expected) {
589            return false;
590        }
591        if (!selected) {
592            return false;
593        }
594        if (selected.indexOf(',') !== -1) {
595            return selected.split(',').map(function (part) {
596                return part.trim();
597            }).indexOf(expected) !== -1;
598        }
599        return selected === expected;
600    }
601
602    function mep_apply_field_conditions($trigger) {
603        let condition_id = $trigger.attr('data-target-condition-id');
604        if (!condition_id) {
605            return;
606        }
607        let selected_value = mep_get_condition_trigger_value($trigger);
608        // Scope to the attendee block (siblings), not the parent field wrapper.
609        let $scope = $trigger.closest('.mep_attendee_info, .mep_attendee_info_hidden');
610        if (!$scope.length) {
611            $scope = $trigger.closest('.mpwem_registration_area, .mpwem_style');
612        }
613        if (!$scope.length) {
614            $scope = $trigger.closest('form');
615        }
616        if (!$scope.length) {
617            $scope = jQuery(document);
618        }
619        $scope.find('[data-condition-id="' + condition_id + '"]').each(function () {
620            let $item = jQuery(this);
621            let depend = ($item.attr('data-depend') || '').toString();
622            if (depend === 'mep_ticket_type') {
623                return;
624            }
625            let condition_value = $item.attr('data-condition-value');
626            if (!condition_value) {
627                return;
628            }
629            if (mep_condition_value_matches(selected_value, condition_value)) {
630                $item.removeClass('dNone').stop(true, true).slideDown('fast');
631            } else {
632                $item.addClass('dNone').stop(true, true).slideUp('fast');
633            }
634        });
635    }
636
637    $(document).on('change', '.mep_form_item [data-target-condition-id]', function () {
638        mep_apply_field_conditions(jQuery(this));
639    });
640}(jQuery));
641//*****************************Related Event***********************************//
642(function ($) {
643    "use strict";
644    function mpwem_related_refresh_slider($slider) {
645        if (!$slider || !$slider.length || !$slider.hasClass('slick-initialized')) {
646            return;
647        }
648        // Clear list-template inline % widths so slick can own exact pixel widths.
649        $slider.find('.slick-slide, .filter_item.mep_event_card').each(function () {
650            var el = this;
651            if (el.style && el.style.width && String(el.style.width).indexOf('%') !== -1) {
652                el.style.removeProperty('width');
653            }
654        });
655        $slider.slick('setPosition');
656    }
657
658    $(document).ready(function () {
659        $('.mpwem_related_area').each(function () {
660            var $area = $(this);
661            var $slider = $area.find('.related_item');
662            if (!$slider.length || $slider.hasClass('slick-initialized')) {
663                return;
664            }
665
666            // Drop grid % widths before init so slides don't overflow / look cut.
667            $slider.find('.filter_item.mep_event_card, .mep-event-list-loop').each(function () {
668                this.style.removeProperty('width');
669            });
670
671            var slideCount = $slider.children('.filter_item, .mep-event-list-loop').length;
672            var desktopShow = Math.min(3, Math.max(1, slideCount));
673            var tabletShow = Math.min(2, desktopShow);
674            var mobileShow = 1;
675
676            $slider.slick({
677                dots: false,
678                arrows: true,
679                prevArrow: $area.find('.related_prev'),
680                nextArrow: $area.find('.related_next'),
681                infinite: slideCount > desktopShow,
682                centerMode: false,
683                variableWidth: false,
684                autoplay: false,
685                autoplaySpeed: 2000,
686                centerPadding: '0px',
687                slidesToShow: desktopShow,
688                slidesToScroll: 1,
689                responsive: [
690                    {
691                        breakpoint: 1024,
692                        settings: {
693                            slidesToShow: tabletShow,
694                            slidesToScroll: 1,
695                            infinite: slideCount > tabletShow,
696                            dots: false,
697                            centerMode: false,
698                            variableWidth: false
699                        }
700                    },
701                    {
702                        breakpoint: 767,
703                        settings: {
704                            slidesToShow: mobileShow,
705                            slidesToScroll: 1,
706                            infinite: slideCount > mobileShow,
707                            dots: false,
708                            centerMode: false,
709                            variableWidth: false
710                        }
711                    }
712                ]
713            }).promise().done(function () {
714                $area.removeClass('on_load_off');
715                mpwem_related_refresh_slider($slider);
716                // Re-apply lazy bg images after slick has real slide widths (incl. clones).
717                $slider.find('.mep_list_thumb [data-bg-image]').each(function () {
718                    var $img = $(this);
719                    var bg_url = $img.data('bg-image');
720                    if (!bg_url) {
721                        return;
722                    }
723                    if ($img.css('background-image') === 'none' || !$img.css('background-image')) {
724                        $img.css({
725                            'background-image': 'url("' + bg_url + '")',
726                            'background-size': 'cover',
727                            'background-position': 'center center',
728                            'background-repeat': 'no-repeat'
729                        });
730                    }
731                });
732                if (typeof mpwem_load_bg_image === 'function') {
733                    mpwem_load_bg_image();
734                }
735                // Recalc after fonts/images settle so the 3rd card isn't clipped.
736                setTimeout(function () {
737                    mpwem_related_refresh_slider($slider);
738                }, 50);
739                $(window).on('load.mpwemRelated', function () {
740                    mpwem_related_refresh_slider($slider);
741                });
742            });
743        });
744    });
745
746    $(window).on('resize.mpwemRelated', function () {
747        $('.mpwem_related_area .related_item.slick-initialized').each(function () {
748            mpwem_related_refresh_slider($(this));
749        });
750    });
751}(jQuery));
752//*****************************Event list***********************************//
753(function ($) {
754    "use strict";
755    $(document).on('click', 'button.mpwem_get_date_list', function () {
756        let $this = $(this);
757        let parent = $this.closest('.mpwem_list_date_list');
758        let target = parent.find('.date_list_area');
759        if (!target.length) {
760            return;
761        }
762        if (target.find('.date_item').length === 0) {
763            let event_id = $this.data('event-id');
764            if (!event_id) {
765                return;
766            }
767            jQuery.ajax({
768                type: 'POST',
769                url: mpwem_script_var.url,
770                data: {
771                    "action": "mpwem_get_date_list",
772                    "post_id": event_id,
773                    "nonce": mpwem_script_var.nonce
774                },
775                beforeSend: function () {
776                    mpwem_loader_xs($this);
777                },
778                success: function (data) {
779                    target.html(data);
780                    target.addClass('open_list mActive').show();
781                    mpwem_loader_remove($this);
782                }
783            });
784        }
785    });
786
787    $(document).on('click', 'button.mep_event_list_grid', function () {
788        let $this = $(this);
789        let parent = $this.closest('.list_with_filter_section');
790        let target = parent.find('.mage_grid_box');
791        let target_data = parent.find('.all_filter_item');
792let id=target_data.attr('data-unq-id');
793let style='grid';
794let column=target_data.attr('data-column');
795let cat=target_data.attr('data-cat');
796let org=target_data.attr('data-org');
797let tag=target_data.attr('data-tag');
798let city=target_data.attr('data-city');
799let country=target_data.attr('data-country');
800let status=target_data.attr('data-status');
801let year=target_data.attr('data-year');
802let sort=target_data.attr('data-sort');
803let show=target_data.attr('data-show');
804let pagination=target_data.attr('data-pagination');
805let pagination_style=target_data.attr('data-pagination-style');
806            jQuery.ajax({
807                type: 'POST',
808                url: mpwem_script_var.url,
809                data: {
810                    "action": "mep_gat_event_list_all",
811                    "id": id,
812                    "style": style,
813                    "column": column,
814                    "cat": cat,
815                    "org": org,
816                    "tag": tag,
817                    "city": city,
818                    "country": country,
819                    "status": status,
820                    "year": year,
821                    "sort": sort,
822                    "show": show,
823                    "pagination": pagination,
824                    "pagination_style": pagination_style,
825                    "nonce": mpwem_script_var.nonce
826                },
827                beforeSend: function () {
828                    showLoader();
829                },
830                success: function (data) {
831                    hideLoader();
832                    target.html(data);
833                    if (typeof mepCalendarInit === 'function') {
834                        mepCalendarInit();
835                    }
836                    target.find('[data-bg-image]:visible').each(function () {
837                        let target = jQuery(this);
838                        if (target.closest('.sliderAllItem').length === 0) {
839                            let width = target.outerWidth();
840                            let height = target.outerHeight();
841                            if (target.css('background-image') === 'none' || width === 0 || height === 0) {
842                                let bg_url = target.data('bg-image');
843                                if (!bg_url || bg_url.width === 0 || bg_url.width === 'undefined') {
844                                    bg_url = mpwem_empty_image_url;
845                                }
846                                mpwem_resize_bg_image_area(target, bg_url);
847                                target.css('background-image', 'url("' + bg_url + '")').promise().done(function () {
848                                    mpwem_loader_remove(jQuery(this));
849                                });
850                            }
851                        }
852
853                    });
854                    parent.find('.mep_event_list_grid').addClass('active');
855                    parent.find('.mep_event_list_list').removeClass('active');
856                    parent.find('.mep_event_list_calender').removeClass('active');
857                    if(parent.find('.mep_event_list_today').hasClass( 'active' )){
858                        parent.find('.mep_event_list_today').trigger('click');
859                    }
860                    if(parent.find('.mep_event_list_this_month').hasClass( 'active' )){
861                        parent.find('.mep_event_list_this_month').trigger('click');
862                    }
863                }
864            });
865
866    });
867    $(document).on('click', 'button.mep_event_list_list', function () {
868        let $this = $(this);
869        let parent = $this.closest('.list_with_filter_section');
870        let target = parent.find('.mage_grid_box');
871        let target_data = parent.find('.all_filter_item');
872let id=target_data.attr('data-unq-id');
873let style='list';
874let column=target_data.attr('data-column');
875let cat=target_data.attr('data-cat');
876let org=target_data.attr('data-org');
877let tag=target_data.attr('data-tag');
878let city=target_data.attr('data-city');
879let country=target_data.attr('data-country');
880let status=target_data.attr('data-status');
881let year=target_data.attr('data-year');
882let sort=target_data.attr('data-sort');
883let show=target_data.attr('data-show');
884let pagination=target_data.attr('data-pagination');
885let pagination_style=target_data.attr('data-pagination-style');
886            jQuery.ajax({
887                type: 'POST',
888                url: mpwem_script_var.url,
889                data: {
890                    "action": "mep_gat_event_list_all",
891                    "id": id,
892                    "style": style,
893                    "column": column,
894                    "cat": cat,
895                    "org": org,
896                    "tag": tag,
897                    "city": city,
898                    "country": country,
899                    "status": status,
900                    "year": year,
901                    "sort": sort,
902                    "show": show,
903                    "pagination": pagination,
904                    "pagination_style": pagination_style,
905                    "nonce": mpwem_script_var.nonce
906                },
907                beforeSend: function () {
908                    showLoader();
909                },
910                success: function (data) {
911                    hideLoader();
912                    target.html(data);
913                    target.find('[data-bg-image]:visible').each(function () {
914                        let target = jQuery(this);
915                        if (target.closest('.sliderAllItem').length === 0) {
916                            let width = target.outerWidth();
917                            let height = target.outerHeight();
918                            if (target.css('background-image') === 'none' || width === 0 || height === 0) {
919                                let bg_url = target.data('bg-image');
920                                if (!bg_url || bg_url.width === 0 || bg_url.width === 'undefined') {
921                                    bg_url = mpwem_empty_image_url;
922                                }
923                                mpwem_resize_bg_image_area(target, bg_url);
924                                target.css('background-image', 'url("' + bg_url + '")').promise().done(function () {
925                                    mpwem_loader_remove(jQuery(this));
926                                });
927                            }
928                        }
929
930                    });
931                    parent.find('.mep_event_list_list').addClass('active');
932                    parent.find('.mep_event_list_grid').removeClass('active');
933                    parent.find('.mep_event_list_calender').removeClass('active');
934                    if(parent.find('.mep_event_list_this_month').hasClass( 'active' )){
935                        parent.find('.mep_event_list_this_month').trigger('click');
936                    }
937                }
938            });
939
940    });
941    $(document).on('click', 'button.mep_event_list_calender', function () {
942        let $this = $(this);
943        let parent = $this.closest('.list_with_filter_section');
944        let target = parent.find('.mage_grid_box');
945        let target_data = parent.find('.all_filter_item');
946        let id=target_data.attr('data-unq-id');
947        let cat=target_data.attr('data-cat');
948        let org=target_data.attr('data-org');
949        let tag=target_data.attr('data-tag');
950        let city=target_data.attr('data-city');
951        let country=target_data.attr('data-country');
952        let status=target_data.attr('data-status');
953        let year=target_data.attr('data-year');
954            jQuery.ajax({
955                type: 'POST',
956                url: mpwem_script_var.url,
957                data: {
958                    "action": "mep_gat_event_calender",
959                    "nonce": mpwem_script_var.nonce,
960                    "cat": cat,
961                    "org": org,
962                    "tag": tag,
963                    "city": city,
964                    "country": country,
965                    "status": status,
966                    "year": year
967                },
968                beforeSend: function () {
969                    showLoader();
970                },
971                success: function (data) {
972                    hideLoader();
973                    target.html(data);
974                    target.find('[data-bg-image]:visible').each(function () {
975                        let target = jQuery(this);
976                        if (target.closest('.sliderAllItem').length === 0) {
977                            let width = target.outerWidth();
978                            let height = target.outerHeight();
979                            if (target.css('background-image') === 'none' || width === 0 || height === 0) {
980                                let bg_url = target.data('bg-image');
981                                if (!bg_url || bg_url.width === 0 || bg_url.width === 'undefined') {
982                                    bg_url = mpwem_empty_image_url;
983                                }
984                                mpwem_resize_bg_image_area(target, bg_url);
985                                target.css('background-image', 'url("' + bg_url + '")').promise().done(function () {
986                                    mpwem_loader_remove(jQuery(this));
987                                });
988                            }
989                        }
990
991                    });
992                    parent.find('.mep_event_list_list').removeClass('active');
993                    parent.find('.mep_event_list_grid').removeClass('active');
994                    parent.find('.mep_event_list_calender').addClass('active');
995                }
996            });
997
998    });
999
1000    $(document).on('click', 'button.mep_event_list_all', function () {
1001        let $this = $(this);
1002        let parent = $this.closest('.list_with_filter_section');
1003        let target = parent.find('.mage_grid_box');
1004        let target_data = parent.find('.all_filter_item');
1005        var items = jQuery('.mep-event-list-loop');
1006        items.each(function () {jQuery(this).show();});
1007        parent.find('.pagination_area').slideUp('fast');
1008        parent.find('.mep_event_list_all').addClass('active');
1009        parent.find('.mep_event_list_today').removeClass('active');
1010        parent.find('.mep_event_list_this_week').removeClass('active');
1011        parent.find('.mep_event_list_this_month').removeClass('active');
1012
1013    });
1014
1015    $(document).on('click', 'button.mep_event_list_today', function () {
1016        let $this = $(this);
1017        let parent = $this.closest('.list_with_filter_section');
1018        let target = parent.find('.mage_grid_box');
1019        let target_data = parent.find('.all_filter_item');
1020
1021        var items = jQuery('.mep-event-list-loop');
1022        let exit=0;
1023        items.each(function () {
1024            let today=$this.attr('data-today');
1025            var date = jQuery(this).data('date');
1026            let date1 = new Date(date);
1027            let date2 = new Date(date);
1028            if (date===today) {
1029                jQuery(this).show();
1030                exit=1;
1031            } else {
1032                jQuery(this).hide();
1033            }
1034        });
1035        if(exit===0){
1036            parent.find('.no_event_found').show();
1037        }else{
1038            parent.find('.no_event_found').hide();
1039        }
1040        parent.find('.pagination_area').slideUp('fast');
1041        parent.find('.mep_event_list_all').removeClass('active');
1042        parent.find('.mep_event_list_this_week').removeClass('active');
1043        parent.find('.mep_event_list_this_month').removeClass('active');
1044        parent.find('.mep_event_list_today').addClass('active');
1045    });
1046    $(document).on('click', 'button.mep_event_list_this_month', function () {
1047        let $this = $(this);
1048        let parent = $this.closest('.list_with_filter_section');
1049
1050        var items = jQuery('.mep-event-list-loop');
1051        let today = new Date();
1052        let year = today.getFullYear();
1053        let month = today.getMonth();
1054        let firstDay = new Date(year, month, 1);
1055        let lastDay = new Date(year, month + 1, 0);
1056        //alert(lastDay);
1057        let exit=0;
1058        items.each(function () {
1059            var date = jQuery(this).data('date');
1060            let date1 = new Date(date);
1061            if (date1 >= firstDay && date1 <= lastDay) {
1062                jQuery(this).show();
1063                exit=1;
1064            } else {
1065                jQuery(this).hide();
1066            }
1067        });
1068        if(exit===0){
1069            parent.find('.no_event_found').show();
1070        }else{
1071            parent.find('.no_event_found').hide();
1072        }
1073        parent.find('.pagination_area').slideUp('fast');
1074        parent.find('.mep_event_list_all').removeClass('active');
1075        parent.find('.mep_event_list_this_week').removeClass('active');
1076        parent.find('.mep_event_list_today').removeClass('active');
1077        parent.find('.mep_event_list_this_month').addClass('active');
1078    });
1079    $(document).on('click', 'button.mep_event_list_this_week', function () {
1080        let $this = $(this);
1081        let parent = $this.closest('.list_with_filter_section');
1082        let target = parent.find('.mage_grid_box');
1083        let target_data = parent.find('.all_filter_item');
1084
1085        var items = jQuery('.mep-event-list-loop');
1086        let exit=0;
1087        items.each(function () {
1088            let week=$this.attr('data-week');
1089            let today=parent.find('.mep_event_list_today').attr('data-today');
1090            var date = jQuery(this).data('date');
1091            let date1 = new Date(date);
1092            let date2 = new Date(today);
1093            let date3 = new Date(week);
1094            if (date1>=date2 && date1<=date3) {
1095                jQuery(this).show();
1096                exit=1;
1097            } else {
1098                jQuery(this).hide();
1099            }
1100        });
1101        if(exit===0){
1102            parent.find('.no_event_found').show();
1103        }else{
1104            parent.find('.no_event_found').hide();
1105        }
1106        parent.find('.pagination_area').slideUp('fast');
1107        parent.find('.mep_event_list_all').removeClass('active');
1108        parent.find('.mep_event_list_today').removeClass('active');
1109        parent.find('.mep_event_list_this_month').removeClass('active');
1110        parent.find('.mep_event_list_this_week').addClass('active');
1111    });
1112    $(document).on('change', 'input[name="filter_with_start_date"]', function (e) {
1113        e.preventDefault();
1114        let $this = $(this);
1115        let parent = $this.closest('.list_with_filter_section');
1116        let target = parent.find('.mage_grid_box');
1117        let target_data = parent.find('.all_filter_item');
1118        let start_date=$this.val();
1119        //alert(start_date);
1120        let end_date=parent.find('input[name="filter_with_end_date"]').val();
1121        let exit=0;
1122        if(start_date && end_date) {
1123            var items = jQuery('.mep-event-list-loop');
1124            items.each(function () {
1125                let week = $this.attr('data-week');
1126                let today = parent.find('.mep_event_list_today').attr('data-today');
1127                var date = jQuery(this).data('date');
1128                let date1 = new Date(date);
1129                let date2 = new Date(start_date);
1130                let date3 = new Date(end_date);
1131                if (date1 >= date2 && date1 <= date3) {
1132                    jQuery(this).show();
1133                    exit=1;
1134                } else {
1135                    jQuery(this).hide();
1136                }
1137            });
1138            if(exit===0){
1139                parent.find('.no_event_found').show();
1140            }else{
1141                parent.find('.no_event_found').hide();
1142            }
1143            parent.find('.pagination_area').slideUp('fast');
1144            parent.find('.mep_event_list_all').removeClass('active');
1145            parent.find('.mep_event_list_today').removeClass('active');
1146            parent.find('.mep_event_list_this_month').removeClass('active');
1147            parent.find('.mep_event_list_this_week').removeClass('active');
1148        }
1149    });
1150    $(document).on('change', 'input[name="filter_with_end_date"]', function (e) {
1151        e.preventDefault();
1152        let $this = $(this);
1153        let parent = $this.closest('.list_with_filter_section');
1154        let target = parent.find('.mage_grid_box');
1155        let target_data = parent.find('.all_filter_item');
1156        let start_date=parent.find('input[name="filter_with_start_date"]').val();
1157        let end_date=$this.val();
1158       // alert(end_date);
1159        let exit=0;
1160        if(start_date && end_date) {
1161            var items = jQuery('.mep-event-list-loop');
1162            items.each(function () {
1163                let week = $this.attr('data-week');
1164                let today = parent.find('.mep_event_list_today').attr('data-today');
1165                var date = jQuery(this).data('date');
1166                let date1 = new Date(date);
1167                let date2 = new Date(start_date);
1168                let date3 = new Date(end_date);
1169                if (date1 >= date2 && date1 <= date3) {
1170                    jQuery(this).show();
1171                    exit=1;
1172                } else {
1173                    jQuery(this).hide();
1174                }
1175            });
1176            if(exit===0){
1177                parent.find('.no_event_found').show();
1178            }else{
1179                parent.find('.no_event_found').hide();
1180            }
1181            parent.find('.pagination_area').slideUp('fast');
1182            parent.find('.mep_event_list_all').removeClass('active');
1183            parent.find('.mep_event_list_today').removeClass('active');
1184            parent.find('.mep_event_list_this_month').removeClass('active');
1185            parent.find('.mep_event_list_this_week').removeClass('active');
1186        }
1187    });
1188    // Advanced Filter Panel Toggle
1189    $(document).on('click', 'button.mep_event_list_filter_toggle', function () {
1190        let $this = $(this);
1191        let parent = $this.closest('.list_with_filter_section');
1192        let panel = parent.find('.mep_event_filter_panel');
1193        panel.slideToggle('fast');
1194        $this.toggleClass('active');
1195        // Initialize datepickers with event dates on first open
1196        if ( ! panel.data('datepicker-init') ) {
1197            let datesAttr = panel.attr('data-event-dates');
1198            let availableDates = [];
1199            try {
1200                availableDates = datesAttr ? JSON.parse(datesAttr) : [];
1201            } catch (e) {
1202                availableDates = [];
1203            }
1204            let $startDate = panel.find('input[name="filter_with_start_date"]');
1205            let $endDate   = panel.find('input[name="filter_with_end_date"]');
1206            function initDatepicker($el) {
1207                $el.datepicker('destroy');
1208                $el.datepicker({
1209                    dateFormat: 'mm/dd/yy',
1210                    beforeShowDay: function (date) {
1211                        let m = date.getMonth() + 1;
1212                        let d = date.getDate();
1213                        let y = date.getFullYear();
1214                        let dateStr = ('0' + m).slice(-2) + '/' + ('0' + d).slice(-2) + '/' + y;
1215                        if ( availableDates.indexOf(dateStr) !== -1 ) {
1216                            return [true, '', 'Available'];
1217                        }
1218                        return [false, '', 'Unavailable'];
1219                    },
1220                    onSelect: function (selectedDate) {
1221                        if ( $(this).attr('name') === 'filter_with_start_date' ) {
1222                            $endDate.datepicker('option', 'minDate', selectedDate);
1223                            $endDate.trigger('change');
1224                        } else if ( $(this).attr('name') === 'filter_with_end_date' ) {
1225                            $startDate.datepicker('option', 'maxDate', selectedDate);
1226                            $startDate.trigger('change');
1227                        }
1228                        //applyAllFilters();
1229                    }
1230                });
1231            }
1232            initDatepicker($startDate);
1233            initDatepicker($endDate);
1234            panel.data('datepicker-init', true);
1235        }
1236    });
1237
1238    // Clear All Filters
1239    $(document).on('click', 'button.mep_event_filter_clear', function () {
1240        let parent = $(this).closest('.mep_event_filter_panel');
1241        parent.find('input[name="filter_with_title"]').val('');
1242        parent.find('input[name="filter_with_start_date"]').val('');
1243        parent.find('input[name="filter_with_end_date"]').val('');
1244        parent.find('select[name="filter_with_category"]').val('');
1245        parent.find('select[name="filter_with_organizer"]').val('');
1246        parent.find('select[name="filter_with_city"]').val('');
1247        parent.find('select[name="filter_with_state"]').val('');
1248        // Also reset legacy single date filter if it exists
1249        parent.find('input[name="filter_with_date"]').val('');
1250        // Show all items
1251        jQuery('.mep-event-list-loop').each(function () {
1252            jQuery(this).show();
1253        });
1254        parent.find('.no_event_found').hide();
1255        // Update count display
1256        var totalItems = jQuery('.mep-event-list-loop').length;
1257        jQuery('.qty_count').text(totalItems);
1258    });
1259    $(document).on('click', 'button.mep_event_filter_close', function () {
1260        let $this = $(this);
1261        let parent = $this.closest('.list_with_filter_section');
1262        let panel = parent.find('.mep_event_filter_panel');
1263        panel.slideToggle('fast');
1264        $this.toggleClass('active');
1265        // Initialize datepickers with event dates on first open
1266        if ( ! panel.data('datepicker-init') ) {
1267            let datesAttr = panel.attr('data-event-dates');
1268            let availableDates = [];
1269            try {
1270                availableDates = datesAttr ? JSON.parse(datesAttr) : [];
1271            } catch (e) {
1272                availableDates = [];
1273            }
1274            let $startDate = panel.find('input[name="filter_with_start_date"]');
1275            let $endDate   = panel.find('input[name="filter_with_end_date"]');
1276            function initDatepicker($el) {
1277                $el.datepicker('destroy');
1278                $el.datepicker({
1279                    dateFormat: 'mm/dd/yy',
1280                    beforeShowDay: function (date) {
1281                        let m = date.getMonth() + 1;
1282                        let d = date.getDate();
1283                        let y = date.getFullYear();
1284                        let dateStr = ('0' + m).slice(-2) + '/' + ('0' + d).slice(-2) + '/' + y;
1285                        if ( availableDates.indexOf(dateStr) !== -1 ) {
1286                            return [true, '', 'Available'];
1287                        }
1288                        return [false, '', 'Unavailable'];
1289                    },
1290                    onSelect: function (selectedDate) {
1291                        if ( $(this).attr('name') === 'filter_with_start_date' ) {
1292                            $endDate.datepicker('option', 'minDate', selectedDate);
1293                            $endDate.trigger('change');
1294                        } else if ( $(this).attr('name') === 'filter_with_end_date' ) {
1295                            $startDate.datepicker('option', 'maxDate', selectedDate);
1296                            $startDate.trigger('change');
1297                        }
1298                        //applyAllFilters();
1299                    }
1300                });
1301            }
1302            initDatepicker($startDate);
1303            initDatepicker($endDate);
1304            panel.data('datepicker-init', true);
1305        }
1306    });
1307}(jQuery));
1308(function ($) {
1309    "use strict";
1310    //*****************************Faq***********************************//
1311    $(document).on('click', '.mep-event-faq-set > a', function () {
1312        let current = $(this);
1313        if (current.hasClass("active")) {
1314            current.removeClass("active");
1315            current.siblings(".mep-event-faq-content").slideUp(200);
1316            $(".mep-event-faq-set > a i").removeClass("fa-minus").addClass("fa-plus");
1317        } else {
1318            $(".mep-event-faq-set > a i").removeClass("fa-minus").addClass("fa-plus");
1319            current.find("i").removeClass("fa-plus").addClass("fa-minus");
1320            $(".mep-event-faq-set > a").removeClass("active");
1321            current.addClass("active");
1322            $(".mep-event-faq-content").slideUp(200);
1323            current.siblings(".mep-event-faq-content").slideDown(200);
1324        }
1325    });
1326}(jQuery));
1327(function ($) {
1328    $(document).on('click', 'button.mep_view_vr_btn', function () {
1329        $(this).closest('tr').next('tr.mep_virtual_event_info_sec').slideToggle('fast');
1330    });
1331    $(document).on('click', '.faq_items [data-collapse-target]', function () {
1332        $(this).find('i').toggleClass('fa-chevron-right fa-chevron-down');
1333    });
1334}(jQuery));
1335/******************** Remove below function after 2025**********************/
1336(function ($) {
1337    "use strict";
1338    $(document).on('click', '.mep-event-list-loop .mp_event_visible_event_time', function (e) {
1339        e.preventDefault();
1340        let target = $(this);
1341        $('.mep-event-list-loop .mp_event_visible_event_time').each(function () {
1342            let current = $(this).siblings('ul.mp_event_more_date_list');
1343            if (current.is(':visible')) {
1344                let active_text = $(this).data('active-text');
1345                $(this).html(active_text);
1346                current.slideUp(200);
1347            }
1348        }).promise().done(function () {
1349            let current_list = target.siblings('ul.mp_event_more_date_list');
1350            if (current_list.length > 0) {
1351                if (current_list.is(':visible')) {
1352                    current_list.slideUp(200);
1353                    target.html(target.data('active-text'));
1354                } else {
1355                    current_list.slideDown(200);
1356                    target.html(target.data('hide-text'));
1357                }
1358            } else {
1359                let event_id = target.data('event-id');
1360                $.ajax({
1361                    type: 'POST',
1362                    url: mpwem_ajax_url,
1363                    data: {"action": "mep_event_list_date_schedule", "event_id": event_id},
1364                    beforeSend: function () {
1365                        target.html('<span class="fas fa-spinner fa-pulse"></span>');
1366                    },
1367                    success: function (data) {
1368                        $(data).insertAfter(target);
1369                        target.html(target.data('hide-text'));
1370                    }
1371                });
1372            }
1373        });
1374    });
1375}(jQuery));
1376
1377
1378function showLoader() {
1379    const loader = document.getElementById('loader-overlay');
1380    loader.classList.add('active');
1381}
1382
1383function hideLoader() {
1384    const loader = document.getElementById('loader-overlay');
1385    loader.classList.remove('active');
1386}
1387// DatePicker Function
1388jQuery(document).ready(function ($) {
1389
1390    if (typeof mpwemDateData === 'undefined') {
1391        return;
1392    }
1393
1394    let selector       = mpwemDateData.selector;
1395    let availableDates = mpwemDateData.availableDates;
1396    let minDateData    = mpwemDateData.minDate;
1397    let maxDateData    = mpwemDateData.maxDate;
1398
1399    $(selector).datepicker({
1400
1401        dateFormat: mpwem_date_format,
1402
1403        minDate: new window.Date(
1404            minDateData.year,
1405            minDateData.month,
1406            minDateData.day
1407        ),
1408
1409        maxDate: new window.Date(
1410            maxDateData.year,
1411            maxDateData.month,
1412            maxDateData.day
1413        ),
1414
1415        autoSize: true,
1416        changeMonth: true,
1417        changeYear: true,
1418
1419        beforeShowDay: function (date) {
1420
1421            let d = date.getDate();
1422            let m = date.getMonth() + 1;
1423            let y = date.getFullYear();
1424
1425            let dmy = d + "-" + m + "-" + y;
1426
1427            if ($.inArray(dmy, availableDates) !== -1) {
1428                return [true, "", "Available"];
1429            }
1430
1431            return [false, "", "Unavailable"];
1432        },
1433        onSelect: function (dateText, data) {
1434
1435            let date = data.selectedYear + '-' +
1436                ('0' + (parseInt(data.selectedMonth) + 1)).slice(-2) + '-' +
1437                ('0' + parseInt(data.selectedDay)).slice(-2);
1438
1439            $(this)
1440                .closest('label')
1441                .find('input[type="hidden"]')
1442                .val(date)
1443                .trigger('change');
1444        }
1445
1446    });
1447
1448});
1449
1450
1451document.querySelectorAll('li').forEach(function(li) {
1452    // চেক করুন এই li তে price আছে কিনা
1453    if (li.querySelector('.woocommerce-Price-amount')) {
1454        let strong = li.querySelector('.wc-item-meta-label');
1455
1456        if (strong) {
1457            // strong element এর ভিতরের সব child nodes চেক করুন
1458            strong.childNodes.forEach(function(node) {
1459                // চেক করুন এটি text node কিনা
1460                if (node.nodeType === Node.TEXT_NODE) {
1461                    // সব text node থেকে : এবং - রিমুভ করে স্পেস দিন
1462                    node.textContent = node.textContent.replace(/[:-]/g, '  ');
1463
1464                    // অতিরিক্ত স্পেস কমাতে চাইলে (optional)
1465                    //node.textContent = node.textContent.replace(/\s+/g, ' ').trim();
1466                }
1467            });
1468        }
1469    }
1470});
1471
1472
1473(function ($) {
1474    "use strict";
1475    $(document).on('submit', '#mpwem_registration', function(e) {
1476        if ($(this).find('.mep-rsvp-submit-btn').length === 0) {
1477            return;
1478        }
1479        e.preventDefault();
1480        const $form = $(this);
1481        const $btn = $form.find('.mep-rsvp-submit-btn');
1482        const $msg = $form.find('.mep-rsvp-message');
1483
1484        $btn.prop('disabled', true).find('span').text('Submitting...');
1485        $msg.hide().removeClass('success error');
1486
1487        $.ajax({
1488            url: mpwem_script_var ? mpwem_script_var.url : mpwem_ajax_url,
1489            type: 'POST',
1490            data: $form.serialize(),
1491            success: function(response) {
1492                if (response.success) {
1493                    $msg.text(response.data.message).addClass('success').show();
1494                    $form.find('input[type="text"], input[type="email"]').val('');
1495                    $form.find('input[type="number"]').val(1);
1496                } else {
1497                    const errorMsg = response.data && response.data.message ? response.data.message : 'An error occurred. Please try again.';
1498                    $msg.text(errorMsg).addClass('error').show();
1499                }
1500            },
1501            error: function() {
1502                $msg.text('Connection error. Please try again.').addClass('error').show();
1503            },
1504            complete: function() {
1505                $btn.prop('disabled', false).find('span').text('Submit RSVP');
1506            }
1507        });
1508    });
1509}(jQuery));
1510
1511/* ============================================================
1512 * Enquiry ("query") form — Announcement-mode events.
1513 * Posts to wp_ajax_mep_submit_enquiry (MPWEM_Hooks::mep_submit_enquiry).
1514 * Deliberately its own <form>, so it never collides with the RSVP handler
1515 * bound to #mpwem_registration above.
1516 * ============================================================ */
1517(function ($) {
1518    "use strict";
1519    $(document).on('submit', '.mpwem_enquiry_form', function (e) {
1520        e.preventDefault();
1521
1522        var $form = $(this);
1523        if ($form.data('mpwemEnquirySubmitting')) {
1524            return;
1525        }
1526
1527        var $btn = $form.find('.mpwem_enquiry_submit_btn');
1528        var $label = $btn.find('span');
1529        var $msg = $form.find('.mpwem_enquiry_message');
1530        var originalLabel = $label.text();
1531
1532        // Let the browser surface its own messages for required/typed fields first.
1533        if (this.checkValidity && !this.checkValidity()) {
1534            this.reportValidity && this.reportValidity();
1535            return;
1536        }
1537
1538        $form.data('mpwemEnquirySubmitting', true);
1539        $btn.prop('disabled', true);
1540        $label.text($btn.data('sending-text') || 'Sending...');
1541        $msg.hide().removeClass('success error').text('');
1542
1543        $.ajax({
1544            url: (typeof mpwem_script_var !== 'undefined' && mpwem_script_var.url) ? mpwem_script_var.url : (typeof mpwem_ajax_url !== 'undefined' ? mpwem_ajax_url : ''),
1545            type: 'POST',
1546            data: $form.serialize(),
1547            success: function (response) {
1548                if (response && response.success) {
1549                    $msg.text(response.data.message).addClass('success').show();
1550                    $form.find('input[type="text"], input[type="email"], textarea').val('');
1551                } else {
1552                    var errorMsg = (response && response.data && response.data.message)
1553                        ? response.data.message
1554                        : 'An error occurred. Please try again.';
1555                    $msg.text(errorMsg).addClass('error').show();
1556                }
1557            },
1558            error: function () {
1559                $msg.text('Connection error. Please try again.').addClass('error').show();
1560            },
1561            complete: function () {
1562                $form.data('mpwemEnquirySubmitting', false);
1563                $btn.prop('disabled', false);
1564                $label.text(originalLabel);
1565            }
1566        });
1567    });
1568}(jQuery));
1569
1570/* ============================================================
1571 * Native Checkout — runs when WooCommerce is not active.
1572 * Intercepts mpwem_book_now clicks and shows the billing modal.
1573 * ============================================================ */
1574(function ($) {
1575    'use strict';
1576
1577    // sessionStorage key prefix used to persist a booking intent across a login redirect.
1578    var PENDING_BOOKING_PREFIX = 'mep_pending_booking_';
1579
1580    // Helper: resolve the selected occurrence's full date AND time for native checkout.
1581    // The hidden mep_event_start_date field can collapse to a date-only value (saved as
1582    // "Y-m-d 00:00") for recurring events that have several times per day, which loses the
1583    // chosen time slot. The date/time selectors always carry the full datetime, so prefer
1584    // them: mpwem_time (date + time-slot) > mpwem_date_time (occurrence) > mep_event_start_date.
1585    // This is native-only and deliberately does not touch the shared $user_date logic used
1586    // by the WooCommerce flow.
1587    function mepResolveEventDate(parent) {
1588        var candidates = [
1589            parent.find('[name="mpwem_time"]').val(),
1590            parent.find('[name="mpwem_date_time"]').val(),
1591            parent.find('[name="mep_event_start_date[]"]').first().val()
1592        ];
1593        // Prefer the first candidate that includes a time component.
1594        for (var i = 0; i < candidates.length; i++) {
1595            var v = $.trim(candidates[i] || '');
1596            if (v && v.indexOf(':') !== -1) { return v; }
1597        }
1598        // No time component anywhere (genuinely date-only event) — use the first value present.
1599        for (var j = 0; j < candidates.length; j++) {
1600            var v2 = $.trim(candidates[j] || '');
1601            if (v2) { return v2; }
1602        }
1603        return '';
1604    }
1605
1606    // Helper: HTML-escape a string for safe insertion into the summary markup.
1607    function mepNativeEsc(str) {
1608        return $('<span>').text(str == null ? '' : String(str)).html();
1609    }
1610
1611    // Helper: present the resolved event datetime, dropping a meaningless midnight time
1612    // (e.g. "2026-07-22 00:00" → "2026-07-22") so only real times are shown.
1613    function mepNativeFormatEventDate(raw) {
1614        raw = $.trim(raw || '');
1615        if (!raw) { return ''; }
1616        return raw.replace(/\s+00:00(:00)?$/, '');
1617    }
1618
1619    // Helper: collect ticket data from the registration form
1620    function mepCollectTickets(parent) {
1621        var tickets = [];
1622        parent.find('[name="option_qty[]"]').each(function () {
1623            var qty = parseInt($(this).val()) || 0;
1624            if (qty <= 0) return;
1625            var price = parseFloat($(this).attr('data-price')) || 0;
1626            var $item = $(this).closest('.mep_ticket_item, .mpwem_ticket_row');
1627            var name  = $item.find('[name="option_name[]"]').val()
1628                     || $item.find('[name="ticket_type[]"]').val()
1629                     || 'Ticket';
1630            tickets.push({ ticket_name: name, ticket_qty: qty, ticket_price: price });
1631        });
1632        return tickets;
1633    }
1634
1635    // Helper: collect form-builder attendee fields (rendered as name="field[]") into a plain object
1636    function mepCollectAttendeeFields(parent) {
1637        var fields = {};
1638        parent.find('.mep_attendee_info [name$="[]"], .mep_attendee_info_hidden [name$="[]"]').each(function () {
1639            var $field = $(this);
1640            if ($field.attr('type') === 'file') {
1641                return;
1642            }
1643            var name = ($field.attr('name') || '').replace(/\[\]$/, '');
1644            if (name) {
1645                fields[name] = $field.val();
1646            }
1647        });
1648        return fields;
1649    }
1650
1651    // Helper: restore previously-selected ticket quantities (used after a login redirect)
1652    function mepRestoreTickets(parent, tickets) {
1653        if (!Array.isArray(tickets)) {
1654            return;
1655        }
1656        tickets.forEach(function (t) {
1657            parent.find('[name="option_qty[]"]').each(function () {
1658                var $qty  = $(this);
1659                var $item = $qty.closest('.mep_ticket_item, .mpwem_ticket_row');
1660                var name  = $item.find('[name="option_name[]"]').val()
1661                         || $item.find('[name="ticket_type[]"]').val();
1662                if (name === t.ticket_name) {
1663                    $qty.val(t.ticket_qty).trigger('change');
1664                }
1665            });
1666        });
1667    }
1668
1669    // Helper: restore previously-entered attendee form fields (used after a login redirect)
1670    function mepRestoreAttendeeFields(parent, fields) {
1671        if (!fields) {
1672            return;
1673        }
1674        Object.keys(fields).forEach(function (name) {
1675            parent.find('.mep_attendee_info [name="' + name + '[]"], .mep_attendee_info_hidden [name="' + name + '[]"]')
1676                .val(fields[name]);
1677        });
1678    }
1679
1680    // Helper: format a number as currency using the JS constants set by php
1681    function mepNativeFormatPrice(amount) {
1682        if (typeof mpwem_price_format === 'function') {
1683            return mpwem_price_format(amount);
1684        }
1685        var symbol   = (typeof mpwem_currency_symbol !== 'undefined')   ? mpwem_currency_symbol   : '$';
1686        var position = (typeof mpwem_currency_position !== 'undefined') ? mpwem_currency_position : 'left';
1687        var decimals = (typeof mpwem_num_of_decimal !== 'undefined')    ? parseInt(mpwem_num_of_decimal) : 2;
1688        var fixed    = parseFloat(amount).toFixed(decimals);
1689        switch (position) {
1690            case 'right':       return fixed + symbol;
1691            case 'left_space':  return symbol + ' ' + fixed;
1692            case 'right_space': return fixed + ' ' + symbol;
1693            default:            return symbol + fixed;
1694        }
1695    }
1696
1697    // Open the native checkout modal, pre-populated with ticket summary
1698    function mepOpenNativeModal(parent) {
1699        var tickets  = mepCollectTickets(parent);
1700        if (!tickets.length) {
1701            alert('Please Select Ticket Type');
1702            return;
1703        }
1704
1705        var total = 0;
1706        var summaryHtml = '';
1707        tickets.forEach(function (t) {
1708            var lineTotal = t.ticket_price * t.ticket_qty;
1709            total += lineTotal;
1710            summaryHtml += '<div class="mep-ticket-summary-row">'
1711                + '<div class="mep-tsr-info">'
1712                +   '<span class="mep-tsr-name">' + mepNativeEsc(t.ticket_name) + '</span>'
1713                +   '<span class="mep-tsr-sub">' + mepNativeEsc(String(t.ticket_qty)) + ' &times; ' + mepNativeFormatPrice(t.ticket_price) + '</span>'
1714                + '</div>'
1715                + '<span class="mep-tsr-total">' + mepNativeFormatPrice(lineTotal) + '</span>'
1716                + '</div>';
1717        });
1718
1719        var $modal    = $('#mep-native-checkout-modal');
1720        var eventDate = mepResolveEventDate(parent);
1721
1722        $modal.find('#mep-native-ticket-summary').html(summaryHtml);
1723        $modal.find('#mep-native-total-display').text(mepNativeFormatPrice(total));
1724
1725        // Event datetime line (hide the time when it's a meaningless midnight value).
1726        var dtText = mepNativeFormatEventDate(eventDate);
1727        var $dt    = $modal.find('#mep-native-event-datetime');
1728        if (dtText) { $dt.text(dtText).show(); } else { $dt.text('').hide(); }
1729        $modal.find('#mep-native-ticket-data').val(JSON.stringify(tickets));
1730        $modal.find('#mep-native-event-date').val(eventDate);
1731        $modal.find('#mep-native-checkout-msg').hide().removeClass('success error').text('');
1732
1733        // Collect attendee field values from the main registration form so they are
1734        // saved with the order even though the fields are not shown inside this modal.
1735        // Only take the first occurrence of each field name (handles multi-ticket layouts
1736        // where the same attendee form is cloned once per ticket row).
1737        // Collect the registration-form fields once per seat, mirroring the WooCommerce
1738        // flow: each field posts as an array indexed by the global seat order and the server
1739        // builds one attendee per seat from it. Only the visible per-seat forms
1740        // (.mep_attendee_info) are read — never the hidden clone template.
1741        var attendeeFieldArrays = {};   // field name -> [value per seat] (submitted to the server)
1742        var fieldOrder  = [];           // field names, in display order
1743        var fieldLabels = {};           // field name -> human label
1744        var fieldTypes  = {};           // field name -> input type
1745        parent.find('.mep_attendee_info [data-field-name][data-d-name]').each(function () {
1746            var $inp  = $(this);
1747            var fname = $inp.data('field-name');
1748            var type  = ($inp.attr('type') || '').toLowerCase();
1749            if (!fname || type === 'file') {
1750                return;
1750 // file uploads are not supported in native checkout
1751            }
1752            (attendeeFieldArrays[fname] = attendeeFieldArrays[fname] || []).push($.trim($inp.val()));
1753            if (!fieldLabels.hasOwnProperty(fname)) {
1754                fieldOrder.push(fname);
1755                fieldTypes[fname]  = type;
1756                fieldLabels[fname] = $.trim($inp.closest('.mp_form_item').find('label span').first().text().replace(/\*+\s*$/, ''))
1757                                  || $.trim($inp.attr('placeholder') || '')
1758                                  || fname;
1759            }
1760        });
1761        $modal.find('#mep-native-attendee-snapshot').val(JSON.stringify(attendeeFieldArrays));
1762
1763        // Build a compact, per-attendee preview of the registration details.
1764        var seatCount = 0;
1765        fieldOrder.forEach(function (f) { seatCount = Math.max(seatCount, attendeeFieldArrays[f].length); });
1766        var detailsHtml = '';
1767        for (var s = 0; s < seatCount; s++) {
1768            var rows = '';
1769            fieldOrder.forEach(function (fname) {
1770                if (fieldTypes[fname] === 'hidden') { return; }
1771                var v = attendeeFieldArrays[fname][s];
1772                v = (v == null) ? '' : $.trim(v);
1773                if (!v) { return; }
1774                rows += '<div class="mep-native-detail-row">'
1775                    + '<span class="mep-ndr-label">' + mepNativeEsc(fieldLabels[fname]) + '</span>'
1776                    + '<span class="mep-ndr-value">' + mepNativeEsc(v) + '</span>'
1777                    + '</div>';
1778            });
1779            if (rows) {
1780                var heading = seatCount > 1 ? ('Attendee ' + (s + 1)) : 'Registration Details';
1781                detailsHtml += '<div class="mep-native-attendee-block">'
1782                    + '<div class="mep-native-detail-title">' + mepNativeEsc(heading) + '</div>'
1783                    + rows + '</div>';
1784            }
1785        }
1786
1787        var $details = $modal.find('#mep-native-attendee-details');
1788        if (detailsHtml) {
1789            $details.html(detailsHtml).show();
1790        } else {
1791            $details.empty().hide();
1792        }
1793
1794        // Prefill the billing form from the event's attendee name/email/phone fields
1795        // (when present) so the user doesn't retype them.
1796        var preBilling = { name: '', email: '', phone: '' };
1797        parent.find('[data-field-name][data-d-name]').each(function () {
1798            var dname = $(this).data('d-name');
1799            var val   = $.trim($(this).val());
1800            if (!val) { return; }
1801            if (dname === 'ea_name'  && !preBilling.name)  { preBilling.name  = val; }
1802            if (dname === 'ea_email' && !preBilling.email) { preBilling.email = val; }
1803            if (dname === 'ea_phone' && !preBilling.phone) { preBilling.phone = val; }
1804        });
1805        if (preBilling.name)  { $modal.find('#mep-native-billing-name').val(preBilling.name); }
1806        if (preBilling.email) { $modal.find('#mep-native-billing-email').val(preBilling.email); }
1807        if (preBilling.phone) { $modal.find('#mep-native-billing-phone').val(preBilling.phone); }
1808
1809        // When login is required to complete checkout, persist the ticket selection so it can
1810        // be restored once the user logs in and is redirected back to this page.
1811        if ($modal.find('.mep-native-login-required').length && window.sessionStorage) {
1812            var eventId = $modal.find('#mep-native-event-id').val();
1813            if (eventId) {
1814                try {
1815                    sessionStorage.setItem(PENDING_BOOKING_PREFIX + eventId, JSON.stringify({
1816                        tickets:   tickets,
1817                        eventDate: eventDate
1818                    }));
1819                } catch (e) {}
1820            }
1821        }
1822
1823        $modal.css('display', 'flex').hide().fadeIn(200);
1824    }
1825
1826    // Intercept book-now when native mode is present
1827    $(document).on('click', '.mpwem_book_now', function () {
1828        var parent = $(this).closest('.mpwem_registration_area');
1829        if (!parent.find('.mpwem_native_checkout_trigger').length) {
1830            return; // WooCommerce mode — let the existing handlers work
1831        }
1832        var totalQty = 0;
1833        parent.find('[name="option_qty[]"]').each(function () {
1834            totalQty += parseInt($(this).val()) || 0;
1835        });
1836        if (totalQty <= 0) {
1837            parent.find('[name="option_qty[]"]').addClass('error');
1838            return;
1839        }
1840        parent.find('[name="option_qty[]"]').removeClass('error');
1841        mepOpenNativeModal(parent);
1842    });
1843
1844    // Close modal
1845    $(document).on('click', '.mep-native-modal-close', function () {
1846        $('#mep-native-checkout-modal').fadeOut(200);
1847    });
1848    $(document).on('click', '#mep-native-checkout-modal', function (e) {
1849        if ($(e.target).is('#mep-native-checkout-modal')) {
1850            $(this).fadeOut(200);
1851        }
1852    });
1853    $(document).on('keydown', function (e) {
1854        if (e.key === 'Escape') {
1855            $('#mep-native-checkout-modal').fadeOut(200);
1856        }
1857    });
1858
1859    // Submit native checkout
1860    $(document).on('click', '#mep-native-confirm-btn', function () {
1861        var $btn       = $(this);
1862        var $modal     = $('#mep-native-checkout-modal');
1863        var $msg       = $modal.find('#mep-native-checkout-msg');
1864        var eventId    = $modal.find('#mep-native-event-id').val();
1865        var nonce      = $modal.find('#mep-native-nonce').val();
1866        var ticketData = $modal.find('#mep-native-ticket-data').val();
1867        var eventDate  = $modal.find('#mep-native-event-date').val();
1868        var payMethod  = $modal.find('[name="mep_payment_method"]:checked').val() || 'offline';
1869
1870        $msg.hide().removeClass('success error').text('');
1871
1872        // Read the attendee field snapshot collected from the main form when the modal opened.
1873        var attendeeFields = {};
1874        var billingName  = '';
1875        var billingEmail = '';
1876        var billingPhone = '';
1877        try {
1878            var snapshotRaw = $modal.find('#mep-native-attendee-snapsh
1878ot').val();
1879            if (snapshotRaw) {
1880                attendeeFields = JSON.parse(snapshotRaw) || {};
1881            }
1882        } catch (e) {}
1883
1884        // Read billing details from the modal's billing form (all fields required).
1885        var $bName = $modal.find('#mep-native-billing-name');
1886        if ($bName.length) {
1887            var $bEmail = $modal.find('#mep-native-billing-email');
1888            var $bPhone = $modal.find('#mep-native-billing-phone');
1889            billingName  = $.trim($bName.val()  || '');
1890            billingEmail = $.trim($bEmail.val() || '');
1891            billingPhone = $.trim($bPhone.val() || '');
1892
1893            $modal.find('.mep-native-input').removeClass('mep-native-input-error');
1894            var missing = [];
1895            if (!billingName)  { missing.push($bName); }
1896            if (!billingEmail) { missing.push($bEmail); }
1897            if (!billingPhone) { missing.push($bPhone); }
1898            if (missing.length) {
1899                missing.forEach(function ($f) { $f.addClass('mep-native-input-error'); });
1900                $msg.text('Please fill in all billing details (name, email and phone).').addClass('error').show();
1901                return;
1902            }
1903        } else {
1904            // Fallback (older template): derive billing from the first attendee's fields.
1905            $('.mpwem_registration_area').find('.mep_attendee_info [data-field-name][data-d-name]').each(function () {
1906                var $inp  = $(this);
1907                var fname = $inp.data('field-name');
1908                var dname = $inp.data('d-name');
1909                var v = attendeeFields[fname];
1910                if (Array.isArray(v)) { v = v[0]; }
1911                if (v === undefined) { return; }
1912                if (dname === 'ea_name'  && !billingName)  billingName  = v;
1913                if (dname === 'ea_email' && !billingEmail) billingEmail = v;
1914                if (dname === 'ea_phone' && !billingPhone) billingPhone = v;
1915            });
1916        }
1917
1918        if (billingEmail && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(billingEmail)) {
1919            $modal.find('#mep-native-billing-email').addClass('mep-native-input-error');
1920            $msg.text('Please enter a valid email address.').addClass('error').show();
1921            return;
1922        }
1923
1924        $btn.prop('disabled', true)
1925            .find('.mep-native-btn-text').hide().end()
1926            .find('.mep-native-btn-loading').show();
1927
1928        var ajaxUrl = (typeof mpwem_script_var !== 'undefined' && mpwem_script_var.url)
1929            ? mpwem_script_var.url
1930            : (typeof mpwem_ajax_url !== 'undefined' ? mpwem_ajax_url : '/wp-admin/admin-ajax.php');
1931
1932        $.ajax({
1933            url: ajaxUrl,
1934            type: 'POST',
1935            data: {
1936                action:         'mep_native_checkout',
1937                nonce:          nonce,
1938                event_id:       eventId,
1939                billing_name:    billingName,
1940                billing_email:   billingEmail,
1941                billing_phone:   billingPhone,
1942                event_date:      eventDate,
1943                ticket_data:     ticketData,
1944                attendee_fields: JSON.stringify(attendeeFields),
1945                payment_method: payMethod
1946            },
1947            success: function (response) {
1948                if (response.success) {
1949                    // Booking succeeded — clear any persisted intent for this event.
1950                    if (window.sessionStorage) {
1951                        try { sessionStorage.removeItem(PENDING_BOOKING_PREFIX + eventId); } catch (e) {}
1952                    }
1953                    $msg.text(response.data.message).addClass('success').show();
1954                    // Gateway redirect (PayPal, Stripe) — go immediately, no delay
1955                    if (response.data.requires_redirect && response.data.redirect) {
1956                        window.location.href = response.data.redirect;
1957                    } else {
1958                        // Free / offline — show success message then redirect to confirmation page
1959                        setTimeout(function () {
1960                            if (response.data.redirect) {
1961                                window.location.href = response.data.redirect;
1962                            } else {
1963                                $modal.fadeOut(300);
1964                            }
1965                        }, 1800);
1966                    }
1967                } else {
1968                    var errMsg = (response.data && response.data.message)
1969                        ? response.data.message
1970                        : 'An error occurred. Please try again.';
1971                    $msg.text(errMsg).addClass('error').show();
1972                    $btn.prop('disabled', false)
1973                        .find('.mep-native-btn-text').show().end()
1974                        .find('.mep-native-btn-loading').hide();
1975                }
1976            },
1977            error: function () {
1978                $msg.text('Connection error. Please try again.').addClass('error').show();
1979                $btn.prop('disabled', false)
1980                    .find('.mep-native-btn-text').show().end()
1981                    .find('.mep-native-btn-loading').hide();
1982            }
1983        });
1984    });
1985
1986    // Restore a booking intent persisted before a login redirect, then reopen the modal.
1987    $(function () {
1988        if (typeof mpwem_script_var === 'undefined' || mpwem_script_var.is_logged_in !== '1' || !window.sessionStorage) {
1989            return;
1990        }
1991        $('.mpwem_registration_area').each(function () {
1992            var $area   = $(this);
1993            var eventId = $area.find('#mep-native-event-id').val();
1994            if (!eventId) {
1995                return;
1996            }
1997            var raw = sessionStorage.getItem(PENDING_BOOKING_PREFIX + eventId);
1998            if (!raw) {
1999                return;
2000            }
2001            sessionStorage.removeItem(PENDING_BOOKING_PREFIX + eventId);
2002            var pending;
2003            try {
2004                pending = JSON.parse(raw);
2005            } catch (e) {
2006                return;
2007            }
2008            mepRestoreTickets($area, pending.tickets);
2009            mepRestoreAttendeeFields($area, pending.attendeeFields);
2010            mepOpenNativeModal($area);
2011        });
2012    });
2013
2014}(jQuery));
2015
2016//*****************************Description Read More***********************************//
2017(function ($) {
2018    "use strict";
2019
2020    function mpwemCountWords(text) {
2021        var trimmed = (text || '').replace(/\s+/g, ' ').trim();
2022        if (!trimmed) {
2023            return 0;
2024        }
2025        return trimmed.split(' ').length;
2026    }
2027
2028    function mpwemGetDescriptionOverflow(content, limit) {
2029        var count = 0;
2030        var reached = false;
2031        var overflow = [];
2032
2033        $(content).contents().each(function () {
2034            if (reached) {
2035                if (this.nodeType === 1) {
2036                    overflow.push(this);
2037                }
2038                return;
2039            }
2040
2041            count += mpwemCountWords(this.textContent || '');
2042            if (count >= limit) {
2043                reached = true;
2044            }
2045        });
2046
2047        return overflow;
2048    }
2049
2050    function mpwemInitDetailsReadMore() {
2051        $('.mpwem_details--has-readmore').each(function () {
2052            var $wrap = $(this);
2053            if ($wrap.data('readmore-ready')) {
2054                return;
2055            }
2056
2057            var $content = $wrap.find('.mpwem_details_content').first();
2058            var $button = $wrap.find('.mpwem_details_readmore').first();
2059            if (!$content.length || !$button.length) {
2060                return;
2061            }
2062
2063            var limit = parseInt($wrap.attr('data-readmore-words'), 10) || 200;
2064            var wordCount = mpwemCountWords($content.text());
2065
2066            if (wordCount <= limit) {
2067                $content.removeClass('is-collapsed');
2068                $button.remove();
2069                $wrap.removeClass('mpwem_details--has-readmore');
2070                $wrap.data('readmore-ready', true);
2071                return;
2072            }
2073
2074            var overflow = mpwemGetDescriptionOverflow($content.get(0), limit);
2075            if (!overflow.length) {
2076                $button.remove();
2077                $wrap.removeClass('mpwem_details--has-readmore');
2078                $wrap.data('readmore-ready', true);
2079                return;
2080            }
2081
2082            $(overflow).addClass('mpwem_details_readmore__overflow');
2083            $content.addClass('is-collapsed');
2084            $wrap.addClass('is-collapsed').data('readmore-ready', true);
2085        });
2086    }
2087
2088    function mpwemInitSpeakerRoleReadMore() {
2089        $(document).on('click', '[data-mep-speaker-role-toggle]', function (e) {
2090            e.preventDefault();
2091            e.stopPropagation();
2092
2093            var $button = $(this);
2094            var $wrap = $button.closest('[data-mep-speaker-role]');
2095            var $text = $wrap.find('.mep-default-speaker__role-text').first();
2096            if (!$wrap.length || !$text.length) {
2097                return;
2098            }
2099
2100            var expanded = $wrap.hasClass('is-expanded');
2101            var shortText = $text.attr('data-short') || '';
2102            var fullText = $text.attr('data-full') || '';
2103
2104            if (expanded) {
2105                $text.text(shortText + '…');
2106                $wrap.removeClass('is-expanded').addClass('is-collapsed');
2107                $button.attr('aria-expanded', 'false');
2108            } else {
2109                $text.text(fullText);
2110                $wrap.addClass('is-expanded').removeClass('is-collapsed');
2111                $button.attr('aria-expanded', 'true');
2112            }
2113        });
2114    }
2115
2116    $(document).ready(function () {
2117        mpwemInitDetailsReadMore();
2118        mpwemInitSpeakerRoleReadMore();
2119    });
2120
2121    $(document).on('click', '.mpwem_details_readmore', function (e) {
2122        e.preventDefault();
2123        var $button = $(this);
2124        var $wrap = $button.closest('.mpwem_details--has-readmore');
2125        var $content = $wrap.find('.mpwem_details_content').first();
2126        if (!$wrap.length || !$content.length) {
2127            return;
2128        }
2129
2130        var expanded = $wrap.hasClass('is-expanded');
2131        if (expanded) {
2132            $content.addClass('is-collapsed');
2133            $wrap.removeClass('is-expanded').addClass('is-collapsed');
2134            $button.attr('aria-expanded', 'false');
2135        } else {
2136            $content.removeClass('is-collapsed');
2137            $wrap.addClass('is-expanded').removeClass('is-collapsed');
2138            $button.attr('aria-expanded', 'true');
2139        }
2140    });
2141}(jQuery));

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