PageSourceSearch

https://intuwellness.com/wp-content/themes/intu-wellness/assets/js/script.js?ver=1783366353

js intuwellness.com collected 2026-10-08 07:55:23 UTC 58,047 bytes, 1,521 lines download raw bytes

1
2/* Product Page Gallery scroll stickyness for desktop */
3document.addEventListener('DOMContentLoaded', function() {
4    const gallery = document.querySelector('.woocommerce-product-gallery');
5    const product = document.querySelector('.product');
6    
7    if (!gallery || !product) return;
8  
9    let lastScrollTop = 0;
10    let ticking = false;
11  
12    function updateGalleryPosition() {
13      const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
14      const productRect = product.getBoundingClientRect();
15      const galleryRect = gallery.getBoundingClientRect();
16  
17      const productTop = productRect.top + scrollTop;
18      const productBottom = productTop + productRect.height;
19      const galleryHeight = galleryRect.height;
20  
21      let newTop;
22      const menuOffset = 60;
23
24      if (scrollTop > productTop - menuOffset && scrollTop + galleryHeight < productBottom) {
25        // Sticky behavior
26        newTop = scrollTop - productTop + menuOffset;
27      } else if (scrollTop + galleryHeight >= productBottom) {
28        // Reached the bottom of the product container
29        newTop = productRect.height - galleryHeight + menuOffset;
30      } else {
31        // At the top of the product container
32        newTop = 0;
33      }
34  
35      gallery.style.transform = `translateY(${newTop}px)`;
36  
37      lastScrollTop = scrollTop;
38      ticking = false;
39    }
40  
41    window.addEventListener('scroll', function() {
42      if (!ticking) {
43        window.requestAnimationFrame(function() {
44          updateGalleryPosition();
45          ticking = false;
46        });
47  
48        ticking = true;
49      }
50    });
51  
52    // Initial position
53    updateGalleryPosition();
54  });
55
56var showSubscribePromo = false;
57
58function checkSubscription() {
59    $('select.wcsatt-options-product-dropdown').val('1_month').trigger('change');
60    // 'yes' or 'no' 
61    var option = $('input[name="subscribe-to-action-input"]:checked').val();
62
63    if ($('.wcsatt-options-product-dropdown option[selected]').length) {
64        var period = parseInt($('.wcsatt-options-product-dropdown option[selected]').val());
65    } else {
66        var period = 1;
67    }
68    var hasSubscription = false;
69    if (option == 'yes') {
70        hasSubscription = true;
71    }
72    $('.m-subscribe-select select').val(period).trigger('change');
73
74    $('.summary .m-price > *').removeClass('is-active');
75
76    var btn_text = 'Buy now';
77    var btn_price = '';
78
79   if ( hasSubscription ) {
80        $('.summary .m-price-offer').addClass('is-active');
81		$('.summary .m-price-main').addClass('is-active');
82        $('.summary .m-price-main').addClass('subscription-price');
83        $('.summary .m-price-main').removeClass('single-price');
84		$('.summary .m-price-main').css('text-decoration', 'line-through');
85		
86        $('#purchase-type-subscribe').prop('checked', true);
87        btn_text = 'Subscribe';
88		$('.summary').attr('data-payment', 'subscription');
89    } else {
90		$('.summary .m-price-main').css('text-decoration', '');
91        $('.summary .m-price-main').addClass('is-active');  
92        $('.summary .m-price-main').addClass('single-price');
93        $('.summary .m-price-main').removeClass('subscription-price');
94        $('#purchase-type-one').prop('checked', true);
95		$('.summary').attr('data-payment', 'single');
96    }
97
98    if ($('.summary .m-price > .is-active > .woocommerce-Price-amount').length) {
99        btn_price = $('.summary .m-price > .is-active > .woocommerce-Price-amount').html();
100    }
101
102    $('.single_add_to_cart_button').html(`
103        <span class="js-cart-button">${btn_text}</span>
104        <span class="js-product-price">${btn_price}</span>
105    `);
106    if ($('.single_add_to_cart_button').hasClass('is-preorder')) {
107        $('.single_add_to_cart_button').html('Pre-order');
108    } else {
109        $('.single_add_to_cart_button').html('Add to bag');
110    }
111    
112    $('[name="instant-buy"]').html(btn_text);
113    if ($('#custom-newsletter-register').is(':checked')) {
114        $('#kl_newsletter_checkbox').prop('checked', 'checked');
115    }
116
117
118}
119function onCheckout() {
120    $('.m-out-different .kl_sms_consent_checkbox_field').insertAfter('.woocommerce-shipping-fields .validate-phone');
121    $('.m-out-different .woocommerce-account-fields').insertAfter('.custom-newsletter-register');
122    $('#billing_email').each(function () {
123        var email = $(this).val();
124        $('.js-checkout-email').text(email);
125    });
126    if ($('#custom-newsletter-register').is(':checked')) {
127        $('#kl_newsletter_checkbox').prop('checked', 'checked');
128    }
129
130
131}
132function formCheck() {
133    $('.gfield input, .gfield select, .gfield textarea').each(function () {
134        var field = $(this).closest('.gfield');
135        var input = $(this);
136        if (input.attr('type') == 'checkbox' || input.attr('type') == 'radio') {
137            field.addClass('not-field');
138        } else {
139            if (input.val() && input.val().length > 0) {
140                field.addClass('has-value');
141            } else {
142                field.removeClass('has-value');
143            }
144        }
145    });
146    $('.gfield input, .gfield select, .gfield textarea').on('blur', function () {
147        var field = $(this).closest('.gfield');
148        var input = $(this);
149        if (input.val() && input.val().length > 0) {
150            field.addClass('has-value');
151        } else {
152            field.removeClass('has-value');
153        }
154    });
155    $('.woocommerce-billing-fields__field-wrapper p input, .woocommerce-billing-fields__field-wrapper p select, .woocommerce-billing-fields__field-wrapper p textarea, .woocommerce-shipping-fields__field-wrapper p input, .woocommerce-shipping-fields__field-wrapper p select, .woocommerce-shipping-fields__field-wrapper p textarea').each(function () {
156        var field = $(this).closest('p');
157        var input = $(this);
158        if (input.attr('type') == 'checkbox' || input.attr('type') == 'radio') {
159            field.addClass('not-field');
160        } else {
161            if (input.val() && input.val().length > 0) {
162                field.addClass('has-value');
163            } else {
164                field.removeClass('has-value');
165            }
166        }
167    });
168    $('.woocommerce-billing-fields__field-wrapper p select, .woocommerce-shipping-fields__field-wrapper p select').each(function () {
169        var field = $(this).closest('p');
170        field.addClass('has-value');
171    });
172    $('.woocommerce-billing-fields__field-wrapper p input, .woocommerce-billing-fields__field-wrapper p select, .woocommerce-billing-fields__field-wrapper p textarea, .woocommerce-shipping-fields__field-wrapper p input, .woocommerce-shipping-fields__field-wrapper p select, .woocommerce-shipping-fields__field-wrapper p textarea').on('blur', function () {
173        var field = $(this).closest('p');
174        var input = $(this);
175        if (input.val() && input.val().length > 0) {
176            field.addClass('has-value');
177        } else {
178            field.removeClass('has-value');
179        }
180    });
181    $('.woocommerce-billing-fields__field-wrapper p select, .woocommerce-shipping-fields__field-wrapper p select').on('blur', function () {
182        var field = $(this).closest('p');
183        field.addClass('has-value');
184    });
185}
186function onResize() {
187    $('body.hero-first .header-main.has-bar').each(function () {
188        $(this).css('padding-top', $('.bar').outerHeight());
189    });
190    $('.mission').each(function () {
191        var height = $(this).find('.mission-secondary').outerHeight();
192        $(this).attr("style", '--secondary:' + height + 'px;');
193    });
194}
195var totalDelay = 0;
196function animationsScatter() {
197    $('.x-down').each(function () {
198        var $this = $(this);
199        if ($(this).isInViewport()) {
200            setTimeout(function () {
201                $this.addClass('x-down-active');
202            }, totalDelay);
203            totalDelay += 350;
204        }
205    });
206}
207function animations() {
208    $('.x-down').each(function () {
209        if ($(this).isInViewport()) {
210            $(this).addClass('x-down-active');
211        }
212    });
213    $('.x-left').each(function () {
214        if ($(this).isInViewport()) {
215            $(this).addClass('x-left-active');
216        }
217    });
218    $('.x-right').each(function () {
219        if ($(this).isInViewport()) {
220            $(this).addClass('x-right-active');
221        }
222    });
223    $('.x-up').each(function () {
224        if ($(this).isInViewport()) {
225            $(this).addClass('x-up-active');
226        }
227    });
228}
229
230function loadAndScroll() {
231    var s = $(window).scrollTop();
232    if (s > 150) {
233        $('body').addClass('sticky-active');
234    } else {
235        $('body').removeClass('sticky-active');
236    }
237}
238function intuUpdatedCheckout() {
239    if ($('[data-id="information"] .ppc-button-wrapper').length > 0 && !$('[data-id="payment"] .ppc-button-wrapper').length) {
240        $('[data-id="information"] .ppc-button-wrapper').appendTo('[data-id="payment"] .payment_method_ppcp-gateway.payment_box');
241    }
242}
243function onReady() {
244    onCheckout();
245
246    animations();
247    $(window).on('resize scroll', function () {
248        animations();
249    });
250
251    if ($('.js-intro-links').length) {
252        var introLinks = $('.js-intro-links').html();
253        $(introLinks).insertAfter('.header-sticky');
254        $('.js-intro-links').remove();
255    }
256
257    var baseUrl = php.site_url;
258    $('#billing_email').on('blur', function () {
259        $('#billing_email_field .custom-error-notice').remove();
260        var email = $(this).val();
261        $.ajax({
262            url: php.ajax_url,
263            type: 'POST',
264            data: {
265                action: 'check_email_account',
266                'email': email,
267            }
268        })
269            .success(function (results) {
270                if (!results.success) {
271                    $('#billing_email_field').append(`<div class="custom-error-notice">It seems like you already have an account. Please <a href="${baseUrl}/my-account/">log in</a> first.</div>`);
272                }
273            })
274
275            .fail(function (data) {
276                console.log(data.responseText);
277                console.log('Request failed: ' + data.statusText);
278            })
279
280    });
281
282    if ($(window).width() <= 767 && $('.igrid-item').length) {
283        $(window).scroll(function () {
284            $('.igrid-item').each(function () {
285                var self = $(this);
286                if (self.isInMiddleViewport()) {
287                    self.addClass('is-hover');
288                } else {
289                    self.removeClass('is-hover');
290                }
291            });
292        });
293    }
294
295
296    $('body').on('click', '.js-custom-add-to-cart', function (e) {
297        e.preventDefault();
298        $('form.cart').submit();
299    });
300    $('body').on('click', '[name="instant-buy"]', function (e) {
301        e.preventDefault();
302        if ($('form.cart input[name="custom-redirect-to"]').length === 0) {
303            $('form.cart').append('<input type="hidden" name="custom-redirect-to" value="checkout">');
304        }
305        $('form.cart').submit();
306    });
307
308    
309
310    $('select.wcsatt-options-product-dropdown').val('3_month').trigger('change');
311    checkSubscription();
312
313    $('body').on('change', 'input[name="subscribe-to-action-input"]', function () {
314        checkSubscription();
315    });
316
317    $('body').on('change', 'input[name="purchase-type"]', function () {
318        if ($(this).val() == 'subscribe') {
319            $('input[name="subscribe-to-action-input"][value="yes"]').prop('checked', true).trigger('change');
320        } else {
321            $('input[name="subscribe-to-action-input"][value="no"]').prop('checked', true).trigger('change');
322        }
323        checkSubscription();
324    });
325
326    $('body').on('change', '.m-subscribe-select select', function () {
327        var months = parseInt($(this).val());
328        $('select.wcsatt-options-product-dropdown').val(months + '_month').trigger('change');
329    });
330
331
332
333    $('.purchase-button').on('click', function() {
334        // Remove active class from all buttons
335        $('.purchase-button').removeClass('active');
336        // Add active class to the clicked button
337        $(this).addClass('active');
338        // Set the radio button based on selection
339        var purchaseType = $(this).data('purchase-type');
340        if(purchaseType === 'subscribe') {
341            $('#purchase-type-subscribe').prop('checked', true).trigger('change');
342            // Show subscription options
343            $('.m-subscribe-select').show();
344        } else {
345            $('#purchase-type-one').prop('checked', true).trigger('change');
346            // Hide subscription options
347            $('.m-subscribe-select').hide();
348        }
349    });
350
351    // On page load, check if purchase type is 'subscribe' and show/hide accordingly
352    if($('#purchase-type-subscribe').is(':checked')) {
353        $('.m-subscribe-select').show();
354    } else {
355        $('.m-subscribe-select').hide();
356    }
357
358    // Handle quantity box selection
359    $('.quantity-box').on('click', function() {
360        // Remove active class from all quantity boxes
361        $('.quantity-box').removeClass('active');
362        // Add active class to the clicked box
363        $(this).addClass('active');
364        // Get the selected quantity from data attribute
365        var selectedQuantity = $(this).data('quantity');
366        // Set the hidden input value
367        $('#selected-quantity').val(selectedQuantity);
368        // Update the quantity input in the form
369        $('input.qty').val(selectedQuantity);
370    });
371
372
373    if ($('body.single-product .woocommerce-message .button').length && $('.woocommerce-message .button').text() == 'View cart') {
374        // 		location.href = php.site_url + '/checkout/';
375        $('#fly-cart').addClass('is-active');
376        $('html').addClass('overlay-active');
377    }
378
379    if ($('.fly-cart-list > *').length && location.href.indexOf('?removed_item') > -1) {
380        $('#fly-cart').addClass('is-active');
381        $('html').addClass('overlay-active');
382    }
383    if ($('.fly-cart-list > *').length && location.href.indexOf('?add-to-cart') > -1) {
384        $('#fly-cart').addClass('is-active');
385        $('html').addClass('overlay-active');
386    }
387
388    $('.js-product-price').each(function () {
389        var price = $('.summary .m-price > .is-active > .woocommerce-Price-amount').html();
390        $(this).html(price);
391    });
392    $('.js-price-afterpay').each(function () {
393        var price = parseFloat($('.summary .m-price > .is-active > .amount bdi').text().substring(1));
394        var div = price / 4;
395        $(this).html(Math.ceil(div * 100) / 100);
396    });
397    var formatCurrency = new Intl.NumberFormat('en-US', {
398        style: 'currency',
399        currency: 'USD',
400    });
401    $('.product .summary input.qty').each(function () {
402        var q = parseInt($(this).val());
403        var p = parseFloat($('.summary .m-price > .is-active > .amount bdi').text().substring(1));
404        var t = p * q;
405        var f = formatCurrency.format(t);
406        $('.js-product-price').text(f);
407        $('.js-price-afterpay').each(function () {
408            var div = t / 4;
409            $(this).html(formatCurrency.format(div));
410        });
411    });
412    $('body').on('change', '.product .summary input.qty', function () {
413        var q = parseInt($(this).val());
414        var p = parseFloat($('.summary .m-price > .is-active > .amount bdi').text().substring(1));
415        var t = p * q;
416        var f = formatCurrency.format(t);
417        $('.js-product-price').text(f);
418        $('.js-price-afterpay').each(function () {
419            var div = t / 4;
420            $(this).html(formatCurrency.format(div));
421        });
422    });
423
424    $('.marquee').each(function () {
425        var self = $(this);
426        var offset = 0;
427        var clone = self.html();
428        setInterval(() => {
429            offset--;
430            self.css('margin-left', offset);
431        }, 35);
432        setInterval(() => {
433            self.append(clone);
434        }, 10000);
435    });
436
437    $('body').on('click', '.m-out-tab .back-button', function (e) {
438        e.preventDefault();
439        var tab = $(this).closest('.m-out-tab');
440        var id = tab.data('id');
441        tab.removeClass('is-active');
442        tab.prev().addClass('is-active');
443        $('.nav-crumbs li[data-id="' + id + '"]').removeClass('active done');
444        $('.nav-crumbs li[data-id="' + id + '"]').prev().addClass('active done');
445    });
446
447
448    $('body').on('click', '.m-out .go-to', function (e) {
449        e.prevent
449Default();
450        var i = $(this).data('target');
451        $('.m-out-tab').removeClass('is-active');
452        $('.m-out-tab[data-id="' + i + '"]').addClass('is-active');
453        $('.nav-crumbs li').removeClass('active done');
454        $('.nav-crumbs li[data-id="' + i + '"]').addClass('done active');
455        $('.nav-crumbs li[data-id="' + i + '"]').prevAll().addClass('done');
456    });
457
458    $('body').on('click', '.m-out .nav-crumbs li.done:not(.active) > span', function (e) {
459        e.preventDefault();
460        var i = $(this).closest('li').data('id');
461        $('.m-out-tab').removeClass('is-active');
462        $('.m-out-tab[data-id="' + i + '"]').addClass('is-active');
463        $('.nav-crumbs li').removeClass('active done');
464        $('.nav-crumbs li[data-id="' + i + '"]').addClass('done active');
465        $('.nav-crumbs li[data-id="' + i + '"]').prevAll().addClass('done');
466    });
467
468    $('body').on('click', '.m-out-tab[data-id="information"] .next-button', function (e) {
469        e.preventDefault();
470        var tab = $(this).closest('.m-out-tab');
471        var id = tab.data('id');
472        var hasErrors = false;
473
474        tab.find('.validate-required').each(function () {
475            var self = $(this);
476            var input = self.find('.woocommerce-input-wrapper > :first-child');
477            if (input[0].nodeName == 'INPUT' || input[0].nodeName == 'TEXTAREA' || input[0].nodeName == 'SELECT') {
478                if (input.attr('type') == 'email') {
479                    if (!isEmail(input.val())) {
480                        self.addClass('has-error');
481                        hasErrors = true;
482                    } else {
483                        self.removeClass('has-error');
484                    }
485                } else {
486                    if (!input.val()) {
487                        self.addClass('has-error');
488                        hasErrors = true;
489                    } else {
490                        self.removeClass('has-error');
491                    }
492                }
493            } else {
494                self.removeClass('has-error');
495            }
496        });
497
498        if ($('#shipping_state').val().length === 0) {
499            if ($('#shipping_state option').length > 0) {
500                $('#shipping_state_field').addClass('has-error');
501                hasErrors = true;
502            }
503            else {
504                $('#shipping_state_field').removeClass('has-error');
505            }
506        }
507        setTimeout(function () {
508            if (!hasErrors) {
509                $('.nav-crumbs li[data-id="' + id + '"]').removeClass('active');
510                $('.nav-crumbs li[data-id="' + id + '"]').next().addClass('active done');
511                tab.removeClass('is-active');
512                tab.next().addClass('is-active');
513
514                if ($('select#shipping_country').length) {
515                    var country = $('#shipping_country option[value="' + $('#shipping_country').val() + '"]').text();
516                } else {
517                    var country = $('#shipping_country_field .woocommerce-input-wrapper > strong').text();
518                }
519                var address = $('#shipping_address_1').val() + ' ' + $('#shipping_address_2').val() + ', ' + $('#shipping_city').val() + ', ' + country;
520                $('.js-checkout-address').text(address);
521            }
522        }, 10);
523    });
524    
525
526
527    if ($('input[name="custom-billing-type"]:checked').val() == 'different') {
528        $('.m-out-different').removeClass('concealed');
529        $('#ship-to-different-address-checkbox').prop('checked', 'checked');
530    } else {
531        $('.m-out-different').addClass('concealed');
532    }
533
534    if ($('#custom-newsletter-register').is(':checked')) {
535        $('#kl_newsletter_checkbox').prop('checked', 'checked');
536    }
537
538
539
540    $('body').on('click', '.m-out-sidebar a.woocommerce-remove-coupon', function (e) {
541        $(this).closest('.checkout_coupon_applied').remove();
542    });
543
544    $('input[name="custom-billing-type"]').on('change', function () {
545        jQuery(document.body).trigger("update_checkout");
546        if ($('input[name="custom-billing-type"]:checked').val() == 'different') {
547            $('.m-out-different').removeClass('concealed');
548            $('#ship-to-different-address-checkbox').prop('checked', 'checked');
549            // $('.js-checkout-address').text('—');
550        } else {
551            $('.m-out-different').addClass('concealed');
552            // if ($('select#shipping_country').length) {
553            //     var country = $('#shipping_country option[value="' + $('#shipping_country').val() + '"]').text();
554            // } else {
555            //     var country = $('#shipping_country_field .woocommerce-input-wrapper > strong').text();
556            // }
557            // var address = $('#shipping_address_1').val() + ' ' + $('#shipping_address_2').val() + ', ' + $('#shipping_city').val() + ', ' + country;
558            // $('.js-checkout-address').text(address);
559        }
560    });
561    $(document).ajaxComplete(function () {
562        if (showSubscribePromo && $('input[name="purchase-type"]:checked').val() == 'one') {
563            $('body').on('click', '.single_add_to_cart_button:not(.was-asked)', function (e) {
564                if ($('input[name="purchase-type"]:checked').val() == 'one') {
565                    e.preventDefault();
566                    $('#popup-save').addClass('is-active');
567                    $(this).addClass('was-asked');
568                    $('html').addClass('overlay-active');
569                    var responseInterval = setInterval(function () {
570                        if (!$('#popup-save').hasClass('is-active')) {
571                            clearInterval(responseInterval);
572                            $('.single_add_to_cart_button').trigger('click');
573                        }
574                    }, 10);
575                }
576            });
577        }
578        var total = $('#order_review .order-total td').html();
579        $('.m-out-total .h3').html(total);
580
581
582        var shipping = $('input.shipping_method:checked').parents('li').find('bdi').text();
583        //console.log(shipping);
584        if (shipping) {
585            $('.js-checkout-shipping').text(shipping);
586        } else {
587            shipping = $('input.shipping_method').parents('li').find('bdi').text();
588            $('.js-checkout-shipping').text(shipping);
589        } // Validate if the shipping method has only one option
590
591    });
592    $('body').on('click', '.m-out-tab[data-id="information"] .next-button', function (e) {
593        if ($('select#shipping_country').length) {
594            var country = $('#shipping_country option[value="' + $('#shipping_country').val() + '"]').text();
595        } else {
596            var country = $('#shipping_country_field .woocommerce-input-wrapper > strong').text();
597        }
598        var address = $('#shipping_address_1').val() + ' ' + $('#shipping_address_2').val() + ', ' + $('#shipping_city').val() + ', ' + country;
599        $('.js-checkout-address').text(address);
600    });
601    $('body').on('click', '.m-out-tab[data-id="shipping"] .next-button', function (e) {
602        e.preventDefault();
603        var tab = $(this).closest('.m-out-tab');
604        var id = tab.data('id');
605        var hasErrors = false;
606
607        tab.find('.m-out-different:not(.concealed) .validate-required').each(function () {
608            var self = $(this);
609            var input = self.find('.woocommerce-input-wrapper > :first-child');
610            if (input[0].nodeName == 'INPUT' || input[0].nodeName == 'TEXTAREA' || input[0].nodeName == 'SELECT') {
611                if (input.attr('type') == 'email') {
612                    if (!isEmail(input.val())) {
613                        self.addClass('has-error');
614                        hasErrors = true;
615                    } else {
616                        self.removeClass('has-error');
617                    }
618                } else {
619                    if (!input.val()) {
620                        self.addClass('has-error');
621                        hasErrors = true;
622                    } else {
623                        self.removeClass('has-error');
624                    }
625                }
626            } else {
627                self.removeClass('has-error');
628            }
629        });
630
631        if (!hasErrors) {
632            $('.nav-crumbs li[data-id="' + id + '"]').removeClass('active');
633            $('.nav-crumbs li[data-id="' + id + '"]').next().addClass('active done');
634            tab.removeClass('is-active');
635            tab.next().addClass('is-active');
636
637            var methodDiv = $('input.shipping_method:checked').closest('li');
638            var method = '';
639            if (methodDiv.find('label').length) {
640                method = methodDiv.find('label').contents()[0].textContent + ' - ' + methodDiv.find('label bdi').text();
641            } else {
642                // console.log($('input.shipping_method').closest('li'));
643                var methodDivSingle = $('input.shipping_method').closest('li');
644                var methodSingle = methodDivSingle.find('label').contents()[0].textContent + '  ' + methodDiv.find('label bdi').text();
645                method = methodSingle
646                //console.log(methodSingle);
647            } // validate if the shipping option has a single option
648            $('.js-checkout-method').text(method);
649        }
650    });
651
652    function checkPaypal() {
653        if ($('input[name="payment_method"]:checked').val() == 'ppcp-gateway') {
654            $('.m-out-tab[data-id="payment"] .m-out-tab-footer .next-button').hide();
655        } else {
656            $('.m-out-tab[data-id="payment"] .m-out-tab-footer .next-button').css('display', 'inline-flex');
657        }
658    }
659    checkPaypal();
660    $('body').on('change', 'input[name="payment_method"]', function () {
661        checkPaypal();
662    });
663
664    $('body').on('click', '.m-out-tab[data-id="payment"] .next-button', function (e) {
665        e.preventDefault();
666        $('#place_order').click();
667    });
668
669    jQuery('body').on('update_checkout', function () {
670        $('body').addClass('is-loading');
671    });
672    jQuery('body').on('checkout_error', function () {
673        if (!$('.js-append-payment .wc_payment_method').length) {
674            $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').appendTo('.js-append-payment');
675        }
676        $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').remove();
677        $('body').removeClass('is-loading');
678    });
679    if ($('#order_review > #ppc-button').length && $('.payment_method_ppcp #ppc-button').length == 0) {
680        $('#order_review > #ppc-button').appendTo('.payment_method_ppcp-gateway');
681    }
682    intuUpdatedCheckout();
683    jQuery('body').on('updated_checkout', function () {
684        if ($('#order_review > #ppc-button').length && $('.payment_method_ppcp #ppc-button').length == 0) {
685            $('#order_review > #ppc-button').appendTo('.payment_method_ppcp-gateway');
686        }
687        if (!$('.js-append-payment .wc_payment_method').length) {
688            $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').appendTo('.js-append-payment');
689        }
690        $('body').removeClass('is-loading');
691
692        if ($('[data-id="shipping"] input[name="billing_email"]').val() == '') {
693            var theEmail = $('[data-id="information"] input[name="billing_email"]').val();
694            $('[data-id="shipping"] #billing_email_field').addClass('has-value');
695            $('[data-id="shipping"] input[name="billing_email"]').val(theEmail).trigger('change');
696        }
697        intuUpdatedCheckout();
698    });
699	
700	jQuery(document.body).on('updated_checkout', function () {
701		var total = $('#order_review .order-total td').html();
702		$('.m-out-total .h3').html(total);
703	});
704
705    if ($('body').hasClass('woocommerce-checkout')) {
706        function appendPaymentCheckout() {
707            if ($('.wc_payment_methods').length) {
708
709                if (!$('.js-append-payment .wc_payment_method').length) {
710                    $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').appendTo('.js-append-payment');
711                }
712                $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').remove();
713
714                $('.m-out-sticky #payment .wc_payment_method ').each(function () {
715
716                    if ($(this).find('input').prop('checked')) {
717
718                        $(".js-append-payment input").prop('checked', false);
719                        $(".js-append-payment").find('#' + $(this).find('input').attr('id')).prop('checked', true);
720
721                    }
722
723                })
724                // $('.m-out-sticky #payment').remove();
725            }
726        }
727        jQuery('body').on('init_checkout', function () {
728            appendPaymentCheckout();
729        });
730        jQuery('body').on('updated_checkout', function () {
731            appendPaymentCheckout();
732        });
733    }
734
735    
736
737    formCheck();
738    jQuery(document).on('gform_page_loaded', function (event, form_id, current_page) {
739        formCheck();
740    });
741
742    $('body').on('change', '.m-reviews-sort select', function (e) {
743        e.preventDefault();
744        var url = $(this).parent().data('url');
745        if ($(this).val() == 'old') {
746            url += '?order-reviews=asc';
747        }
748        $div = $('<div />');
749        $('.m-reviews-search input').val('');
750        $('.m-reviews-body').addClass('is-loading');
751        $div.load(url + ' .m-reviews', function () {
752            $(".m-reviews-body").empty().append($div.find('.m-reviews-body > *'));
753            $('.m-reviews-body').removeClass('is-loading');
754        });
755    });
756    $('body').on('click', '.m-reviews-pagination a', function (e) {
757        e.preventDefault();
758        var url = $(this).attr('href');
759        $('.m-reviews-search').val('');
760        $div = $('<div />');
761        $('.m-reviews-body').addClass('is-loading');
762        $div.load(url + ' .m-reviews', function () {
763            $(".m-reviews-body").empty().append($div.find('.m-reviews-body > *'));
764            $('.m-reviews-body').removeClass('is-loading');
765        });
766    });
767
768    $('body').on('keyup', '.m-reviews-search input', function (e) {
769        e.preventDefault();
770        var url = $(this).parent().data('url');
771        if ($(this).val().length > 0) {
772            url += '?search-reviews=' + $(this).val();
773        }
774        $('.m-reviews-sort select').val('new');
775        $div = $('<div />');
776        $('.m-reviews-body').addClass('is-loading');
777        $div.load(url + ' .m-reviews', function () {
778            $(".m-reviews-body").empty().append($div.find('.m-reviews-body > *'));
779            $('.m-reviews-body').removeClass('is-loading');
780        });
781    });
782
783    $('body').on('click', '.m-reviews-sort-toggle', function (e) {
784        e.preventDefault();
785        $(this).closest('.m-reviews-sort').addClass('is-active');
786    });
787    $('body').on('change', '.m-reviews-sort select', function (e) {
788        $(this).closest('.m-reviews-sort').removeClass('is-active');
789    });
790    $('body').on('click', '.toggle-product-text', function (e) {
791        e.preventDefault();
792        if(!$(this).hasClass('is-active')) 
793        {
794            $(this).text("- Read Less");
795        }
796        else
797        {
798            $(this).text("+ Read More");
799        }
800        $(this).toggleClass('is-active');
801        
802        $('.custom-product-text').slideToggle();
803    });
804
805    $('.woocommerce-product-gallery a').fancybox({
806        'selector': '.woocommerce-product-gallery a',
807        'loop': true,
808    });
809
810    $('body').on('click', '.m-index .load-more a', function (e) {
811        e.preventDefault();
812        var $button = $(this);
813        $button.text('Please wait...')
814        $div = $('<div />');
815        $div.load($(this).attr('href') + ' .m-index', function () {
816            $(".m-index-list > .set").append($div.find('.m-index-list > .set > *'));
817            if ($div.find('.load-more a').length) {
818                $button.text('Load more').attr('href', $div.find('.load-more a').attr('href'));
819            } else {
820                $button.parent().remove();
821            }
822        });
823
824    });
825
826    $('body').on('click', '.faq-header', function (e) {
827        e.preventDefault();
828        var item = $(this).closest('.faq-item');
829        if (item.hasClass('is-active')) {
830            item.removeClass('is-active');
831            item.find('.faq-body').slideUp();
832        } else {
833            item.addClass('is-active');
834            item.find('.faq-body').slideDown();
835
836        }
837    });
838    $('body').on('click', '.fly-tabs-nav a', function (e) {
839        e.preventDefault();
840        var nr = $(this).index() + 1;
841        var group = $(this).closest('.fly-tabs');
842        group.find('.fly-tabs-nav a').removeClass('is-active');
843        $(this).addClass('is-active');
844        group.find('.fly-tab').removeClass('is-active');
845        group.find('.fly-tab[data-id="' + nr + '"]').addClass('is-active');
846    });
847
848
849    $('body').on('click', '#fly-cart .stepper-decrease, #fly-cart .stepper-increase', function (e) {
850        var qty = parseInt($(this).closest('.stepper').find('> div').text());
851        var n = qty - 1;
852        if ($(this).hasClass('stepper-increase')) {
853            n = qty + 1;
854        }
855        if (qty > 1) {
856            $('.stepper').addClass('is-loading');
857            var cart_item_key = $(this).closest('.stepper').data('key');
858            $.ajax({
859                type: 'POST',
860                dataType: 'json',
861                url: php.ajax_url,
862                data: { action: 'update_item_from_cart', 'cart_item_key': cart_item_key, 'qty': n, },
863                success: function (data) {
864                    var count = data.data.cart_count;
865                    $('.js-cart-count').text(count);
866                    $('.stepper').removeClass('is-loading');
867                    var $div = $('<div />');
868                    $('#fly-cart .fly-card-inner').addClass('is-loading');
869                    $div.load(php.site_url + ' #fly-cart', function () {
870                        $("#fly-cart .fly-card-inner").empty().append($div.find('.fly-card-inner > *'));
871                        $('#fly-cart .fly-card-inner').removeClass('is-loading');
872                    });
873                }
874            });
875        }
876    });
877
878    $('.quantity .stepper > div').each(function () {
879        var initial = $(this).closest('.quantity').find('input.qty').val();
880        $(this).text(initial);
881    });
882    /*
883    $('body').on('click', '.stepper-increase', function (e) {
884        e.preventDefault();
885        var el = $(this).closest('.stepper');
886        var qty = el.find('> div');
887        var amount = parseInt(qty.text());
888        qty.text(amount + 1);
889        var input = $(this).closest('.quantity').find('input.qty');
890        input.val(amount + 1).trigger('change');
891    });
892    $('body').on('click', '.stepper-decrease', function (e) {
893        e.preventDefault();
894        var el = $(this).closest('.stepper');
895        var qty = el.find('> div');
896        var amount = parseInt(qty.text());
897        if (amount > 1) {
898            qty.text(amount - 1);
899            var input = $(this).closest('.quantity').find('input.qty');
900            input.val(amount - 1).trigger('change');
901        }
902    });
903    */
904   
905    $(document.body).on('updated_cart_totals', function () {
906        $('.js-cart-count').text($('.woocommerce-cart-form__contents').data('count'));
907
908        var $div = $('<div />');
909        $('#fly-cart .fly-card-inner').addClass('is-loading');
910        $div.load(php.site_url + ' #fly-cart', function () {
911            $("#fly-cart .fly-card-inner").empty().append($div.find('.fly-card-inner > *'));
912            $('#fly-cart .fly-card-inner').removeClass('is-loading');
913        });
914    });
915
916    $('body').on('click', '.fly-close', function (e) {
917        e.preventDefault();
918        $('.fly').removeClass('is-active');
919        $('html').removeClass('overlay-active');
920    });
921    $('body').on('click', '.menu-button', function (e) {
922        e.preventDefault();
923        $('html').toggleClass('menu-is-active');
924    });
925    $('body').on('click', '.nav-panel li.menu-item-has-children > a > .menu-item-dropdown-toggle', function (e) {
926        e.preventDefault();
927        $('.menu-page-1').css('margin-left', '-100vw');
928        var items = $(this).closest('li').find('> ul').html();
929        $('.menu-page-2 .nav-panel > ul').empty().append(items);
930    });
931    $('body').on('click', '.menu-page-2 a.back', function (e) {
932        e.preventDefault();
933        $('.menu-page-1').css('margin-left', '0vw');
934    });
935
936    $('body').on('click', '.popup-close, .js-close-popup', function (e) {
937        e.preventDefault();
938        $('.popup-outer').removeClass('is-active');
939        $('html').removeClass('overlay-active');
940    });
941
942    $('.popup-form form').on('submit', function () {
943        $('.popup-outer').removeClass('is-active');
944        $('html').removeClass('overlay-active');
945    });
946
947    $('body').on('click', '.js-switch-subscribe', function (e) {
948        e.preventDefault();
949        $('#purchase-type-subscribe').prop('checked', true).trigger('change');
950        $('.popup-outer').removeClass('is-active');
951        $('html').removeClass('overlay-active');
952    });
953
954    $('body').on('change', 'input[name="purchase-type"]', function () {
955        var q = parseInt($('.product .summary input.qty').val());
956        var p = parseFloat($('.summary .m-price > .is-active > .amount bdi').text().substring(1));
957        var t = p * q;
958        var f = formatCurrency.format(t);
959        var s = formatCurrency.format(t * 0.15);
960        if ($(this).val() == 'one') {
961            $('.js-price-save').text(s);
962            if (showSubscribePromo) {
963                $('#popup-save').addClass('is-active');
964                $('html').addClass('overlay-active');
965            }
966            $('.summary .m-price > *').removeClass('is-active');
967            $('.summary .m-price > :nth-child(1)').addClass('is-active');
968        } else {
969            //$('.summary .m-price > *').removeClass('is-active');
970            $('.summary .m-price > :nth-child(2)').addClass('is-active');
971        }
972        $('.js-product-price').each(function () {
973            $(this).html(f);
974        });
975        $('.js-price-afterpay').each(function () {
976            var div = t / 4;
977            $(this).html(formatCurrency.format(div));
978        });
979    });
980
981    $('body').on('click', '.popup-outer', function (e) {
982        if (e.target !== this) {
983            return;
984        }
985        e.preventDefault();
986        $('.popup-outer').removeClass('is-active');
987        $('html').removeClass('overlay-active');
988    });
989    $('body').on('click', '.fly', function (e) {
990        if (e.target !== this) {
991            return;
992        }
993        e.preventDefault();
994        $('.fly').removeClass('is-active');
995        $('html').removeClass('overlay-active');
996    });
997    $('body').on('click', 'a[href^="#popup-"]', function (e) {
998        e.preventDefault();
999        var i = $(this).attr('href').substring(7);
1000        $('#popup-' + i).addClass('is-active');
1001        $('html').addClass('overlay-active');
1002    });
1003    $('body').on('click', 'a[href^="#fly-"]', function (e) {
1004        e.preventDefault();
1005        $('html').removeClass('menu-is-active');
1006        var i = $(this).attr('href').substring(5);
1007        $('#fly-' + i).addClass('is-active');
1008        $('html').addClass('overlay-active');
1009    });
1010
1011    if ($(window).width() <= 767) {
1012        $('.m-cart-body .woocommerce-cart-form__cart-item').each(function () {
1013            var self = $(this);
1014            self.find('.product-quantity .quantity').insertAfter(self.find('.custom-product-cart > :nth-child(2) > :nth-child(1)'));
1015            self.find('.product-subtotal .woocommerce-Price-amount').insertAfter(self.find('.custom-product-cart > :nth-child(2) > :nth-child(1)'));
1016        });
1017    }
1018
1019    loadAndScroll();
1020    $(window).scroll(function () {
1021        loadAndScroll();
1022    });
1023    onResize();
1024    $(window).resize(function () {
1025        onResize();
1026    })
1027
1028    $('.testimonials-body .owl-carousel').owlCarousel({
1029        items: 1,
1030        loop: true,
1031        nav: true,
1032        dots: false,
1033        margin: 100,
1034        autoplay: true,
1035        autoplayTimeout: 6000,
1036        navText: ['', ''],
1037    });
1038    $('.fp-slider .owl-carousel').owlCarousel({
1039        items: 2,
1040        loop: true,
1041        nav: true,
1042        dots: false,
1043        margin: 10,
1044        navText: ['', ''],
1045        responsive: {
1046            768: {
1047                items: 3,
1048                margin: 20,
1049            }
1050        }
1051    });
1052    $('.product-slider .owl-carousel').owlCarousel({
1053        items: 1,
1054        loop: true,
1055        nav: false,
1056        dots: true,
1057        margin: 0,
1058        navText: ['', ''],
1059    });
1060
1061    $('.m-out-shipping').each(function () {
1062        var text = $(this).contents().get(0).nodeValue.trim();
1063        $(this).contents().get(0).remove();
1064        $(this).prepend('<div class="h5 upper color-1 mb-h">Shipping Method</div>');
1065    });
1066
1067    function recentNav() {
1068        $('.recent-body').each(function () {
1069            var height = $(this).find('.card-image').first().outerHeight();
1070            $('.recent-body .owl-nav').css('max-height', height);
1071        });
1072    }
1073    $('.recent-body .owl-carousel').owlCarousel({
1074        loop: true,
1075        nav: true,
1076        dots: false,
1077        margin: 20,
1078        navText: ['', ''],
1079        items: 1,
1080        responsive: {
1081            768: {
1082                items: 2
1083            },
1084            1025: {
1085                items: 3
1086            },
1087        },
1088        onInitialized: function () {
1089            recentNav();
1090        },
1091        onResized: function () {
1092            recentNav();
1093        },
1094    });
1095}
1096
1097$ = jQuery.noConflict();
1098
1099let vh = window.innerHeight * 0.01;
1100document.documentElement.style.setProperty('--vh', vh + 'px');
1101
1102// Usage: height: calc(var(--vh, 1vh) * 100);
1103
1104
1105/***** Resize Items *****/
1106resizeItems = function () {
1107
1108    /***** Something *****/
1109    if ($("#something").length > 0) {
1110
1111    };
1112
1113    // only on desktop
1114    if (w > 1025) {
1115
1116    }
1117    // on tablet
1118    if (w < 1026) {
1119
1120    }
1121    // on phone 
1122    if (w < 768) {
1123
1124    }
1125
1126};
1127
1128
1129$(window).on('load', function () {
1130    /***** Resize Items *****/
1131    resizeItems();
1132
1133
1134    /***** Transitional Effects *****/
1135    setTimeout(function () {
1136        $("body a, body input[type='submit'], button").addClass("loaded");
1137    }, 1000);
1138
1139});
1140
1141$(document).ready(function () {
1142    /***** Resize Items *****/
1143    resizeItems();
1144    onReady();
1145
1146});
1147
1148
1149var w = $(window).width();
1150$(window).resize(function () {
1151    /***** Resize Items *****/
1152    if ($(window).width() == w) return;
1153    w = $(window).width();
1154    resizeItems();
1155});
1156
1157
1158/***** Adjust Height Function *****/
1159jQuery.fn.adjustHeight = function () {
1160    var maxHeightFound = 0;
1161    this.css('min-height', '1px');
1162    if (this.is('a')) {
1163        this.removeClass('loaded');
1164    };
1165    this.each(function () {
1166        if ($(this).height() > maxHeightFound) {
1167            maxHeightFound = $(this).height();
1168        }
1169    });
1170    this.css('min-height', maxHeightFound);
1171    if (this.is('a')) {
1172        this.addClass('loaded');
1173    };
1174};
1175
1176jQuery.fn.adjustOuterHeight = function () {
1177    var maxHeightFound = 0;
1178    this.css('min-height', '1px');
1179    this.each(function () {
1180        if ($(this).outerHeight(true) > maxHeightFound) {
1181            maxHeightFound = $(this).outerHeight(true);
1182        }
1183    });
1184    this.css('min-height', maxHeightFound);
1185};
1186
1187jQuery.fn.isInViewport = function () {
1188    var elementTop = $(this).offset().top;
1189    var elementBottom = elementTop + $(this).outerHeight();
1190
1191    var viewportTop = $(window).scrollTop();
1192    var viewportBottom = viewportTop + $(window).height();
1193
1194    return elementBottom > viewportTop && elementTop < viewportBottom;
1195};
1196
1197jQuery.fn.isInMiddleViewport = function () {
1198    var elementTop = $(this).offset().top;
1199    var elementBottom = elementTop + $(this).outerHeight();
1200
1201    var viewportTop = $(window).scrollTop() + $(window).height() * 0.6;
1202
1203    return viewportTop > elementTop;
1204};
1205
1206function isEmail(email) {
1207    var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
1208    return regex.test(email);
1209}
1210
1211/* Get cookie value by name */
1212function getCookie(c_name) {
1213    var c_value = " " + document.cookie;
1214    var c_start = c_value.indexOf(" " + c_name + "=");
1215    if (c_start == -1) {
1216        c_value = null;
1217    }
1218    else {
1219        c_start = c_value.indexOf("=", c_start) + 1;
1220        var c_end = c_value.indexOf(";", c_start);
1221        if (c_end == -1) {
1222            c_end = c_value.length;
1223        }
1224        c_value = unescape(c_value.substring(c_start, c_end));
1225    }
1226    return c_value;
1227}
1228
1229/* Set cookie value and expiry by name */
1230function createCookie(name, value, days) {
1231    var expires;
1232
1233    if (days) {
1234        var date = new Date();
1235        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
1236        expires = "; expires=" + date.toGMTString();
1237    } else {
1238        expires = "";
1239    }
1240    document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/";
1241}
1242
1243/* Load checkout page with cookies value. */
1244$(document).ready(function () {
1245    var current_path = window.location.pathname;
1246
1247    // Remove paypal for subscription for cart.
1248    if (current_path === '/my-bag/') {
1249        if ($('tr').hasClass('recurring-totals')) {
1250            $('.ppc-button-wrapper').remove();
1251            $('.ppc-button-wrapper').css('display', 'none');
1252        }
1253    }
1254
1255    // Remove paypal for subscription for checkout
1256    if (current_path === '/checkout/') {
1257
1258        if ($('tr').hasClass('recurring-total')) {
1259            console.log('yes');
1260            $('.wc_payment_method.payment_method_ppcp-gateway').remove();
1261            $('.wc_payment_method.payment_method_ppcp-gateway').css('display', 'none');
1262        }
1263    }
1264
1265    // Add disclaimer for non AUS shipping.
1266    var ship_country = $('#shipping_country').val();
1267    if (ship_country !== 'AU') {
1268        $('.m-out-shipping.m-out-box').append('<div class="shipping_disclaimer"><strong>Please note:</strong> The prices shown on this site are in AUD $. International purchases are not eligible for returns. Customers purchasing from outside Australia are responsible for the payment of international shipment and the duties that may occur.</div>')
1269        $('.shipping_disclaimer').css('margin-top', '10px');
1270        $('.shipping_disclaimer').css('padding', '10px');
1271        $('.shipping_disclaimer').css('font-size', '12px');
1272        $('.shipping_disclaimer').css('border', '1px solid #CCC');
1273        $('.shipping_disclaimer').css('background-color', '#EFEFEF');
1274        $('.shipping_disclaimer').css('border-radius', '4px');
1275    }
1276
1277    $('#custom-newsletter-register').on('change', function (e) {
1278        e.preventDefault();
1279        $('#kl_newsletter_checkbox').prop('checked', $('#custom-newsletter-register').prop('checked'));
1280    });
1281
1282    $('#kl_newsletter_checkbox').on('change', function (e) {
1283        e.preventDefault();
1284        $('#custom-newsletter-register').prop('checked', $('#kl_newsletter_checkbox').prop('checked'));
1285    });
1286
1287});
1288
1289jQuery(document).ready(function($) {
1290    var selectedQuantity = 1; // Default selected tub quantity
1291    var quantityInput = 1;    // Default input quantity
1292    var subscriptionDiscount = 0.85;
1293
1294    // Tiered discount promo (July 2026). window.intuPromo is localized from
1295    // include/tiered-promo.php; .onetime / .subscribe hold the fraction OFF per
1296    // tier ([0]=1 item, [1]=2 items, [2]=3+ items). Display only — the real
1297    // money-off is applied by Woo Discount Rules Pro.
1298    var promo = window.intuPromo || { active: false, onetime: [], subscribe: [], defaultSubscribe: false, syncFrequency: false };
1299
1300    var isSubscription = !!(promo.active && promo.defaultSubscribe); // Flag to check if it's a subscription
1301    // Per-tier price multipliers (1 - fraction off), indexed by box order.
1302    var specialSaleQuantityPctOff       = promo.active ? promo.onetime.map(function (f) { return 1 - f; }) : [];
1303    var specialSaleSubscriptionPctOff   = promo.active ? promo.subscribe.map(function (f) { return 1 - f; }) : [];
1304    var specialSaleSubscriptionDiscount = 0;
1305    var specialSaleSubscriptionSavingsLabel = ''; //Sale Messaging for subscription
1306    var specialSaleSavingsLabel = []; //Sale Messaging for subscription
1307
1308    // Tier index (0-based) for the currently selected total quantity, c
1308apped at 3.
1309    function promoTierIndex() {
1310        return Math.min(Math.max(selectedQuantity * quantityInput, 1), 3) - 1;
1311    }
1312
1313    // Robustly read a price out of an element, whatever the markup variant.
1314    // .m-price-main may contain the amount directly, or nested in <del>/<ins>
1315    // when a display discount (e.g. "40% OFF" sku badge) is active — the first
1316    // .amount inside is always the original/base price.
1317    function readPrice(selector) {
1318        var el = $(selector).first();
1319        if (!el.length) { return 0; }
1320        var v = parseFloat(el.text().replace(/[^0-9.]/g, ''));
1321        return isNaN(v) ? 0 : v;
1322    }
1323
1324    // Update the live "X% off" badge next to Quantity for the selected tier.
1325    function updateTierBadge() {
1326        if (!promo.active) { return; }
1327        var arr = isSubscription ? promo.subscribe : promo.onetime;
1328        var pct = Math.round((arr[promoTierIndex()] || 0) * 100);
1329        $('.js-tier-badge').text(pct + '% off').show();
1330    }
1331
1332    // Live main price (top of summary) for the promo. The original
1333    // .m-price-main / .m-price-offer elements stay in the DOM untouched —
1334    // other scripts read prices out of them — but are hidden via CSS while
1335    // the promo row (struck base total, discounted total, % badge) shows.
1336    var promoBasePrice = 0;
1337    function updateMainPromoPrice() {
1338        if (!promo.active) { return; }
1339        var wrap = $('.summary .m-price');
1340        if (!wrap.length) { return; }
1341        if (!promoBasePrice) {
1342            promoBasePrice = readPrice('.summary .m-price .m-price-main .amount bdi');
1343            if (!promoBasePrice) { return; }
1344        }
1345        var totalQty = Math.max(selectedQuantity * quantityInput, 1);
1346        var arr = isSubscription ? promo.subscribe : promo.onetime;
1347        var frac = arr[Math.min(totalQty, 3) - 1] || 0;
1348        var baseTotal = promoBasePrice * totalQty;
1349        var discTotal = baseTotal * (1 - frac);
1350
1351        if (!wrap.find('.js-promo-price').length) {
1352            wrap.addClass('promo-price-active');
1353            wrap.append('<span class="js-promo-strike"></span><span class="js-promo-price"></span><span class="js-promo-pct"></span>');
1354        }
1355        wrap.find('.js-promo-strike').text('$' + baseTotal.toFixed(2));
1356        wrap.find('.js-promo-price').text('$' + discTotal.toFixed(2));
1357        wrap.find('.js-promo-pct').text(Math.round(frac * 100) + '% off');
1358    }
1359
1360    // Function to update prices based on quantity and purchase type
1361    function updatePrices() {
1362        var basePrice = readPrice('.summary .m-price .m-price-main .amount bdi');
1363        var subscriptionPrice = readPrice('.summary .m-price .m-price-offer .amount bdi');
1364        if (!basePrice) { updateTierBadge(); return; }
1365
1366        var index = 0;
1367        $('.quantity-box').each(function() {
1368            var quantity = $(this).data('quantity');
1369            var numTubs = $(this).data('num_tubs');
1370            var verboseName = $(this).data('verbose_name');
1371            var verboseNamePlural = $(this).data('verbose_name_plural');
1372            var totalPrice, pricePerTub, savings;
1373            
1374            if (isSubscription) {
1375                if (promo.active && specialSaleSubscriptionPctOff[index]) {
1376                    totalPrice = (basePrice * specialSaleSubscriptionPctOff[index]) * quantity;
1377                    pricePerTub = totalPrice / quantity;
1378                } else if (specialSaleSubscriptionDiscount) {
1379                    totalPrice = (basePrice * specialSaleSubscriptionDiscount) * quantity;
1380                    pricePerTub = totalPrice / quantity;
1381                } else {
1382                    totalPrice = subscriptionPrice * quantity;
1383                    pricePerTub = subscriptionPrice;
1384                }
1385
1386                savings = (basePrice * quantity) - totalPrice;
1387            } else {
1388                if (quantity === 1) {
1389                    totalPrice = basePrice;
1390                    if(specialSaleQuantityPctOff[index]) {
1391                        totalPrice = basePrice * specialSaleQuantityPctOff[index];
1392                    } 
1393                    pricePerTub = totalPrice;
1394                    savings = 0;
1395                } else {
1396                    if(specialSaleQuantityPctOff[index]) {
1397                        totalPrice = (basePrice * specialSaleQuantityPctOff[index]) * quantity;
1398                    } else {
1399                        totalPrice = (basePrice * subscriptionDiscount) * quantity;
1400                    }
1401                    pricePerTub = totalPrice / quantity;
1402                    savings = (basePrice * quantity) - totalPrice;
1403                }
1404            }
1405
1406            $(this).find('.box-price-per-tub').text('$' + totalPrice.toFixed(2) + ' Total');
1407            if (numTubs > 1) {
1408                $(this).find('.box-price').html('$' + (pricePerTub / numTubs).toFixed(2) + '<small>/' + verboseName + '</small>');
1409            } else {
1410                $(this).find('.box-price').html('$' + pricePerTub.toFixed(2) + '<small>/' + verboseName + '</small>');
1411            }
1412
1413            // Update savings label
1414            if(isSubscription && specialSaleSubscriptionSavingsLabel) {
1415                $(this).find('.savings-label').text(specialSaleSubscriptionSavingsLabel).show();
1416            } else if (!isSubscription && specialSaleSavingsLabel[index]) {
1417                $(this).find('.savings-label').text(specialSaleSavingsLabel[index]).show();
1418            } else {
1419                
1420                if (savings > 0) {
1421                    $(this).find('.savings-label').text('Save $' + savings.toFixed(2)).show();
1422                } else {
1423                    $(this).find('.savings-label').hide();
1424                }
1425            }
1426
1427            // Per-box "X% off" label (promo only).
1428            if (promo.active) {
1429                var boxFraction = isSubscription ? promo.subscribe[index] : promo.onetime[index];
1430                if (boxFraction) {
1431                    $(this).find('.js-box-pct').text(Math.round(boxFraction * 100) + '% off').show();
1432                }
1433            }
1434            index++;
1435        });
1436
1437        updateTierBadge();
1438        updateMainPromoPrice();
1439    }
1440
1441    // Initialize prices on page load
1442    updatePrices();
1443
1444    // Initialize stepper display next to Add to bag with current qty
1445    if ($('.purchase-actions .stepper > div').length) {
1446        var currentQty = parseInt($('input.qty').val() || 1);
1447        $('.purchase-actions .stepper > div').text(currentQty);
1448    }
1449
1450    // Handle purchase type selection
1451    $('input[name="purchase-type"]').on('change', function() {
1452        isSubscription = ($(this).val() === 'subscribe');
1453        updatePrices();
1454    });
1455
1456    // Handle quantity box selection
1457    $('.quantity-box').on('click', function() {
1458        $('.quantity-box').removeClass('active');
1459        $(this).addClass('active');
1460        selectedQuantity = parseInt($(this).data('quantity'));
1461        $('input[name="selected-quantity"]').val(selectedQuantity);
1462        // Auto-match delivery frequency to quantity (1 -> 30d, 2 -> 60d, 3 -> 90d).
1463        if (promo.active && promo.syncFrequency) {
1464            $('#custom-subscription-period').val(Math.min(selectedQuantity, 3)).trigger('change');
1465        }
1466        updatePrices();
1467    });
1468
1469    // Handle stepper increase
1470    $('body').on('click', '.stepper-increase', function (e) {
1471        e.preventDefault();
1472        var el = $(this).closest('.stepper');
1473        var qtyDisplay = el.find('> div');
1474        quantityInput = parseInt(qtyDisplay.text()) + 1;
1475        qtyDisplay.text(quantityInput);
1476        // Update quantity input
1477        $('input.qty').val(quantityInput).trigger('change');
1478        updatePrices();
1479    });
1480
1481    // Handle stepper decrease
1482    $('body').on('click', '.stepper-decrease', function (e) {
1483        e.preventDefault();
1484        var el = $(this).closest('.stepper');
1485        var qtyDisplay = el.find('> div');
1486        quantityInput = parseInt(qtyDisplay.text());
1487        if (quantityInput > 1) {
1488            quantityInput -= 1;
1489            qtyDisplay.text(quantityInput);
1490            // Update quantity input
1491            $('input.qty').val(quantityInput).trigger('change');
1492            updatePrices();
1493        }
1494    });
1495
1496    // Keep stepper display in sync if qty input changes elsewhere
1497    $('body').on('change keyup', 'input.qty', function() {
1498        var val = parseInt($(this).val() || 1);
1499        $('.purchase-actions .stepper > div').text(val);
1500        quantityInput = val;
1501    });
1502
1503    // Before form submission, compute total quantity
1504    $('form.cart').on('submit', function(e) {
1505        var totalQuantity = selectedQuantity * quantityInput;
1506        $('input.qty').val(totalQuantity);
1507    });
1508
1509    // Auto-select Subscribe & save on load when the promo is running.
1510    if (promo.active && promo.defaultSubscribe && $('#purchase-type-subscribe').length) {
1511        $('.purchase-button').removeClass('active');
1512        $('.purchase-button[data-purchase-type="subscribe"]').addClass('active');
1513        $('.m-subscribe-select').show();
1514        $('#purchase-type-subscribe').prop('checked', true).trigger('change');
1515        isSubscription = true;
1516        if (promo.syncFrequency) {
1517            $('#custom-subscription-period').val(Math.min(selectedQuantity, 3)).trigger('change');
1518        }
1519        updatePrices();
1520    }
1521});

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.