PageSourceSearch

https://demo.restropress.com/pizza-shop/wp-content/plugins/restrop…/rp-frontend.js?ver=3.4.6.1789221024

js restropress.com collected 2026-09-25 08:59:55 UTC 200,192 bytes, 5,644 lines download raw bytes

1/* Get RestroPress Cookie */
2function rp_getCookie(cname) {
3  var name = cname + "=";
4  var ca = document.cookie.split(';');
5  for (var i = 0; i < ca.length; i++) {
6    var c = ca[i];
7    while (c.charAt(0) == ' ') c = c.substring(1);
8    if (c.indexOf(name) != -1) {
9      var value = c.substring(name.length, c.length);
10      try {
11        return decodeURIComponent(value.replace(/\+/g, '%20'));
12      } catch (error) {
13        return value;
14      }
15    }
16  }
17  return "";
18}
19function remove_show_service_options() {
20  jQuery('#rpressModal')
21    .removeClass('show-service-options');
22}
23/* Set default addons */
24function rp_checked_default_subaddon() {
25  if (jQuery('#fooditem-details .rp-addons-data-wrapper .food-item-list.active').length > 0) {
26    jQuery('#fooditem-details .rp-addons-data-wrapper .food-item-list.active').each(function () {
27      var element = jQuery(this).find('input');
28      if (element.hasClass('checked')) {
29        jQuery(this).find('input').prop('checked', true);
30      }
31    });
32  }
33}
34/* Set RestroPress Cookie */
35function rp_setCookie(cname, cvalue, ex_time) {
36  var d = new Date();
37  d.setTime(d.getTime() + (ex_time * 60 * 1000));
38  var expires = "expires=" + d.toUTCString();
39  document.cookie = cname + "=" + cvalue + "; " + expires + ";path=/";
40}
41function rp_clearCookie(cname) {
42  document.cookie = cname + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
43}
44function rp_is_old_ui_ux_enabled() {
45  return (typeof rp_scripts !== 'undefined') && String(rp_scripts.old_ui_ux || '') 
45=== '1';
46}
47function rp_format_currency_value(value) {
48  var numeric = parseFloat(value);
49  if (isNaN(numeric)) {
50    numeric = 0;
51  }
52
53  var decimalPlaces = parseInt(rp_scripts.currency_decimals, 10);
54  if (isNaN(decimalPlaces)) {
55    decimalPlaces = 2;
56  }
57
58  if (String(rp_scripts.currency_value_type || 'float') === 'round') {
59    decimalPlaces = 0;
60    numeric = Math.round(numeric);
61  }
62
63  var amount = numeric.toFixed(decimalPlaces);
64  var decimalSeparator = rp_scripts.decimal_separator || '.';
65  var thousandsSeparator = rp_scripts.thousands_separator || ',';
66
67  if (decimalSeparator !== '.') {
68    amount = amount.split('.').join(decimalSeparator);
69  }
70
71  var amountParts = amount.split(decimalSeparator);
72  amountParts[0] = amountParts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
73  amount = amountParts.join(decimalSeparator);
74
75  if (rp_scripts.currency_pos === 'before') {
76    return rp_scripts.currency_sign + amount;
77  }
78
79  return amount + rp_scripts.currency_sign;
80}
81function rp_clear_service_selection_cookies(includeAddressContext) {
82  var cookieKeys = [
83    'service_type',
84    'service_time',
85    'service_time_text',
86    'service_date',
87    'delivery_date',
88    'service_date_manual'
89  ];
90
91  if (includeAddressContext) {
92    cookieKeys = cookieKeys.concat([
93      'delivery_zip',
94      'delivery_location',
95      'delivery_address',
96      'branch',
97      'branch_name'
98    ]);
99  }
100
101  for (var i = 0; i < cookieKeys.length; i++) {
102    rp_clearCookie(cookieKeys[i]);
103  }
104}
105function rp_clear_old_ui_service_cookies() {
106  rp_clear_service_selection_cookies(true);
107}
108/* Get RestroPress Storage Data */
109function rp_get_storage_data() {
110  var oldUiUxEnabled = rp_is_old_ui_ux_enabled();
111  var $ = (typeof jQuery !== 'undefined') ? jQuery : null;
112  if (oldUiUxEnabled && $) {
113    var cartQty = parseInt((typeof rp_scripts !== 'undefined' ? rp_scripts.cart_quantity : 0) || 0, 10);
114    var hasCartItemElements = $('ul.rpress-cart > li.rpress-cart-item').length > 0;
115    if (cartQty === 0 && !hasCartItemElements && !window.rpJustSelectedService) {
116      return false;
117    }
118  }
119
120  var serviceType = (rp_getCookie('service_type') || '')
121    .toString()
122    .trim()
123    .toLowerCase();
124  if (!serviceType || (serviceType !== 'delivery' && serviceType !== 'pickup')) {
125    return false;
126  }
127
128  if (!oldUiUxEnabled) {
129    return true;
130  }
131
132  var $ = (typeof jQuery !== 'undefined') ? jQuery : null;
133  var serviceTime = (rp_getCookie('service_time') || '')
134    .toString()
135    .trim();
136  var serviceDate = (rp_getCookie('service_date') || rp_getCookie('delivery_date') || '')
137    .toString()
138    .trim();
139  var deliveryZip = (rp_getCookie('delivery_zip') || '')
140    .toString()
141    .trim();
142  var deliveryLocation = (rp_getCookie('delivery_location') || '')
143    .toString()
144    .trim();
145  var deliveryAddress = (rp_getCookie('delivery_address') || '')
146    .toString()
147    .trim();
148  var branchId = (rp_getCookie('branch') || '')
149    .toString()
150    .trim();
151  var branchName = (rp_getCookie('branch_name') || '')
152    .toString()
153    .trim();
154
155  var hasDateSelect = false;
156  var hasTimeSelect = false;
157  var hasBranchSelector = false;
158  var hasLocationField = false;
159  var hasZipField = false;
160  var hasAddressField = false;
161
162  if ($) {
163    var $servicePanel = $('.delivery-settings-wrapper#nav-' + serviceType);
164    if (!$servicePanel.length) {
165      $servicePanel = $('.delivery-settings-wrapper.active, .delivery-settings-wrapper.show').first();
166    }
167    if (!$servicePanel.length) {
168      $servicePanel = $(document);
169    }
170
171    hasDateSelect = $servicePanel.find('.rpress_get_delivery_dates').length > 0;
172    hasTimeSelect = $servicePanel.find('.rpress_get_delivery_hours, .rpress-pickup-hours, #rpress-' + serviceType + '-hours, .rpress-allowed-delivery-hrs').length > 0;
173    hasBranchSelector = $('select[name="branch"], #rp-location, #rpress_location').length > 0;
174    hasLocationField = $('input#rp_delivery_location, input[name="rp_delivery_location"]').length > 0;
175    hasZipField = $('input#rp_delivery_zone, input[name="rp_delivery_zone"]').length > 0;
176    hasAddressField = $('input#rp_delivery_address, input[name="rp_delivery_address"], input#rp_street_address').length > 0;
177  }
178
179  var isServiceTimeDisabled = false;
180  if (window.rp_otil_vars) {
181    isServiceTimeDisabled =
182      (serviceType === 'pickup' && window.rp_otil_vars.disable_pickup_time === '1') ||
183      (serviceType === 'delivery' && window.rp_otil_vars.disable_delivery_time === '1');
184  }
185
186  if (hasDateSelect && !serviceDate) {
187    return false;
188  }
189
190  if (hasTimeSelect && !isServiceTimeDisabled && !serviceTime) {
191    return false;
192  }
193
194  if (hasBranchSelector && !branchId && !branchName) {
195    return false;
196  }
197
198  if (serviceType === 'delivery') {
199    if (hasLocationField && !deliveryLocation) {
200      return false;
201    }
202
203    if (hasZipField && !deliveryZip) {
204      return false;
205    }
206
207    if (hasAddressField && !deliveryAddress && !branchName) {
208      return false;
209    }
210  }
211
212  return true;
213}
214/* Display Dynamic Addon Price Based on Selected Variation */
215function show_dymanic_pricing(container, ele) {
216  var price_key = ele.val();
217  if (price_key !== 'undefined') {
218    var $wrapper = jQuery('#' + container + ' .rp-addons-data-wrapper');
219    jQuery('#' + container + ' .rp-addons-data-wrapper .food-item-list')
220      .removeClass('active');
221    jQuery('#' + container + ' .rp-addons-data-wrapper .food-item-list.list_' + price_key)
222      .addClass('active');
223    // remove border from the last active only
224    $wrapper.find('.food-item-list.active').last().css('border-bottom', '0');
225  }
226}
227/* Calculate Live Price On Click */
228function update_modal_live_price(fooditem_container) {
229  //Add changes code
230  var single_price = parseFloat(jQuery('#rpressModal .cart-item-price')
231    .attr('data-price'));
232  var quantity = parseInt(jQuery('input[name=quantity]')
233    .val());
234  /* Act on the variations */
235  jQuery('#' + fooditem_container + ' .rp-variable-price-wrapper .food-item-list')
236    .each(function () {
237      var element = jQuery(this)
238        .find('input');
239      if (element.is(':checked')) {
240        // Dynamic addon Price
241        show_dymanic_pricing(fooditem_container, element);
242        var attrs = element.attr('data-value');
243        var attrs_arr = attrs.split('|');
244        var price = attrs_arr[2];
245        single_price = parseFloat(price);
246      }
247    });
248  /* Act on the addons */
249  jQuery('#' + fooditem_container + ' .rp-addons-data-wrapper .food-item-list.active')
250    .each(function () {
251      var element = jQuery(this)
252        .find('input');
253      if (element.is(':checked')) {
254        var attrs = element.val();
255        var attrs_arr = attrs.split('|');
256        var price = attrs_arr[2];
257        if (price != '') {
258          single_price = parseFloat(single_price) + parseFloat(price);
259        }
260      }
261    });
262  /* Updating as per current quantity */
263  total_price = single_price * quantity;
264  /* Update the price in Submit Button */
265  total_price_v = rp_format_currency_value(total_price);
266  jQuery('#rpressModal .cart-item-price')
267    .html(total_price_v);
268
269  jQuery('#rpressModal .cart-item-price')
270    .attr('data-current', single_price.toFixed(2));
271}
272function isStoreOpen() {
273  if (typeof rp_scripts === 'undefined') return true; // fail-safe
274
275  if (rp_scripts.always_open === '1') return true;
276
277  if (rp_scripts.open_hours === '' || rp_scripts.close_hours === '') return false; // no hours set, assume close
278
279  var open = rp_scripts.open_hours;
280  var close = rp_scripts.close_hours;
281
282  function parseTime(t) {
283    if (typeof t !== 'string') return null;
284
285    var d = new Date();
286    var time = t.toLowerCase().replace(/\s/g, '');
287    var match12 = time.match(/^(\d{1,2}):(\d{2})(am|pm)$/);
288    var match24 = time.match(/^(\d{1,2}):(\d{2})$/);
289    var hours;
290    var minutes;
291
292    if (match12) {
293      hours = parseInt(match12[1], 10);
294      minutes = parseInt(match12[2], 10);
295      if (match12[3] === 'pm' && hours < 12) hours += 12;
296      if (match12[3] === 'am' && hours === 12) hours = 0;
297    } else if (match24) {
298      hours = parseInt(match24[1], 10);
299      minutes = parseInt(match24[2], 10);
300    } else {
301      return null;
302    }
303
304    if (hours > 23 || minutes > 59) return null;
305
306    d.setHours(hours, minutes, 0, 0);
307    return d;
308  }
309
310  var now = new Date();
311  var openTime = parseTime(open);
312  var closeTime = parseTime(close);
313
314  if (!openTime || !closeTime) return false;
315
316  if (closeTime.getTime() === openTime.getTime()) return false;
317
318  // Handle overnight windows (for example 18:00 to 02:00).
319  if (closeTime < openTime) {
320    return (now >= openTime || now <= closeTime);
321  }
322
323  return (now >= openTime && now <= closeTime);
324}
325/* RestroPress Frontend Functions */
326jQuery(function ($) {
327  if (rp_is_old_ui_ux_enabled()) {
328    $('body').addClass('rp-old-ui-ux-enabled');
329  } else {
330    $('body').removeClass('rp-old-ui-ux-enabled');
331  }
332
333  // The delivery zip / postcode field (from the Delivery Fee extension) is a
334  // plain text input, so the browser paints its address-autofill control (the
335  // stray "..." box) inside the schedule popup. Turn autofill off on those
336  // fields so the input stays clean. Re-run on focus in case the field is
337  // injected after load.
338  function rpDisableZipAutofill(scope) {
339    $(scope || document)
340      .find('input#rp_delivery_zone, input[name="rp_delivery_zone"], #rpress-postcode, #rpress_postcode, input[name="rpress_postcode"]')
341      .attr({ autocomplete: 'off', 'data-lpignore': 'true', 'data-1p-ignore': 'true' });
342  }
343  rpDisableZipAutofill();
344  $(document).on('focusin', 'input#rp_delivery_zone, input[name="rp_delivery_zone"]', function () {
345    $(this).attr({ autocomplete: 'off', 'data-lpignore': 'true', 'data-1p-ignore': 'true' });
346  });
347
348  function rp_has_rpress_interactive_ui() {
349    return $('#rpressDateTime, #rpressModal, #rpress_checkout_wrap, .rpress-section').length > 0;
350  }
351
352  function rp_has_visible_open_modal($modals) {
353    var hasVisible = false;
354    $modals.each(function () {
355      var $modal = $(this);
356      var isOpen = $modal.hasClass('is-open') || $modal.attr('aria-hidden') === 'false';
357      if (!isOpen) {
358        return;
359      }
360      if ($modal.find('.modal__container:visible').length > 0 || $modal.is(':visible')) {
361        hasVisible = true;
362      }
363    });
364    return hasVisible;
365  }
366
367  function rp_reset_stuck_modal_state() {
368    if (!rp_has_rpress_interactive_ui()) {
369      return;
370    }
371
372    var $serviceModal = $('#rpressDateTime');
373    var $itemModal = $('#rpressModal');
374    var $modals = $serviceModal.add($itemModal);
375    var $overlays = $('.modal__overlay, .micromodal-overlay, .modal-overlay');
376    var modalVisible = rp_has_visible_open_modal($modals);
377    var hasStaleOpenState = $modals.filter(function () {
378      var $modal = $(this);
379      return (
380        $modal.hasClass('is-open') ||
381        $modal.attr('aria-hidden') === 'false' ||
382        $modal.hasClass('show-service-options') ||
383        $modal.hasClass('show-order-details')
384      );
385    }).length > 0;
386    var bodyLocked = $('body').hasClass('modal-open') || $('body').css('overflow') === 'hidden' || $('html').css('overflow') === 'hidden';
387
388    // If no modal is actually visible, force-clear stale overlays/locks.
389    if (!modalVisible && (hasStaleOpenState || $overlays.length > 0 || bodyLocked)) {
390      $modals
391        .removeClass('is-open loading show-service-options show-order-details rpress-order-details-context')
392        .attr('aria-hidden', 'true');
393
394      $('html, body')
395        .removeClass('modal-open')
396        .css('overflow', '');
397    }
398  }
399
400  rp_reset_stuck_modal_state();
401  setTimeout(rp_reset_stuck_modal_state, 200);
402  setTimeout(rp_reset_stuck_modal_state, 600);
403
404  $(document).on('rpress_checked_slots rp-checkout-update-service-option', function () {
405    setTimeout(rp_reset_stuck_modal_state, 100);
406  });
407
408  function rp_fix_footer_click_intercept() {
409    var footer = document.getElementById('site-footer');
410    if (!footer) {
411      return;
412    }
413
414    var selectors = [
415      '#editDateTime',
416      '.rpress-category-link',
417      '.rpress-checkout-cart',
418      '.rpress_go_to_checkout',
419      '.rpress-cart .rpress_checkout a',
420      '#rpress_purchase_form input[type="text"]',
421      '#rpress_checkout_wrap'
422    ];
423
424    var candidate = null;
425    for (var i = 0; i < selectors.length; i++) {
426      var node = document.querySelector(selectors[i]);
427      if (!node) {
428        continue;
429      }
430      var rect = node.getBoundingClientRect();
431      if (rect.width > 0 && rect.height > 0) {
432        candidate = node;
433        break;
434      }
435    }
436
437    if (!candidate) {
438      return;
439    }
440
441    var r = candidate.getBoundingClientRect();
442    var hit = document.elementFromPoint(r.left + (r.width / 2), r.top + (r.height / 2));
443    if (hit && (hit === footer || footer.contains(hit))) {
444      var main = document.querySelector('main, #content, .site-main');
445      if (main) {
446        main.style.position = 'relative';
447        main.style.zIndex = '3';
448      }
449      footer.style.position = 'relative';
450      footer.style.zIndex = '1';
451    }
452  }
453
454  rp_fix_footer_click_intercept();
455  setTimeout(rp_fix_footer_click_intercept, 120);
456  $(window).on('resize.rpFooterFix load.rpFooterFix', rp_fix_footer_click_intercept);
457  $(document).ajaxComplete(function () {
458    setTimeout(rp_fix_footer_click_intercept, 60);
459  });
460
461  function rp_update_mobile_cart_summary(total, quantity) {
462    var parsedQty = parseInt(quantity, 10);
463    if (isNaN(parsedQty) || parsedQty < 0) {
464      parsedQty = 0;
465    }
466
467    var formattedTotal = (typeof total === 'string' && total.length)
468      ? total
469      : rp_format_currency_value(0);
470
471    $('.rp-mb-price').text(formattedTotal);
472    $('.rp-mb-quantity').text(parsedQty);
473    $('span.rpress-cart-quantity').text(parsedQty);
474
475    var hasItems = parsedQty > 0;
476    if (hasItems) {
477      $('.rpress-mobile-cart-icons').css('display', 'flex');
478      $('.rpress.item-order').show();
479    } else {
480      $('.rpress-mobile-cart-icons').hide();
481    }
482
483    $('.container-actionmenu').toggleClass('cart-has-items', hasItems);
484  }
485
486  function rp_refresh_sidebar_cart_summary(summaryHtml) {
487    var $summaryTarget = $('.rpress-cart-summary-area').first();
488    if ($summaryTarget.length) {
489      $summaryTarget.html((typeof summaryHtml === 'string') ? summaryHtml : '');
490      return;
491    }
492
493    var $cart = $('ul.rpress-cart');
494    if (!$cart.length) {
495      return;
496    }
497
498    $cart.find('div.rpress-cart-total-wrap, li.cart_item.rpress_checkout, li.cart_item.rpress_subtotal, li.cart_item.rpress_cart_tax, li.cart_item.rpress_user_discount, li.cart_item.rpress_cart_fee, li.cart_item.rpress_total, li.rpress-delivery-fee')
499      .remove();
500
501    if (typeof summaryHtml === 'string' && summaryHtml.length) {
502      $cart.append(summaryHtml);
503    }
504  }
505
506  function rp_get_first_field_value($scope, selectors) {
507    var $root = ($scope && $scope.length) ? $scope : $(document);
508    var value = '';
509    var $fields = $root.find(selectors);
510
511    $fields.filter(':visible').each(function () {
512      value = ($(this).val() || '').toString().trim();
513      return !value;
514    });
515
516    if (value) {
517      return value;
518    }
519
520    $fields.each(function () {
521      value = ($(this).val() || '').toString().trim();
522      return !value;
523    });
524
525    if (!value && $root[0] !== document) {
526      $fields = $(selectors);
527
528      $fields.filter(':visible').each(function () {
529        value = ($(this).val() || '').toString().trim();
530        return !value;
531      });
532
533      if (value) {
534        return value;
535      }
536
537      $fields.each(function () {
538        value = ($(this).val() || '').toString().trim();
539        return !value;
540      });
541    }
542
543    return value;
544  }
545
546  function rp_encode_cookie_value(value) {
547    if (!value) {
548      return '';
549    }
550
551    try {
552      return encodeURIComponent(decodeURIComponent(String(value).replace(/\+/g, '%20')));
553    } catch (error) {
554      return encodeURIComponent(String(value));
555    }
556  }
557
558  function rp_persist_delivery_context_for_update($scope, response, serviceType) {
559    if (String(serviceType || '').toLowerCase() !== 'delivery') {
560      return;
561    }
562
563    response = response || {};
564    var expireTime = rp_scripts.expire_cookie_time;
565    var deliveryZip = response.delivery_zip || rp_get_first_field_value(
566      $scope,
567      'input[id="rp_delivery_zone"], input[name="rp_delivery_zone"], #rpress-postcode, #rpress_postcode, input[name="rpress_postcode"]'
568    );
569    var deliveryLocation = response.delivery_location || response.delivery_address || rp_get_first_field_value(
570      $scope,
571      'input[id="rp_delivery_location"], input[name="rp_delivery_location"], #rpress-delivery-address, input[name="rpress_delivery_address"]'
572    );
573    var deliveryLatLng = response.delivery_latlng || rp_get_first_field_value(
574      $scope,
575      'input[id="rp_delivery_latllng"], input[name="rp_delivery_latllng"]'
576    );
577    var branchId = response.branch || response.branch_id || rp_get_first_field_value(
578      $scope,
579      'select[name="branch"], #rp-location, #rpress_location, input[name="rpress_location"]:checked, input[name="rpress_location_pickup"]:checked'
580    );
581
582    if (deliveryZip) {
583      rp_setCookie('delivery_zip', deliveryZip, expireTime);
584    }
585
586    if (deliveryLocation) {
587      var encodedLocation = rp_encode_cookie_value(deliveryLocation);
588      rp_setCookie('delivery_location', encodedLocation, expireTime);
589      rp_setCookie('delivery_address', encodedLocation, expireTime);
590    }
591
592    if (deliveryLatLng) {
593      rp_setCookie('delivery_latlng', deliveryLatLng, expireTime);
594    }
595
596    if (branchId) {
597      rp_setCookie('branch', branchId, expireTime);
598      rp_setCookie('rpress_chosen_location_id', branchId, expireTime);
599    }
600  }
601
602  function rp_decode_cookie_value(value) {
603    if (!value) {
604      return '';
605    }
606
607    try {
608      return decodeURIComponent(String(value).replace(/\+/g, '%20')).trim();
609    } catch (error) {
610      return String(value).trim();
611    }
612  }
613
614  function rp_is_delivery_fee_extension_active() {
615    return typeof window.DeliveryFeeVars !== 'undefined' && window.DeliveryFeeVars !== null;
616  }
617
618  function rp_is_old_ui_delivery_context_invalid(serviceType, $scope) {
619    if (!rp_is_old_ui_ux_enabled()) {
620      return false;
621    }
622
623    if (String(serviceType || '').toLowerCase() !== 'delivery') {
624      return false;
625    }
626
627    if (!rp_is_delivery_fee_extension_active()) {
628      return false;
629    }
630
631    if (!rp_has_valid_delivery_fee_context(serviceType, $scope)) {
632      return true;
633    }
634
635    return String(window.rpDeliveryFeeValidationState || '') === 'invalid';
636  }
637
638  function rp_has_valid_delivery_fee_context(serviceType, $scope) {
639    if (String(serviceType || '').toLowerCase() !== 'delivery') {
640      return true;
641    }
642
643    if (!rp_is_delivery_fee_extension_active()) {
644      return true;
645    }
646
647    var method = String((window.DeliveryFeeVars.delivery_fee_method || 'zip_based')).toLowerCase();
648    var $context = ($scope && $scope.length) ? $scope : $(document);
649
650    var deliveryZip = rp_get_first_field_value(
651      $context,
652      'input[id="rp_delivery_zone"], input[name="rp_delivery_zone"], #rpress-postcode, #rpress_postcode, input[name="rpress_postcode"]'
653    ) || rp_decode_cookie_value(rp_getCookie('delivery_zip'));
654
655    var deliveryLocation = rp_get_first_field_value(
656      $context,
657      'input[id="rp_delivery_location"], input[name="rp_delivery_location"], #rpress-delivery-address, input[name="rpress_delivery_address"]'
658    ) || rp_decode_cookie_value(rp_getCookie('delivery_location')) || rp_decode_cookie_value(rp_getCookie('delivery_address'));
659
660    if (method === 'location_based') {
661      return !!deliveryLocation;
662    }
663
664    return !!deliveryZip;
665  }
666
667  function rp_get_delivery_fee_context_error(serviceType) {
668    if (String(serviceType || '').toLowerCase() !== 'delivery') {
669      return '';
670    }
671
672    var method = String((window.DeliveryFeeVars && window.DeliveryFeeVars.delivery_fee_method) || 'zip_based').toLowerCase();
673    if (method === 'location_based') {
674      return (window.DeliveryFeeVars && (window.DeliveryFeeVars.error_empty_address || window.DeliveryFeeVars.error_invalid_location)) || 'Please enter your location';
675    }
676
677    return (window.DeliveryFeeVars && window.DeliveryFeeVars.error_empty_zip) || 'Please enter your zip/postal code';
678  }
679
680  function rp_open_legacy_service_options_modal(fooditemId) {
681    if (!$('#rpressModal').length || !rp_scripts || !rp_scripts.ajaxurl || !rp_scripts.service_type_nonce) {
682      return false;
683    }
684
685    $('#rpressModal')
686      .addClass('show-service-options')
687      .removeClass('rpress-delivery-options rpress-food-options checkout-error');
688
689    $.ajax({
690      type: "POST",
691      data: {
692        action: 'rpress_show_delivery_options',
693        fooditem_id: fooditemId || '',
694        security: rp_scripts.service_type_nonce
695      },
696      dataType: "json",
697      url: rp_scripts.ajaxurl,
698      success: function (response) {
699        if (!response || !response.data) {
700          return;
701        }
702
703        var $modal = $('#rpressModal');
704        if (fooditemId) {
705          $modal.attr('data-pending-fooditem-id', fooditemId);
706          $modal.attr('data-service-modal-context', 'add-to-cart');
707        }
708        $modal.find('.modal-title').html(response.data.html_title || '');
709        $modal.find('.modal-body').html(response.data.html || '');
710        if (typeof window.rp_prepare_old_ui_modal_selection === 'function') {
711          window.rp_prepare_old_ui_modal_selection($modal.find('.modal-body'));
712        }
713        MicroModal.show('rpressModal', {
714          disableScroll: true
715        });
716        $(document.body).trigger('opened_service_options', [response.data]);
717      }
718    });
719
720    return true;
721  }
722
723  function rp_get_delivery_change_helper_html() {
724    if (!rp_is_old_ui_ux_enabled()) {
725      return '';
726    }
727
728    return '' +
729      '<span class="rp-delivery-change-helper">' +
730      '<span class="rp-delivery-change-tooltip-icon" tabindex="0" aria-label="Delivery address help">?</span>' +
731      '<span class="rp-delivery-change-tooltip-text">Change service type, date and time</span>' +
732      '</span>';
733  }
734
735  function rp_ensure_order_details_modal() {
736    var $modal = $('#rpressModal').first();
737    if ($modal.length) {
738      return $modal;
739    }
740
741    var modalHtml = [
742      '<div class="modal micromodal-slide" id="rpressModal" aria-hidden="true">',
743      '  <div class="modal__overlay" tabindex="-1" data-micromodal-close>',
744      '    <div class="modal__container modal-content" role="dialog" aria-modal="true">',
745      '      <header class="modal__header modal-header">',
746      '        <h2 class="modal__title modal-title"></h2>',
747      '        <button class="modal__close" aria-label="Close modal" data-micromodal-close></button>',
748      '      </header>',
749      '      <main class="modal__content modal-body"></main>',
750      '    </div>',
751      '  </div>',
752      '</div>'
753    ].join('');
754
755    $('body').append(modalHtml);
756    return $('#rpressModal').first();
757  }
758
759  // Show order details on popup
760  $(document)
761    .on('click', '.rpress-view-order-btn', function (e) {
762      e.preventDefault();
763      var self = $(this);
764      var $modal = rp_ensure_order_details_modal();
765      if (!$modal.length) {
766        return;
767      }
768      var isDashboardOrHistory = self.closest('.user-dashboard-wrapper, #rpress_user_history').length > 0;
769      var action = 'rpress_show_order_details';
770      var order_id = self.attr('data-order-id');
771      var data = {
772        action: action,
773        order_id: order_id,
774        security: rp_scripts.order_details_nonce
775      };
776      $modal
777        .addClass('show-order-details');
778      if (isDashboardOrHistory) {
779        $modal.addClass('rpress-order-details-context');
780      } else {
781        $modal.removeClass('rpress-order-details-context');
782      }
783      $.ajax({
784        type: "POST",
785        data: data,
786        dataType: "json",
787        url: rp_scripts.ajaxurl,
788        beforeSend: (jqXHR, object) => {
789          self.addClass('rp-loading');
790          self.find('.rp-ajax-toggle-text')
791            .addClass('rp-text-visibility');
792        },
793        complete: (jqXHR, object) => {
794          self.removeClass('rp-loading');
795          self.find('.rp-ajax-toggle-text')
796            .removeClass('rp-text-visibility');
797        },
798        success: function (response) {
799          if (!response || response.success !== true || !response.data || typeof response.data.html !== 'string') {
800            return;
801          }
802          $modal.find('.modal__container')
803            .html(response.data.html);
804          if (typeof MicroModal !== 'undefined' && typeof MicroModal.show === 'function') {
805            MicroModal.show('rpressModal', {
806              disableScroll: true
807            });
808          } else {
809            $modal
810              .addClass('is-open')
811              .attr('aria-hidden', 'false');
812            $('html, body')
813              .addClass('modal-open')
814              .css('overflow', 'hidden');
815          }
816        },
817        error: function () {
818          $modal.removeClass('show-order-details rpress-order-details-context');
819        }
820      })
821    });
822  $(document).on('click', '#rpressModal.show-order-details .modal__close', function (e) {
823    e.preventDefault();
824    if (typeof MicroModal !== 'undefined' && typeof MicroModal.close === 'function') {
825      MicroModal.close('rpressModal');
826    } else {
827      $('#rpressModal')
828        .removeClass('is-open show-order-details rpress-order-details-context')
829        .attr('aria-hidden', 'true');
830      $('html, body')
831        .removeClass('modal-open')
832        .css('overflow', '');
833    }
834  });
835  // Sticky category menu on mobile
836  $(window)
837    .resize(function () {
838      if ($(window)
839        .width() > 769) {
840        $('.sticky-sidebar.cat-lists')
841          .removeClass('rp-mobile-cat');
842      } else {
843        $('.sticky-sidebar.cat-lists')
844          .addClass('rp-mobile-cat');
845      }
846    })
847    .resize();
848  // Hide Mneu on Click Float Cart
849  $(document)
850    .on('click', '.rpress-category-item', function () {
851      $('.rp-mb-cat-ft-btn')
852        .click();
853    });
854  // Hide Mneu on Click Items
855  $(document)
856    .on('click', '.rpress-mobile-cart-icons', function () {
857      $('.rp-cat-overlay')
858        .click();
859    });
860  // RP Hide overlay
861  $(document)
862    .on('click', '.rp-cat-overlay', function () {
863      $('.rp-mb-cat-ft-btn')
864        .click();
865    });
866  // Toggel mobile category menu
867  $('.rp-mb-cat-ft-btn')
868    .on('click', function () {
869      $('.rp-mb-cat-ft-btn')
870        .toggleClass('rp-close-menu');
871      $('.sticky-sidebar.cat-lists')
872        .toggleClass('rp-hide');
873      $('body')
874        .toggleClass('rp-cat-no-scroll');
875      if ($('.sticky-sidebar.cat-lists')
876        .hasClass('rp-hide'))
877        $('body')
878          .append('<div class="rp-cat-overlay"></div>');
879      else
880        $('.rp-cat-overlay')
881          .remove();
882    });
883  $('.rp-mb-cat-ft-btn')
884    .click(function () {
885      $('.rp-mobile-cat')
886        .toggle('fast');
887      if ($(this)
888        .hasClass('rp-close-menu')) {
889        $('.rp-mb-cat-txt')
890          .html(`<i class="fa fa-cutlery" aria-hidden="true"></i> ${rpress_scripts.close}`);
891      } else {
892        $('.rp-mb-cat-txt')
893          .html(`<i class="fa fa-cutlery" aria-hidden="true"></i> ${rpress_scripts.menu}`);
894      }
895    });
896  //Remove loading from modal
897  $('#rpressModal')
898    .removeClass('loading');
899  //Remove service options from modal
900  $('#rpressModal')
901    .removeClass('show-service-options');
902  $('#rpressModal')
903    .removeClass('minimum-order-notice');
904  $('#rpressModal')
905    .on('hidden.bs.modal', function () {
906      $('#rpressModal')
907        .removeClass('show-service-options');
908      $('#rpressModal')
909        .removeClass('minimum-order-notice');
910    });
911  var ServiceType = rp_scripts.service_options;
912  if (ServiceType == 'delivery_and_pickup') {
913    ServiceType = 'delivery';
914  }
915  function rp_get_active_service_time_select($scope, preferredServiceType) {
916    var $root = ($scope && $scope.length) ? $scope : $(document);
917    var serviceType = (preferredServiceType || '')
918      .toLowerCase();
919    var $select = $();
920
921    if (serviceType) {
922      $select = $root.find('.delivery-settings-wrapper#nav-' + serviceType + ' .rpress-hrs')
923        .first();
924      if ($select.length) {
925        return $select;
926      }
927
928      // Service pane exists but does not render a time selector (for example closed service).
929      // Do not fall back to another service selector in this case.
930      if ($root.find('.delivery-settings-wrapper#nav-' + serviceType).length) {
931        return $select;
932      }
933    }
934
935    $select = $root.find('.delivery-settings-wrapper.active .rpress-hrs')
936      .first();
937    if ($select.length) {
938      return $select;
939    }
940
941    $select = $root.find('.delivery-settings-wrapper.show .rpress-hrs')
942      .first();
943    if ($select.length) {
944      return $select;
945    }
946
947    $select = $root.find('.delivery-settings-wrapper:visible .rpress-hrs')
948      .first();
949    if ($select.length) {
950      return $select;
951    }
952
953    return $root.find('#rpress-delivery-hours, .rpress-hrs')
954      .first();
955  }
956  function rp_restore_service_time_select($select, serviceTime, allowFallbackSelection) {
957    if (!$select || !$select.length) {
958      return '';
959    }
960
961    var requestedTime = (serviceTime || '')
962      .trim();
963    var selectedValue = '';
964    var shouldFallback = (allowFallbackSelection !== false);
965
966    if (requestedTime && $select.find('option[value="' + requestedTime + '"]').length) {
967      selectedValue = requestedTime;
968    } else if (requestedTime) {
969      var $matchingOption = $select.find('option')
970        .filter(function () {
971          return $(this)
972            .text()
973            .trim() === requestedTime;
974        })
975        .first();
976      if ($matchingOption.length) {
977        selectedValue = $matchingOption.val();
978      }
979    }
980
981    if (!selectedValue) {
982      var currentSelectedTime = ($select.val() || '')
983        .toString()
984        .trim();
985      if (currentSelectedTime && $select.find('option[value="' + currentSelectedTime + '"]').length) {
986        selectedValue = currentSelectedTime;
987      }
988    }
989
990    if (!selectedValue && shouldFallback) {
991      var $firstSelectableOption = $select.find('option')
992        .filter(function () {
993          var optionValue = ($(this)
994            .val() || '')
995            .toString()
996            .trim();
997          return optionValue !== '' && !$(this)
998            .prop('disabled');
999        })
1000        .first();
1001
1002      if (!$firstSelectableOption.length) {
1003        $firstSelectableOption = $select.find('option')
1004          .first();
1005      }
1006
1007      selectedValue = $firstSelectableOption.val() || '';
1008    }
1009
1010    $select.val(selectedValue || '');
1011
1012    return selectedValue;
1013  }
1014  function rp_restore_service_date_select($select, serviceDate, allowFallbackSelection) {
1015    if (!$select || !$select.length) {
1016      return '';
1017    }
1018
1019    var requestedDate = (serviceDate || '')
1020      .toString()
1021      .trim();
1022    var selectedValue = '';
1023    var shouldFallback = (allowFallbackSelection !== false);
1024
1025    if (requestedDate && $select.find('option[value="' + requestedDate + '"]').length) {
1026      selectedValue = requestedDate;
1027    } else if (requestedDate) {
1028      var $matchingOption = $select.find('option')
1029        .filter(function () {
1030          return ($(this)
1031            .text() || '')
1032            .toString()
1033            .trim() === requestedDate;
1034        })
1035        .first();
1036      if ($matchingOption.length) {
1037        selectedValue = $matchingOption.val();
1038      }
1039    }
1040
1041    if (!selectedValue) {
1042      var currentSelectedDate = ($select.val() || '')
1043        .toString()
1044        .trim();
1045      if (currentSelectedDate && $select.find('option[value="' + currentSelectedDate + '"]').length) {
1046        selectedValue = currentSelectedDate;
1047      }
1048    }
1049
1050    if (!selectedValue && shouldFallback) {
1051      var $firstSelectableOption = $select.find('option')
1052        .filter(function () {
1053          var optionValue = ($(this)
1054            .val() || '')
1055            .toString()
1056            .trim();
1057          return optionValue !== '' && !$(this)
1058            .prop('disabled');
1059        })
1060        .first();
1061
1062      if (!$firstSelectableOption.length) {
1063        $firstSelectableOption = $select.find('option')
1064          .first();
1065      }
1066
1067      selectedValue = ($firstSelectableOption.val() || '')
1068        .toString()
1069        .trim();
1070    }
1071
1072    $select.val(selectedValue || '');
1073
1074    return selectedValue;
1075  }
1076  function rp_remove_select_placeholder($select) {
1077    if (!$select || !$select.length) {
1078      return;
1079    }
1080    $select.find('option[data-rp-placeholder="1"]').remove();
1081  }
1082  function rp_prepare_old_ui_modal_selection($scope) {
1083    if (!rp_is_old_ui_ux_enabled()) {
1084      return;
1085    }
1086
1087    var $root = ($scope && $scope.length) ? $scope : $(document);
1088    var selectedServiceType = (rp_getCookie('service_type') || '')
1089      .toString()
1090      .trim()
1091      .toLowerCase();
1092    var selectedServiceDate = (rp_getCookie('service_date') || rp_getCookie('delivery_date') || '')
1093      .toString()
1094      .trim();
1095    var selectedServiceTime = (rp_getCookie('service_time') || rp_getCookie('service_time_text') || '')
1096      .toString()
1097      .trim();
1098    var requiresServiceChoice = $root.find('#rpressdeliveryTab .single-service-selected').length > 1;
1099
1100    if (!selectedServiceType && requiresServiceChoice) {
1101      selectedServiceType = rp_get_active_service_type(
1102        $root,
1103        (rp_scripts && rp_scripts.default_service) ? rp_scripts.default_service : 'delivery'
1104      );
1105
1106      if (!selectedServiceType) {
1107        var $firstServiceTab = $root.find('#rpressdeliveryTab .single-service-selected')
1108          .first();
1109        if ($firstServiceTab.length) {
1110          selectedServiceType = String($firstServiceTab.data('service-type') || '')
1111            .toLowerCase();
1112        }
1113      }
1114    }
1115
1116    if (selectedServiceType) {
1117      rp_sync_service_ui_state($root, selectedServiceType, false);
1118    }
1119
1120    $root.find('.rpress_get_delivery_dates').each(function () {
1121      var $dateSelect = $(this);
1122      rp_remove_select_placeholder($dateSelect);
1123      rp_restore_service_date_select($dateSelect, selectedServiceDate, true);
1124    });
1125
1126    $root.find('.delivery-settings-wrapper').each(function () {
1127      var $pane = $(this);
1128      var paneServiceType = String($pane.attr('id') || '')
1129        .replace(/^nav-/, '')
1130        .toLowerCase();
1131
1132      $pane.find('.rpress-hrs').each(function () {
1133        var $timeSelect = $(this);
1134        if (rp_is_service_time_hidden(paneServiceType)) {
1135          return;
1136        }
1137        rp_remove_select_placeholder($timeSelect);
1138        rp_restore_service_time_select($timeSelect, selectedServiceTime, true);
1139      });
1140    });
1141  }
1142  function rp_is_service_time_hidden(serviceType) {
1143    var normalizedServiceType = String(serviceType || '')
1144      .toLowerCase();
1145    if (!window.rp_otil_vars) {
1146      return false;
1147    }
1148
1149    return (
1150      (normalizedServiceType === 'pickup' && window.rp_otil_vars.disable_pickup_time === '1') ||
1151      (normalizedServiceType === 'delivery' && window.rp_otil_vars.disable_delivery_time === '1')
1152    );
1153  }
1154  function rp_get_asap_fallback_time(serviceType) {
1155    var normalizedServiceType = String(serviceType || '')
1156      .toLowerCase();
1157    var fallbackTime = 'ASAP';
1158
1159    if (normalizedServiceType === 'pickup' && window.rp_otil_vars && window.rp_otil_vars.pickup_asap_text) {
1160      fallbackTime += ' ' + window.rp_otil_vars.pickup_asap_text;
1161    } else if (normalizedServiceType === 'delivery' && window.rp_otil_vars && window.rp_otil_vars.delivery_asap_text) {
1162      fallbackTime += ' ' + window.rp_otil_vars.delivery_asap_text;
1163    }
1164
1165    return fallbackTime;
1166  }
1167
1168  function rp_is_date_like_text(value) {
1169    return /^\d{1,4}([./-])\d{1,2}\1\d{1,4}$/.test(
1170      (value || '')
1171        .toString()
1172        .trim()
1173    );
1174  }
1175
1176  function rp_get_active_service_closed_message($scope, serviceType) {
1177    var normalizedServiceType = String(serviceType || '')
1178      .toLowerCase();
1179    var $root = ($scope && $scope.length) ? $scope : $(document);
1180    var selectors = [];
1181
1182    if (normalizedServiceType) {
1183      selectors = selectors.concat([
1184        '.delivery-settings-wrapper#nav-' + normalizedServiceType + '.active.show .rpress-service-closed-message .rpress-closed-message-text',
1185        '.delivery-settings-wrapper#nav-' + normalizedServiceType + '.active.show .rpress-service-closed-message',
1186        '.delivery-settings-wrapper#nav-' + normalizedServiceType + ' .rpress-service-closed-message .rpress-closed-message-text',
1187        '.delivery-settings-wrapper#nav-' + normalizedServiceType + ' .rpress-service-closed-message',
1188        '.rpress-service-closed-message[data-service-type="' + normalizedServiceType + '"] .rpress-closed-message-text',
1189        '.rpress-service-closed-message[data-service-type="' + normalizedServiceType + '"]'
1190      ]);
1191    }
1192
1193    selectors = selectors.concat([
1194      '.delivery-settings-wrapper.active.show .rpress-service-closed-message .rpress-closed-message-text',
1195      '.delivery-settings-wrapper.active.show .rpress-service-closed-message'
1196    ]);
1197
1198    for (var i = 0; i < selectors.length; i++) {
1199      var message = $root.find(selectors[i])
1200        .first()
1201        .text()
1202        .trim();
1203      if (!message && !$root.is(document)) {
1204        message = $(document)
1205          .find(selectors[i])
1206          .first()
1207          .text()
1208          .trim();
1209      }
1210      if (message && !rp_is_date_like_text(message)) {
1211        return message;
1212      }
1213    }
1214
1215    return '';
1216  }
1217
1218  function rp_update_inline_service_display(selection, oldUiUxEnabled) {
1219    if (!selection) {
1220      return;
1221    }
1222
1223    var $deliveryDate = $('#deliveryDate');
1224    var $deliveryTime = $('#deliveryTime');
1225    var $summaryWrap = $deliveryDate.closest('.rpress_order-address-wrap');
1226
1227    if (selection.serviceClosedMessage) {
1228      $summaryWrap.addClass('rpress-store-closed-inline');
1229      $deliveryDate
1230        .addClass('rp-store-timing-notice rpress-closed-summary-text')
1231        .text(selection.serviceClosedMessage);
1232      $deliveryTime.text('');
1233      return;
1234    }
1235
1236    $summaryWrap.removeClass('rpress-store-closed-inline');
1237    $deliveryDate.removeClass('rp-store-timing-notice rpress-closed-summary-text');
1238
1239    if (selection.serviceDateText && (!oldUiUxEnabled || rp_getCookie('service_date') || rp_getCookie('delivery_date'))) {
1240      $deliveryDate.text(selection.serviceDateText);
1241    }
1242    if (selection.serviceTimeText && (!oldUiUxEnabled || rp_getCookie('service_time') || rp_getCookie('service_time_text'))) {
1243      $deliveryTime.text(selection.serviceTimeText);
1244    }
1245  }
1246
1247  function rp_apply_service_defaults($scope, preferredServiceType, persistCookies, requireExplicitSelection, preferCurrentSelection) {
1248    var shouldPersistCookies = (persistCookies !== false);
1249    var enforceManualSelection = (requireExplicitSelection === true);
1250    var shouldPreferCurrentSelection = (preferCurrentSelection === true);
1251    var $root = ($scope && $scope.length) ? $scope : $(document);
1252    var serviceType = rp_get_active_service_type($root, preferredServiceType);
1253    serviceType = rp_sync_service_ui_state($root, serviceType, shouldPersistCookies) || serviceType;
1254
1255    var requestedServiceDate = (rp_getCookie('service_date') || rp_getCookie('delivery_date') || '')
1256      .toString()
1257      .trim();
1258    var requestedServiceDateText = (rp_getCookie('delivery_date') || '')
1259      .toString()
1260      .trim();
1261    if (requestedServiceDateText && !/\d/.test(requestedServiceDateText)) {
1262      requestedServiceDateText = '';
1263    }
1264    var $activeDateSelect = rp_get_active_service_date_select($root, serviceType);
1265    var serviceDate = '';
1266    var serviceDateText = '';
1267    var serviceClosedMessage = rp_get_active_service_closed_message($root, serviceType);
1268
1269    if (shouldPreferCurrentSelection && $activeDateSelect.length) {
1270      requestedServiceDate = ($activeDateSelect.val() || '')
1271        .toString()
1272        .trim();
1273    }
1274
1275    if ($activeDateSelect.length) {
1276      serviceDate = rp_restore_service_date_select(
1277        $activeDateSelect,
1278        requestedServiceDate,
1279        !enforceManualSelection
1280      );
1281      serviceDateText = ($activeDateSelect.find('option:selected')
1282        .text() || '')
1283        .toString()
1284        .trim();
1285    } else {
1286      serviceDate = requestedServiceDate;
1287      serviceDateText = requestedServiceDateText || requestedServiceDate;
1288    }
1289
1290    if (!$activeDateSelect.length && !serviceDateText) {
1291      var fallbackDateText = ($('#deliveryDate').first().text() || '')
1292        .toString()
1293        .trim()
1294        .replace(/,\s*$/, '');
1295      if (fallbackDateText) {
1296        serviceDateText = fallbackDateText;
1297      }
1298    }
1299
1300    if (serviceDate && shouldPersistCookies) {
1301      rp_setCookie('service_date', serviceDate, rp_scripts.expire_cookie_time);
1302      if (!serviceClosedMessage) {
1303        rp_setCookie('delivery_date', serviceDateText || serviceDate, rp_scripts.expire_cookie_time);
1304      }
1305    }
1306
1307    var requestedServiceTime = (rp_getCookie('service_time') || rp_getCookie('service_time_text') || '')
1308      .toString()
1309      .trim();
1310    var $activeTimeSelect = rp_get_active_service_time_select($root, serviceType);
1311    var serviceTime = '';
1312    var serviceTimeText = '';
1313    var isServiceTimeHidden = rp_is_service_time_hidden(serviceType);
1314
1315    if (shouldPreferCurrentSelection && $activeTimeSelect.length) {
1316      requestedServiceTime = ($activeTimeSelect.val() || '')
1317        .toString()
1318        .trim();
1319    }
1320
1321    if (isServiceTimeHidden) {
1322      serviceTime = rp_get_asap_fallback_time(serviceType);
1323      serviceTimeText = serviceTime;
1324    } else if ($activeTimeSelect.length) {
1325      serviceTime = rp_restore_service_time_select(
1326        $activeTimeSelect,
1327        requestedServiceTime,
1328        !enforceManualSelection
1329      );
1330      serviceTimeText = ($activeTimeSelect.find('option:selected')
1331        .text() || '')
1332        .toString()
1333        .trim();
1334    } else {
1335      serviceTime = requestedServiceTime;
1336      serviceTimeText = requestedServiceTime;
1337    }
1338
1339    if (!$activeTimeSelect.length) {
1340      var fallbackTimeText = ($('#deliveryTime').first().text() || '')
1341        .toString()
1342        .trim();
1343      if (fallbackTimeText) {
1344        serviceTimeText = fallbackTimeText;
1345      }
1346    }
1347
1348    if (serviceTime && shouldPersistCookies) {
1349      rp_setCookie('service_time', serviceTime, rp_scripts.expire_cookie_time);
1350      rp_setCookie('service_time_text', serviceTimeText || serviceTime, rp_scripts.expire_cookie_time);
1351    }
1352
1353    return {
1354      serviceType: serviceType,
1355      serviceDate: serviceDate,
1356      serviceDateText: serviceClosedMessage || serviceDateText,
1357      serviceClosedMessage: serviceClosedMessage,
1358      serviceTime: serviceTime,
1359      serviceTimeText: serviceTimeText
1360    };
1361  }
1362  function rp_get_active_service_type($scope, fallbackServiceType) {
1363    var $root = ($scope && $scope.length) ? $scope : $(document);
1364    var serviceType = '';
1365    var $activeServiceTab = $root.find('#rpressdeliveryTab .single-service-selected[aria-selected="true"]')
1366      .first();
1367
1368    if (!$activeServiceTab.length) {
1369      $activeServiceTab = $root.find('#rpressdeliveryTab .nav-item.active .single-service-selected')
1370        .first();
1371    }
1372
1373    if (!$activeServiceTab.length) {
1374      $activeServiceTab = $root.find('#rpressdeliveryTab .single-service-selected.active')
1375        .first();
1376    }
1377
1378    if ($activeServiceTab.length) {
1379      serviceType = String($activeServiceTab.data('service-type') || '')
1380        .toLowerCase();
1381    }
1382
1383    if (!serviceType) {
1384      var $activeServicePane = $root.find('.delivery-settings-wrapper.active[id^="nav-"], .delivery-settings-wrapper.show[id^="nav-"]')
1385        .first();
1386      if ($activeServicePane.length) {
1387        serviceType = String($activeServicePane.attr('id') || '')
1388          .replace(/^nav-/, '')
1389          .toLowerCase();
1390      }
1391    }
1392
1393    if (!serviceType) {
1394      var $serviceTabsWrapper = $root.find('.rpress-tabs-wrapper.service-option-delivery, .rpress-tabs-wrapper.service-option-pickup')
1395        .first();
1396      if ($serviceTabsWrapper.length) {
1397        if ($serviceTabsWrapper.hasClass('service-option-delivery')) {
1398          serviceType = 'delivery';
1399        } else if ($serviceTabsWrapper.hasClass('service-option-pickup')) {
1400          serviceType = 'pickup';
1401        }
1402      }
1403    }
1404
1405    if (!serviceType) {
1406      serviceType = String(
1407        fallbackServiceType || rp_getCookie('service_type') || rp_scripts.default_service || 'delivery'
1408      )
1409        .toLowerCase();
1410    }
1411
1412    if (serviceType !== 'delivery' && serviceType !== 'pickup') {
1413      serviceType = 'delivery';
1414    }
1415
1416    return serviceType;
1417  }
1418  function rp_sync_service_ui_state($scope, serviceType, persist
1418Cookie) {
1419    var normalizedServiceType = String(serviceType || '')
1420      .toLowerCase();
1421
1422    if (normalizedServiceType !== 'delivery' && normalizedServiceType !== 'pickup') {
1423      return '';
1424    }
1425
1426    var $root = ($scope && $scope.length) ? $scope : $(document);
1427    var $wrappers = $root.find('.rpress-tabs-wrapper');
1428
1429    if (!$wrappers.length && $root.hasClass('rpress-tabs-wrapper')) {
1430      $wrappers = $root;
1431    }
1432
1433    $wrappers.each(function () {
1434      var $wrapper = $(this);
1435      var $serviceTab = $wrapper.find('#rpressdeliveryTab .single-service-selected[data-service-type="' + normalizedServiceType + '"]')
1436        .first();
1437
1438      $wrapper.removeClass('service-option-delivery service-option-pickup')
1439        .addClass('service-option-' + normalizedServiceType);
1440
1441      if ($serviceTab.length) {
1442        $wrapper.find('#rpressdeliveryTab .nav-item').removeClass('active');
1443        $wrapper.find('#rpressdeliveryTab .single-service-selected')
1444          .removeClass('active')
1445          .attr('aria-selected', 'false');
1446
1447        $serviceTab
1448          .addClass('active')
1449          .attr('aria-selected', 'true');
1450        $serviceTab.closest('.nav-item').addClass('active');
1451
1452        var targetPane = $serviceTab.attr('href');
1453        if (targetPane && targetPane.charAt(0) === '#') {
1454          $wrapper.find('.delivery-settings-wrapper').removeClass('active show');
1455          $wrapper.find(targetPane).addClass('active show');
1456        }
1457
1458        var serviceHeadingLabel = ($serviceTab.find('.rpress-service-tab-label').first().text() || $serviceTab.text() || '')
1459          .toString()
1460          .trim();
1461        var $serviceHeading = $wrapper.find('.rpress-checkout-service-heading').first();
1462        if ($serviceHeading.length) {
1463          $serviceHeading
1464            .removeClass('is-service-delivery is-service-pickup')
1465            .addClass('is-service-' + normalizedServiceType);
1466          if (serviceHeadingLabel) {
1467            $serviceHeading.find('.rpress-checkout-service-heading-text')
1468              .text(serviceHeadingLabel);
1469          }
1470        }
1471      }
1472    });
1473
1474    if (persistCookie !== false) {
1475      rp_setCookie('service_type', normalizedServiceType, rp_scripts.expire_cookie_time);
1476    }
1477
1478    return normalizedServiceType;
1479  }
1480  function rp_sync_service_selection_cookies($scope, preferredServiceType) {
1481    var defaults = rp_apply_service_defaults($scope, preferredServiceType);
1482    if (!defaults.serviceTimeText) {
1483      defaults.serviceTimeText = ($('#deliveryTime')
1484        .first()
1485        .text() || '')
1486        .toString()
1487        .trim();
1488      if (defaults.serviceTimeText) {
1489        rp_setCookie('service_time_text', defaults.serviceTimeText, rp_scripts.expire_cookie_time);
1490      }
1491    }
1492
1493    return defaults;
1494  }
1495  function rp_get_active_service_date_select($scope, preferredServiceType) {
1496    var $root = ($scope && $scope.length) ? $scope : $(document);
1497    var serviceType = (preferredServiceType || '')
1498      .toLowerCase();
1499    var $select = $();
1500
1501    if (serviceType) {
1502      $select = $root.find('.delivery-settings-wrapper#nav-' + serviceType + ' .rpress_get_delivery_dates')
1503        .first();
1504      if ($select.length) {
1505        return $select;
1506      }
1507    }
1508
1509    $select = $root.find('.delivery-settings-wrapper.active .rpress_get_delivery_dates')
1510      .first();
1511    if ($select.length) {
1512      return $select;
1513    }
1514
1515    $select = $root.find('.delivery-settings-wrapper.show .rpress_get_delivery_dates')
1516      .first();
1517    if ($select.length) {
1518      return $select;
1519    }
1520
1521    $select = $root.find('.delivery-settings-wrapper:visible .rpress_get_delivery_dates')
1522      .first();
1523    if ($select.length) {
1524      return $select;
1525    }
1526
1527    return $root.find('.rpress_get_delivery_dates')
1528      .first();
1529  }
1530  // Expose helpers for other frontend blocks that execute in separate jQuery scopes.
1531  window.rp_get_active_service_type = rp_get_active_service_type;
1532  window.rp_sync_service_ui_state = rp_sync_service_ui_state;
1533  window.rp_sync_service_selection_cookies = rp_sync_service_selection_cookies;
1534  window.rp_get_active_service_time_select = rp_get_active_service_time_select;
1535  window.rp_restore_service_time_select = rp_restore_service_time_select;
1536  window.rp_restore_service_date_select = rp_restore_service_date_select;
1537  window.rp_apply_service_defaults = rp_apply_service_defaults;
1538  window.rp_update_inline_service_display = rp_update_inline_service_display;
1539  window.rp_is_service_time_hidden = rp_is_service_time_hidden;
1540  window.rp_is_old_ui_ux_enabled = rp_is_old_ui_ux_enabled;
1541  window.rp_clear_service_selection_cookies = rp_clear_service_selection_cookies;
1542  window.rp_clear_old_ui_service_cookies = rp_clear_old_ui_service_cookies;
1543  window.rp_prepare_old_ui_modal_selection = rp_prepare_old_ui_modal_selection;
1544
1545  // When add button is hidden or in grid view, clicking a food card should behave like clicking add button.
1546  $(document).on('click', 'body.rpress-add-button-hidden .rpress-section .rpress_fooditem, .rpress_fooditems_grid .rpress_fooditem, .rpress-grid.rpress_fooditem', function (e) {
1547    var $target = $(e.target);
1548    if ($target.closest('a, button, input, select, textarea, label, .rpress_fooditem_buy_button, .rpress_purchase_submit_wrapper, .rpress_fooditem_quantity_wrapper, .rpress-thumbnail-popup').length) {
1549      return;
1550    }
1551
1552    var $card = $(this);
1553    if ($card.hasClass('product_not_available')) {
1554      return;
1555    }
1556
1557    var $addButton = $card.find('.rpress-add-to-cart')
1558      .first();
1559
1560    if (!$addButton.length || $addButton.hasClass('rp-loading') || $addButton.prop('disabled')) {
1561      return;
1562    }
1563
1564    e.preventDefault();
1565    $addButton.trigger('click');
1566  });
1567
1568  // Add to Cart (delegated to support AJAX category filtering & dynamic grid rendering)
1569  $(document).on('click', '.rpress-add-to-cart', function (e) {
1570      e.preventDefault();
1571      var _self = $(this);
1572      var fooditem_id = _self.attr('data-fooditem-id');
1573      var oldUiUxEnabled = rp_is_old_ui_ux_enabled();
1574      var hasRequiredServiceContext = rp_get_storage_data();
1575      if (window.rpJustSelectedService) {
1576        window.rpJustSelectedService = false;
1577        hasRequiredServiceContext = true;
1578      }
1579      var $serviceTypeScope = $('.rpress-delivery-wrap .rpress-tabs-wrapper:visible').first();
1580      var activeServiceTypeForValidation = rp_get_active_service_type(
1581        $serviceTypeScope.length ? $serviceTypeScope : $(document),
1582        rp_getCookie('service_type') || rp_scripts.default_service || 'delivery'
1583      );
1584      activeServiceTypeForValidation = rp_sync_service_ui_state($(document), activeServiceTypeForValidation) || activeServiceTypeForValidation;
1585      var forceOldUiServiceModal = rp_is_old_ui_delivery_context_invalid(activeServiceTypeForValidation, $(document));
1586
1587      if (oldUiUxEnabled && (!hasRequiredServiceContext || forceOldUiServiceModal)) {
1588        if (forceOldUiServiceModal) {
1589          tata.error('Error', rp_get_delivery_fee_context_error(activeServiceTypeForValidation), { position: "tr" });
1590        }
1591        rp_open_legacy_service_options_modal(fooditem_id);
1592        return;
1593      }
1594
1595      if (activeServiceTypeForValidation === 'delivery') {
1596        var delivery_zip = rp_getCookie('delivery_zip');
1597        var delivery_location = rp_getCookie('delivery_location');
1598        var delivery_address = rp_getCookie('delivery_address');
1599
1600        if (!delivery_zip) {
1601          var $rp_delivery_zone = $('input#rp_delivery_zone'); // adjust selector if needed
1602          // Check if the delivery zone input exists and has a value
1603          if ($rp_delivery_zone.length > 0 && !$rp_delivery_zone.val().trim()) {
1604            // Show error
1605            tata.error('Error', 'Please enter ZIP code', { position: "tr" });
1606
1607            // Trigger Edit button click after 1 second
1608            setTimeout(function () {
1609              $('#editDateTime').trigger('click');
1610            }, 500);
1611
1612            return; // stop further execution
1613          }
1614        }
1615
1616        if (!delivery_location) {
1617          var $rp_delivery_location = $('input#rp_delivery_location'); // adjust selector if needed
1618          if (!delivery_address) {
1619            // Check if the delivery zone input exists and has a value
1620            if ($rp_delivery_location.length > 0 && !$rp_delivery_location.val().trim()) {
1621              // Show error
1622              tata.error('Error', 'Please enter location', { position: "tr" });
1623
1624              // Trigger Edit button click after 1 second
1625              setTimeout(function () {
1626                $('#editDateTime').trigger('click');
1627              }, 500);
1628
1629              return; // stop further execution
1630            }
1631          }
1632        }
1633      }
1634
1635      var $serviceScope = $('.rpress-delivery-wrap .rpress-tabs-wrapper:visible')
1636        .first();
1637      var syncedSelection = rp_sync_service_selection_cookies(
1638        $serviceScope.length ? $serviceScope : $(document)
1639      );
1640      var serviceType = syncedSelection.serviceType;
1641
1642      var $serviceControlsScope = $('#rpressDateTime-content');
1643      if (!$serviceControlsScope.length) {
1644        $serviceControlsScope = $('#rpressDateTime');
1645      }
1646      if (!$serviceControlsScope.length) {
1647        $serviceControlsScope = $(document);
1648      }
1649
1650      var normalizedSelection = rp_apply_service_defaults($serviceControlsScope, serviceType);
1651      serviceType = normalizedSelection.serviceType || serviceType;
1652      var serviceDate = (normalizedSelection.serviceDate || '')
1653        .toString()
1654        .trim();
1655      var serviceTime = (normalizedSelection.serviceTime || '')
1656        .toString()
1657        .trim();
1658
1659      var getClosedMessage = function () {
1660        var selectors = [
1661          '.delivery-settings-wrapper#nav-' + serviceType + '.active.show .rpress-service-closed-message .rpress-closed-message-text:visible',
1662          '.delivery-settings-wrapper#nav-' + serviceType + '.active.show .rpress-service-closed-message:visible',
1663          '.delivery-settings-wrapper#nav-' + serviceType + ' .rpress-service-closed-message .rpress-closed-message-text:visible',
1664          '.delivery-settings-wrapper#nav-' + serviceType + ' .rpress-service-closed-message:visible',
1665          '#rpressDateTime .delivery-settings-wrapper.active.show .rpress-service-closed-message .rpress-closed-message-text:visible',
1666          '#rpressDateTime .delivery-settings-wrapper.active.show .rpress-service-closed-message:visible',
1667          '.delivery-settings-wrapper#nav-' + serviceType + '.active.show .rpress-service-closed-message .rpress-closed-message-text',
1668          '.delivery-settings-wrapper#nav-' + serviceType + '.active.show .rpress-service-closed-message',
1669          '#rpressDateTime .delivery-settings-wrapper.active.show .rpress-service-closed-message .rpress-closed-message-text',
1670          '#rpressDateTime .delivery-settings-wrapper.active.show .rpress-service-closed-message'
1671        ];
1672        for (var i = 0; i < selectors.length; i++) {
1673          var message = $(selectors[i])
1674            .first()
1675            .text()
1676            .trim();
1677          if (message && !/^\d{1,4}([./-])\d{1,2}\1\d{1,4}$/.test(message)) {
1678            return message;
1679          }
1680        }
1681        return '';
1682      };
1683
1684      var serviceClosedMessage = getClosedMessage();
1685      if (serviceClosedMessage) {
1686        tata.error('Error', serviceClosedMessage, { position: "tr" });
1687        return;
1688      }
1689
1690      var isServiceTimeDisabled = rp_is_service_time_hidden(serviceType);
1691
1692      if (!isServiceTimeDisabled && !serviceTime) {
1693        var closedMessage = serviceClosedMessage || getClosedMessage();
1694        if (closedMessage) {
1695          tata.error('Error', closedMessage, { position: "tr" });
1696        } else {
1697          $('#editDateTime').trigger('click');
1698          var $serviceDateModal = $('#rpressDateTime');
1699          var isDateTimeModalVisible = $serviceDateModal.length &&
1700            ($serviceDateModal.hasClass('is-open') || $serviceDateModal.attr('aria-hidden') === 'false') &&
1701            $serviceDateModal.find('.modal__container:visible').length > 0;
1702
1703          if (!isDateTimeModalVisible) {
1704            var $legacyServiceChange = $('.delivery-change:visible').first();
1705            if (!$legacyServiceChange.length) {
1706              $legacyServiceChange = $('.delivery-change').first();
1707            }
1708            if ($legacyServiceChange.length) {
1709              $legacyServiceChange.trigger('click');
1710            }
1711          }
1712        }
1713        return;
1714      }
1715      var rp_get_delivery_data = hasRequiredServiceContext;
1716      $('#rpressModal')
1717        .removeClass('rpress-delivery-options rpress-food-options checkout-error');
1718      $('#rpressModal .qty')
1719        .val('1');
1720      $('#rpressModal')
1721        .find('.cart-action-text')
1722        .html(rp_scripts.add_to_cart);
1723      if (!rp_get_delivery_data) {
1724        var action = 'rpress_show_delivery_options';
1725        var security = rp_scripts.service_type_nonce;
1726        $('#rpressModal')
1727          .addClass('show-service-options');
1728      } else {
1729        $('#rpressModal')
1730          .removeClass('show-service-options');
1731        var action = 'rpress_show_products';
1732        var security = rp_scripts.show_products_nonce;
1733      }
1734      var foodItemName = _self.attr('data-title');
1735      var price = _self.attr('data-price');
1736      var variable_price = _self.attr('data-variable-price');
1737      var data = {
1738        action: action,
1739        fooditem_id: fooditem_id,
1740        security: security,
1741        service_type: serviceType,
1742        selected_date: serviceDate,
1743        selected_time: serviceTime
1744      };
1745      $.ajax({
1746        type: "POST",
1747        data: data,
1748        dataType: "json",
1749        url: rp_scripts.ajaxurl,
1750        beforeSend: (jqXHR, status) => {
1751          _self.addClass('rp-loading');
1752          _self.find('.add-icon').addClass('icon-loading-toggle');
1753          _self.find('.rp-ajax-toggle-text')
1754            .addClass('rp-text-visibility');
1755        },
1756        xhrFields: {
1757          withCredentials: true
1758        },
1759        complete: (jqXHR, object) => {
1760          _self.removeClass('rp-loading');
1761          _self.find('.add-icon').removeClass('icon-loading-toggle');
1762          _self.find('.rp-ajax-toggle-text')
1763            .removeClass('rp-text-visibility');
1764
1765        },
1766        success: function (response) {
1767          if (response?.success === false && response?.data?.status === 'error') {
1768            tata.error('Error', response?.data?.error_msg, { position: "tr" });
1769            return;
1770          }
1771          MicroModal.show('rpressModal', {
1772            disableScroll: true
1773          });
1774          $('#rpressModal').removeClass('loading');
1775
1776          $('#rpressModal .modal-title')
1777            .html(response.data.html_title);
1778          $('#rpressModal .modal-body')
1779            .html(response.data.html);
1780          $('#rpressModal .cart-item-price')
1781            .html(response.data.price);
1782          $('#rpressModal .item-description')
1783            .html(response.data.description);
1784
1785          // Set the image only when one exists. An empty src makes the browser
1786          // re-request the page URL and render a broken image, so remove the
1787          // attribute and hide the element when the item has no photo.
1788          var $itemImage = $('#rpressModal .item-image');
1789          if (response.data.image_url) {
1790            $itemImage.attr('src', response.data.image_url).prop('hidden', false);
1791          } else {
1792            $itemImage.removeAttr('src').prop('hidden', true);
1793          }
1794          $('#rpressModal .cart-item-price')
1795            .attr('data-price', response.data.price_raw);
1796          // Trigger event so themes can refresh other areas.
1797          $(document.body)
1798            .trigger('opened_service_options', [response.data]);
1799          $('#rpressModal')
1800            .find('.submit-fooditem-button')
1801            .attr('data-cart-action', 'add-cart');
1802          $('#rpressModal')
1803            .find('.cart-action-text')
1804            .html(rp_scripts.add_to_cart);
1805          if (fooditem_id !== '' && price !== '') {
1806            $('#rpressModal')
1807              .find('.submit-fooditem-button')
1808              .attr('data-item-id', fooditem_id);
1809            $('#rpressModal')
1810              .find('.submit-fooditem-button')
1811              .attr('data-title', foodItemName);
1812            $('#rpressModal')
1813              .find('.submit-fooditem-button')
1814              .attr('data-item-price', price);
1815            $('#rpressModal')
1816              .find('.submit-fooditem-button')
1817              .attr('data-item-qty', 1);
1818          }
1819          update_modal_live_price('fooditem-details');
1820          rp_checked_default_subaddon();
1821        }
1822      });
1823    });
1824  // Update Cart
1825  // The whole cart item body is a role="button" edit trigger; Enter/Space fire it.
1826  $('.rpress-sidebar-cart')
1827    .on('keydown', '.rpress-edit-from-cart', function (e) {
1828      if (e.which === 13 || e.which === 32) {
1829        e.preventDefault();
1830        $(this).trigger('click');
1831      }
1832    })
1833    .on('click', '.rpress-edit-from-cart', function (e) {
1834      e.preventDefault();
1835      var _self = $(this);
1836      _self.parents('.rpress-cart-item')
1837        .addClass('edited');
1838      var CartItemId = _self.attr('data-remove-item');
1839      var FoodItemId = _self.attr('data-item-id');
1840      var FoodItemName = _self.attr('data-item-name');
1841      var FoodQuantity = _self.parents('.rpress-cart-item')
1842        .find('.rpress-cart-item-qty')
1843        .text();
1844      var action = 'rpress_edit_cart_fooditem';
1845      var security = rp_scripts.edit_cart_fooditem_nonce;
1846      var data = {
1847        action: action,
1848        cartitem_id: CartItemId,
1849        fooditem_id: FoodItemId,
1850        fooditem_name: FoodItemName,
1851        security: security,
1852      };
1853      if (CartItemId !== '') {
1854        $.ajax({
1855          type: "POST",
1856          data: data,
1857          dataType: "json",
1858          url: rp_scripts.ajaxurl,
1859          beforeSend: (jqXHR, status) => {
1860            _self.addClass('rp-loading');
1861            _self.find('.rp-ajax-toggle-text')
1862              .addClass('rp-text-visibility');
1863          },
1864          complete: (jqXHR, object) => {
1865            _self.removeClass('rp-loading');
1866            _self.find('.rp-ajax-toggle-text')
1867              .removeClass('rp-text-visibility');
1868          },
1869          xhrFields: {
1870            withCredentials: true
1871          },
1872          success: function (response) {
1873            MicroModal.show('rpressModal', {
1874              disableScroll: true
1875            });
1876            $('#rpressModal')
1877              .removeClass('checkout-error');
1878            $('#rpressModal')
1879              .removeClass('show-service-options');
1880            $('#rpressModal')
1881              .removeClass('loading');
1882            $('#rpressModal .modal-title')
1883              .html(response.data.html_title);
1884            $('#rpressModal')
1885              .find(".qty")
1886              .val(FoodQuantity);
1887            $('#rpressModal .item-description').html(response.data.description);
1888            $('#rpressModal')
1889              .find('.submit-fooditem-button')
1890              .attr('data-item-id', FoodItemId);
1891            $('#rpressModal')
1892              .find('.submit-fooditem-button')
1893              .attr('data-title', FoodItemName);
1894            // Set the image only when one exists (empty src re-requests the page
1895            // URL and shows a broken image); hide the element otherwise.
1896            var $editItemImage = $('#rpressModal .item-image');
1897            if (response.data.image_url) {
1898              $editItemImage.attr('src', response.data.image_url).prop('hidden', false);
1899            } else {
1900              $editItemImage.removeAttr('src').prop('hidden', true);
1901            }
1902            $('#rpressModal')
1903              .find('.submit-fooditem-button')
1904              .attr('data-cart-key', CartItemId);
1905            $('#rpressModal')
1906              .find('.submit-fooditem-button')
1907              .attr('data-cart-action', 'update-cart');
1908            $('#rpressModal')
1909              .find('.submit-fooditem-button')
1910              .find('.cart-action-text')
1911              .html(rp_scripts.update_cart);
1912            $('#rpressModal')
1913              .find('.submit-fooditem-button')
1914              .find('.cart-item-price')
1915              .html(response.data.price);
1916            $('#rpressModal')
1917              .find('.submit-fooditem-button')
1918              .find('.cart-item-price')
1919              .attr('data-price', response.data.price_raw);
1920            $('#rpressModal')
1921              .find('.submit-fooditem-button')
1922              .attr('data-item-qty', FoodQuantity);
1923            $('#rpressModal .modal-body')
1924              .html(response.data.html);
1925
1926            // Auto-check addons that were already selected.
1927            if (response.data.addon_items) {
1928              $.each(response.data.addon_items, function (i, addon) {
1929                var addonId = addon.addon_id;
1930                var qty = addon.quantity;
1931
1932                // Find all checkboxes that belong to this addon_id (multiple clones may exist)
1933                var $checkboxes = $('#rpressModal .modal-body input[type="checkbox"][value^="' + addonId + '|"]');
1934
1935                if ($checkboxes.length) {
1936                  $checkboxes.each(function (index, checkbox) {
1937                    var $cb = $(checkbox);
1938                    $cb.prop('checked', true);
1939
1940                    // Go to its quantity input inside .food-item-list
1941                    var $qtyInput = $cb.closest('.food-item-list').find('.addon_qty');
1942
1943                    if ($qtyInput.length) {
1944                      $qtyInput.val(qty);   // set correct quantity
1945
1946                      // 🔥 Optional: also mark its parent .food-item-list as "active" if your UI needs it
1947                      $cb.closest('.food-item-list').addClass('active');
1948                    }
1949                  });
1950                }
1951              });
1952            }
1953            update_modal_live_price('fooditem-update-details');
1954          }
1955        });
1956      }
1957    });
1958  // Add to Cart / Update Cart Button From Popup
1959  $(document).on('click', '.submit-fooditem-button', function (e) {
1960    e.preventDefault();
1961    var self = $(this);
1962    var cartAction = self.attr('data-cart-action');
1963    var text = self.find('span.cart-action-text').text();
1964    var validation = '';
1965    // Checking the Required & Max addon settings for Addons
1966    if (jQuery('.addons-wrapper').length > 0) {
1967      jQuery('.addons-wrapper').each(function (index, el) {
1968        var _self = jQuery(this);
1969        var addon = _self.attr('data-id');
1970        var is_required = _self.children('input.addon_is_required').val();
1971        var max_addons = _self.children('input.addon_max_limit').val();
1972        var min_addons = _self.children('input.addon_min_limit').val();
1973        var checked = _self.find('.food-item-list.active input:checked').length;
1974
1975        var customValidation = {
1976          isValid: true,
1977          message: '',
1978          element: _self,
1979          minAddons: min_addons,
1980          maxAddons: max_addons,
1981          checkedAddons: checked
1982        };
1983
1984        // Trigger custom validation hook
1985        $(document).trigger('rpress_addon_validation', customValidation);
1986        _self.find('.rp-addon-error')
1987          .removeClass('rp-addon-error');
1988        if (is_required == 'yes' && checked == 0) {
1989          _self.find('.rp-addon-required').addClass('rp-addon-error');
1990          validation = 1;
1991        }
1991 else if (max_addons != 0 && checked > max_addons) {
1992          _self.find('.rp-addon-required').addClass('rp-addon-error');
1993          _self.find('.rp-max-addon').addClass('rp-addon-error');
1994          _self.find(".rpress-addon-category").addClass('rp-addon-error');
1995
1996          validation = 1;
1997        } else if (min_addons != 0 && checked < min_addons) {
1998          _self.find('.rp-addon-required').addClass('rp-addon-error');
1999          _self.find('.rp-min-addon').addClass('rp-addon-error');
2000          _self.find(".rpress-addon-category").addClass('rp-addon-error');
2001
2002          validation = 1;
2003        } else if (!customValidation.isValid) {
2004          _self.find('.rp-addon-required').addClass('rp-addon-error');
2005          _self.find('.rp-min-addon').addClass('rp-addon-error');
2006          _self.find(".rpress-addon-category").addClass('rp-addon-error');
2007          validation = 1;
2008        }
2009
2010        if (validation === 1) {
2011          var $error = $('#rpressModal .rp-addon-error').first();
2012          if ($error.length) {
2013            $error[0].scrollIntoView({ behavior: 'smooth', block: 'start' });
2014          }
2015        }
2016
2017        if (validation != '') {
2018          self.removeClass('disable_click');
2019          self.find('.cart-action-text')
2020            .text(text);
2021          return false;
2022        }
2023      });
2024    }
2025    if (cartAction == 'add-cart' && validation == '') {
2026      self.addClass('disable_click');
2027      var this_form = self.parents('.modal')
2028        .find('form#fooditem-details .food-item-list.active input');
2029      var itemId = self.attr('data-item-id');
2030      var itemName = self.attr('data-title');
2031      var itemQty = self.attr('data-item-qty');
2032      var FormData = this_form.serializeArray();
2033      var SpecialInstruction = self.parents('.modal')
2034        .find('textarea.special-instructions')
2035        .val();
2036      var action = 'rpress_add_to_cart';
2037      var data = {
2038        action: action,
2039        fooditem_id: itemId,
2040        fooditem_qty: itemQty,
2041        special_instruction: SpecialInstruction,
2042        post_data: FormData,
2043        security: rp_scripts.add_to_cart_nonce
2044      };
2045      const float_menu = $(".container-actionmenu");
2046
2047      if (itemId !== '') {
2048        $.ajax({
2049          type: "POST",
2050          data: data,
2051          dataType: "json",
2052          url: rp_scripts.ajaxurl,
2053          xhrFields: {
2054            withCredentials: true
2055          },
2056          beforeSend: (jqXHR, object) => {
2057            self.addClass('rp-loading');
2058            self.find('.rp-ajax-toggle-text')
2059              .addClass('rp-text-visibility')
2060            if (float_menu.length > 0) {
2061              float_menu.removeClass("cart-has-items");
2062            }
2063          },
2064          complete: (jqXHR, object) => {
2065            self.removeClass('rp-loading');
2066            self.find('.rp-ajax-toggle-text')
2067              .removeClass('rp-text-visibility')
2068          },
2069          success: function (response) {
2070            if (response) {
2071              $('.rpress-mobile-cart-icons')
2072                .css({
2073                  display: 'flex'
2074                });
2075              self.removeClass('disable_click');
2076              self.find('.cart-action-text')
2077                .text(text);
2078              var serviceType = rp_getCookie('service_type');
2079              var serviceTime = rp_getCookie('service_time');
2080              var serviceTimeText = rp_getCookie('service_time_text');
2081              var serviceDate = rp_getCookie('delivery_date');
2082              $('ul.rpress-cart')
2083                .find('li.cart_item.empty')
2084                .remove();
2085              $('ul.rpress-cart')
2086                .find('li.cart_item.rpress_subtotal')
2087                .remove();
2088              $('ul.rpress-cart')
2089                .find('li.cart_item.cart-sub-total')
2090                .remove();
2091              $('ul.rpress-cart')
2092                .find('li.cart_item.rpress_cart_tax')
2093                .remove();
2094              $('ul.rpress-cart')
2095                .find('li.cart_item.rpress-cart-meta.rpress-delivery-fee')
2096                .remove();
2097              $('ul.rpress-cart')
2098                .find('li.cart_item.rpress-cart-meta.rpress_subtotal')
2099                .remove();
2100              $('ul.rpress-cart').append(response.cart_item);
2101              if (float_menu.length > 0) {
2102                float_menu.addClass("cart-has-items");
2103              }
2104
2105              rp_update_mobile_cart_summary(response.total, response.cart_quantity);
2106              if (serviceType !== undefined) {
2107                serviceLabel = window.localStorage.getItem('serviceLabel');
2108                var orderInfo = '<span class="delMethod">' + serviceLabel + ', ' + serviceDate + '</span>';
2109                if (serviceTime !== undefined) {
2110                  // Check if the string contains 'ASAP'
2111                  if (serviceTime.includes('ASAP')) {
2112                    // Remove 'ASAP' from the string
2113                    serviceTimeText = serviceTime.replace('ASAP', '');
2114                    serviceTimeText = rp_scripts.asap_txt + ' ' + serviceTimeText;
2115                  }
2116                  orderInfo += '<span class="delTime">, ' + serviceTimeText + '</span>';
2117                }
2118                $('.delivery-items-options')
2119                  .find('.delivery-opts')
2120                  .html(orderInfo);
2121                if ($('.delivery-wrap .delivery-change')
2122                  .length == 0) {
2123                  var changeText = rp_is_old_ui_ux_enabled() ? 'Change' : (rp_scripts.change_txt || 'Change?');
2124                  var helperHtml = rp_is_old_ui_ux_enabled() ? rp_get_delivery_change_helper_html() : '';
2125                  $("<a href='#' class='delivery-change'><span class='rp-ajax-toggle-text'>" + changeText + "</span></a>" + helperHtml)
2126                    .insertAfter(".delivery-opts");
2127                }
2128              }
2129              $('.delivery-items-options')
2130                .css('display', 'block');
2131              // Always reveal the cart summary/checkout once an item is added.
2132              // The ".rpress.item-order" header is now always present in the
2133              // template, so the removeClass below must not be gated by it or
2134              // the checkout button stays hidden until a page refresh.
2135              $('div.rpress-sidebar-main-wrap div.rpress-sidebar-cart-wrap').removeClass('empty-cart');
2136              if ($('div.rpress.item-order').length == 0) {
2137                var orderitems = $('<div class="rpress item-order"><h4>Ordered menu</h4><span>1 items</span></div>');
2138                $('div.rpress-sidebar-main-wrap div.rpress-sidebar-cart-wrap').prepend(orderitems);
2139              }
2140              if ($('li.rpress-cart-item')
2141                .length > 0) {
2142                $('a.rpress-clear-cart')
2143                  .show();
2144              } else {
2145                $('a.rpress-clear-cart')
2146                  .hide();
2147              }
2148              if (typeof response.cart_summary === 'string') {
2149                rp_refresh_sidebar_cart_summary(response.cart_summary);
2150              }
2151              $(document.body)
2152                .trigger('rpress_added_to_cart', [response]);
2153              MicroModal.close('rpressModal');
2154              tata.success(window.rp_scripts.success, self.attr('data-title') + window.rp_scripts.added_to_cart, {
2155                position: "tr"
2156              })
2157            }
2158          }
2159        })
2160      }
2161    }
2162    if (cartAction == 'update-cart' && validation == '') {
2163
2164      self.addClass('disable_click');
2165      var this_form = self.parents('.modal')
2166        .find('form#fooditem-update-details .food-item-list.active input');
2167      var itemId = self.attr('data-item-id');
2168      var itemPrice = self.attr('data-item-price');
2169      var cartKey = self.attr('data-cart-key');
2170      var itemQty = self.attr('data-item-qty');
2171      var FormData = this_form.serializeArray();
2172      var SpecialInstruction = self.parents('.modal')
2173        .find('textarea.special-instructions')
2174        .val();
2175      var action = 'rpress_update_cart_items';
2176      var data = {
2177        action: action,
2178        fooditem_id: itemId,
2179        fooditem_qty: itemQty,
2180        fooditem_cartkey: cartKey,
2181        special_instruction: SpecialInstruction,
2182        post_data: FormData,
2183        security: rp_scripts.update_cart_item_nonce
2184      };
2185
2186      if (itemId !== '') {
2187        $.ajax({
2188          type: "POST",
2189          data: data,
2190          dataType: "json",
2191          url: rp_scripts.ajaxurl,
2192          xhrFields: {
2193            withCredentials: true
2194          },
2195          success: function (response) {
2196            self.removeClass('disable_click');
2197            self.find('.cart-action-text')
2198              .text(text);
2199            if (response) {
2200              html = response.cart_item;
2201              $('ul.rpress-cart')
2202                .find('li.cart_item.empty')
2203                .remove();
2204              $('.rpress-cart >li.rpress-cart-item')
2205                .each(function (index, item) {
2206                  $(this)
2207                    .find("[data-cart-item]")
2208                    .attr('data-cart-item', index);
2209                  $(this)
2210                    .attr('data-cart-key', index);
2211                  $(this)
2212                    .attr('data-remove-item', index);
2213                });
2214              $('ul.rpress-cart')
2215                .find('li.edited')
2216                .replaceWith(function () {
2217                  let obj = $(html);
2218                  obj.attr('data-cart-key', response.cart_key);
2219                  obj.find(".rpress-edit-from-cart")
2220                    .attr("data-cart-item", response.cart_key);
2221                  obj.find(".rpress-edit-from-cart")
2222                    .attr("data-remove-item", response.cart_key);
2223                  obj.find("a.rpress_remove_from_cart")
2224                    .attr("data-cart-item", response.cart_key);
2225                  obj.find("a.rpress_remove_from_cart")
2226                    .attr("data-remove-item", response.cart_key);
2227                  return obj;
2228                });
2229              $('ul.rpress-cart')
2230                .find('.cart-total')
2231                .html(response.total);
2232              $('ul.rpress-cart')
2233                .find('.cart-subtotal')
2234                .html(response.subtotal);
2235              $('ul.rpress-cart')
2236                .find('.cart-tax')
2237                .html(response.tax);
2238              rp_update_mobile_cart_summary(response.total, response.cart_quantity);
2239              if (typeof response.cart_summary === 'string') {
2240                rp_refresh_sidebar_cart_summary(response.cart_summary);
2241              }
2242              $(document.body)
2243                .trigger('rpress_items_updated', [response]);
2244              MicroModal.close('rpressModal');
2245            }
2246          }
2247        });
2248      }
2249    }
2250  });
2251
2252  // --- Sidebar cart quantity stepper -------------------------------------
2253  // The − / value / + control on each sidebar cart line. +/− hit the
2254  // rpress_cart_item_quantity AJAX (keyed by cart_key, preserves add-ons); at
2255  // qty 1 the − morphs into a trash and reuses the existing remove flow.
2256  function rpSetStepperState($stepper) {
2257    var q = parseInt($stepper.find('.rp-qty-val').text(), 10) || 1;
2258    $stepper.toggleClass('is-one', q <= 1);
2259  }
2260  function rpSyncSteppers(scope) {
2261    $(scope || document).find('.rpress-qty-stepper').each(function () {
2262      rpSetStepperState($(this));
2263    });
2264  }
2265  function rpApplyCartItemResponse(response) {
2266    if (!response || typeof response.cart_item !== 'string' || response.cart_item === '') {
2267      return;
2268    }
2269    var $new = $(response.cart_item);
2270    $new.attr('data-cart-key', response.cart_key);
2271    var $old = $('ul.rpress-cart > li.rpress-cart-item[data-cart-key="' + response.cart_key + '"]').first();
2272    if ($old.length) {
2273      $old.replaceWith($new);
2274    }
2275    rpSyncSteppers($new);
2276    if (typeof response.cart_summary === 'string') {
2277      rp_refresh_sidebar_cart_summary(response.cart_summary);
2278    }
2279    rp_update_mobile_cart_summary(response.total, response.cart_quantity);
2280    $(document.body).trigger('rpress_items_updated', [response]);
2281  }
2282  function rpChangeCartQty($stepper, newQty) {
2283    if ($stepper.hasClass('rp-qty-busy')) { return; }
2284    $stepper.addClass('rp-qty-busy');
2285    $.ajax({
2286      type: 'POST',
2287      url: rp_scripts.ajaxurl,
2288      dataType: 'json',
2289      xhrFields: { withCredentials: true },
2290      data: {
2291        action: 'rpress_cart_item_quantity',
2292        cart_key: $stepper.attr('data-cart-key'),
2293        quantity: newQty,
2294        security: rp_scripts.update_cart_item_nonce
2295      },
2296      success: function (response) {
2297        $stepper.removeClass('rp-qty-busy');
2298        rpApplyCartItemResponse(response);
2299      },
2300      error: function () {
2301        $stepper.removeClass('rp-qty-busy');
2302      }
2303    });
2304  }
2305  $('body').on('click', '.rpress-qty-stepper .rp-qty-inc', function (e) {
2306    e.preventDefault();
2307    var $stepper = $(this).closest('.rpress-qty-stepper');
2308    var q = parseInt($stepper.find('.rp-qty-val').text(), 10) || 1;
2309    rpChangeCartQty($stepper, q + 1);
2310  });
2311  $('body').on('click', '.rpress-qty-stepper .rp-qty-dec', function (e) {
2312    e.preventDefault();
2313    var $stepper = $(this).closest('.rpress-qty-stepper');
2314    var q = parseInt($stepper.find('.rp-qty-val').text(), 10) || 1;
2315    if (q <= 1) {
2316      $stepper.closest('.rpress-cart-item').find('.rpress-remove-from-cart').trigger('click');
2317      return;
2318    }
2319    rpChangeCartQty($stepper, q - 1);
2320  });
2321  $(function () { rpSyncSteppers(document); });
2322  $(document.body).on('rpress_items_updated rpress_cart_item_removed rpress_cart_item_added', function () {
2323    rpSyncSteppers(document);
2324  });
2325  // -----------------------------------------------------------------------
2326
2327  // Add Service Date and Time
2328  $('body')
2329    .on('click', '.rpress-delivery-opt-update', function (e) {
2330      e.preventDefault();
2331      var _self = $(this);
2332      var foodItemId = (_self.attr('data-food-id') || '')
2333        .toString()
2334        .trim();
2335      if (!foodItemId) {
2336        foodItemId = ($('#rpressModal').attr('data-pending-fooditem-id') || '')
2337          .toString()
2338          .trim();
2339      }
2340      var $updateScope = _self.parents('.rpress-tabs-wrapper')
2341        .first();
2342      if (!$updateScope.length) {
2343        $updateScope = $('#rpressDateTime .rpress-tabs-wrapper')
2344          .first();
2345      }
2346
2347      var serviceType = '';
2348      var serviceLabel = '';
2349      var $activeServiceTab = $updateScope.find('.nav-item.active a, .single-service-selected.active')
2350        .first();
2351      if (!$activeServiceTab.length) {
2352        $activeServiceTab = $('.rpress-tabs-wrapper')
2353          .find('.nav-item.active a, .single-service-selected.active')
2354          .first();
2355      }
2356      if ($activeServiceTab.length) {
2357        serviceType = ($activeServiceTab.attr('data-service-type') || '')
2358          .toString()
2359          .toLowerCase();
2360        serviceLabel = ($activeServiceTab.text() || '')
2361          .toString()
2362          .trim();
2363        window.localStorage.setItem('serviceLabel', serviceLabel);
2364      }
2365
2366      var oldUiUxEnabled = rp_is_old_ui_ux_enabled();
2367      var hasMultipleServiceTabs = $updateScope.find('#rpressdeliveryTab .single-service-selected').length > 1;
2368      if (oldUiUxEnabled && hasMultipleServiceTabs && !serviceType) {
2369        tata.error('Error', 'Please select a service type', { position: "tr" });
2370        return false;
2371      }
2372
2373      var normalizedSelection = rp_apply_service_defaults(
2374        $updateScope.length ? $updateScope : $(document),
2375        serviceType,
2376        true,
2377        oldUiUxEnabled,
2378        true
2379      );
2380
2381      serviceType = normalizedSelection.serviceType || serviceType || rp_getCookie('service_type') || rp_scripts.default_service || 'delivery';
2382      if (oldUiUxEnabled) {
2383        var isDeliveryFeeContextValid = rp_has_valid_delivery_fee_context(serviceType, $updateScope);
2384        if (!isDeliveryFeeContextValid) {
2385          tata.error('Error', rp_get_delivery_fee_context_error(serviceType), { position: "tr" });
2386          rp_open_legacy_service_options_modal(foodItemId);
2387          return false;
2388        }
2389      }
2390      var serviceTime = normalizedSelection.serviceTime;
2391      var serviceTimeText = normalizedSelection.serviceTimeText || serviceTime;
2392      var serviceDate = normalizedSelection.serviceDate;
2393      var hasServiceDateSelect = rp_get_active_service_date_select(
2394        $updateScope.length ? $updateScope : $(document),
2395        serviceType
2396      ).length > 0;
2397      var hasServiceTimeSelect = rp_get_active_service_time_select(
2398        $updateScope.length ? $updateScope : $(document),
2399        serviceType
2400      ).length > 0;
2401      if (oldUiUxEnabled && hasServiceDateSelect && !serviceDate) {
2402        tata.error('Error', 'Please select a date', { position: "tr" });
2403        return false;
2404      }
2405      if (oldUiUxEnabled && hasServiceTimeSelect && !rp_is_service_time_hidden(serviceType) && !serviceTime) {
2406        tata.error('Error', 'Please select a time', { position: "tr" });
2407        return false;
2408      }
2409      var sDate = serviceDate || rp_getCookie('service_date') || '';
2410      var action = 'rpress_check_service_slot';
2411      var data = {
2412        action: action,
2413        serviceType: serviceType,
2414        serviceTime: serviceTime,
2415        service_date: sDate,
2416        security: rp_scripts.service_type_nonce,
2417      };
2418      $.ajax({
2419        type: "POST",
2420        data: data,
2421        dataType: "json",
2422        url: rpress_scripts.ajaxurl,
2423        xhrFields: {
2424          withCredentials: true
2425        },
2426        beforeSend: (jqXHR, status) => {
2427          _self.addClass('rp-loading');
2428          _self.find('.rp-ajax-toggle-text')
2429            .addClass('rp-text-visibility');
2430        },
2431        complete: (jqXHR, oject) => {
2432          _self.removeClass('rp-loading');
2433          _self.find('.rp-ajax-toggle-text')
2434            .removeClass('rp-text-visibility');
2435        },
2436        success: function (response) {
2437          _self.removeClass('rp-loading');
2438          _self.find('.rp-ajax-toggle-text')
2439            .removeClass('rp-text-visibility');
2440          if (response.status == 'error') {
2441            _self.text(rpress_scripts.update);
2442            if (oldUiUxEnabled) {
2443              window.rpDeliveryFeeValidationState = 'invalid';
2444            }
2445            tata.error(rp_scripts.error, response.error_msg || response.msg || rp_scripts.closed_message);
2446            return false;
2447          } else {
2448            if (oldUiUxEnabled) {
2449              window.rpDeliveryFeeValidationState = 'valid';
2450            }
2451            rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time);
2452            if (serviceDate) {
2453              rp_setCookie('service_date', serviceDate, rp_scripts.expire_cookie_time);
2454              rp_setCookie('delivery_date', normalizedSelection.serviceDateText || serviceDate, rp_scripts.expire_cookie_time);
2455              rp_setCookie('service_date_manual', serviceDate, rp_scripts.expire_cookie_time);
2456            }
2457            if (serviceTime) {
2458              rp_setCookie('service_time', serviceTime, rp_scripts.expire_cookie_time);
2459              rp_setCookie('service_time_text', serviceTimeText, rp_scripts.expire_cookie_time);
2460            } else {
2461              rp_setCookie('service_time', '', rp_scripts.expire_cookie_time);
2462              rp_setCookie('service_time_text', '', rp_scripts.expire_cookie_time);
2463            }
2464            if (oldUiUxEnabled) {
2465              rp_persist_delivery_context_for_update($updateScope, response, serviceType);
2466              if (!rp_has_valid_delivery_fee_context(serviceType, $updateScope)) {
2467                tata.error('Error', rp_get_delivery_fee_context_error(serviceType), { position: "tr" });
2468                rp_open_legacy_service_options_modal(foodItemId);
2469                return false;
2470              }
2471            }
2472            var $modal = $('#rpressModal');
2473            $modal.removeClass('show-service-options loading');
2474            if (foodItemId) {
2475              window.rpJustSelectedService = true;
2476              $modal.removeAttr('data-pending-fooditem-id data-service-modal-context');
2477              if (typeof MicroModal !== 'undefined') {
2478                MicroModal.close('rpressModal');
2479              }
2480              $modal.find('.modal-title').empty();
2481              $modal.find('.modal-body').empty();
2482              setTimeout(function () {
2483                var $targetBtn = $('#rpress_fooditem_' + foodItemId).find('.rpress-add-to-cart').first();
2484                if (!$targetBtn.length) {
2485                  $targetBtn = $('.rpress-add-to-cart[data-fooditem-id="' + foodItemId + '"]').first();
2486                }
2487                if ($targetBtn.length) {
2488                  $targetBtn.trigger('click');
2489                }
2490              }, 150);
2491            } else {
2492              $modal.removeAttr('data-pending-fooditem-id data-service-modal-context');
2493              if (typeof MicroModal !== 'undefined') {
2494                MicroModal.close('rpressModal');
2495              }
2496              $modal.find('.modal-title').empty();
2497              $modal.find('.modal-body').empty();
2498              var selectedDateLabel = normalizedSelection.serviceDateText || rp_getCookie('delivery_date') || serviceDate || '';
2499              if (serviceType && serviceTime) {
2500                $('.delivery-wrap .delivery-opts')
2501                  .html('<span class="delMethod">' + serviceLabel + ',</span> <span class="delTime"> ' + selectedDateLabel + ', ' + serviceTimeText + '</span>');
2502              } else if (serviceType) {
2503                $('.delivery-items-options')
2504                  .find('.delivery-opts')
2505                  .html('<span class="delMethod">' + serviceLabel + ',</span> <span class="delTime"> ' + selectedDateLabel + '</span>');
2506              }
2507            }
2508            //Trigger checked slot event so that it can be used by theme/plugins
2509            if (typeof response.total !== 'undefined') {
2510              rp_update_mobile_cart_summary(response.total, response.cart_quantity);
2511            }
2512            if (typeof response.cart_summary === 'string') {
2513              rp_refresh_sidebar_cart_summary(response.cart_summary);
2514            }
2515            $(document.body)
2516              .trigger('rpress_checked_slots', [response]);
2517            // Refresh checkout fragments without forcing a full page reload loop.
2518            if (rpress_scripts.is_checkout == '1') {
2519              $(document.body).trigger('rp-refresh-checkout-service');
2520            }
2521          }
2522        }
2523      });
2524    });
2525  $('body')
2526    .on('click', '.rpress-editaddress-submit-btn', function (e) {
2527      e.preventDefault();
2528      var _self = $(this);
2529      var foodItemId = _self.attr('data-food-id');
2530      var $updateScope = _self.parents('.rpress-tabs-wrapper')
2531        .first();
2532      if (!$updateScope.length) {
2533        $updateScope = $('#rpressDateTime .rpress-tabs-wrapper')
2534          .first();
2535      }
2536      var serviceType = '';
2537      var serviceLabel = '';
2538      var $activeServiceTab = $updateScope.find('.nav-item.active a, .single-service-selected.active')
2539        .first();
2540      if (!$activeServiceTab.length) {
2541        $activeServiceTab = $('.rpress-tabs-wrapper')
2542          .find('.nav-item.active a, .single-service-selected.active')
2543          .first();
2544      }
2545      if ($activeServiceTab.length) {
2546        serviceType = ($activeServiceTab.attr('data-service-type') || '')
2547          .toString()
2548          .toLowerCase();
2549        serviceLabel = ($activeServiceTab.text() || '')
2550          .toString()
2551          .trim();
2552        window.localStorage.setItem('serviceLabel', serviceLabel);
2553      }
2554
2555      var oldUiUxEnabled = rp_is_old_ui_ux_enabled();
2556      var hasMultipleServiceTabs = $updateScope.find('#rpressdeliveryTab .single-service-selected').length > 1;
2557      if (oldUiUxEnabled && hasMultipleServiceTabs && !serviceType) {
2558        tata.error('Error', 'Please select a service type', { position: "tr" });
2559        return false;
2560      }
2561
2562      var normalizedSelection = rp_apply_service_defaults(
2563        $updateScope.length ? $updateScope : $(document),
2564        serviceType,
2565        true,
2566        oldUiUxEnabled,
2567        true
2568      );
2569
2570      serviceType = normalizedSelection.serviceType || serviceType || rp_getCookie('service_type') || rp_scripts.default_service || 'delivery';
2571      var serviceTime = normalizedSelection.serviceTime;
2572      var serviceTimeText = normalizedSelection.serviceTimeText || serviceTime;
2573      var serviceDate = normalizedSelection.serviceDate;
2574      var hasServiceDateSelect = rp_get_active_service_date_select(
2575        $updateScope.length ? $updateScope : $(document),
2576        serviceType
2577      ).length > 0;
2578      var hasServiceTimeSelect = rp_get_active_service_time_select(
2579        $updateScope.length ? $updateScope : $(document),
2580        serviceType
2581      ).length > 0;
2582      if (oldUiUxEnabled && hasServiceDateSelect && !serviceDate) {
2583        tata.error('Error', 'Please select a date', { position: "tr" });
2584        return false;
2585      }
2586      if (oldUiUxEnabled && hasServiceTimeSelect && !rp_is_service_time_hidden(serviceType) && !serviceTime) {
2587        tata.error('Error', 'Please select a time', { position: "tr" });
2588        return false;
2589      }
2590      var sDate = serviceDate || rp_getCookie('service_date') || '';
2591      var action = 'rpress_check_service_slot';
2592      var data = {
2593        action: action,
2594        serviceType: serviceType,
2595        serviceTime: serviceTime,
2596        service_date: sDate,
2597        security: rp_scripts.service_type_nonce,
2598      };
2599      $.ajax({
2600        type: "POST",
2601        data: data,
2602        dataType: "json",
2603        url: rpress_scripts.ajaxurl,
2604        xhrFields: {
2605          withCredentials: true
2606        },
2607        beforeSend: (jqXHR, status) => {
2608          _self.addClass('rp-loading');
2609          _self.find('.rp-ajax-toggle-text')
2610            .addClass('rp-text-visibility');
2611        },
2612        complete: (jqXHR, oject) => {
2613          _self.removeClass('rp-loading');
2614          _self.find('.rp-ajax-toggle-text')
2615            .removeClass('rp-text-visibility');
2616        },
2617        success: function (response) {
2618          _self.removeClass('rp-loading');
2619          _self.find('.rp-ajax-toggle-text')
2620            .removeClass('rp-text-visibility');
2621          if (response.status == 'error') {
2622            _self.text(rpress_scripts.update);
2623            if (oldUiUxEnabled) {
2624              window.rpDeliveryFeeValidationState = 'invalid';
2625            }
2626            tata.error(rp_scripts.error, response.error_msg || response.msg || rp_scripts.closed_message);
2627            return false;
2628          } else {
2629            if (oldUiUxEnabled) {
2630              window.rpDeliveryFeeValidationState = 'valid';
2631            }
2632            rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time);
2633            if (serviceDate) {
2634              rp_setCookie('service_date', serviceDate, rp_scripts.expire_cookie_time);
2635              rp_setCookie('delivery_date', normalizedSelection.serviceDateText || serviceDate, rp_scripts.expire_cookie_time);
2636              rp_setCookie('service_date_manual', serviceDate, rp_scripts.expire_cookie_time);
2637            }
2638            if (serviceTime) {
2639              rp_setCookie('service_time', serviceTime, rp_scripts.expire_cookie_time);
2640              rp_setCookie('service_time_text', serviceTimeText || serviceTime, rp_scripts.expire_cookie_time);
2641            } else {
2642              rp_setCookie('service_time', '', rp_scripts.expire_cookie_time);
2643              rp_setCookie('service_time_text', '', rp_scripts.expire_cookie_time);
2644            }
2645            if (oldUiUxEnabled) {
2646              rp_persist_delivery_context_for_update($updateScope, response, serviceType);
2647            }
2648            $('#rpressModal')
2649              .removeClass('show-service-options');
2650            if (foodItemId) {
2651              $('#rpressModal')
2652                .addClass('loading');
2653              $('#rpress_fooditem_' + foodItemId)
2654                .find('.rpress-add-to-cart')
2655                .trigger('click');
2656              MicroModal.close('rpressModal');
2657            } else {
2658              MicroModal.close('rpressModal');
2659              var selectedDateLabel = normalizedSelection.serviceDateText || rp_getCookie('delivery_date') || serviceDate || '';
2660              if (serviceType && serviceTime) {
2661                $('.delivery-wrap .delivery-opts')
2662                  .html('<span class="delMethod">' + serviceLabel + ',</span> <span class="delTime"> ' + selectedDateLabel + ', ' + serviceTimeText + '</span>');
2663              } else if (serviceType) {
2664                $('.delivery-items-options')
2665                  .find('.delivery-opts')
2666                  .html('<span class="delMethod">' + serviceLabel + ',</span> <span class="delTime"> ' + selectedDateLabel + '</span>');
2667              }
2668            }
2669
2670            //Trigger checked slot event so that it can be used by theme/plugins
2671            if (typeof response.total !== 'undefined') {
2672              rp_update_mobile_cart_summary(response.total, response.cart_quantity);
2673            }
2674            if (typeof response.cart_summary === 'string') {
2675              rp_refresh_sidebar_cart_summary(response.cart_summary);
2676            }
2677            $(document.body)
2678              .trigger('rpress_checked_slots', [response]);
2679            // Refresh checkout fragments without forcing a full page reload loop.
2680            if (rpress_scripts.is_checkout == '1') {
2681              $(document.body).trigger('rp-refresh-checkout-service');
2682            }
2683          }
2684
2685          // Close the modal
2686          MicroModal.close('rpressDateTime');
2687        }
2688      });
2689    });
2690  // Open modal when button is clicked
2691  $(document).on('click', '#editDateTime', function (e) {
2692    e.preventDefault();
2693    var self = $(this);
2694
2695    var openLegacyServiceOptionsModal = function () {
2696      var $serviceChange = $('.delivery-change:visible').first();
2697      if (!$serviceChange.length) {
2698        $serviceChange = $('.delivery-change').first();
2699      }
2700
2701      if ($serviceChange.length) {
2702        $serviceChange.trigger('click');
2703        return true;
2704      }
2705
2706      if (!$('#rpressModal').length || !rp_scripts || !rp_scripts.ajaxurl || !rp_scripts.service_type_nonce) {
2707        return false;
2708      }
2709
2710      $('#rpressModal').addClass('show-service-options');
2711      $.ajax({
2712        type: "POST",
2713        data: {
2714          action: 'rpress_show_delivery_options',
2715          security: rp_scripts.service_type_nonce
2716        },
2717        dataType: "json",
2718        url: rp_scripts.ajaxurl,
2719        success: function (response) {
2720          if (!response || !response.data) {
2721            return;
2722          }
2723          $('#rpressModal .modal-title').html(response.data.html_title || '');
2724          $('#rpressModal .modal-body').html(response.data.html || '');
2725          if (typeof window.rp_prepare_old_ui_modal_selection === 'function') {
2726            window.rp_prepare_old_ui_modal_selection($('#rpressModal .modal-body'));
2727          }
2728          MicroModal.show('rpressModal', {
2729            disableScroll: true
2730          });
2731          $(document.body).trigger('opened_service_options', [response.data]);
2732        }
2733      });
2734
2735      return true;
2736    };
2737
2738    // Old UI/UX uses the legacy popup flow.
2739    if (rp_is_old_ui_ux_enabled()) {
2740      if (openLegacyServiceOptionsModal()) {
2741        return;
2742      }
2743    }
2744
2745    var $dateTimeModal = $('#rpressDateTime');
2746    var hasDateTimeMarkup = $dateTimeModal.length &&
2747      $dateTimeModal.find('.modal__overlay').length > 0 &&
2748      $dateTimeModal.find('.modal__container').length > 0;
2749
2750    if (!hasDateTimeMarkup) {
2751      if (openLegacyServiceOptionsModal()) {
2752        return;
2753      }
2754    }
2755
2756    var serviceType = rp_getCookie('service_type') || rp_scripts.default_service || 'delivery';
2757    var shouldPersistDefaults = !rp_is_old_ui_ux_enabled();
2758    if (shouldPersistDefaults) {
2759      rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time);
2760    }
2761    rp_apply_service_defaults(
2762      $('#rpressDateTime-content'),
2763      serviceType,
2764      shouldPersistDefaults,
2765      rp_is_old_ui_ux_enabled()
2766    );
2767    if (typeof window.rp_prepare_old_ui_modal_selection === 'function') {
2768      window.rp_prepare_old_ui_modal_selection($('#rpressDateTime-content'));
2769    }
2770
2771    $('.rpress-mobile-cart-icons').hide();
2772
2773    MicroModal.show('rpressDateTime', {
2774      disableScroll: true
2775    });
2776
2777  });
2778  $('body').on('click', '.rpress-editaddress-submit-btn', function (e) {
2779    e.preventDefault();
2780
2781    var $modal = $('#rpressDateTime-content');
2782    if (!$modal.length) {
2783      $modal = $('#rpressDateTime');
2784    }
2785    var activeServiceType = rp_getCookie('service_type') || rp_scripts.default_service || 'delivery';
2786    var selection = rp_apply_service_defaults($modal.length ? $modal : $(document), activeServiceType, true, false, true);
2787    var selectedDateText = (selection.serviceDateText || rp_getCookie('delivery_date') || '')
2788      .toString()
2789      .trim();
2790    var selectedTimeText = (selection.serviceTimeText || selection.serviceTime || rp_getCookie('service_time_text') || '')
2791      .toString()
2792      .trim();
2793
2794    if (selectedDateText) {
2795      $('#deliveryDate').text(selectedDateText);
2796    }
2797
2798    if (selectedTimeText) {
2799      $('#deliveryTime').text(selectedTimeText);
2800    }
2801
2802    $('.rpress-mobile-cart-icons').show();
2803  });
2804  // Update Service Date and Time
2805  $(document).on('click', '.delivery-change', function (e) {
2806    e.preventDefault();
2807    var self = $(this);
2808    var action = 'rpress_show_delivery_options';
2809    var ServiceType = rp_getCookie('service_type');
2810    var ServiceTime = rp_getCookie('service_time');
2811    var text = self.text();
2812    var data = {
2813      action: action,
2814      security: rp_scripts.service_type_nonce
2815    }
2816    $('#rpressModal').addClass('show-service-options');
2817    $.ajax({
2818      type: "POST",
2819      data: data,
2820      dataType: "json",
2821      url: rp_scripts.ajaxurl,
2822      beforeSend: (jqXHR, obj) => {
2823        self.addClass('rp-loading');
2824        self.find('.rp-ajax-toggle-text')
2825          .addClass('rp-text-visibility')
2826      },
2827      complete: (jqXHR, obj) => {
2828        self.removeClass('rp-loading');
2829        self.find('.rp-ajax-toggle-text')
2830          .removeClass('rp-text-visibility')
2831      },
2832      success: function (response) {
2833        // self.text(text);
2834        $('#rpressModal .modal-title')
2835          .html(response.data.html_title);
2836        $('#rpressModal .modal-body')
2837          .html(response.data.html);
2838        if (typeof window.rp_prepare_old_ui_modal_selection === 'function') {
2839          window.rp_prepare_old_ui_modal_selection($('#rpressModal .modal-body'));
2840        }
2841        MicroModal.show('rpressModal', {
2842          disableScroll: true
2843        });
2844        if ($('.rpress-tabs-wrapper')
2845          .length) {
2846          if (ServiceTime !== '') {
2847            $('.rpress-delivery-wrap')
2848              .find('select#rpress-' + ServiceType + '-hours')
2849              .val(ServiceTime);
2850          }
2851          $('.rpress-delivery-wrap')
2852            .find('a#nav-' + ServiceType + '-tab')
2853            .trigger('click');
2854        }
2855        // Trigger event so themes can refresh other areas.
2856        $(document.body).trigger('opened_service_options', [response.data]);
2857      }
2858    })
2859  });
2860  // Remove Item from Cart
2861  $(document)
2862    .on('click', '.rpress-remove-from-cart', function (event) {
2863      if ($('.rpress-remove-from-cart')
2864        .length == 1 && !confirm(rp_scripts.confirm_empty_cart)) {
2865        return false;
2866      }
2867      var $this = $(this),
2868        item = $this.data('cart-item'),
2869        action = $this.data('action'),
2870        id = $this.data('fooditem-id'),
2871        security = rp_scripts.edit_cart_fooditem_nonce,
2872        data = {
2873          action: action,
2874          cart_item: item,
2875          security: security
2876        };
2877      $.ajax({
2878        type: "POST",
2879        data: data,
2880        dataType: "json",
2881        url: rpress_scripts.ajaxurl,
2882        xhrFields: {
2883          withCredentials: true
2884        },
2885        success: function (response) {
2886          if (response.removed) {
2887            // Remove the $this cart item
2888            $("[data-cart-item='" + item + "']")
2889              .closest('.rpress-cart-item, .rpress_cart_item')
2890              .remove();
2891            // Check to see if the purchase form(s) for this fooditem is present on this page
2892            if ($('[id^=rpress_purchase_' + id + ']')
2893              .length) {
2894              $('[id^=rpress_purchase_' + id + '] .rpress_go_to_checkout')
2895                .hide();
2896              $('[id^=rpress_purchase_' + id + '] a.rpress-add-to-cart')
2897                .show()
2898                .removeAttr('data-rpress-loading');
2899              if (rpress_scripts.quantities_enabled == '1') {
2900                $('[id^=rpress_purchase_' + id + '] .rpress_fooditem_quantity_wrapper')
2901                  .show();
2902              }
2903            }
2904            rp_update_mobile_cart_summary(response.total, response.cart_quantity);
2905            $(document.body)
2906              .trigger('rpress_quantity_updated', [response.cart_quantity]);
2907            if (rpress_scripts.taxes_enabled) {
2908              $('.cart_item.rpress_subtotal span')
2909                .html(response.subtotal);
2910              $('.cart_item.rpress_cart_tax span')
2911                .html(response.tax);
2912            }
2913            $('.cart_item.rpress_total span.rpress-cart-quantity')
2914              .html(response.cart_quantity);
2915            $('.cart_item.rpress_total span.cart-total')
2916              .html(response.total);
2917            if (typeof response.cart_summary === 'string') {
2918              rp_refresh_sidebar_cart_summary(response.cart_summary);
2919            }
2920            if (response.cart_quantity == 0) {
2921              rp_clear_service_selection_cookies(false);
2922              $('#deliveryDate').text('');
2923              $('#deliveryTime').text('');
2924              $('.delivery-items-options').hide();
2925              $('li.rpress-cart-meta, .cart_item.rpress_subtotal, .rpress-cart-number-of-items, .cart_item.rpress_checkout, .cart_item.rpress_cart_tax, .cart_item.rpress_total')
2926                .hide();
2927              $('.rpress-cart')
2928                .each(function () {
2929                  var cart_wrapper = $(this)
2930                    .parent();
2931                  if (cart_wrapper) {
2932                    cart_wrapper.addClass('cart-empty')
2933                    cart_wrapper.removeClass('cart-not-empty');
2934                  }
2935                  if ($(this).is('ul')) {
2936                    $(this)
2937                      .append('<li class="cart_item empty">' + rpress_scripts.empty_cart_message + '</li>');
2938                  }
2939                });
2940            }
2941            $(document.body)
2942              .trigger('rpress_cart_item_removed', [response]);
2943            $('ul.rpress-cart > li.rpress-cart-item')
2944              .each(function (index, item) {
2945                $(this)
2946                  .find("[data-cart-item]")
2947                  .attr('data-cart-item', index);
2948                $(this)
2949                  .find("[data-remove-item]")
2950                  .attr('data-remove-item', index);
2951                $(this)
2952                  .attr('data-cart-key', index);
2953              });
2954            // check if no item in cart left
2955            if ($('li.rpress-cart-item')
2956              .length == 0) {
2957              $('div.rpress.item-order').hide();
2958              $('li.rpress-cart-meta')
2959                .hide();
2960              $('li.delivery-items-options')
2961                .hide();
2962              $('a.rpress-clear-cart')
2963                .hide();
2964            }
2965          }
2966        }
2967      });
2968      return false;
2969    });
2970  // Clear All Fooditems from Cart
2971  $(document)
2972    .on('click', 'a.rpress-clear-cart', function (e) {
2973      e.preventDefault();
2974      if (confirm(rp_scripts.confirm_empty_cart)) {
2975        var self = $(this);
2976        var old_text = self.html();
2977        var action = 'rpress_clear_cart';
2978        var data = {
2979          security: rp_scripts.clear_cart_nonce,
2980          action: action
2981        }
2982        $.ajax({
2983          type: "POST",
2984          data: data,
2985          dataType: "json",
2986          url: rp_scripts.ajaxurl,
2987          xhrFields: {
2988            withCredentials: true
2989          },
2990          beforeSend: (jqXHR, object) => {
2991            self.addClass('rp-loading')
2992            self.find('.rp-ajax-toggle-text')
2993              .addClass('rp-text-visibility')
2994          },
2995          complete: (jqXHR, object) => {
2996            self.removeClass('rp-loading')
2997            self.find('.rp-ajax-toggle-text')
2998              .removeClass('rp-text-visibility')
2999          },
3000          success: function (response) {
3001            if (response.status == 'success') {
3002              rp_clear_service_selection_cookies(false);
3003              $('#deliveryDate').text('');
3004              $('#deliveryTime').text('');
3005              rp_update_mobile_cart_summary(rp_format_currency_value(0), 0);
3006              $(document.body)
3007                .trigger('rpress_quantity_updated', [0]);
3008              $(".rpress-sidebar-main-wrap")
3009                .css("left", "100%")
3010                .removeClass('rp-cart-drawer-open');
3011              $('body').removeClass('rp-mobile-cart-open');
3012              $('ul.rpress-cart')
3013                .find('li.cart_item.rpress_total')
3014                .css('display', 'none');
3015              $('ul.rpress-cart')
3016                .find('li.cart_item.rpress_checkout')
3017                .css('display', 'none');
3018              $('ul.rpress-cart')
3019                .find('li.rpress-cart-item')
3020                .remove();
3021              $('ul.rpress-cart')
3022                .find('li.cart_item.empty')
3023                .remove();
3024              $('ul.rpress-cart')
3025                .find('li.rpress_subtotal')
3026                .remove();
3027              $('ul.rpress-cart')
3028                .find('li.rpress_cart_tax')
3029                .remove();
3030              $('ul.rpress-cart')
3031                .find('li.rpress-delivery-fee')
3032                .remove();
3033              rp_refresh_sidebar_cart_summary('');
3034              $('ul.rpress-cart')
3035                .append(response.response);
3036              $('.rpress-cart-number-of-items')
3037                .css('display', 'none');
3038              $('.delivery-items-options')
3039                .css('display', 'none');
3040              self.hide();
3041              tata.success(window.rp_scripts.success, window.rp_scripts.success_empty_cart, {
3042                position: "tr"
3043              })
3044            }
3045          }
3046        });
3047      }
3048    });
3049  // Proceed to Checkout
3050  $(document)
3051    .on('click', '.cart_item.rpress_checkout a', function (e) {
3052      e.preventDefault();
3053      rp_sync_service_selection_cookies($('.rpress-delivery-wrap .rpress-tabs-wrapper:visible').first());
3054      var checkoutServiceType = (
3055        rp_getCookie('service_type') ||
3056        rp_get_active_service_type($('.rpress-delivery-wrap .rpress-tabs-wrapper:visible').first(), rp_scripts.default_service || 'delivery') ||
3057        rp_scripts.default_service ||
3058        'delivery'
3059      ).toString().toLowerCase();
3060      if (rp_is_old_ui_ux_enabled()) {
3061        if (rp_is_old_ui_delivery_context_invalid(checkoutServiceType, $('#rpress_checkout_wrap').length ? $('#rpress_checkout_wrap') : $(document))) {
3062          tata.error('Error', rp_get_delivery_fee_context_error(checkoutServiceType), { position: "tr" });
3063          rp_open_legacy_service_options_modal('');
3064          return false;
3065        }
3066        if (!rp_has_valid_delivery_fee_context(checkoutServiceType, $('#rpress_checkout_wrap').length ? $('#rpress_checkout_wrap') : $(document))) {
3067          tata.error('Error', rp_get_delivery_fee_context_error(checkoutServiceType), { position: "tr" });
3068          rp_open_legacy_service_options_modal('');
3069          return false;
3070        }
3071      }
3072      var CheckoutUrl = rp_scripts.checkout_page;
3073      var _self = $(this);
3074      var OrderText = _self.text();
3075      var action = 'rpress_proceed_checkout';
3076      var data = {
3077        action: action,
3078        security: rp_scripts.proceed_checkout_nonce,
3079      }
3080
3081      $.ajax({
3082        type: "POST",
3083        data: data,
3084        dataType: "json",
3085        url: rp_scripts.ajaxurl,
3086        beforeSend: function () {
3087          _self.addClass('rp-loading');
3088          _self.children('.rp-ajax-toggle-text')
3089            .addClass('rp-text-visibility');
3090        },
3091        success: function (response) {
3092          if (response.status == 'error') {
3093            if (response.error_msg) {
3094              errorString = response.error_msg;
3095            }
3096            tata.error(rp_scripts.error, errorString);
3097            _self.removeClass('rp-loading');
3098            _self.children('.rp-ajax-toggle-text')
3099              .removeClass('rp-text-visibility');
3100            if (response && response.error_type === "service_time_not_set") {
3101              $("#editDateTime").trigger('click');
3102              return;
3103            }
3104          } else {
3105            window.location.replace(rp_scripts.checkout_page)
3106            return;
3107          }
3108        }
3109      })
3110    });
3111  $(document)
3112    .on('click', 'span.special-instructions-link', function (e) {
3113      e.preventDefault();
3114      $(this)
3115        .parent('div')
3116        .find('.special-instructions')
3117        .toggleClass('hide');
3118    });
3119  $('body')
3120    .on('click', '.rpress-filter-toggle', function () {
3121      $('div.rpress-filter-wrapper')
3122        .toggleClass('active');
3123    });
3124  function rp_get_mobile_cart_quantity_value() {
3125    var quantityText = $('.rp-mb-quantity').first().text();
3126    var quantity = parseInt(quantityText, 10);
3127
3128    if (isNaN(quantity) || quantity < 0) {
3129      quantity = 0;
3130    }
3131
3132    return quantity;
3133  }
3134
3135  function rp_open_mobile_cart_drawer() {
3136    $(".rpress-sidebar-main-wrap")
3137      .css("left", "0%")
3138      .addClass('rp-cart-drawer-open');
3139    $('body').addClass('rp-mobile-cart-open');
3140    $('.rpress-mobile-cart-icons').hide();
3141  }
3142
3143  function rp_close_mobile_cart_drawer() {
3144    $(".rpress-sidebar-main-wrap")
3145      .css("left", "100%")
3146      .removeClass('rp-cart-drawer-open');
3147    $('body').removeClass('rp-mobile-cart-open');
3148
3149    if (rp_get_mobile_cart_quantity_value() > 0) {
3150      $('.rpress-mobile-cart-icons').css('display', 'flex');
3151    } else {
3152      $('.rpress-mobile-cart-icons').hide();
3153    }
3154  }
3155
3156  $(".rp-cart-left-wrap")
3157    .click(function () {
3158      rp_open_mobile_cart_drawer();
3159    });
3160  //Triggering cart
3161  $(".rp-cart-right-wrap")
3162    .click(function () {
3163      $(".cart_item.rpress_checkout a")
3164        .trigger('click');
3165    });
3166  $(".close-cart-ic")
3167    .click(function () {
3168      rp_close_mobile_cart_drawer();
3169    });
3170  // Show Image on Modal
3171  if ($.fn.fancybox) {
3172    $(".rpress-thumbnail-popup")
3173      .fancybox({
3174        openEffect: 'elastic',
3175        closeEffect: 'elastic',
3176        helpers: {
3177          title: {
3178            type: 'inside'
3179          }
3180        }
3181      });
3182  }
3183  if ($(window)
3184    .width() > 991) {
3185    var totalHeight = $('header:eq(0)')
3186      .length > 0 ? $('header:eq(0)')
3187        .height() + 30 : 120;
3188    if ($(".sticky-sidebar")
3189      .length != '') {
3190      $('.sticky-sidebar')
3191        .rpressStickySidebar({
3192          additionalMarginTop: totalHeight,
3193          minWidth: 992
3194        });
3195    }
3196  } else {
3197    var totalHeight = $('header:eq(0)')
3198      .length > 0 ? $('header:eq(0)')
3199        .height() + 30 : 70;
3200  }
3201});
3202/* Make Addons and Variables clickable for Live Price */
3203jQuery(document)
3204  .ajaxComplete(function () {
3205    jQuery('#fooditem-details .food-item-list input')
3206      .on('click', function (event) {
3207        update_modal_live_price('fooditem-details');
3208      });
3209    jQuery('#fooditem-update-details .food-item-list input')
3210      .on('click', function (event) {
3211        update_modal_live_price('fooditem-update-details');
3212      });
3213  });
3214/* RestroPress Sticky Sidebar - Imported from rp-sticky-sidebar.js */
3215function rp_get_dynamic_scroll_offset() {
3216  var isOrderOnlineView = jQuery('body').hasClass('order-online') || jQuery('.order-online .rpress-section').length > 0;
3217  var overlayBottom = 0;
3218  var selectors = ['#wpadminbar'];
3219  var basePadding = 12;
3220  var viewportWidth = window.innerWidth || jQuery(window).width() || 1024;
3221  var offsetCap = viewportWidth <= 1024 ? 96 : 180;
3222
3223  if (!isOrderOnlineView) {
3224    selectors.push('header:eq(0)');
3225  }
3226
3227  selectors = selectors.concat([
3228    '.order-online .rpress-section .make-me-sticky:visible',
3229    '.desktop-scroll-menu .make-me-sticky:visible',
3230    '.mobile-scroll-menu .make-me-sticky:visible',
3231    '.rpress-mobile-menu-wrap .make-me-sticky:visible'
3232  ]);
3233
3234  selectors.forEach(function (selector) {
3235    jQuery(selector).each(function () {
3236      var $element = jQuery(this);
3237      if (!$element.is(':visible')) {
3238        return;
3239      }
3240
3241      var position = ($element.css('position') || '').toLowerCase();
3242      if (position !== 'fixed' && position !== 'sticky') {
3243        return;
3244      }
3245
3246      var rect = this.getBoundingClientRect ? this.getBoundingClientRect() : null;
3247      if (!rect || rect.height <= 0 || rect.bottom <= 0) {
3248        return;
3249      }
3250
3251      // Count only bars occupying the top viewport band.
3252      if (rect.top > 140) {
3253        return;
3254      }
3255
3256      overlayBottom = Math.max(overlayBottom, rect.bottom);
3257    });
3258  });
3259
3260  return Math.max(0, Math.min(offsetCap, Math.round(overlayBottom + basePadding)));
3261}
3262
3263function rp_resolve_category_target($trigger, preferredSelector) {
3264  if (!$trigger || !$trigger.length) {
3265    return jQuery();
3266  }
3267
3268  var selector = '';
3269  var dataId = parseInt($trigger.data('id'), 10);
3270  if (!isNaN(dataId) && dataId > 0) {
3271    selector = '#menu-category-' + dataId;
3272  } else if (typeof preferredSelector === 'string' && preferredSelector.length > 0) {
3273    selector = preferredSelector;
3274  } else {
3275    selector = $trigger.attr('href') || '';
3276  }
3277
3278  if (!selector) {
3279    return jQuery();
3280  }
3281
3282  if (selector.charAt(0) !== '#') {
3283    selector = '#' + selector;
3284  }
3285
3286  var $scope = $trigger.closest('.rpress-section');
3287  var $target = jQuery();
3288
3289  if ($scope.length) {
3290    $target = $scope.find(selector + '.rpress-element-title').first();
3291    if (!$target.length) {
3292      $target = $scope.find(selector).first();
3293    }
3294  }
3295
3296  if (!$target.length) {
3297    $target = jQuery(selector + '.rpress-element-title:visible').first();
3298  }
3299  if (!$target.length) {
3300    $target = jQuery(selector + '.rpress-element-title').first();
3301  }
3302  if (!$target.length) {
3303    $target = jQuery(selector + ':visible').first();
3304  }
3305  if (!$target.length) {
3306    $target = jQuery(selector).first();
3307  }
3308
3309  // Fallback for theme overrides that still use slug anchors like "#beer".
3310  if (!$target.length && selector.charAt(0) === '#') {
3311    var slug = selector.substring(1);
3312    if (slug && slug.indexOf('menu-category-') !== 0) {
3313      if ($scope.length) {
3314        $target = $scope.find('.menu-category-wrap[data-cat-id="' + slug + '"]').first().closest('.rpress-element-title');
3315      }
3316      if (!$target.length) {
3317        $target = jQuery('.menu-category-wrap[data-cat-id="' + slug + '"]:visible').first().closest('.rpress-element-title');
3318      }
3319      if (!$target.length) {
3320        $target = jQuery('.menu-category-wrap[data-cat-id="' + slug + '"]').first().closest('.rpress-element-title');
3321      }
3322    }
3323  }
3324
3325  var normalizeCategoryLabel = function (text) {
3326    return (text || '')
3327      .replace(/\(\s*\d+\s*\)/g, '')
3328      .replace(/\s+\d+\s*$/, '')
3329      .replace(/\s+/g, ' ')
3330      .trim()
3331      .toLowerCase();
3332  };
3333
3334  var getLinkLabel = function () {
3335    if (!$trigger || !$trigger.length) {
3336      return '';
3337    }
3338    var $clone = $trigger.clone();
3339    $clone.find('span').remove();
3340    return normalizeCategoryLabel($clone.text());
3341  };
3342
3343  var getHeadingLabel = function ($heading) {
3344    if (!$heading || !$heading.length) {
3345      return '';
3346    }
3347    var $title = $heading.find('h5.rpress-cat').first();
3348    return normalizeCategoryLabel($title.length ? $title.text() : $heading.text());
3349  };
3350
3351  // Guard against mismatched link->href mappings by validating label vs heading.
3352  if ($target.length) {
3353    var linkLabel = getLinkLabel();
3354    var targetLabel = getHeadingLabel($target);
3355    var mismatch = (
3356      linkLabel &&
3357      targetLabel &&
3358      targetLabel.indexOf(linkLabel) === -1 &&
3359      linkLabel.indexOf(targetLabel) === -1
3360    );
3361
3362    if (mismatch) {
3363      var $candidateHeadings = $scope.length
3364        ? $scope.find('.rpress-element-title')
3365        : jQuery('.rpress-element-title');
3366
3367      var $matchingByLabel = $candidateHeadings.filter(function () {
3368        var label = getHeadingLabel(jQuery(this));
3369        return label === linkLabel || label.indexOf(linkLabel) !== -1 || linkLabel.indexOf(label) !== -1;
3370      }).first();
3371
3372      if ($matchingByLabel.length) {
3373        $target = $matchingByLabel;
3374      } else {
3375        var $siblings = $trigger.closest('ul').find('a');
3376        var linkIndex = $siblings.index($trigger);
3377        if (linkIndex >= 0 && linkIndex < $candidateHeadings.length) {
3378          $target = $candidateHeadings.eq(linkIndex);
3379        }
3380      }
3381    }
3382  }
3383
3384  return $target;
3385}
3386
3387function rp_scroll_to_category_target($target) {
3388  if (!$target || !$target.length) {
3389    return;
3390  }
3391
3392  var $page = jQuery('html, body');
3393  var initialOffset = rp_get_dynamic_scroll_offset();
3394  var initialDestination = Math.max(0, $target.offset().top - initialOffset);
3395
3396  $page.stop(true).animate({
3397    scrollTop: initialDestination
3398  }, 420, function () {
3399    var raf = window.requestAnimationFrame || function (cb) {
3400      window.setTimeout(cb, 16);
3401    };
3402
3403    raf(function () {
3404      if (!$target.length) {
3405        return;
3406      }
3407
3408      var liveOffset = rp_get_dynamic_scroll_offset();
3409      var rect = $target[0].getBoundingClientRect();
3410      var delta = rect.top - liveOffset;
3411
3412      if (Math.abs(delta) > 3) {
3413        var correctedDestination = Math.max(0, jQuery(window).scrollTop() + delta);
3414        $page.stop(true).animate({
3415          scrollTop: correctedDestination
3416        }, 160);
3417      }
3418    });
3419  });
3420}
3421
3422function rp_close_action_menu_if_open() {
3423  var container = document.querySelector('.container-actionmenu');
3424  var burger = document.getElementById('actionburger');
3425  var menu = document.querySelector('.actionmenu');
3426
3427  if (!container || !burger || !menu) {
3428    return;
3429  }
3430
3431  if (!burger.classList.contains('is-expanded')) {
3432    return;
3433  }
3434
3435  burger.classList.remove('is-expanded');
3436  menu.classList.remove('slides-up');
3437  menu.classList.add('slides-down');
3438
3439  var icon = burger.querySelector('i');
3440  var textNode = burger.querySelector('.menu-text');
3441  var menuText = burger.getAttribute('data-text-menu') || 'Menu';
3442  var menuIcon = burger.getAttribute('data-icon-menu') || 'fa fa-cutlery';
3443
3444  if (icon) {
3445    icon.className = menuIcon;
3446  }
3447  if (textNode) {
3448    textNode.textContent = menuText;
3449  }
3450}
3451
3452jQuery(function ($) {
3453  if ($(window).width() > 991) {
3454    if ($(".sticky-sidebar").length > 0) {
3455      $('.sticky-sidebar').rpressStickySidebar({
3456        additionalMarginTop: rp_get_dynamic_scroll_offset(),
3457        minWidth: 992
3458      });
3459    }
3460  }
3461  // Category Navigation
3462  $('body')
3463    .on('click', '.rpress-category-link', function (e) {
3464      e.preventDefault();
3465      var $target = rp_resolve_category_target($(this));
3466      if (!$target.length) {
3467        return;
3468      }
3469      rp_scroll_to_category_target($target);
3470    });
3471  $('.rpress-category-item')
3472    .on('click', function () {
3473      $('.rpress-category-item')
3474        .removeClass('current');
3475      $(this)
3476        .addClass('current');
3477    });
3478});
3479jQuery(function ($) {
3480  // Dedicated handler for bottom mobile action-menu category links.
3481  // This ensures the action-menu path always scrolls via controlled offset logic.
3482  $('body')
3483    .off('click.rpActionMenuCategory', '.container-actionmenu .actionmenu a[href^="#menu-category-"]')
3484    .on('click.rpActionMenuCategory', '.container-actionmenu .actionmenu a[href^="#menu-category-"]', function (e) {
3485      e.preventDefault();
3486      e.stopPropagation();
3487      e.stopImmediatePropagation();
3488
3489      var $link = $(this);
3490      var $target = rp_resolve_category_target($link, $link.attr('href') || '');
3491      var selectedHref = $link.attr('href') || '';
3492      var selectedTermId = selectedHref.replace('#menu-category-', '');
3493
3494      // Keep all category nav UIs in sync immediately on click.
3495      $('.container-actionmenu .actionmenu .cd-dropdown-content a').removeClass('mnuactive');
3496      $link.addClass('mnuactive');
3497
3498      if (selectedTermId) {
3499        $('.pn-ProductNav_Link').removeAttr('aria-selected');
3500        $('.pn-ProductNav_Link[href="#menu-category-' + selectedTermId + '"]')
3501          .attr('aria-selected', 'true')
3502          .addClass('mnuactive');
3503
3504        $('.rpress-category-lists .rpress-category-link').removeClass('active');
3505        $('.rpress-category-lists .rpress-category-link').parent().removeClass('current');
3506        var $listMatch = $('.rpress-category-lists .rpress-category-link[data-id="' + selectedTermId + '"]').first();
3507        if ($listMatch.length) {
3508          $listMatch.addClass('active');
3509          $listMatch.parent().addClass('current');
3510        }
3511      }
3512
3513      rp_close_action_menu_if_open();
3514
3515      if ($target.length) {
3516        setTimeout(function () {
3517          rp_scroll_to_category_target($target);
3518        }, 60);
3519      }
3520
3521      return false;
3522    });
3523
3524  // Smooth scroll for category dropdown and horizontal nav
3525  $('body').on('click', '.cd-dropdown-content a, .pn-ProductNav_Link', function (e) {
3526    e.preventDefault();
3527    e.stopPropagation();
3528
3529    const $link = $(this);
3530    const targetSelector = $link.attr('href') || '';
3531    const $target = rp_resolve_category_target($link, targetSelector);
3532    const isActionMenuLink = $link.closest('.container-actionmenu').length > 0;
3533    const isCdDropdownLink = $link.closest('.cd-dropdown').length > 0;
3534    const selectedTermId = targetSelector.replace('#menu-category-', '');
3535
3536    if (isActionMenuLink) {
3537      rp_close_action_menu_if_open();
3538    }
3539
3540    if (isCdDropdownLink) {
3541      $('.cd-dropdown').removeClass('dropdown-is-active');
3542      $('.cd-dropdown-trigger').removeClass('dropdown-is-active');
3543      $('body').removeClass('cd-overlay-open');
3544      $('.rpress-cat-overlay').remove();
3545      $('.rpress-mobile-cart-icons').show();
3546    }
3547
3548    if ($target.length) {
3549      setTimeout(function () {
3550        rp_scroll_to_category_target($target);
3551      }, (isActionMenuLink || isCdDropdownLink) ? 80 : 0);
3552    }
3553
3554    if (selectedTermId) {
3555      $('.rpress-category-lists .rpress-category-link').removeClass('active');
3556      $('.rpress-category-lists .rpress-category-link').parent().removeClass('current');
3557      var $listLink = $('.rpress-category-lists .rpress-category-link[data-id="' + selectedTermId + '"]').first();
3558      if ($listLink.length) {
3559        $listLink.addClass('active');
3560        $listLink.parent().addClass('current');
3561      }
3562    }
3563
3564    // Set aria-selected on horizontal nav
3565    if ($link.hasClass('pn-ProductNav_Link')) {
3566      $('.pn-ProductNav_Link').removeAttr('aria-selected');
3567      $link.attr('aria-selected', 'true');
3568    }
3569
3570    // Highlight dropdown item
3571    if ($link.closest('.cd-dropdown-content').length) {
3572      $('.cd-dropdown-content li a').removeClass('mnuactive');
3573      $link.addClass('mnuactive');
3574    }
3575  });
3576
3577});
3578
3579/* Cart Quantity Changer - Imported from cart-quantity-changer.js */
3580jQuery(function ($) {
3581  //quantity Minus
3582  var liveQtyVal;
3583  jQuery(document)
3584    .on('click', '.qtyminus', function (e) {
3585      // Stop acting like a button
3586      e.preventDefault();
3587      // Get the field name
3588      fieldName = 'quantity';
3589      // Get its current value
3590      var currentVal = parseInt(jQuery('input[name=' + fieldName + ']')
3591        .val());
3592      // If it isn't undefined or its greater than 0
3593      if (!isNaN(currentVal) && currentVal > 1) {
3594        // Decrement one only if value is > 1
3595        jQuery('input[name=' + fieldName + ']')
3596          .val(currentVal - 1);
3597        jQuery('.qtyplus')
3598          .removeAttr('style');
3599        liveQtyVal = currentVal - 1;
3600      } else {
3601        // Otherwise put a 0 there
3602        jQuery('input[name=' + fieldName + ']')
3603          .val(1);
3604        jQuery('.qtyminus')
3605          .css('cursor', 'not-allowed');
3606        liveQtyVal = 1;
3607      }
3608      console.log(liveQtyVal);
3609
3610      jQuery(this)
3611        .parents('footer.modal-footer')
3612        .find('a.submit-fooditem-button')
3613        .attr('data-item-qty', liveQtyVal);
3614      jQuery(this)
3615        .parents('footer.modal__footer')
3616        .find('a.submit-fooditem-button')
3617        .attr('data-item-qty', liveQtyVal);
3618      // Updating live price as per quantity
3619      var total_price = parseFloat(jQuery('#rpressModal .cart-item-price')
3620        .attr('data-current'));
3621      var new_price = parseFloat(total_price * liveQtyVal);
3622      new_price_v = rp_format_currency_value(new_price);
3623      jQuery('#rpressModal .cart-item-price')
3624        .html(new_price_v);
3625    });
3626  jQuery(document)
3627    .on('click', '.qtyplus', function (e) {
3628      // Stop acting like a button
3629      e.preventDefault();
3630      // Get the field name
3631      fieldName = 'quantity';
3632      // Get its current value
3633      var currentVal = parseInt(jQuery('input[name=' + fieldName + ']').val());
3634      // If is not undefined
3635      if (!isNaN(currentVal)) {
3636        jQuery('input[name=' + fieldName + ']')
3637          .val(currentVal + 1);
3638        jQuery('.qtyminus')
3639          .removeAttr('style');
3640        liveQtyVal = currentVal + 1;
3641      } else {
3642        // Otherwise put a 0 there
3643        jQuery('input[name=' + fieldName + ']')
3644          .val(1);
3645        liveQtyVal = 1;
3646      }
3647      jQuery(this)
3648        .parents('footer.modal__footer')
3649        .find('a.submit-fooditem-button')
3650        .attr('data-item-qty', liveQtyVal);
3651      jQuery(this)
3652        .parents('footer.modal__footer')
3653        .find('a.submit-fooditem-button')
3654        .attr('data-item-qty', liveQtyVal);
3655      // Updating live price as per quantity
3656      var total_price = parseFloat(jQuery('#rpressModal .cart-item-price')
3657        .attr('data-current'));
3658      var new_price = parseFloat(total_price * liveQtyVal);
3659      new_price_v = rp_format_currency_value(new_price);
3660      jQuery('#rpressModal .cart-item-price')
3661        .html(new_price_v);
3662    });
3663  jQuery(document)
3664    .on("input", ".qty", function () {
3665      this.value = this.value.replace(/\D/g, '');
3666    });
3667  jQuery(document)
3668    .on('keyup', '.qty', function (e) {
3669      // Updating live price as per quantity
3670      liveQtyVal = jQuery(this)
3671        .val();
3672      var total_price = parseFloat(jQuery('#rpressModal .cart-item-price')
3673        .attr('data-current'));
3674      var new_price = parseFloat(total_price * liveQtyVal);
3675      new_price_v = rp_format_currency_value(new_price);
3676      jQuery('#rpressModal .cart-item-price')
3677        .html(new_price_v);
3678    });
3679});
3680jQuery(function ($) {
3681  // Detect whether list or grid is currently visible
3682  function getCurrentViewContainer() {
3683    if ($('.rpress_fooditems_list:visible').length) {
3684      return $('.rpress_fooditems_list');
3685    } else if ($('.rpress_fooditems_grid:visible').length) {
3686      return $('.rpress_fooditems_grid');
3687    } else {
3688      return $('.rpress_fooditems_list'); // default fallback
3689    }
3690  }
3691
3692  // Step 1: Add searchable data attribute to all .rpress-title-holder elements (in both views)
3693  $('.rpress-title-holder').each(function () {
3694    $(this).attr('data-search-term', $(this).text().toLowerCase());
3695  });
3696
3697  // Step 2: Live search
3698  $('#rpress-food-search').on('keyup', function () {
3699    var searchTerm = $(this).val().toLowerCase();
3700    var $viewContainer = getCurrentViewContainer();
3701    var visibleTermIds = [];
3702
3703    // Reset states
3704    $viewContainer.find('.rpress-element-title').removeClass('matched not-matched');
3705
3706    $viewContainer.find('.rpress_fooditem').each(function () {
3707      var $foodItem = $(this);
3708      var $titleHolder = $foodItem.find('.rpress-title-holder');
3709      var itemText = $titleHolder.data('search-term') || $titleHolder.text().toLowerCase();
3710      var termId = $foodItem.attr('data-term-id');
3711
3712      if (searchTerm === '' || itemText.includes(searchTerm)) {
3713        $foodItem.show();
3714        visibleTermIds.push(termId);
3715      } else {
3716        $foodItem.hide();
3717      }
3718    });
3719
3720    // Show/hide category headings
3721    $viewContainer.find('.rpress-element-title').each(function () {
3722      var termId = $(this).data('term-id');
3723      if (visibleTermIds.includes(termId.toString())) {
3724        $(this).show().addClass('matched');
3725      } else {
3726        $(this).hide().addClass('not-matched');
3727      }
3728    });
3729
3730    // === CATEGORY NAVIGATION HIDE/SHOW ===
3731    $('.rpress-category-lists .rpress-category-link').each(function () {
3732      var termId = $(this).data('id');
3733      if (visibleTermIds.includes(termId.toString())) {
3734        $(this).parent().show();
3735      } else {
3736        $(this).parent().hide();
3737      }
3738    });
3739
3740    // Dropdown menu in grid view
3741    $('.cd-dropdown-content a[href^="#menu-category-"]').each(function () {
3742      var termId = $(this).attr('href').replace('#menu-category-', '');
3743      if (visibleTermIds.includes(termId)) {
3744        $(this).closest('li').show();
3745      } else {
3746        $(this).closest('li').hide();
3747      }
3748    });
3749
3750    // Horizontal nav in grid view
3751    $('.pn-ProductNav_Contents .pn-ProductNav_Link').each(function () {
3752      var termId = $(this).attr('href').replace('#menu-category-', '');
3753      if (visibleTermIds.includes(termId)) {
3754        $(this).show();
3755      } else {
3756        $(this).hide();
3757      }
3758    });
3759
3760  });
3761});
3762
3763/* RestroPress active category highlighter */
3764jQuery(function ($) {
3765  const rp_category_links = $('.rpress-category-lists .rpress-category-link');
3766  const rp_category_links_grid = $('#pnProductNavContents .pn-ProductNav_Link, #pnProductNavContentsMobile .pn-ProductNav_Link');
3767  if (rp_category_links.length > 0) {
3768    function rp_apply_list_active_term(termId) {
3769      if (typeof termId === 'undefined' || termId === null || termId === '') {
3770        return;
3771      }
3772      var normalizedId = String(termId);
3773      var $matchedLink = rp_category_links.filter(function () {
3774        return String($(this).data('id') || '') === normalizedId;
3775      }).first();
3776
3777      if (!$matchedLink.length) {
3778        return;
3779      }
3780
3781      rp_category_links.removeClass('active');
3782      $matchedLink.addClass('active');
3783
3784      rp_category_links.parent().removeClass('current');
3785      $matchedLink.parent().addClass('current');
3786    }
3787
3788    function rp_detect_active_term_from_scroll() {
3789      var anchorLine = rp_get_dynamic_scroll_offset() + 2;
3790      var activeTermId = '';
3791      var firstVisibleTermId = '';
3792
3793      $('.rpress-element-title[id^="menu-category-"]:visible').each(function () {
3794        var $heading = $(this);
3795        var termId = String($heading.data('term-id') || '').trim();
3796        if (!termId) {
3797          var fallbackId = String($heading.attr('id') || '').replace('menu-category-', '');
3798          termId = fallbackId.trim();
3799        }
3800        if (!termId) {
3801          return;
3802        }
3803
3804        var top = this.getBoundingClientRect().top;
3805        if (!firstVisibleTermId && top > -120) {
3806          firstVisibleTermId = termId;
3807        }
3808        if (top <= anchorLine) {
3809          activeTermId = termId;
3810        }
3811      });
3812
3813      return activeTermId || firstVisibleTermId || '';
3814    }
3815
3816    var rp_update_list_active_on_scroll = function () {
3817      rp_apply_list_active_term(rp_detect_active_term_from_scroll());
3818    };
3819
3820    // Immediate visual selection for clicked list categories.
3821    $('body')
3822      .off('click.rpListActive', '.rpress-category-lists .rpress-category-link')
3823      .on('click.rpListActive', '.rpress-category-lists .rpress-category-link', function () {
3824        rp_apply_list_active_term($(this).data('id'));
3825      });
3826
3827    rp_update_list_active_on_scroll();
3828    window.addEventListener('scroll', rp_update_list_active_on_scroll, { passive: true });
3829    window.addEventListener('resize', rp_update_list_active_on_scroll);
3830  }
3831
3832  if (rp_category_links_grid.length > 0) {
3833    const header_height = $('header:eq(0)').height();
3834    // Drive BOTH the desktop and mobile category navs (identical markup, different
3835    // IDs). Previously only the desktop nav was wired, so on mobile the active
3836    // category never highlighted or moved its indicator on scroll.
3837    const navGroups = [
3838      { $nav: $('#pnProductNav'),       $contents: $('#pnProductNavContents'),       $indicator: $('#pnIndicator') },
3839      { $nav: $('#pnProductNavMobile'), $contents: $('#pnProductNavContentsMobile'), $indicator: $('#pnIndicatorMobile') }
3840    ].filter(function (g) { return g.$contents.length; });
3841    let current_category = rp_category_links_grid.eq(0).attr('href').substr(1);
3842
3843    navGroups.forEach(function (g) {
3844      if (g.$contents.css('position') === 'static') {
3845        g.$contents.css('position', 'relative');
3846      }
3847    });
3848
3849    function rpNavGroupVisible(g) {
3850      return g.$contents.length && g.$contents.is(':visible') && g.$contents[0].getBoundingClientRect().width > 0;
3851    }
3852
3853    // ---- helper: position one group's indicator under its active link ----
3854    function moveIndicatorInGroup(g, $link) {
3855      if (!$link || !$link.length || !g.$indicator.length) return;
3856      const linkRect = $link[0].getBoundingClientRect();
3857      const contentsRect = g.$contents[0].getBoundingClientRect();
3858      const left = Math.round(linkRect.left - contentsRect.left + (g.$contents.scrollLeft() || 0));
3859      const width = Math.round(linkRect.width);
3860      g.$indicator.css({ width: width + 'px', transform: 'translateX(' + left + 'px)' });
3861      scrollActiveIntoView(g, $link);
3862    }
3863
3864    // ---- move the indicator under the active category in every VISIBLE nav ----
3865    function moveIndicatorTo(category) {
3866      navGroups.forEach(function (g) {
3867        if (!rpNavGroupVisible(g)) return; // skip the hidden nav (e.g. mobile on desktop)
3868        const $link = g.$contents.find('.pn-ProductNav_Link').filter('[href="#' + category + '"]');
3869        if ($link.length) moveIndicatorInGroup(g, $link);
3870      });
3871    }
3872
3873    // ---- helper: scroll a group's scroller so the link is visible/centered ----
3874    function scrollActiveIntoView(g, $link) {
3875      if (!$link || !$link.length) return;
3876
3877      // Choose real scroller (outer nav) - fallback to contents if outer missing
3878      const $scroller = g.$nav.length ? g.$nav : g.$contents;
3879      if (!$scroller.length) return;
3880
3881      const scrollerEl = $scroller[0];
3882      const maxScroll = scrollerEl.scrollWidth - scrollerEl.clientWidth;
3883
3884      const linkRect = $link[0].getBoundingClientRect();
3885      const scrollerRect = scrollerEl.getBoundingClientRect();
3886
3887      // Current scrollLeft
3888      const currentScroll = $scroller.scrollLeft();
3889
3890      // left of link relative to scrollable content coordinates:
3891      // (element left on screen - scroller left on screen) + currentScroll
3892      let leftRelativeToScroller = linkRect.left - scrollerRect.left + currentScroll;
3893
3894      // center the link
3895      let desired = leftRelativeToScroller - (scrollerEl.clientWidth / 2) + ($link.outerWidth() / 2);
3896
3897      // clamp
3898      desired = Math.max(0, Math.min(desired, maxScroll));
3899
3900      // If the inner contents currently has a transform (arrow animation in progress),
3901      // animated scrollLeft may behave unexpectedly. In that case use scrollIntoView fallback:
3902      const contentsTransform = getComputedStyle(g.$contents[0]).transform;
3903      if (contentsTransform && contentsTransform !== 'none') {
3904        // fallback - ask the browser to scroll the nearest scrollable ancestor
3905        try {
3906          $link[0].scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' });
3907          return;
3908        } catch (e) {
3909          // if not supported, continue to jQuery animate fallback
3910        }
3911      }
3912
3913      // animate scrollLeft (smooth)
3914      $scroller.stop().animate({ scrollLeft: desired }, 350);
3915    }
3916
3917    // ---- main scanning function (updates current_category + classes) ----
3918    function RpScrollingCategoriesgrid() {
3919      // determine current category based on section positions
3920      rp_category_links_grid.each(function () {
3921        const section_id = $(this).attr('href').substr(1);
3922        const section = document.getElementById(section_id);
3923        if (section && section.getBoundingClientRect().top < header_height + 40) {
3924          current_category = section_id;
3925        }
3926      });
3927
3928      // Update active link classes/aria
3929      const $activeLink = rp_category_links_grid
3930        .removeAttr('aria-selected').removeClass('mnuactive')
3931        .filter(`[href="#${current_category}"]`)
3932        .attr('aria-selected', 'true').addClass('mnuactive');
3933
3934      // Move indicator + ensure visible (in every visible nav)
3935      if ($activeLink.length) {
3936        moveIndicatorTo(current_category);
3937      }
3938
3939      // Sync the dropdown menu
3940      $(".cd-dropdown-content a")
3941        .removeClass("mnuactive")
3942        .filter(`[href="#${current_category}"]`)
3943        .addClass("mnuactive");
3944    }
3945
3946    // Run once on load
3947    RpScrollingCategoriesgrid();
3948
3949    // Update on page scroll / resize (throttle-friendly native listeners)
3950    window.addEventListener('scroll', RpScrollingCategoriesgrid, { passive: true });
3951    window.addEventListener('resize', RpScrollingCategoriesgrid);
3952
3953    // Utility to get current section in view (used elsewhere)
3954    function getCurrentCategoryInView() {
3955      let scrollTop = $(window).scrollTop();
3956      let current = null;
3957
3958      $(".rpress-category-lists .rpress-category-wrap").each(function () {
3959        if ($(this).offset().top <= scrollTop + 100) {
3960          current = $(this).attr("id");
3961        }
3962      });
3963
3964      return current;
3965    }
3966
3967    // On window scroll (content scroll, not nav scroll) — keep dropdown and indicator in sync
3968    $(window).on("scroll", function () {
3969      let current = getCurrentCategoryInView();
3970      if (!current) return;
3971
3972      const $active = rp_category_links_grid.filter(`[href="#${current}"]`);
3973      if ($active.length) {
3974        moveIndicatorTo(current);
3975
3976        // Sync dropdown
3977        const activeHref = $active.attr("href");
3978        $(".cd-dropdown-content a").removeClass("mnuactive");
3979        $(`.cd-dropdown-content a[href="${activeHref}"]`).addClass("mnuactive");
3980      }
3981    });
3982
3983    // Nav link click instant feedback
3984    $(document).on("click", ".pn-ProductNav_Link", function (e) {
3985      const $this = $(this);
3986      // Move indicator & scroll into view immediately (in every visible nav)
3987      moveIndicatorTo($this.attr("href").substr(1));
3988
3989      // Sync dropdown
3990      const activeHref = $this.attr("href");
3991      $(".cd-dropdown-content a").removeClass("mnuactive");
3992      $(`.cd-dropdown-content a[href="${activeHref}"]`).addClass("mnuactive");
3993    });
3994
3995  }
3996
3997  $(document)
3998    .ready(function () {
3999      var getActiveServiceTimeSelect = (typeof window.rp_get_active_service_time_select === 'function')
4000        ? window.rp_get_active_service_time_select
4001        : function ($scope, preferredServiceType) {
4002          var $root = ($scope && $scope.length) ? $scope : $(document);
4003          var serviceType = (preferredServiceType || '').toLowerCase();
4004          var $select = $();
4005
4006          if (serviceType) {
4007            $select = $root.find('.delivery-settings-wrapper#nav-' + serviceType + ' .rpress-hrs').first();
4008            if ($select.length) {
4009              return $select;
4010            }
4011          }
4012
4013          $select = $root.find('.delivery-settings-wrapper.active .rpress-hrs').first();
4014          if ($select.length) {
4015            return $select;
4016          }
4017
4018          return $root.find('#rpress-delivery-hours, .rpress-hrs').first();
4019        };
4020
4021      var restoreServiceTimeSelect = (typeof window.rp_restore_service_time_select === 'function')
4022        ? window.rp_restore_service_time_select
4023        : function ($select, serviceTime) {
4024          if (!$select || !$select.length) {
4025            return '';
4026          }
4027
4028          var requestedTime = (serviceTime || '').trim();
4029          var selectedValue = '';
4030
4031          if (requestedTime && $select.find('option[value="' + requestedTime + '"]').length) {
4032            selectedValue = requestedTime;
4033          } else if (requestedTime) {
4034            var $matchingOption = $select.find('option').filter(function () {
4035              return $(this).text().trim() === requestedTime;
4036            }).first();
4037            if ($matchingOption.length) {
4038              selectedValue = $matchingOption.val();
4039            }
4040          }
4041
4042          if (!selectedValue) {
4043            var $firstSelectableOption = $select.find('option').filter(function () {
4044              var optionValue = ($(this).val() || '').toString().trim();
4045              return optionValue !== '' && !$(this).prop('disabled');
4046            }).first();
4047            if (!$firstSelectableOption.length) {
4048              $firstSelectableOption = $select.find('option').first();
4049            }
4050            selectedValue = $firstSelectableOption.val() || '';
4051          }
4052
4053          if (selectedValue) {
4054            $select.val(selectedValue);
4055          }
4056
4057          return selectedValue;
4058        };
4059      var applyServiceDefaults = (typeof window.rp_apply_service_defaults === 'function')
4060        ? window.rp_apply_service_defaults
4061        : null;
4062
4063      var checkoutUpdateInFlight = false;
4064      var lastCheckoutServiceType = '';
4065      var checkoutServiceTabSelector = '#rpress_checkout_wrap .single-service-selected, .rp-checkout-service-option .single-service-selected, #rpress_checkout_order_details .rpress-delivery-options .single-service-selected, .rpress-delivery-options .single-service-selected, #rpressdeliveryTab .single-service-selected';
4066      var checkoutServiceTimeSelector = '#rpress_checkout_wrap .rpress-hrs, .rp-checkout-service-option .rpress-hrs, #rpress_checkout_order_details .rpress-delivery-options .rpress-hrs, .rpress-hrs';
4067      var getCheckoutServiceScope = function () {
4068        var $scope = $('.rp-checkout-service-option').first();
4069        if ($scope.length) {
4070          return $scope;
4071        }
4072
4073        $scope = $('#rpress_checkout_order_details .rpress-delivery-options .rpress-tabs-wrapper').first();
4074        if ($scope.length) {
4075          return $scope;
4076        }
4077
4078        $scope = $('#rpress_checkout_order_details .rpress-tabs-wrapper').first();
4079        if ($scope.length) {
4080          return $scope;
4081        }
4082
4083        $scope = $('#rpress_checkout_wrap .rpress-delivery-options .rpress-tabs-wrapper').first();
4084        if ($scope.length) {
4085          return $scope;
4086        }
4087
4088        $scope = $('.rpress-delivery-wrap .rpress-tabs-wrapper').first();
4089        if ($scope.length) {
4090          return $scope;
4091        }
4092
4093        return $('#rpress_checkout_wrap').first();
4094      };
4095      var findCheckoutServiceTab = function (serviceType) {
4096        serviceType = (serviceType || '').toLowerCase();
4097        if (!serviceType) {
4098          return $();
4099        }
4100
4101        var $scope = getCheckoutServiceScope();
4102        if (!$scope.length) {
4103          return $();
4104        }
4105
4106        return $scope.find('#rpressdeliveryTab .single-service-selected[data-service-type="' + serviceType + '"]')
4107          .first();
4108      };
4109      var syncCheckoutServiceTabs = function (serviceType) {
4110        serviceType = (serviceType || '').toLowerCase();
4111        if (!serviceType) {
4112          return;
4113        }
4114
4115        var $activeServiceTab = findCheckoutServiceTab(serviceType);
4116        if (!$activeServiceTab.length) {
4117          return;
4118        }
4119
4120        var $wrapper = $activeServiceTab.closest('.rpress-tabs-wrapper');
4121        $wrapper.find('#rpressdeliveryTab .nav-item').removeClass('active');
4122        $wrapper.find('#rpressdeliveryTab .single-service-selected')
4123          .removeClass('active')
4124          .attr('aria-selected', 'false');
4125
4126        $activeServiceTab
4127          .addClass('active')
4128          .attr('aria-selected', 'true');
4129        $activeServiceTab.closest('.nav-item').addClass('active');
4130
4131        var targetTab = $activeServiceTab.attr('href');
4132        if (targetTab && targetTab.charAt(0) === '#') {
4133          $wrapper.find('.delivery-settings-wrapper').removeClass('active show');
4134          $wrapper.find(targetTab).addClass('active show');
4135        }
4136
4137        var checkoutServiceLabel = ($activeServiceTab.find('.rpress-service-tab-label').first().text() || $activeServiceTab.text() || '')
4138          .toString()
4139          .trim();
4140        var $checkoutServiceHeading = $wrapper.find('.rpress-checkout-service-heading').first();
4141        if ($checkoutServiceHeading.length) {
4142          $checkoutServiceHeading
4143            .removeClass('is-service-delivery is-service-pickup')
4144            .addClass('is-service-' + serviceType);
4145          if (checkoutServiceLabel) {
4146            $checkoutServiceHeading.find('.rpress-checkout-service-heading-text')
4147              .text(checkoutServiceLabel);
4148          }
4149        }
4150      };
4151
4152      var refreshCheckoutServiceOption = async function () {
4153        if ($('#rpress_checkout_order_details').length === 0) {
4154          return;
4155        }
4156
4157        if (!rp_scripts.update_service_nonce) {
4158          return;
4159        }
4160
4161        if (checkoutUpdateInFlight) {
4162          return;
4163        }
4164
4165        checkoutUpdateInFlight = true;
4166        $('#rpress_checkout_order_details')
4167          .addClass('rp-loading');
4168
4169        try {
4170          const requestBody = new URLSearchParams();
4171          requestBody.set('action', 'rpress_checkout_update_service_option');
4172          requestBody.set('security', rp_scripts.update_service_nonce);
4173
4174          const promiseData = await fetch(rp_scripts.ajaxurl, {
4175            method: 'POST',
4176            credentials: 'same-origin',
4177            headers: {
4178              'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
4179            },
4180            body: requestBody.toString()
4181          });
4182          if (!promiseData.ok) {
4183            throw new Error('Checkout refresh request failed');
4184          }
4185
4186          const html = await promiseData.json();
4187          if (!html || !html.success || !html.data) {
4188            throw new Error('Invalid checkout refresh payload');
4189          }
4190
4191          $('#rpress_checkout_order_details')
4192            .replaceWith(html.data['order_html']);
4193          $('#rpress_checkout_cart_wrap')
4194            .html(html.data['cart_html']);
4195          $('.rpress_cart_amount')
4196            .replaceWith(html.data['total_amount']);
4197          var restoredServiceType = rp_getCookie('service_type') || lastCheckoutServiceType;
4198          syncCheckoutServiceTabs(restoredServiceType);
4199          var $checkoutScope = getCheckoutServiceScope();
4200          if (applyServiceDefaults) {
4201            applyServiceDefaults($checkoutScope.length ? $checkoutScope : $(document), restoredServiceType);
4202          } else {
4203            var $activeTimeSelect = getActiveServiceTimeSelect($checkoutScope, restoredServiceType);
4204            restoreServiceTimeSelect($activeTimeSelect, rp_getCookie('service_time'));
4205          }
4206          $(document.body)
4207            .trigger('rp-checkout-update-service-option', [html]);
4208        } catch (e) {
4209          // Skip transient checkout refresh failures.
4210        } finally {
4211          checkoutUpdateInFlight = false;
4212          $('#rpress_checkout_order_details')
4213            .removeClass('rp-loading');
4214        }
4215      };
4216
4217      // Infinate scroll for order history page 
4218      createObserver();
4219      //Select service type on checkout page 
4220      let chkServiceType = (rp_getCookie('service_type') || '')
4221        .toLowerCase();
4222      if (!chkServiceType) {
4223        var $initialCheckoutScope = getCheckoutServiceScope();
4224        chkServiceType = ($initialCheckoutScope.find('#rpressdeliveryTab .single-service-selected.active')
4225          .first()
4226          .data('service-type') || '')
4227          .toLowerCase();
4228        if (chkServiceType) {
4229          rp_setCookie('service_type', chkServiceType, rp_scripts.expire_cookie_time);
4230        }
4231      }
4232      if (chkServiceType) {
4233        syncCheckoutServiceTabs(chkServiceType);
4234        const $serviceTab = findCheckoutServiceTab(chkServiceType);
4235        lastCheckoutServiceType = chkServiceType;
4236        if ($serviceTab.length) {
4237          var $checkoutScope = getCheckoutServiceScope();
4238          if (applyServiceDefaults) {
4239            applyServiceDefaults($checkoutScope.length ? $checkoutScope : $(document), chkServiceType);
4240          } else {
4241            var $activeTimeSelect = getActiveServiceTimeSelect($checkoutScope, chkServiceType);
4242            restoreServiceTimeSelect($activeTimeSelect, rp_getCookie('service_time'));
4243          }
4244        }
4245      }
4246      $(document)
4247        .off('click.rpressCheckoutService', checkoutServiceTabSelector)
4248        .on('click.rpressCheckoutService', checkoutServiceTabSelector, async function (event) {
4249          const $clickedTab = $(this);
4250          if (!$clickedTab.closest('#rpress_checkout_wrap, .rp-checkout-service-option, #rpress_checkout_order_details, .rpress-delivery-wrap, .rpress-tabs-wrapper, .rpress-delivery-options, #rpressdeliveryTab, #rpressDateTime').length) {
4251            return;
4252          }
4253
4254          event.preventDefault();
4255          const serviceType_ = String($clickedTab
4256            .data('service-type') || '')
4257            .toLowerCase();
4258
4259          if (!serviceType_) {
4260            return;
4261          }
4262
4263          if (serviceType_ === lastCheckoutServiceType && $('#rpress_checkout_order_details').length > 0) {
4264            return;
4265          }
4266
4267          lastCheckoutServiceType = serviceType_;
4268          syncCheckoutServiceTabs(serviceType_);
4269          rp_setCookie('service_type', serviceType_, rp_scripts.expire_cookie_time);
4270          var $checkoutScope = getCheckoutServiceScope();
4271          if (applyServiceDefaults) {
4272            applyServiceDefaults($checkoutScope.length ? $checkoutScope : $(document), serviceType_);
4273          } else {
4274            var $activeTimeSelect = getActiveServiceTimeSelect($checkoutScope, serviceType_);
4275            if ($activeTimeSelect.length) {
4276              var selectedTime = $activeTimeSelect.val() || '';
4277              var selectedTimeText = $activeTimeSelect.find('option:selected')
4278                .text()
4279                .trim();
4280              if (selectedTime) {
4281                rp_setCookie('service_time', selectedTime, rp_scripts.expire_cookie_time);
4282              }
4283              if (selectedTimeText) {
4284                rp_setCookie('service_time_text', selectedTimeText, rp_scripts.expire_cookie_time);
4285              }
4286            }
4287          }
4288          await refreshCheckoutServiceOption();
4289        });
4290      //set cookies on checkout page onchange service type
4291      $(document)
4292        .off('change.rpressCheckoutServiceTime', checkoutServiceTimeSelector)
4293        .on('change.rpressCheckoutServiceTime', checkoutServiceTimeSelector, function (event) {
4294          if (!$(this).closest('#rpress_checkout_wrap, .rp-checkout-service-option, #rpress_checkout_order_details, .rpress-delivery-wrap, .rpress-tabs-wrapper, .rpress-delivery-options, #rpressdeliveryTab, #rpressDateTime').length) {
4295            return;
4296          }
4297
4298          if (!event.originalEvent) {
4299            return;
4300          }
4301          var $checkoutScope = getCheckoutServiceScope();
4302          $checkoutScope.find('.rpress-delivery-opt-update')
4303            .first()
4304            .trigger('click');
4305        });
4306      $(document.body)
4307        .off('rp-refresh-checkout-service.rpress')
4308        .on('rp-refresh-checkout-service.rpress', function () {
4309          refreshCheckoutServiceOption();
4310        });
4311      $(document.body)
4312        .off('rpress_checkout_error.rpressScroll')
4313        .on('rpress_checkout_error.rpressScroll', function () {
4314          setTimeout(function () {
4315            var $errors = $('.rpress_errors:visible, .rpress-errors-wrap:visible, .rpress-alert-error:visible, .rpress-error:visible').first();
4316            if ($errors.length) {
4317              var targetTop = Math.max(0, $errors.offset().top - 120);
4318              $('html, body').stop().animate({ scrollTop: targetTop }, 400);
4319            }
4320          }, 50);
4321        });
4322      //Remove the additional service date dropdown
4323      if (typeof rp_st_vars !== 'undefined' && rp_st_vars.enabled_sevice_type == 'delivery_and_pickup') {
4324        $('.delivery-settings-wrapper#nav-pickup .delivery-time-wrapper:eq(0)')
4325          .remove();
4326      }
4327      var selectedServiceType = chkServiceType || rp_getCookie('service_type');
4328      var $checkoutScope = getCheckoutServiceScope();
4329      if (applyServiceDefaults) {
4330        applyServiceDefaults($checkoutScope.length ? $checkoutScope : $(document), selectedServiceType);
4331      } else {
4332        var serviceTime = rp_getCookie('service_time');
4333        if (serviceTime) {
4334          var $activeTimeSelect = getActiveServiceTimeSelect($checkoutScope, selectedServiceType);
4335          restoreServiceTimeSelect($activeTimeSelect, serviceTime);
4336        }
4337      }
4338    })
4339
4340  var rpressClearingFees = false;
4341  $(document).on('click', 'a.rpress_cart_remove_item_btn', function (e) {
4342    var btnCount = $('.rpress_cart_remove_item_btn').length;
4343
4344    // Check if there's only one element
4345    if (btnCount === 1 && !rpressClearingFees) {
4346      e.preventDefault();
4347      e.stopImmediatePropagation();
4348      var $btn = $(this);
4349      rpressClearingFees = true;
4350
4351      var postData = {
4352        action: 'rpress_remove_fees_after_empty_cart',
4353        security: rp_scripts.clear_cart_nonce,
4354        gateway: rpress_gateway
4355      };
4356
4357      $.ajax({
4358        type: "POST",
4359        data: postData,
4360        dataType: "json",
4361        url: rpress_global_vars.ajaxurl,
4362        success: function (response) {
4363          // Trigger a click event on the same button
4364          $btn.click();
4365        }
4366      }).fail(function (data) {
4367        rpressClearingFees = false;
4368      });
4369    }
4370  });
4371  // 
4372});
4373let page = 1;
4374let rpressOrderHistoryLoading = false;
4375const infinateCallback = async function (entries, observer) {
4376  for (var i = 0; i < entries.length; i++) {
4377    let cahnge = entries[i];
4378    if (cahnge.isIntersecting && !rpressOrderHistoryLoading) {
4379      rpressOrderHistoryLoading = true;
4380      const $loadContainer = jQuery('#rp-order-history-infi-load-container');
4381      $loadContainer
4382        .html('<h2 class="rp-infi-load"><div class="rp-infi-loading">Loading...</div></h2>');
4383      page = page + 1;
4384      try {
4385        const data = await fetch(`${rp_scripts.ajaxurl}?action=rpress_more_order_history&security=${rp_scripts.order_details_nonce}&paged=${page}`);
4386        const html = await data.json();
4387        const responseData = html && html.data ? html.data : {};
4388        const $historyGrid = jQuery('#rpress_user_history .rpress-order-history-grid, #rpress_user_history .repress-history-inner')
4389          .first();
4390        if (responseData.html && $historyGrid.length) {
4391          $historyGrid.append(responseData.html);
4392        }
4393        if (String(responseData.found_post || '0') === '0') {
4394          $loadContainer.hide();
4395          observer.unobserve(cahnge.target);
4396        } else {
4397          $loadContainer.empty();
4398        }
4399      } catch (error) {
4400        page = Math.max(1, page - 1);
4401        $loadContainer.empty();
4402        if (window.console && window.console.log) {
4403          console.log(error);
4404        }
4405      } finally {
4406        rpressOrderHistoryLoading = false;
4407      }
4408    }
4409  }
4410}
4411const createObserver = () => {
4412  const options = {
4413    threshold: 0,
4414  }
4415  const lastDiv = document.getElementById('rp-order-history-infi-load-container');
4416  if (!lastDiv) return;
4417  const observer = new IntersectionObserver(infinateCallback, options);
4418  observer.observe(lastDiv)
4419}
4420// Refresh page after coming from prev page
4421if (performance.navigation.type == 2) {
4422  var navReloadKey = 'rpress_nav_reloaded';
4423  if (!window.sessionStorage.getItem(navReloadKey)) {
4424    window.sessionStorage.setItem(navReloadKey, '1');
4425    location.reload(true);
4426  }
4427} else {
4428  window.sessionStorage.removeItem('rpress_nav_reloaded');
4429}
4430jQuery('.rpress_fooditems_list').find('.rpress_fooditem_inner').each(function (index, item) {
4431  if (0 === jQuery(this).find('.rpress-thumbnail-holder').length) {
4432    jQuery(this).addClass('no-thumbnail-img');
4433  }
4434});
4435jQuery(document).ready(function ($) {
4436  $(document).on('change', '.rp-variable-price-option', function () {
4437    rp_checked_default_subaddon();
4438  });
4439});
4440
4441jQuery(document).ready(function ($) {
4442  function rp_get_mobile_cart_quantity_from_dom() {
4443    var selectors = [
4444      '.rp-mb-quantity',
4445      '.rpress-cart-head-count .rpress-cart-quantity',
4446      'span.rpress-cart-quantity'
4447    ];
4448
4449    for (var i = 0; i < selectors.length; i++) {
4450      var rawValue = $(selectors[i]).first().text();
4451      if (!rawValue) {
4452        continue;
4453      }
4454
4455      var parsedValue = parseInt(String(rawValue).replace(/[^0-9-]/g, ''), 10);
4456      if (!isNaN(parsedValue) && parsedValue >= 0) {
4457        return parsedValue;
4458      }
4459    }
4460
4461    var cartItemCount = $('ul.rpress-cart > li.rpress-cart-item').length;
4462    return cartItemCount > 0 ? cartItemCount : 0;
4463  }
4464
4465  function rp_sync_mobile_cart_bar_state() {
4466    var $mobileCartBar = $('.rpress-mobile-cart-icons');
4467    var $actionMenuContainer = $('.container-actionmenu');
4468    var $mobileCartDrawer = $('.rpress-sidebar-main-wrap');
4469
4470    if (!$mobileCartBar.length && !$actionMenuContainer.length) {
4471      return;
4472    }
4473
4474    var quantity = rp_get_mobile_cart_quantity_from_dom();
4475    var hasItems = quantity > 0;
4476    var isTransientlyHidden = $('body').hasClass('rp-mobile-cart-open') ||
4477      $('body').hasClass('cd-overlay-open') ||
4478      $('.cd-dropdown').hasClass('dropdown-is-active') ||
4479      $('#rpressDateTime.is-open, #rpressModal.is-open, #rpressDateTime[aria-hidden="false"], #rpressModal[aria-hidden="false"]').length > 0;
4480
4481    if ($mobileCartBar.length) {
4482      if (!hasItems) {
4483        $mobileCartDrawer
4484          .css('left', '100%')
4485          .removeClass('rp-cart-drawer-open');
4486        $('body').removeClass('rp-mobile-cart-open');
4487        $mobileCartBar.hide();
4488      } else if (!isTransientlyHidden) {
4489        $mobileCartBar.css('display', 'flex');
4490      }
4491    }
4492
4493    $actionMenuContainer.toggleClass('cart-has-items', hasItems);
4494  }
4495
4496  rp_sync_mobile_cart_bar_state();
4497  setTimeout(rp_sync_mobile_cart_bar_state, 120);
4498  $(window).on('load pageshow resize', rp_sync_mobile_cart_bar_state);
4499  $(document.body).on('rpress_items_updated rpress_quantity_updated rpress_cart_item_removed rpress_checked_slots', function () {
4500    setTimeout(rp_sync_mobile_cart_bar_state, 20);
4501  });
4502
4503  $(document.body).on('rpress_cart_item_removed', function (event, response) {
4504    var isCheckout = false;
4505    if (typeof rp_scripts !== 'undefined' && rp_scripts.is_checkout === '1') {
4506      isCheckout = true;
4507    } else if (typeof rpress_scripts !== 'undefined' && rpress_scripts.is_checkout === '1') {
4508      isCheckout = true;
4509    }
4510
4511    if (isCheckout) {
4512      if (response && response.cart_quantity == 0) {
4513        var pleaseWaitText = (typeof rp_scripts !== 'undefined' && rp_scripts.please_wait) ? rp_scripts.please_wait : 'Please Wait...';
4514        $('#rpress_checkout_wrap').html('<div class="rpress-empty-cart-loading" style="text-align:center; padding: 50px 0;"><div class="rpress-loading-spinner" style="border: 4px solid rgba(0,0,0,.1); width: 36px; height: 36px; border-radius: 50%; border-left-color: #ED5575; animation: spin 1s linear infinite; margin: 0 auto 15px auto;"></div><p>' + pleaseWaitText + '</p></div>');
4515        if (!$('#rpress-spinner-style').length) {
4516          $('head').append('<style id="rpress-spinner-style">@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }</style>');
4517        }
4518        window.location.reload();
4519      } else {
4520        $(document.body).trigger('rp-refresh-checkout-service.rpress');
4521      }
4522    }
4523  });
4524
4525  // Handle tab switching and cookie update on service tab click
4526  $(document)
4527    .off('click.rpressServiceTabs', '.rpress-tabs-wrapper .nav-link')
4528    .on('click.rpressServiceTabs', '.rpress-tabs-wrapper .nav-link', function (e) {
4529      var $this = $(this);
4530      var $wrapper = $this.closest('.rpress-tabs-wrapper');
4531
4532      // Checkout has a dedicated service-switch flow; skip the generic tab updater here.
4533      if ($wrapper.closest('.rp-checkout-service-option, #rpress_checkout_order_details').length) {
4534        return;
4535      }
4536
4537      e.preventDefault();
4538
4539      // Remove active class from all nav-items and nav-links
4540      $wrapper.find('.nav-item').removeClass('active');
4541      $wrapper.find('.nav-link').removeClass('active');
4542
4543      // Add active class to clicked tab
4544      $this.addClass('active');
4545      $this.closest('.nav-item').addClass('active');
4546
4547      // Show the tab content if needed
4548      var targetTab = $this.attr('href');
4549      if (targetTab) {
4550        var $targetPane = $wrapper.closest('.rpress-time-preference-wrap, .rpress-delivery-wrap, .rp-checkout-service-option, #rpress_checkout_order_details')
4551          .find(targetTab)
4552          .first();
4553
4554        if (!$targetPane.length) {
4555          $targetPane = $(targetTab).first();
4556        }
4557
4558        if ($targetPane.length) {
4559          var $tabContent = $targetPane.closest('.tab-content');
4560          if ($tabContent.length) {
4561            $tabContent.find('.tab-pane').removeClass('active show');
4562          } else {
4563            $wrapper.find('.tab-pane').removeClass('active show');
4564          }
4565          $targetPane.addClass('active show');
4566        }
4567      }
4568
4569      // Update cookies for service type and label
4570      var serviceType = String($this.data('service-type') || '')
4571        .toLowerCase();
4572      var serviceLabel = $this.text().trim();
4573      var oldUiUxEnabled = (typeof window.rp_is_old_ui_ux_enabled === 'function') && window.rp_is_old_ui_ux_enabled();
4574      if (serviceType) {
4575        rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time);
4576        var $dateTimeModal = $('#rpressDateTime');
4577        var isDateTimeModalOpen = $dateTimeModal.length &&
4578          ($dateTimeModal.hasClass('is-open') || $dateTimeModal.attr('aria-hidden') === 'false');
4579
4580        updataModalOnServiceTypeChange(serviceType);
4581        if (oldUiUxEnabled) {
4582          if (typeof window.rp_prepare_old_ui_modal_selection === 'function') {
4583            window.rp_prepare_old_ui_modal_selection($wrapper.length ? $wrapper : $(document));
4584          }
4585        } else if (typeof window.rp_apply_service_defaults === 'function') {
4586          window.rp_apply_service_defaults($wrapper.length ? $wrapper : $(document), serviceType);
4587        }
4588      }
4589      if (typeof Cookies !== 'undefined') {
4590        Cookies.set('service_label', serviceLabel, { expires: 1 });
4591      }
4592
4593      // Optionally update UI somewhere else if needed
4594      $('.delivery-opts').html('<span class="delMethod">' + serviceLabel + '</span>');
4595    });
4596
4597  /**
4598 * Fire a ajax call to update the modal 
4599 * on change of service type
4600 * @author RestroPress
4601 * @param {string} service_type
4602 */
4603  var rpModalSwitchRequestSeq = 0;
4604  const updataModalOnServiceTypeChange = function (service_type) {
4605    var requestedServiceType = String(service_type || '')
4606      .toLowerCase();
4607    var requestSeq = ++rpModalSwitchRequestSeq;
4608
4609    $.get(`${rp_scripts.ajaxurl}?action=rpress_update_modal_on_service_switch&service_type=${service_type}&security=${rp_scripts.service_type_nonce}`, function (res) {
4610      // Ignore stale out-of-order responses from earlier service switches.
4611      if (requestSeq !== rpModalSwitchRequestSeq) {
4612        return;
4613      }
4614
4615      if (res && res.success && res.data.modal_html && res.data.time_option_html) {
4616        rp_setCookie('service_type', requestedServiceType, rp_scripts.expire_cookie_time);
4617
4618        var $existingDateTimeModal = $("#rpressDateTime");
4619        var wasDateTimeModalOpen = $existingDateTimeModal.length &&
4620          ($existingDateTimeModal.hasClass('is-open') || $existingDateTimeModal.attr('aria-hidden') === 'false');
4621
4622        if (wasDateTimeModalOpen) {
4623          var $newModal = $(res.data.modal_html);
4624          var $newContainer = $newModal.find('.modal__container');
4625          if ($newContainer.length) {
4626            $("#rpressDateTime .modal__container").html($newContainer.html());
4627          }
4628        } else {
4629          $("#rpressDateTime").replaceWith(res.data.modal_html);
4630        }
4631
4632        $(".rpress-option-col.rpress-edit-address-wrap").html(
4633          `<span class="left-brdr"></span>${res.data.time_option_html}`
4634        );
4635
4636        if (typeof window.rp_prepare_old_ui_modal_selection === 'function') {
4637          window.rp_prepare_old_ui_modal_selection($('#rpressDateTime-content'));
4638        }
4639        if (typeof window.rp_apply_service_defaults === 'function') {
4640          var oldUiUxEnabled = (typeof window.rp_is_old_ui_ux_enabled === 'function') && window.rp_is_old_ui_ux_enabled();
4641          var selection = window.rp_apply_service_defaults(
4642            $('#rpressDateTime-content'),
4643            requestedServiceType,
4644            !oldUiUxEnabled,
4645            oldUiUxEnabled
4646          );
4647          if (selection && selection.serviceDateText) {
4648            $("#deliveryDate").text(selection.serviceDateText);
4649          }
4650          if (selection && selection.serviceTimeText) {
4651            $("#deliveryTime").text(selection.serviceTimeText);
4652          }
4653        }
4654
4655      }
4656    });
4657  };
4658});
4659
4660/* Global cross-page order status watcher for browser notifications */
4661(function (window) {
4662  "use strict";
4663
4664  if (typeof window.rp_scripts === "undefined" || !window.fetch || !window.URLSearchParams) {
4665    return;
4666  }
4667
4668  var STORAGE_KEY = "rpress_live_order_tracker_v1";
4669  var TERMINAL_STATUSES = {
4670    completed: true,
4671    cancelled: true,
4672    failed: true
4673  };
4674
4675  var pollTimer = null;
4676  var pusherClient = null;
4677  var pollRequestInFlight = false;
4678
4679  function parseJson(value) {
4680    if (!value) {
4681      return null;
4682    }
4683
4684    try {
4685      return JSON.parse(value);
4686    } catch (e) {
4687      return null;
4688    }
4689  }
4690
4691  function readTracker() {
4692    if (!window.localStorage) {
4693      return null;
4694    }
4695
4696    return parseJson(window.localStorage.getItem(STORAGE_KEY));
4697  }
4698
4699  function writeTracker(tracker) {
4700    if (!window.localStorage || !tracker) {
4701      return;
4702    }
4703
4704    try {
4705      window.localStorage.setItem(STORAGE_KEY, JSON.stringify(tracker));
4706    } catch (e) {
4707      // Ignore storage failures.
4708    }
4709  }
4710
4711  function clearTracker() {
4712    if (!window.localStorage) {
4713      return;
4714    }
4715
4716    try {
4717      window.localStorage.removeItem(STORAGE_KEY);
4718    } catch (e) {
4719      // Ignore storage failures.
4720    }
4721  }
4722
4723  function isValidTracker(tracker) {
4724    if (!tracker || !tracker.payment_id || !tracker.payment_key || !tracker.security) {
4725      return false;
4726    }
4727
4728    if (tracker.expires_at && Date.now() > parseInt(tracker.expires_at, 10)) {
4729      return false;
4730    }
4731
4732    return true;
4733  }
4734
4735  function getNotifiedStorageKey(paymentId) {
4736    return "rpress_live_order_notified_" + String(paymentId);
4737  }
4738
4739  function markNotified(paymentId, statusKey) {
4740    if (!window.localStorage || !paymentId || !statusKey) {
4741      return;
4742    }
4743
4744    try {
4745      window.localStorage.setItem(getNotifiedStorageKey(paymentId), String(statusKey));
4746    } catch (e) {
4747      // Ignore storage failures.
4748    }
4749  }
4750
4751  function shouldNotify(paymentId, statusKey) {
4752    if (!window.localStorage || !paymentId || !statusKey) {
4753      return true;
4754    }
4755
4756    var storageKey = getNotifiedStorageKey(paymentId);
4757    var lastStatus = null;
4758
4759    try {
4760      lastStatus = window.localStorage.getItem(storageKey);
4761      if (lastStatus === String(statusKey)) {
4762        return false;
4763      }
4764      window.localStorage.setItem(storageKey, String(statusKey));
4765      return true;
4766    } catch (e) {
4767      return true;
4768    }
4769  }
4770
4771  function showBrowserNotification(orderNumber, statusLabel) {
4772    if (!("Notification" in window) || Notification.permission !== "granted") {
4773      return;
4774    }
4775
4776    var title = "Order update #" + orderNumber;
4777    var body = "Status: " + statusLabel;
4778
4779    if ("serviceWorker" in navigator) {
4780      navigator.serviceWorker.getRegistration().then(function (registration) {
4781        if (registration && typeof registration.showNotification === "function") {
4782          registration.showNotification(title, {
4783            body: body,
4784            tag: "rpress-order-" + orderNumber
4785          });
4786          return;
4787        }
4788
4789        try {
4790          new Notification(title, { body: body });
4791        } catch (e) {
4792          // Ignore browser-level notification errors.
4793        }
4794      }).catch(function () {
4795        try {
4796          new Notification(title, { body: body });
4797        } catch (e) {
4798          // Ignore browser-level notification errors.
4799        }
4800      });
4801      return;
4802    }
4803
4804    try {
4805      new Notification(title, { body: body });
4806    } catch (e) {
4807      // Ignore browser-level notification errors.
4808    }
4809  }
4810
4811  function handleIncomingStatus(data, notifyOnChange) {
4812    if (!data || !data.payment_id || !data.status) {
4813      return;
4814    }
4815
4816    var tracker = readTracker();
4817    if (!isValidTracker(tracker) || parseInt(tracker.payment_id, 10) !== parseInt(data.payment_id, 10)) {
4818      return;
4819    }
4820
4821    var previousStatus = tracker.status || "";
4822    tracker.status = data.status;
4823    tracker.status_label = data.status_label || data.status;
4824    tracker.order_number = data.order_number || tracker.order_number;
4825    tracker.updated_at_unix = data.updated_at_unix || tracker.updated_at_unix || 0;
4826    var statusChanged = previousStatus !== tracker.status;
4827
4828    if (notifyOnChange && statusChanged && shouldNotify(tracker.payment_id, tracker.status)) {
4829      showBrowserNotification(tracker.order_number || tracker.payment_id, tracker.status_label);
4830    }
4831
4832    if (TERMINAL_STATUSES[tracker.status]) {
4833      clearTracker();
4834      stopWatchers();
4835      return;
4836    }
4837
4838    if (!tracker.expires_at || Date.now() > parseInt(tracker.expires_at, 10)) {
4839      tracker.expires_at = Date.now() + (6 * 60 * 60 * 1000);
4840    }
4841
4842    writeTracker(tracker);
4843  }
4844
4845  function fetchLatestStatus() {
4846    if (pollRequestInFlight) {
4847      return;
4848    }
4849
4850    var tracker = readTracker();
4851    if (!isValidTracker(tracker)) {
4852      stopWatchers();
4853      clearTracker();
4854      return;
4855    }
4856
4857    var body = new URLSearchParams();
4858    body.set("action", "rpress_receipt_order_status");
4859    body.set("payment_id", String(tracker.payment_id));
4860    body.set("payment_key", String(tracker.payment_key));
4861    body.set("security", String(tracker.security));
4862
4863    pollRequestInFlight = true;
4864    fetch(window.rp_scripts.ajaxurl, {
4865      method: "POST",
4866      credentials: "same-origin",
4867      headers: {
4868        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
4869      },
4870      body: body.toString()
4871    })
4872      .then(function (response) {
4873        return response.json();
4874      })
4875      .then(function (result) {
4876        if (!result || !result.success || !result.data) {
4877          return;
4878        }
4879
4880        handleIncomingStatus(result.data, true);
4881      })
4882      .catch(function () {
4883        // Ignore transient errors.
4884      })
4885      .then(function () {
4886        pollRequestInFlight = false;
4887      });
4888  }
4889
4890  function startPolling() {
4891    if (pollTimer) {
4892      return;
4893    }
4894
4895    fetchLatestStatus();
4896    pollTimer = window.setInterval(fetchLatestStatus, 10000);
4897  }
4898
4899  function stopPolling() {
4900    if (pollTimer) {
4901      window.clearInterval(pollTimer);
4902      pollTimer = null;
4903    }
4904  }
4905
4906  function stopWatchers() {
4907    stopPolling();
4908
4909    if (pusherClient && typeof pusherClient.disconnect === "function") {
4910      pusherClient.disconnect();
4911      pusherClient = null;
4912    }
4913  }
4914
4915  function connectPusher(tracker) {
4916    var realtime = tracker.realtime || {};
4917    if (!realtime.enabled || !realtime.key || !realtime.channel || !realtime.event || typeof window.Pusher === "undefined") {
4918      return false;
4919    }
4920
4921    var options = {
4922      forceTLS: !!realtime.forceTLS
4923    };
4924
4925    if (realtime.cluster) {
4926      options.cluster = realtime.cluster;
4927    }
4928
4929    if (realtime.wsHost) {
4930      options.wsHost = realtime.wsHost;
4931    }
4932
4933    if (realtime.wsPort) {
4934      options.wsPort = parseInt(realtime.wsPort, 10);
4935    }
4936
4937    if (realtime.wssPort) {
4938      options.wssPort = parseInt(realtime.wssPort, 10);
4939    }
4940
4941    try {
4942      pusherClient = new window.Pusher(realtime.key, options);
4943    } catch (e) {
4944      return false;
4945    }
4946
4947    var channel = pusherClient.subscribe(realtime.channel);
4948
4949    channel.bind(realtime.event, function (payload) {
4950      handleIncomingStatus(payload || {}, true);
4951    });
4952
4953    channel.bind("pusher:subscription_error", function () {
4954      startPolling();
4955    });
4956
4957    if (pusherClient.connection && typeof pusherClient.connection.bind === "function") {
4958      pusherClient.connection.bind("error", function () {
4959        startPolling();
4960      });
4961    }
4962
4963    return true;
4964  }
4965
4966  function loadScript(url, callback) {
4967    if (!url) {
4968      callback(false);
4969      return;
4970    }
4971
4972    var scripts = document.getElementsByTagName("script");
4973    for (var i = 0; i < scripts.length; i++) {
4974      if (scripts[i].src === url) {
4975        callback(true);
4976        return;
4977      }
4978    }
4979
4980    var script = document.createElement("script");
4981    script.src = url;
4982    script.async = true;
4983    script.onload = function () {
4984      callback(true);
4985    };
4986    script.onerror = function () {
4987      callback(false);
4988    };
4989    document.head.appendChild(script);
4990  }
4991
4992  function startWatcher() {
4993    var tracker = readTracker();
4994    if (!isValidTracker(tracker)) {
4995      clearTracker();
4996      return;
4997    }
4998
4999    if (tracker.status && TERMINAL_STATUSES[tracker.status]) {
5000      clearTracker();
5001      return;
5002    }
5003
5004    if (tracker.status) {
5005      markNotified(tracker.payment_id, tracker.status);
5006    }
5007
5008    var realtime = tracker.realtime || {};
5009    if (!realtime.enabled) {
5010      startPolling();
5011      return;
5012    }
5013
5014    if (typeof window.Pusher !== "undefined") {
5015      if (connectPusher(tracker)) {
5016        window.setTimeout(fetchLatestStatus, 1200);
5017      } else {
5018        startPolling();
5019      }
5020      return;
5021    }
5022
5023    loadScript(realtime.script_url, function (loaded) {
5024      if (!loaded) {
5025        startPolling();
5026        return;
5027      }
5028
5029      if (connectPusher(tracker)) {
5030        window.setTimeout(fetchLatestStatus, 1200);
5031      } else {
5032        startPolling();
5033      }
5034    });
5035  }
5036
5037  startWatcher();
5038  window.addEventListener("beforeunload", stopWatchers);
5039})(window);
5040
5041
5042
5043/*---foodmenutab---*/
5044var SETTINGS = {
5045  navBarTravelling: false,
5046  navBarTravelDirection: "",
5047  navBarTravelDistance: 150
5048};
5049
5050var colours = {
5051  0: "#867100",
5052  1: "#7F4200",
5053  2: "#99813D",
5054  3: "#40FEFF",
5055  4: "#14CC99",
5056  5: "#00BAFF",
5057  6: "#0082B2",
5058  7: "#B25D7A",
5059  8: "#00FF17",
5060  9: "#006B49",
5061  10: "#00B27A",
5062  11: "#996B3D",
5063  12: "#CC7014",
5064  13: "#40FF8C",
5065  14: "#FF3400",
5066  15: "#ECBB5E",
5067  16: "#ECBB0C",
5068  17: "#B9D912",
5069  18: "#253A93",
5070  19: "#125FB9"
5071};
5072
5073document.documentElement.classList.remove("no-js");
5074document.documentElement.classList.add("js");
5075
5076function initProductNav(config) {
5077  const nav = document.getElementById(config.nav);
5078  const contents = document.getElementById(config.contents);
5079  const indicator = document.getElementById(config.indicator);
5080  const leftBtn = document.getElementById(config.leftBtn);
5081  const rightBtn = document.getElementById(config.rightBtn);
5082
5083  if (!nav || !contents || !indicator || !leftBtn || !rightBtn) return;
5084
5085  nav.setAttribute("data-overflowing", determineOverflow(contents, nav));
5086  moveIndicator(nav.querySelector('[aria-selected="true"]'), indicator, colours[0], contents);
5087
5088  let ticking = false;
5089  nav.addEventListener("scroll", function () {
5090    if (!ticking) {
5091      window.requestAnimationFrame(function () {
5092        nav.setAttribute("data-overflowing", determineOverflow(contents, nav));
5093        ticking = false;
5094      });
5095    }
5096    ticking = true;
5097  });
5098
5099  leftBtn.addEventListener("click", function () {
5100    if (SETTINGS.navBarTravelling) return;
5101    const overflow = determineOverflow(contents, nav);
5102    if (overflow === "left" || overflow === "both") {
5103      const availableScrollLeft = nav.scrollLeft;
5104      const distance = availableScrollLeft < SETTINGS.navBarTravelDistance * 2
5105        ? availableScrollLeft
5106        : SETTINGS.navBarTravelDistance;
5107
5108      contents.style.transform = `translateX(${distance}px)`;
5109      contents.classList.remove("pn-ProductNav_Contents-no-transition");
5110      SETTINGS.navBarTravelDirection = "left";
5111      SETTINGS.navBarTravelling = true;
5112    }
5113    nav.setAttribute("data-overflowing", determineOverflow(contents, nav));
5114  });
5115
5116  rightBtn.addEventListener("click", function () {
5117    if (SETTINGS.navBarTravelling) return;
5118    const overflow = determineOverflow(contents, nav);
5119    if (overflow === "right" || overflow === "both") {
5120      const navBarRightEdge = contents.getBoundingClientRect().right;
5121      const scrollerRightEdge = nav.getBoundingClientRect().right;
5122      const availableScrollRight = Math.floor(navBarRightEdge - scrollerRightEdge);
5123      const distance = availableScrollRight < SETTINGS.navBarTravelDistance * 2
5124        ? availableScrollRight
5125        : SETTINGS.navBarTravelDistance;
5126
5127      contents.style.transform = `translateX(-${distance}px)`;
5128      contents.classList.remove("pn-ProductNav_Contents-no-transition");
5129      SETTINGS.navBarTravelDirection = "right";
5130      SETTINGS.navBarTravelling = true;
5131    }
5132    nav.setAttribute("data-overflowing", determineOverflow(contents, nav));
5133  });
5134
5135  contents.addEventListener("transitionend", function () {
5136    const tr = getComputedStyle(contents).transform;
5137    const amount = Math.abs(parseInt(tr.split(",")[4]) || 0);
5138    contents.style.transform = "none";
5139    contents.classList.add("pn-ProductNav_Contents-no-transition");
5140    if (SETTINGS.navBarTravelDirection === "left") {
5141      nav.scrollLeft -= amount;
5142    } else {
5143      nav.scrollLeft += amount;
5144    }
5145    SETTINGS.navBarTravelling = false;
5146  });
5147
5148  contents.addEventListener("click", function (e) {
5149    if (!e.target.classList.contains('pn-ProductNav_Link')) return;
5150    const links = Array.from(contents.querySelectorAll(".pn-ProductNav_Link"));
5151    links.forEach(link => link.setAttribute("aria-selected", "false"));
5152    e.target.setAttribute("aria-selected", "true");
5153    moveIndicator(e.target, indicator, colours[links.indexOf(e.target)], contents);
5154  });
5155
5156  window.addEventListener("resize", function () {
5157    const selected = nav.querySelector('[aria-selected="true"]');
5158    if (selected) moveIndicator(selected, indicator, null, contents);
5159  });
5160}
5161
5162function moveIndicator(item, indicator, color, container) {
5163  if (!item || !indicator) return;
5164  const textPosition = item.getBoundingClientRect();
5165  const containerLeft = container.getBoundingClientRect().left;
5166  const distance = textPosition.left - containerLeft;
5167  const scroll = container.scrollLeft;
5168  indicator.style.transform = `translateX(${distance + scroll}px) scaleX(${textPosition.width * 0.01})`;
5169  if (color) indicator.style.backgroundColor = color;
5170}
5171
5172function determineOverflow(content, container) {
5173  const containerRect = container.getBoundingClientRect();
5174  const contentRect = content.getBoundingClientRect();
5175  if (
5176    containerRect.left > contentRect.left &&
5177    containerRect.right < contentRect.right
5178  ) {
5179    return "both";
5180  } else if (contentRect.left < containerRect.left) {
5181    return "left";
5182  } else if (contentRect.right > containerRect.right) {
5183    return "right";
5184  } else {
5185    return "none";
5186  }
5187}
5188
5189// Initialize both desktop and mobile tab navigations
5190initProductNav({
5191  nav: 'pnProductNav',
5192  contents: 'pnProductNavContents',
5193  indicator: 'pnIndicator',
5194  leftBtn: 'pnAdvancerLeft',
5195  rightBtn: 'pnAdvancerRight'
5196});
5197
5198initProductNav({
5199  nav: 'pnProductNavMobile',
5200  contents: 'pnProductNavContentsMobile',
5201  indicator: 'pnIndicatorMobile',
5202  leftBtn: 'pnAdvancerLeftMobile',
5203  rightBtn: 'pnAdvancerRightMobile'
5204});
5205
5206jQuery(function ($) {
5207  if (window.location.pathname === '/order-online/') {
5208    $('body').addClass('order-online');
5209  }
5210  $('.rpress-category-lists .rpress-category-link:first').addClass('current');
5211  $('.rpress-category-lists li:first').addClass('current');
5212
5213  $('.cd-dropdown-trigger').on('click', function () {
5214    $('body').toggleClass('cd-overlay-open');
5215
5216    if ($('body').hasClass('cd-overlay-open')) {
5217      // Add overlay if opening
5218      if ($('.rpress-cat-overlay').length === 0) {
5219        var cdDropdown = $('.cd-dropdown-wrapper .cd-dropdown');
5220        $('<div class="rpress-cat-overlay"></div>').insertAfter(cdDropdown);
5221      }
5222    } else {
5223      // Remove overlay if closing
5224      $('.rpress-cat-overlay').remove();
5225    }
5226  });
5227  $('.cd-close').on('click', function () {
5228    $('body').removeClass('cd-overlay-open');
5229    $('.rpress-cat-overlay').remove();
5230  });
5231  $(document).on('click', '.rpress-editaddress-cancel-btn', function (e) {
5232    if (e) {
5233      e.preventDefault();
5234    }
5235    $('.rpress-mobile-cart-icons').show();
5236    if (typeof MicroModal !== 'undefined') {
5237      try {
5238        MicroModal.close('rpressDateTime');
5239      } catch (err) {}
5240    }
5241    var $modal = $('#rpressDateTime');
5242    if ($modal.length) {
5243      $modal.removeClass('is-open').attr('aria-hidden', 'true');
5244    }
5245  });
5246  $('.cd-dropdown-trigger').on('click', function (event) {
5247    event.preventDefault();
5248    $('.rpress-mobile-cart-icons').hide();
5249    toggleNav();
5250  });
5251
5252  $('.cd-dropdown .cd-close').on('click', function (event) {
5253    event.preventDefault();
5254    $('.rpress-mobile-cart-icons').show();
5255    toggleNav();
5256  });
5257
5258  function toggleNav() {
5259    var navIsVisible = (!$('.cd-dropdown').hasClass('dropdown-is-active'));
5260    $('.cd-dropdown').toggleClass('dropdown-is-active', navIsVisible);
5261    $('.cd-dropdown-trigger').toggleClass('dropdown-is-active', navIsVisible);
5262
5263    if (!navIsVisible) {
5264      $('.cd-dropdown').one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function () {
5265        $('.has-children ul').addClass('is-hidden');
5266        $('.move-out').removeClass('move-out');
5267        $('.is-active').removeClass('is-active');
5268      });
5269    }
5270  }
5271
5272  function rp_sync_checkout_service_heading($scope, serviceType) {
5273    var $root = ($scope && $scope.length) ? $scope : $(document);
5274    var $wrapper = $root.closest('.rpress-tabs-wrapper');
5275    if (!$wrapper.length) {
5276      $wrapper = $root.find('.rpress-tabs-wrapper').first();
5277    }
5278    if (!$wrapper.length) {
5279      return;
5280    }
5281
5282    var normalizedServiceType = String(serviceType || '')
5283      .toLowerCase();
5284    if (normalizedServiceType !== 'delivery' && normalizedServiceType !== 'pickup') {
5285      normalizedServiceType = window.rp_get_active_service_type($wrapper, 'delivery');
5286    }
5287
5288    var $heading = $wrapper.find('.rpress-checkout-service-heading').first();
5289    if (!$heading.length) {
5290      return;
5291    }
5292
5293    var $activeTab = $wrapper.find('#rpressdeliveryTab .single-service-selected[data-service-type="' + normalizedServiceType + '"]').first();
5294    var label = $activeTab.find('.rpress-service-tab-label').first().text().trim();
5295    if (!label) {
5296      label = normalizedServiceType.charAt(0).toUpperCase() + normalizedServiceType.slice(1);
5297    }
5298
5299    $heading.find('.rpress-checkout-service-heading-text').text(label);
5300    $heading.removeClass('is-service-delivery is-service-pickup').addClass('is-service-' + normalizedServiceType);
5301  }
5302
5303  var oldUiUxEnabled = rp_is_old_ui_ux_enabled();
5304
5305  var serviceType = rp_getCookie('service_type');
5306  if (serviceType) {
5307    var capitalized = serviceType.charAt(0).toUpperCase() + serviceType.slice(1);
5308    $('.rpress-service-label').text(capitalized);
5309  }
5310  var $initialOrderServiceScope = $('.rpress-delivery-wrap .rpress-tabs-wrapper:visible')
5311    .first();
5312  var initialServiceType = window.rp_get_active_service_type(
5313    $initialOrderServiceScope.length ? $initialOrderServiceScope : $(document),
5314    serviceType || rp_scripts.default_service || 'delivery'
5315  );
5316  window.rp_sync_service_ui_state(
5317    $initialOrderServiceScope.length ? $initialOrderServiceScope : $(document),
5318    initialServiceType,
5319    !oldUiUxEnabled
5320  );
5321  rp_sync_checkout_service_heading(
5322    $initialOrderServiceScope.length ? $initialOrderServiceScope : $(document),
5323    initialServiceType
5324  );
5325  $(document).on('rp_delivery_fee_validation', function (event, response) {
5326    if (!rp_is_old_ui_ux_enabled()) {
5327      return;
5328    }
5329    response = response || {};
5330    if (response.status === 'error' || parseInt(response.delivery_fee_error || 0, 10) === 1) {
5331      window.rpDeliveryFeeValidationState = 'invalid';
5332      return;
5333    }
5334
5335    if (response.status === 'success') {
5336      window.rpDeliveryFeeValidationState = 'valid';
5337    }
5338  });
5339  $(document).on('input change', '#rp_delivery_zone, #rp_delivery_location, #rpress-delivery-address, #rpress-postcode, #rpress_postcode', function () {
5340    if (!rp_is_old_ui_ux_enabled()) {
5341      return;
5342    }
5343    window.rpDeliveryFeeValidationState = 'unknown';
5344  });
5345  if (!oldUiUxEnabled) {
5346    window.rp_sync_service_selection_cookies(
5347      $initialOrderServiceScope.length ? $initialOrderServiceScope : $(document),
5348      initialServiceType
5349    );
5350  }
5351  $(document).on('click', '#rpressdeliveryTab .single-service-selected, .single-service-selected', function (e) {
5352    var $serviceTab = $(this);
5353    var selectedServiceType = String($serviceTab.data('service-type') || '')
5354      .toLowerCase();
5355
5356    if (selectedServiceType) {
5357      var capitalized = selectedServiceType.charAt(0).toUpperCase() + selectedServiceType.slice(1);
5358      $('.rpress-service-label').text(capitalized);
5359    }
5360
5361    setTimeout(function () {
5362      var $serviceScope = $serviceTab.closest('.rpress-tabs-wrapper');
5363      window.rp_sync_service_ui_state(
5364        $serviceScope.length ? $serviceScope : $(document),
5365        selectedServiceType,
5366        !oldUiUxEnabled
5367      );
5368      rp_sync_checkout_service_heading(
5369        $serviceScope.length ? $serviceScope : $(document),
5370        selectedServiceType
5371      );
5372      if (!oldUiUxEnabled) {
5373        var selectedServiceDefaults = window.rp_sync_service_selection_cookies(
5374          $serviceScope.length ? $serviceScope : $(document),
5375          selectedServiceType
5376        );
5377        if (typeof window.rp_update_inline_service_display === 'function') {
5378          window.rp_update_inline_service_display(selectedServiceDefaults, oldUiUxEnabled);
5379        }
5380      }
5381    }, 0);
5382  });
5383
5384  setTimeout(function () {
5385    // Do not force change events on checkout; this can retrigger slot checks.
5386    if (String(rpress_scripts.is_checkout) === '1') {
5387      return;
5388    }
5389
5390    var $hours = $("#rpressDateTime #rpress-delivery-hours, #rpressModal #rpress-delivery-hours").first();
5391    if (!$hours.length) {
5392      return;
5393    }
5394
5395    var selectedVal = $hours.find("option:selected").val();
5396    if (!selectedVal) {
5397      selectedVal = $hours.find("option:first").val();
5398    }
5399
5400    if (selectedVal) {
5401      $hours.val(selectedVal);
5402    }
5403  }, 1000);
5404
5405  $(document).on('click', '.rp-variable-price-wrapper .radio-container', function () {
5406    var $radio = $(this).find('input[type="radio"]');
5407
5408    if ($radio.length) {
5409      var name = $radio.attr('name');
5410
5411      // Uncheck all radios in this group
5412      $('input[name="' + name + '"]').prop('checked', false);
5413
5414      // Check the clicked one
5415      $radio.prop('checked', true).trigger('change');
5416
5417      // Optional: manage "checked" class on container
5418      $('.radio-container').removeClass('checked');
5419      $(this).addClass('checked');
5420    }
5421  });
5422});
5423jQuery(document).ready(function ($) {
5424  $('.menu-category-wrap').first().addClass('first-menu-category-wrap');
5425
5426
5427  var $nav = $('#pnProductNav');
5428
5429  function checkOverflow() {
5430    if ($nav.attr('data-overflowing') !== 'right') {
5431      $nav.parent('.pn-ProductNav_Wrapper').addClass('background-hidden');
5432    } else {
5433      $nav.parent('.pn-ProductNav_Wrapper').removeClass('background-hidden');
5434    }
5435  }
5436
5437  // Run once on page load
5438  checkOverflow();
5439
5440  function updateTooManyAdds($span) {
5441    var textOnly = $span.text().trim();
5442    var $parent = $span.closest('.rpress-price-holder');
5443
5444    if ($parent.length) {
5445      if (textOnly.length > 3) {
5446        $parent.addClass('too-many-adds');
5447      } else {
5448        $parent.removeClass('too-many-adds');
5449      }
5450    }
5451  }
5452
5453  // Initial check on page load
5454  $('span.rpress-add-to-cart-label.rp-ajax-toggle-text').each(function () {
5455    updateTooManyAdds($(this));
5456  });
5457
5458  // Observe only the spans
5459  $('span.rpress-add-to-cart-label.rp-ajax-toggle-text').each(function () {
5460    var targetNode = this;
5461
5462    var observer = new MutationObserver(function () {
5463      updateTooManyAdds($(targetNode));
5464    });
5465
5466    observer.observe(targetNode, {
5467      characterData: true,
5468      subtree: true,
5469      childList: true
5470    });
5471  });
5472});
5473
5474jQuery(document).ready(function ($) {
5475
5476  var oldUiUxEnabled = rp_is_old_ui_ux_enabled();
5477
5478  if (oldUiUxEnabled) {
5479    var cartQty = parseInt((typeof rp_scripts !== 'undefined' ? rp_scripts.cart_quantity : 0) || 0, 10);
5480    var hasCartItemElements = $('ul.rpress-cart > li.rpress-cart-item').length > 0;
5481    var isCartEmpty = (cartQty === 0) && !hasCartItemElements;
5482
5483    var isSuccessPage = (typeof rp_scripts !== 'undefined' && String(rp_scripts.is_success_page || '') === '1') ||
5484      ($('#rpress_receipt_history, .rpress_purchase_receipt, .rp-order-confirmation-wrap, .rpress-receipt-wrap, .rpress_checkout_receipt').length > 0) ||
5485      (window.location.href.indexOf('payment-confirmation') !== -1) ||
5486      (window.location.href.indexOf('payment-id') !== -1) ||
5487      (window.location.href.indexOf('order-confirmation') !== -1);
5488
5489    if (isSuccessPage || isCartEmpty) {
5490      rp_clear_service_selection_cookies(false);
5491    }
5492  }
5493  var $selectionScope = $('#rpressDateTime-content');
5494  if (!$selectionScope.length) {
5495    $selectionScope = $('#rpressDateTime');
5496  }
5497  if (!$selectionScope.length) {
5498    $selectionScope = $('.rpress-delivery-wrap .rpress-tabs-wrapper:visible').first();
5499  }
5500
5501  var selection = null;
5502  if (oldUiUxEnabled) {
5503    if (typeof window.rp_prepare_old_ui_modal_selection === 'function') {
5504      window.rp_prepare_old_ui_modal_selection($selectionScope.length ? $selectionScope : $(document));
5505    }
5506
5507    var oldUiServiceType = (rp_getCookie('service_type') || rp_scripts.default_service || 'delivery')
5508      .toString()
5509      .toLowerCase();
5510    selection = (typeof window.rp_apply_service_defaults === 'function')
5511      ? window.rp_apply_service_defaults(
5512        $selectionScope.length ? $selectionScope : $(document),
5513        oldUiServiceType,
5514        false
5515      )
5516      : null;
5517  } else {
5518    var serviceType = rp_getCookie('service_type') || rp_scripts.default_service || 'delivery';
5519    rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time);
5520    selection = (typeof window.rp_apply_service_defaults === 'function')
5521      ? window.rp_apply_service_defaults(
5522        $selectionScope.length ? $selectionScope : $(document),
5523        serviceType,
5524        true
5525      )
5526      : null;
5527  }
5528
5529  if (typeof window.rp_update_inline_service_display === 'function') {
5530    window.rp_update_inline_service_display(selection, oldUiUxEnabled);
5531  }
5532
5533  function initStickyMenu() {
5534    var $menu = $('.desktop-scroll-menu .make-me-sticky');
5535    var $sidebar = $('.sticky-sidebar');
5536
5537    if ($(window).width() > 991 && $menu.length > 0) {
5538      // Fixed offset from top — clear the WP admin bar when it's fixed (logged
5539      // in), else the fixed nav sits behind it. Absolute admin bar (≤600px) or
5540      // logged out reports 0.
5541      var $adminBar = $('#wpadminbar');
5542      var stickyTop = ($adminBar.length && $adminBar.css('position') === 'fixed') ? ($adminBar.outerHeight() || 0) : 0;
5543
5544      var menuOffset = $menu.offset().top;
5545
5546      $(window).off('.stickyMenu'); // Remove previous events
5547
5548      $(window).on('scroll.stickyMenu', function () {
5549        var scrollTop = $(window).scrollTop();
5550
5551        if (scrollTop + stickyTop >= menuOffset) {
5552          $menu.css({
5553            'position': 'fixed',
5554            'top': stickyTop + 'px',
5555            'left': $menu.offset().left + 'px',
5556            'width': $menu.outerWidth(),
5557            'z-index': 999
5558          });
5559        } else {
5560          $menu.css({
5561            'position': 'static',
5562            'width': '',
5563            'top': '',
5564            'left': '',
5565            'z-index': ''
5566          });
5567        }
5568      });
5569
5570      // Recalculate left & width on resize. Reset the menu to its natural size -
5571      // never force the horizontal category nav to the sidebar's height (that left
5572      // a large empty band around the nav after resizing).
5573      $(window).on('resize.stickyMenu', function () {
5574        $menu.css({
5575          'position': 'static',
5576          'width': '',
5577          'top': '',
5578          'left': '',
5579          'height': ''
5580        });
5581        menuOffset = $menu.offset().top;
5582      });
5583
5584    } else {
5585      // Reset sticky behavior on mobile
5586      $menu.css({
5587        'position': 'static',
5588        'height': 'auto'
5589      });
5590    }
5591  }
5592
5593  initStickyMenu();
5594  $(window).on('resize', initStickyMenu);
5595  /**
5596   * Action Menu Toggle for Mobile
5597   */
5598  var actionContainer = document.querySelector(".container-actionmenu");
5599  var burger = document.getElementById("actionburger");
5600  var menu = document.querySelector(".actionmenu");
5601
5602  if (actionContainer && burger && menu) {
5603    var toggleActionMenu = function () {
5604      burger.classList.toggle("is-expanded");
5605
5606      // Get the icon and text elements
5607      var icon = burger.querySelector('i');
5608      var textNode = burger.querySelector('.menu-text');
5609      var isExpanded = burger.classList.contains('is-expanded');
5610
5611      // Get texts and icons from data attributes
5612      var menuText = burger.getAttribute('data-text-menu');
5613      var closeText = burger.getAttribute('data-text-close');
5614      var menuIcon = burger.getAttribute('data-icon-menu');
5615      var closeIcon = burger.getAttribute('data-icon-close');
5616
5617      if (isExpanded) {
5618        menu.classList.replace("slides-down", "slides-up");
5619        if (icon) {
5620          icon.className = closeIcon;
5621        }
5622        if (textNode) {
5623          textNode.textContent = closeText;
5624        }
5625      } else {
5626        menu.classList.replace("slides-up", "slides-down");
5627        if (icon) {
5628          icon.className = menuIcon;
5629        }
5630        if (textNode) {
5631          textNode.textContent = menuText;
5632        }
5633      }
5634    };
5635
5636    // Toggle only when the menu button itself is clicked.
5637    burger.addEventListener("click", function (event) {
5638      event.preventDefault();
5639      event.stopPropagation();
5640      toggleActionMenu();
5641    });
5642
5643  }
5644});

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.