PageSourceSearch

https://pharmacysyria.com/assets/front-end/js/custom.js

js pharmacysyria.com collected 2026-10-02 01:39:49 UTC 99,096 bytes, 2,899 lines download raw bytes

1"use strict";
2
3(function ($) {
4    $(".profile-aside-btn").on("click", function () {
5        $("#shop-sidebar, .profile-aside-overlay").toggleClass("active");
6    });
7    $(".profile-aside-close-btn, .profile-aside-overlay").on(
8        "click",
9        function () {
10            $("#shop-sidebar, .profile-aside-overlay").removeClass("active");
11        }
12    );
13
14    $(".stopPropagation").on("click", function (e) {
15        e.stopPropagation();
16    });
17
18    try {
19        $('[data-toggle="tooltip"]').tooltip();
20    } catch (e) {
21    }
22})(jQuery);
23
24$(document).ready(function () {
25    const stickyElement = $(".bottom-sticky_ele");
26    const offsetElement = $(".bottom-sticky_offset");
27
28    if (stickyElement.length !== 0) {
29        $(window).on("scroll", function () {
30            const elementOffset =
31                offsetElement.offset().top - $(window).height() / 1.2;
32            const scrollTop = $(window).scrollTop();
33
34            if (scrollTop >= elementOffset) {
35                stickyElement.addClass("stick");
36            } else {
37                stickyElement.removeClass("stick");
38            }
39        });
40    }
41
42    getReferralCodeFromURL();
43    renderOfferBarFunction("#announcement");
44
45    /*==================================
46    19: Changing svg color
47    ====================================*/
48    $("img.svg").each(function () {
49        var $img = jQuery(this);
50        var imgID = $img.attr("id");
51        var imgClass = $img.attr("class");
52        var imgURL = $img.attr("src");
53
54        jQuery.get(
55            imgURL,
56            function (data) {
57                // Get the SVG tag, ignore the rest
58                var $svg = jQuery(data).find("svg");
59
60                // Add replaced image's ID to the new SVG
61                if (typeof imgID !== "undefined") {
62                    $svg = $svg.attr("id", imgID);
63                }
64                // Add replaced image's classes to the new SVG
65                if (typeof imgClass !== "undefined") {
66                    $svg = $svg.attr("class", imgClass + " replaced-svg");
67                }
68
69                // Remove any invalid XML tags as per http://validator.w3.org
70                $svg = $svg.removeAttr("xmlns:a");
71
72                // Check if the viewport is set, else we gonna set it if we can.
73                if (
74                    !$svg.attr("viewBox") &&
75                    $svg.attr("height") &&
76                    $svg.attr("width")
77                ) {
78                    $svg.attr(
79                        "viewBox",
80                        "0 0 " + $svg.attr("height") + " " + $svg.attr("width")
81                    );
82                }
83                // Replace image with new SVG
84                $img.replaceWith($svg);
85            },
86            "xml"
87        );
88    });
89});
90
91function renderOfferBarFunction(sectionSelector) {
92    let hideUntil = localStorage.getItem("offerBarHideUntil");
93    if (hideUntil) {
94        let currentTime = Date.now();
95        if (currentTime < hideUntil) {
96            $(sectionSelector).slideUp("fast");
97        } else {
98            $(sectionSelector).slideDown("fast");
99            localStorage.removeItem("offerBarHideUntil");
100        }
101    } else {
102        $(sectionSelector).slideDown("fast");
103    }
104}
105
106toastr.options = {
107    closeButton: false,
108    debug: false,
109    newestOnTop: false,
110    progressBar: false,
111    positionClass: "toast-top-right",
112    preventDuplicates: false,
113    onclick: null,
114    showDuration: "300",
115    hideDuration: "1000",
116    timeOut: "5000",
117    extendedTimeOut: "1000",
118    showEasing: "swing",
119    hideEasing: "linear",
120    showMethod: "fadeIn",
121    hideMethod: "fadeOut",
122};
123
124$(".get-currency-change-function").on("click", function () {
125    let code = $(this).data("code");
126    currencyChangeFunction(code);
127});
128
129function currencyChangeFunction(currency_code) {
130    $.ajaxSetup({
131        headers: { "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content") },
132    });
133    $.ajax({
134        type: "POST",
135        url: $("#route-currency-change").data("url"),
136        data: { currency_code: currency_code },
137        success: function (data) {
138            toastr.success(data.message);
139            location.reload();
140        },
141    });
142}
143
144$(".change-language").on("click", function () {
145    $.ajaxSetup({
146        headers: {
147            "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
148        },
149    });
150    $.ajax({
151        type: "POST",
152        url: $(this).data("action"),
153        data: {
154            language_code: $(this).data("language-code"),
155        },
156        success: function (data) {
157            toastr.success(data.message);
158            location.reload();
159        },
160    });
161});
162
163function getReferralCodeFromURL() {
164    let getAuthStatus = $("#is-customer-auth-active").data("value");
165    if (getAuthStatus == 0) {
166        const currentUrl = new URL(window.location.href);
167        const referralCodeParameter = new URLSearchParams(
168            currentUrl.search
169        ).get("referral_code");
170        if (referralCodeParameter) {
171            let referralCodeInput = $("#referral_code");
172            if ($("#is-request-customer-auth-sign-up").data("value")) {
173                if (referralCodeInput.length) {
174                    referralCodeInput.val(referralCodeParameter);
175                }
176            } else {
177                let redirectLink = $("#route-customer-auth-sign-up").data(
178                    "url"
179                );
180                window.location.href =
181                    redirectLink +
182                    "?referral_code=" +
183                    referralCodeParameter;
184            }
185        }
186    }
187}
188
189$(".web-announcement-slideUp").on("click", function () {
190    $("#announcement").slideUp(300);
191    let hideUntil = Date.now() + 300000;
192    localStorage.setItem("offerBarHideUntil", hideUntil);
193});
194
195$(".category-menu-toggle-btn").on("click", function () {
196    $(".megamenu-wrap").toggleClass("show");
197});
198
199$(".navbar-tool-icon-box").on("click", function () {
200    $(".megamenu-wrap").removeClass("show");
201});
202
203$(window).on("scroll", function () {
204    $(".megamenu-wrap").removeClass("show");
205});
206
207$(".close-search-form-mobile").on("click", function () {
208    $(".search-form-mobile").removeClass("active");
209    // Otherwise the suggestion card lingers over the page with stale results.
210    $(".search-card").hide();
211});
212$(".open-search-form-mobile").on("click", function () {
213    $(".search-form-mobile").addClass("active");
214    // The overlay is visibility:hidden until its slide transition ends, and a
215    // hidden input refuses focus - wait the transition out.
216    setTimeout(function () {
217        $(".search-form-mobile .search-bar-input").trigger("focus");
218    }, 350);
219});
220
221$(".get-view-by-onclick").on("click", function () {
222    location.href = $(this).data("link");
223});
224
225$("#inputChecked").change(function () {
226    if ($(this).is(":checked")) {
227        $("#sign-up").removeAttr("disabled");
228    } else {
229        $("#sign-up").attr("disabled", "disabled");
230    }
231});
232
233$(".submitVerifyForm").on("click", function () {
234    let formElement = $(this).closest("form");
235    formElement.attr("action", formElement.data("verify"));
236    $(this).closest("form").submit();
237});
238
239$(".resendVerifyForm").on("click", function () {
240    let formElement = $(this).closest("form");
241    formElement.attr("action", formElement.data("resend"));
242    $(this).closest("form").submit();
243});
244
245// $(".resendVerifyForm").on('click', function () {
246//     $("input.otp-field").val("");
247//     $.ajaxSetup({
248//         headers: {
249//             "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
250//         },
251//     });
252//     $.ajax({
253//         url: $(this).data("url"),
254//         method: "POST",
255//         dataType: "json",
256//         data: {
257//             user_id: $(this).data("userid"),
258//         },
259//         beforeSend: function () {
260//             $("#loading").show();
261//         },
262//         success: function (data) {
263//             if (data.status == 1) {
264//                 let new_counter = $(".verifyCounter");
265//                 let new_seconds = data.new_time;
266
267//                 function new_tick() {
268//                     let minutes = Math.floor(new_seconds / 60);
269//                     let seconds = new_seconds % 60;
270//                     new_seconds--;
271//                     new_counter.html(
272//                         minutes +
273//                             ":" +
274//                             (seconds < 10 ? "0" : "") +
275//                             String(seconds)
276//                     );
277//                     if (new_seconds > 0) {
278//                         setTimeout(new_tick, 1000);
279//                         $(".resend-otp-button").attr("disabled", true);
280//                         $(".resend_otp_custom").slideDown();
281//                     } else {
282//                         $(".resend-otp-button").removeAttr("disabled");
283//                         new_counter.html("0:00");
284//                         $(".resend_otp_custom").slideUp();
285//                     }
286//                 }
287
288//                 new_tick();
289
290//                 toastr.success($("#message-otp-sent-again").data("text"));
291//             } else {
292//                 toastr.error($("#message-wait-for-new-code").data("text"));
293//             }
294//         },
295//         complete: function () {
296//             $("#loading").hide();
297//         },
298//     });
299// });
300
301$("#customerOtpVerify").click(function () {
302    $("input.otp-field").val("");
303    $.ajaxSetup({
304        headers: {
305            "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
306        },
307    });
308    $.ajax({
309        url: $(this).data("url"),
310        method: "POST",
311        dataType: "json",
312        data: {
313            identity: $(this).data("identity"),
314        },
315        beforeSend: function () {
316            $("#loading").addClass("d-grid");
317        },
318        success: function (data) {
319            if (data.status == 1) {
320                let newCounter = $(".verifyCounter");
321                let newSeconds = data.new_time;
322
323                function new_tick() {
324                    let minutes = Math.floor(newSeconds / 60);
325                    let seconds = newSeconds % 60;
326                    newSeconds--;
327                    newCounter.html(
328                        minutes +
329                        ":" +
330                        (seconds < 10 ? "0" : "") +
331                        String(seconds)
332                    );
333                    if (newSeconds > 0) {
334                        setTimeout(new_tick, 1000);
335                        $(".resend-otp-button").attr("disabled", true);
336                        $(".resend_otp_custom").slideDown();
337                    } else {
338                        $(".resend-otp-button").removeAttr("disabled");
339                        newCounter.html("0:00");
340                        $(".resend_otp_custom").slideUp();
341                    }
342                }
343
344                new_tick();
345                toastr.success(data.message);
346            } else {
347                toastr.error(data.message);
348            }
349        },
350        complete: function () {
351            $("#loading").removeClass("d-grid");
352        },
353    });
354});
355
356
357$(".check-password-match").on("change", function () {
358    checkPasswordMatch();
359});
360
361function checkPasswordMatch() {
362    let password = $("#password").val();
363    let confirmPassword = $("#confirm_password").val();
364    let messageElement = $("#message");
365    messageElement.removeAttr("style");
366    messageElement.html("");
367    if (confirmPassword === "") {
368        messageElement.attr("style", "color:black");
369        messageElement.html($("#message-please-retype-password").data("text"));
370    } else if (password === "") {
371        messageElement.removeAttr("style");
372        messageElement.html("");
373    } else if (password !== confirmPassword) {
374        messageElement.html($("#message-password-not-match").data("text"));
375        messageElement.attr("style", "color:red");
376    } else if (confirmPassword.length <= 6) {
377        messageElement.html($("#message-password-need-longest").data("text"));
378        messageElement.attr("style", "color:red");
379    } else {
380        messageElement.html($("#message-password-match").data("text"));
381        messageElement.attr("style", "color:green");
382    }
383}
384
385$(document).ready(function () {
386    $("#confirm_password").keyup(checkPasswordMatch);
387});
388
389function accountImageReadURL(input) {
390    if (input.files && input.files[0]) {
391        let maxFileSizeLimit = Number(input?.dataset?.maxSize || ($('#imageUploadMaxSize').data('max-size') || 20)) * 1024 * 1024;
392        if (!(maxFileSizeLimit && maxFileSizeLimit < input.files[0]?.size)) {
393            setTimeout(function () {
394                var reader = new FileReader();
395                reader.onload = function (e) {
396                    $("#blah").attr("src", e.target.result);
397                };
398                reader.readAsDataURL(input.files[0]);
399            }, 1000)
400        }
401    }
402}
403
404$("#files").change(function () {
405    accountImageReadURL(this);
406});
407
408$(".update-account-info").on("click", function () {
409    $("#profile_form").submit();
410});
411
412$(".call-route-alert").on("click", function () {
413    let route = $(this).data("route");
414    let message = $(this).data("message");
415    route_alert(route, message);
416});
417
418$(".filter-ico-button").on("click", function () {
419    $(".__shop-page-sidebar").toggleClass("active");
420});
421
422$(".shop-page-sidebar-close").on("click", function () {
423    $(".__shop-page-sidebar").removeClass("active");
424});
425
426$(".action-sort-shop-products-by-data").on("change", function () {
427    sortShopProductsByData($(this).val());
428});
429
430$("#shop-view-chat-form").on("submit", function (e) {
431    e.preventDefault();
432    $.ajaxSetup({
433        headers: {
434            "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
435        },
436    });
437    $.ajax({
438        type: "post",
439        url: $("#route-messages-store").data("url"),
440        data: $("#shop-view-chat-form").serialize(),
441        success: function (response) {
442            toastr.success($("#message-send-successfully").data("text"), {
443                CloseButton: true,
444                ProgressBar: true,
445            });
446            $("#shop-view-chat-form").trigger("reset");
447        },
448    });
449});
450
451$(".menu--caret").on("click", function (e) {
452    var element = $(this).closest(".menu--caret-accordion");
453    if (element.hasClass("open")) {
454        element.removeClass("open");
455        element.find(".menu--caret-accordion").removeClass("open");
456        element.find(".card-body").slideUp(300, "swing");
457    } else {
458        element.addClass("open");
459        element.children(".card-body").slideDown(300, "swing");
460        element
461            .siblings(".menu--caret-accordion")
462            .children(".card-body")
463            .slideUp(300, "swing");
464        element.siblings(".menu--caret-accordion").removeClass("open");
465        element
466            .siblings(".menu--caret-accordion")
467            .find(".menu--caret-accordion")
468            .removeClass("open");
469        element
470            .siblings(".menu--caret-accordion")
471            .find(".card-body")
472            .slideUp(300, "swing");
473    }
474});
475
476$("#seller-chat-form").on("submit", function (e) {
477    e.preventDefault();
478    $.ajaxSetup({
479        headers: {
480            "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
481        },
482    });
483    $.ajax({
484        type: "post",
485        url: $("#route-messages-store").data("url"),
486        data: $(this).serialize(),
487        success: function (response) {
488            toastr.success($("#message-send-successfully").data("text"), {
489                CloseButton: true,
490                ProgressBar: true,
491            });
492            $("#seller-chat-form").trigger("reset");
493        },
494    });
495});
496
497$("#deliveryman-chat-form").on("submit", function (e) {
498    e.preventDefault();
499    $.ajaxSetup({
500        headers: {
501            "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
502        },
503    });
504    $.ajax({
505        type: "post",
506        url: $("#route-messages-store").data("url"),
507        data: $(this).serialize(),
508        success: function (response) {
509            toastr.success($("#message-send-successfully").data("text"), {
510                CloseButton: true,
511                ProgressBar: true,
512            });
513            $("#deliveryman-chat-form").trigger("reset");
514        },
515    });
516});
517
518$(".rating-label-wrap input[type=range]").on("change", function () {
519    let ratingVal = $(this).val();
520    let ratingContent = $(".rating_content_delivery_man");
521    let rattingTextAreaClass = $(".text-area-class");
522    let rattingMessages = $("#message-ratingContent");
523    let htmlDir = $("#system-session-direction").data("value");
524    let position = "left";
525    if (htmlDir === "rtl") {
526        position = "right";
527    }
528    switch (ratingVal) {
529        case "1":
530            ratingContent
531                .text(rattingMessages.data("poor"))
532                .css(position, "5px");
533            rattingTextAreaClass.attr("placeholder", "");
534            break;
535        case "2":
536            ratingContent
537                .text(rattingMessages.data("average"))
538                .css(position, "36px");
539            rattingTextAreaClass.attr("placeholder", "");
540            break;
541        case "3":
542            ratingContent
543                .text(rattingMessages.data("good"))
544                .css(position, "85px");
545            rattingTextAreaClass.attr(
546                "placeholder",
547                rattingMessages.data("good-message")
548            );
549            break;
550        case "4":
551            ratingContent
552                .text(rattingMessages.data("good2"))
553                .css(position, "112px");
554            rattingTextAreaClass.attr(
555                "placeholder",
556                rattingMessages.data("good2-message")
557            );
558            break;
559        case "5":
560            ratingContent
561                .text(rattingMessages.data("excellent"))
562                .css(position, "155px");
563            rattingTextAreaClass.attr(
564                "placeholder",
565                rattingMessages.data("excellent-message")
566            );
567            break;
568        default:
569            break;
570    }
571});
572
573$("#add_fund_to_wallet_form_btn").on("click", function () {
574    if (!$("input[name='payment_method']:checked").val()) {
575        toastr.error($("#message-select-payment-method").data("text"));
576    }
577});
578
579$("#add-fund-amount-input").on("keyup", function () {
580    if (!isNaN($(this).val()) && $(this).val() < 0) {
581        $(this).val(0);
582        toastr.error($("#message-cannot-input-minus-value").data("text"));
583    }
584});
585
586$(".click-to-copy-coupon").on("click", function () {
587    let copiedText = $(this).data("value");
588    navigator.clipboard
589        .writeText(copiedText)
590        .then(function () {
591            toastr.success($("#message-successfully-copied").data("text"));
592        })
593        .catch(function (error) {
594            toastr.error($("#message-copied-failed").data("text"));
595        });
596});
597$(".click-to-copy-data-value").on("click", function () {
598    let copiedText = $(this).data("value");
599    let tempTextarea = $("<textarea>");
600    $("body").append(tempTextarea);
601    tempTextarea.val(copiedText).select();
602    document.execCommand("copy");
603    tempTextarea.remove();
604    toastr.success($("#message-successfully-copied").data("text"));
605});
606
607
608$("#customer-register-form").on("submit", function (e) {
609    e.preventDefault();
610    $.ajax({
611        type: "POST",
612        url: $(this).data("action"),
613        data: $(this).serialize(),
614        beforeSend: function () {
615            $("#loading").addClass("d-grid");
616        },
617        success: function (response) {
618            if (response.errors) {
619                for (let index = 0; index < response.errors.length; index++) {
620                    toastr.error(response.errors[index].message);
621                }
622            } else if (response.error) {
623                toastr.error(response.error);
624            } else if (response.status === 1) {
625                toastr.success(response.message);
626            }
627
628            if (response?.redirect_url) {
629                window.location.href = response.redirect_url;
630            }
631        },
632        error: function () {
633
634        },
635        complete: function () {
636            $("#loading").removeClass("d-grid");
637        },
638    });
639});
640
641$(".remove-img-row-by-key").on("click", function () {
642    let reviewId = $(this).data("review-id");
643    let getPhoto = $(this).data("photo");
644    let key = $(this).data("key");
645
646    $.ajaxSetup({
647        headers: { "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content") },
648    });
649    $.ajax({
650        type: "POST",
651        url: $(this).data("route"),
652        data: {
653            id: reviewId,
654            name: getPhoto,
655        },
656        success: function (response) {
657            if (response.message) {
658                toastr.success(response.message);
659            }
660            $(".img_row" + key).remove();
661        },
662    });
663});
664
665$(".customer-account-delete-by-route").on("click", function () {
666    $("#shop-sidebar").removeClass("active");
667    $(".profile-aside-overlay ").removeClass("active");
668    let route = $(this).data("route");
669    let message = $(this).data("message");
670    route_alert(route, message);
671});
672
673$(".show-instant-image").on("click", function () {
674    let link = $(this).data("link");
675    showInstantImage(link);
676});
677
678function showInstantImage(link) {
679    $("#attachment-view").attr("src", link);
680    $("#show-modal-view").modal("toggle");
681}
682
683function couponCode() {
684    $("#apply-coupon-code").on("click", function () {
685        $.ajaxSetup({
686            headers: {
687                "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
688            },
689        });
690        $.ajax({
691            type: "POST",
692            url: $("#route-coupon-apply").data("url"),
693            data: $("#coupon-code-ajax").serializeArray(),
694            success: function (data) {
695                let messages = data.messages;
696                if (data.status) {
697                    toastr.success(messages);
698                } else {
699                    toastr.error(messages);
700                }
701                setTimeout(function () {
702                    location.reload();
703                }, 2000);
704            },
705        });
706    });
707}
708
709couponCode();
710
711$(".password-toggle-btn").on("click", function () {
712    let checkbox = $(this).find("input[type=checkbox]");
713    let eyeIcon = $(this).find("i");
714    checkbox.change(function () {
715        if (checkbox.is(":checked")) {
716            eyeIcon.removeClass("tio-hidden").addClass("tio-invisible");
717        } else {
718            eyeIcon.removeClass("tio-invisible").addClass("tio-hidden");
719        }
720    });
721});
722
723$(".filter-show-btn").on("click", function () {
724    $("#shop-sidebar").toggleClass("show active");
725});
726
727$(".cz-sidebar-header .close").on("click", function () {
728    $("#shop-sidebar").removeClass("show active");
729});
730
731$(".remove-address-by-modal").on("click", function () {
732    let link = $(this).data("link");
733    $("#remove-address-link").attr("href", link);
734    $("#remove-address").modal("show");
735});
736
737var backgroundImage = $("[data-bg-img]");
738backgroundImage
739    .css("background-image", function () {
740        return 'url("' + $(this).data("bg-img") + '")';
741    })
742    .removeAttr("data-bg-img")
743    .addClass("bg-img");
744
745$(".get-order-again-function").on("click", function () {
746    let orderId = $(this).data("id");
747    order_again(orderId);
748});
749
750function order_again(orderId) {
751    $.ajaxSetup({
752        headers: {
753            "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
754        },
755    });
756    $.ajax({
757        type: "POST",
758        url: $("#route-cart-order-again").data("url"),
759        data: { order_id: orderId },
760        beforeSend: function () {
761            $("#loading").show();
762        },
763        success: function (response) {
764            if (response.status === 1) {
765                updateNavCart();
766                toastr.success(response.message, {
767                    CloseButton: true,
768                    ProgressBar: true,
769                    timeOut: 3000,
770                });
771                location.href = response.redirect_url;
772                return false;
773            } else if (response.status === 0) {
774                toastr.warning(response.message, {
775                    CloseButton: true,
776                    ProgressBar: true,
777                    timeOut: 2000,
778                });
779                return false;
780            }
781        },
782        complete: function () {
783            $("#loading").hide();
784        },
785    });
786}
787
788(function () {
789    // Header search typeahead. The old handlers fired an uncancelled GET per
790    // keystroke, flashed the full-page #loading overlay on every key, and let
791    // an out-of-order response paint an older query's results over a newer
792    // one. One debounced, abortable request at a time instead — and the
793    // suggestions gained arrow-key navigation. (A second copy of the handler
794    // targeted .search-bar-input-mobile, a selector this theme never renders.)
795    let searchDebounce = null;
796    let searchRequest = null;
797
798    function searchCardOf(input) {
799        return input.closest(".search_form").find(".search-card");
800    }
801
802    function runProductSearch(input) {
803        let name = input.val();
804        input.data("given-value", name);
805        let card = searchCardOf(input);
806        let box = card.find(".search-result-box");
807
808        if (searchRequest) {
809            searchRequest.abort();
810            searchRequest = null;
811        }
812        // The endpoint rejects a blank name with a 422, so whitespace-only
813        // input clears the box instead of asking.
814        if (!name.trim().length) {
815            box.empty();
816            return;
817        }
818
819        card.css("display", "block");
820        searchRequest = $.get({
821            url: $("#route-searched-products").data("url"),
822            dataType: "json",
823            data: {
824                name: name,
825            },
826            beforeSend: function () {
827                card.addClass("search-card--busy");
828            },
829            success: function (data) {
830                box.empty().html(data.result);
831            },
832            complete: function () {
833                card.removeClass("search-card--busy");
834                searchRequest = null;
835            },
836        });
837    }
838
839    $(document).on("keyup", ".search-bar-input", function (event) {
840        // Navigation keys are handled in the keydown handler below and must
841        // not refire the search.
842        if (["ArrowDown", "ArrowUp", "Enter", "Escape"].indexOf(event.key) !== -1) {
843            return;
844        }
845        let input = $(this);
846        clearTimeout(searchDebounce);
847        searchDebounce = setTimeout(function () {
848            runProductSearch(input);
849        }, 250);
850    });
851
852    // Hover keeps its old behaviour: preview the suggestion in the input,
853    // restore what was typed on leave. Delegated, because the rows are
854    // re-rendered on every response.
855    $(document).on("mouseover", ".search-result-product", function () {
856        let input = $(this).closest(".search_form").find(".search-bar-input");
857        input.val($(this).data("product-name"));
858    });
859    $(document).on("mouseleave", ".search-result-product", function () {
860        let input = $(this).closest(".search_form").find(".search-bar-input");
861        input.val(input.data("given-value"));
862    });
863
864    // Arrow keys walk the suggestions and write the highlighted name into the
865    // input, so Enter's native form submit searches for exactly what is lit.
866    // Escape puts the typed text back and closes the card.
867    $(document).on("keydown", ".search-bar-input", function (event) {
868        let input = $(this);
869        let card = searchCardOf(input);
870        let rows = card.find(".search-result-product");
871
872        if (event.key === "Escape") {
873            // A search-type input clears itself on Escape by default, which
874            // would wipe the text this handler just restored.
875            event.preventDefault();
876            input.val(input.data("given-value"));
877            card.hide();
878            return;
879        }
880        if (!rows.length || (event.key !== "ArrowDown" && event.key !== "ArrowUp")) {
881            return;
882        }
883
884        event.preventDefault();
885        let current = rows.index(rows.filter(".is-active"));
886        let next = event.key === "ArrowDown"
887            ? (current + 1) % rows.length
888            : (current <= 0 ? rows.length - 1 : current - 1);
889        rows.removeClass("is-active");
890        let row = rows.eq(next).addClass("is-active");
891        input.val(row.data("product-name"));
892        row[0].scrollIntoView({ block: "nearest" });
893    });
894})();
895
896$(".clickable").click(function () {
897    window.location = $(this).find("a").attr("href");
898    return false;
899});
900
901function addWishlist(product_id, modalId) {
902    $.ajaxSetup({
903        headers: { "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content") },
904    });
905    $.ajax({
906        url: $("#route-store-wishlist").data("url"),
907        method: "POST",
908        data: { product_id: product_id },
909        success: function (data) {
910            if (data.value == 1) {
911                $(".countWishlist").html(data.count);
912                $(".countWishlist-" + product_id).text(data.product_count);
913                $(".tooltip").html("");
914                $(`.wishlist_icon_${product_id}`)
915                    .removeClass("fa fa-heart-o")
916                    .addClass("fa fa-heart");
917                $(".wishlist-tooltip").find(".remove").hide();
918                $(".wishlist-tooltip").find(".add").show();
919                $(".wishlist-tooltip").show();
920                const timer = setTimeout(() => {
921                    $(".wishlist-tooltip").hide();
922                }, 2000);
923                $(`#${modalId}`).modal("show");
924                return () => clearTimeout(timer);
925            } else if (data.value == 2) {
926                $(".wishlist-tooltip").find(".remove").show();
927                $(".wishlist-tooltip").find(".add").hide();
928                $(".wishlist-tooltip").show();
929                const timer = setTimeout(() => {
930                    $(".wishlist-tooltip").hide();
931                }, 2000);
932                $(".countWishlist").html(data.count);
933                $(".countWishlist-" + product_id).text(data.product_count);
934                $(`.wishlist_icon_${product_id}`)
935                    .removeClass("fa fa-heart")
936                    .addClass("fa fa-heart-o");
937                return () => clearTimeout(timer);
938            } else {
939                $("#login-alert-modal").modal("show");
940            }
941        },
942    });
943}
944
945$(".function-remove-wishList").on("click", function () {
946    let productId = $(this).data("id");
947    let modalId = $(this).data("modal");
948    removeWishlist(productId, modalId);
949});
950
951function removeWishlist(productId, modalId) {
952    $.ajaxSetup({
953        headers: {
954            "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
955        },
956    });
957    $.ajax({
958        url: $("#route-delete-wishlist").data("url"),
959        method: "POST",
960        data: { id: productId },
961        beforeSend: function () {
962            $("#loading").show();
963        },
964        success: function (data) {
965            $(`#${modalId}`).modal("show");
966            let countWishlistElement = $(".countWishlist");
967            let messageNoDataFound = $("#message-no-data-found").data("text");
968            countWishlistElement.html(
969                parseInt(countWishlistElement.html()) - 1
970            );
971            $("#row_id" + productId).hide();
972            $(".tooltip").html("");
973            if (parseInt(countWishlistElement.html()) % 15 === 0) {
974                let wishlistPaginatedPage = $("#wishlist_paginated_page");
975                if (wishlistPaginatedPage.val() == 1) {
976                    $("#set-wish-list")
977                        .empty()
978                        .append(
979                            `<h6 class="text-muted text-center">` +
980                            messageNoDataFound +
981                            `</h6>`
982                        );
983                } else {
984                    let pageValue = wishlistPaginatedPage.val();
985                    window.location.href =
986                        $("#route-wishlists").data("url") +
987                        "?page=" +
988                        (pageValue - 1);
989                }
990            }
991        },
992        complete: function () {
993            $("#loading").hide();
994        },
995    });
996}
997
998function renderQuickViewFunction() {
999    $(".action-product-quick-view").on("click", function () {
1000        let productId = $(this).data("product-id");
1001        productQuickView(productId);
1002    });
1003}
1004
1005$(window).on("load", function () {
1006    renderQuickViewFunction();
1007});
1008
1009function productQuickView(product_id) {
1010    $.get({
1011        url: $("#route-quick-view").data("url"),
1012        dataType: "json",
1013        data: {
1014            product_id: product_id,
1015        },
1016        beforeSend: function () {
1017            $("#loading").show();
1018        },
1019        success: function (data) {
1020            $("#quick-view-modal").empty().html(data.view);
1021            renderOwlCarouselSilder();
1022            commonFunctionalityForProductView();
1023            $("#quick-view").modal("show");
1024        },
1025        complete: function () {
1026            $("#loading").hide();
1027        },
1028    });
1029}
1030
1031$(".action-hide-billing-address").on("click", function () {
1032    hideBillingAddressFunction();
1033});
1034
1035// Apply the checkbox's initial state at load — the handler above only ran on
1036// click, so a default-checked box still showed the expanded billing form.
1037if ($("#same_as_shipping_address").length) {
1038    hideBillingAddressFunction();
1039}
1040
1041function hideBillingAddressFunction() {
1042    let checkSameAsShipping = $("#same_as_shipping_address").is(":checked");
1043    if (checkSameAsShipping) {
1044        $("#hide_billing_address").hide();
1045    } else {
1046        $("#hide_billing_address").show();
1047    }
1048}
1049
1050$(".action-billing-address-hide").on("click", function () {
1051    billingAddressFunction();
1052});
1053
1054function billingAddressFunction() {
1055
1056
1057    $("#bh-0").prop("checked", true);
1058    $("#billing_model").collapse();
1059}
1060
1061$(".minimum-order-amount-message").on("click", function () {
1062    toastr.error($(this).data("title"), {
1063        CloseButton: true,
1064        ProgressBar: true,
1065    });
1066});
1067
1068function productQuickViewFunctionalityInitialize() {
1069    cartQuantityInitialize();
1070
1071    getVariantPrice("#quick-view .add-to-cart-details-form");
1072
1073    $("#quick-view .add-to-cart-details-form input")
1074        .off("change.quickview")
1075        .on("change.quickview", function () {
1076            getVariantPrice("#quick-view .add-to-cart-details-form");
1077        });
1078
1079    $(document).ready(function () {
1080        $('[data-toggle="tooltip"]').tooltip();
1081        $('[data-toggle="popover"]').popover();
1082    });
1083
1084    $(".quick-view-preview-image-by-color").on("click", function () {
1085        let id = $("#preview-img" + $(this).data("key"));
1086        $(id).click();
1087    });
1088}
1089
1090$(".product-details-sticky-collapse-btn").on("click", function () {
1091    $(this).toggleClass("rotate-180");
1092    $(".product-details-sticky-top").slideToggle("slow");
1093});
1094
1095function hideProductDetailsStickySection() {
1096    $("html, body").animate({ scrollTop: 0 }, "slow");
1097    setTimeout(() => {
1098        $(".product-details-sticky-section").removeClass("active");
1099    });
1100}
1101
1102function addToCart(
1103    formSelector = ".add-to-cart-details-form",
1104    redirect_to_checkout = false,
1105    url = null
1106) {
1107    if (checkValidityForVariantPrice(formSelector)) {
1108        $.ajaxSetup({
1109            headers: {
1110                "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
1111            },
1112        });
1113
1114        // The exist-key must come from the form being submitted: the page holds
1115        // several add-to-cart forms (main, sticky, quick-view), and reading the
1116        // document's first key routed updates at the wrong cart line.
1117        let existCartItem = $(formSelector).find('.product-exist-in-cart-list[name="key"]').val() || "";
1118        // Buy-now buttons pass data-auth as a STRING; "false" is truthy, which
1119        // used to send buy_now=1 on the guest path and skip the update route.
1120        let redirectToCheckoutValue = redirect_to_checkout.toString();
1121        let redirectToCheckout = redirectToCheckoutValue === "true";
1122
1123        let formActionUrl = $("#route-cart-add").data("url");
1124        if (existCartItem !== "" && !redirectToCheckout) {
1125            formActionUrl = $("#route-cart-updateQuantity-guest").data("url");
1126        }
1127
1128        $.post({
1129            url: formActionUrl,
1130            data: $(formSelector)
1131                .serializeArray()
1132                .concat({
1133                    name: "buy_now",
1134                    value: redirectToCheckout ? 1 : 0,
1135                }),
1136            beforeSend: function () {
1137                $("#loading").show();
1138            },
1139            success: function (response) {
1140                if (response.status === 2) {
1141                    if (redirectToCheckoutValue !== "false") {
1142                        hideProductDetailsStickySection();
1143                        $("#buyNowModal-body").html(
1144                            response.shippingMethodHtmlView
1145                        );
1146                        $("#quick-view").modal("hide");
1147                        $("#buyNowModal").modal("show");
1148                        return false;
1149                    }
1150                }
1151                if (response.status == 1) {
1152                    // Open the cart drawer once the refreshed cart is in the DOM,
1153                    // so the added item is visible — unless this add is about to
1154                    // redirect to checkout, where a drawer would only flash. When
1155                    // the drawer opens it IS the confirmation, so the toast only
1156                    // shows on the paths where no drawer will appear.
1157                    let drawerWillOpen =
1158                        redirectToCheckoutValue !== "true" &&
1159                        typeof window.openCartDrawer === "function";
1160                    updateNavCart(function () {
1161                        if (drawerWillOpen) {
1162                            window.openCartDrawer();
1163                        }
1164                    });
1165                    if (!drawerWillOpen) {
1166                        toastr.success(response.message, {
1167                            CloseButton: true,
1168                            ProgressBar: true,
1169                        });
1170                    }
1171
1172                    let actionAddToCartBtn = $(formSelector).find(".product-add-to-cart-button");
1173                    $(formSelector).find('.product-exist-in-cart-list[name="key"]').val(response.in_cart_key);
1174                    actionAddToCartBtn.html(actionAddToCartBtn.data("update"));
1175
1176                    let topAddToCartBtn = $('.add-to-cart-details-form').find('.product-add-to-cart-button');
1177                    let bottomStickyAddToCart = $('.add-to-cart-sticky-form').find('.product-add-to-cart-button');
1178                    topAddToCartBtn.html(topAddToCartBtn.data("update"));
1179                    bottomStickyAddToCart.html(bottomStickyAddToCart.data("update"));
1180
1181                    $('.add-to-cart-details-form').find('.product-exist-in-cart-list[name="key"]').val(response.in_cart_key);
1182                    $('.add-to-cart-sticky-form').find('.product-exist-in-cart-list[name="key"]').val(response.in_cart_key);
1183                    if (response?.product_variant_type === "single_variant") {
1184                        $(".add-to-cart-details-form")
1185                            .find(".product-add-to-cart-button")
1186                            .html(actionAddToCartBtn.data("update"));
1187                        $(".add-to-cart-sticky-form")
1188                            .find(".product-add-to-cart-button")
1189                            .html(actionAddToCartBtn.data("update"));
1190                    }
1191
1192                    $(".close-quick-view-modal").click();
1193
1194                    if (
1195                        redirectToCheckoutValue === "true" &&
1196                        response.redirect_to_url
1197                    ) {
1198                        setTimeout(function () {
1199                            location.href = response.redirect_to_url;
1200                        }, 100);
1201                    } else if (redirectToCheckoutValue === "true") {
1202                        setTimeout(function () {
1203                            location.href = url;
1204                        }, 100);
1205                    }
1206
1207                    return false;
1208                } else if (response.status == 0) {
1209                    if (
1210                        redirectToCheckoutValue !== "false" ||
1211                        !redirect_to_checkout
1212                    ) {
1213                        hideProductDetailsStickySection();
1214                        $("#out-of-stock-modal-message").html(response.message);
1215                        $("#out-of-stock-modal").modal("show");
1216                        return false;
1217                    }
1218                }
1219            },
1220            complete: function () {
1221                $("#loading").hide();
1222            },
1223        });
1224    } else {
1225        Swal.fire({
1226            type: "info",
1227            title: "Cart",
1228            text: $("#message-please-choose-all-options").data("text"),
1229        });
1230    }
1231}
1232
1233function commonFunctionalityForProductView() {
1234    $(".product-buy-now-button").on("click", function () {
1235        let parentForm = $(this).data("form");
1236        let redirectStatus = $(this).data("auth")?.toString();
1237        let url = $(this).data("route");
1238        addToCart(
1239            parentForm ?? ".add-to-cart-details-form",
1240            redirectStatus,
1241            url
1242        );
1243        if (redirectStatus === "false") {
1244            setTimeout(function () {
1245                location.href = url;
1246            }, 100);
1247        }
1248    });
1249
1250    $(".product-add-to-cart-button").on("click", function () {
1251        let parentElement = $(this).closest(".product-cart-option-container");
1252        let productCartForm = parentElement.find(".addToCartDynamicForm");
1253        addToCart(productCartForm ?? $(".add-to-cart-details-form"));
1254    });
1255
1256    $(".product-action-add-wishlist").on("click", function () {
1257        let id = $(this).data("product-id");
1258        addWishlist(id);
1259    });
1260
1261    $(".product-restock-request-button").on("click", function () {
1262        let isLoggedIn = $(this).data("auth")?.toString();
1263        if (isLoggedIn === "true" || isLoggedIn === "1") {
1264            let parentElement = $(this).closest(
1265                ".product-cart-option-container"
1266            );
1267            let productCartForm = parentElement.find(".addToCartDynamicForm");
1268            let getFrom = $(this).data("form")?.toString();
1269
1270            if (productCartForm?.length <= 0 && getFrom && getFrom !== "") {
1271                productCartForm = $(getFrom);
1272            }
1273            getRequestForProductRestock(productCartForm);
1274        } else {
1275            $("#login-alert-modal").modal("show");
1276        }
1277    });
1278
1279    function getRequestForProductRestock(formElement) {
1280        let button = $(".product-restock-request-button");
1281        $.ajaxSetup({
1282            headers: {
1283                "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
1284            },
1285        });
1286        $.ajax({
1287            url: $("#route-product-restock-request").data("url"),
1288            type: "POST",
1289            data: formElement.serializeArray(),
1290            beforeSend: function () {
1291                $("#loading").show();
1292            },
1293            success: function (response) {
1294                responseManager(response);
1295                button.attr("disabled", true);
1296                button.text(button.data("requested"));
1297
1298                try {
1299                    subscribeToNotificationTopics([response?.fcm_topic]);
1300                } catch (e) {
1301                    console.log(e);
1302                }
1303            },
1304            complete: function () {
1305                $("#loading").hide();
1306            },
1307        });
1308    }
1309}
1310
1311commonFunctionalityForProductView();
1312
1313function checkoutFromCartList() {
1314    let orderNote = $("#order_note").val();
1315    $.post({
1316        url: $("#route-order-note").data("url"),
1317        data: {
1318            _token: $('meta[name="_token"]').attr("content"),
1319            order_note: orderNote,
1320        },
1321        beforeSend: function () {
1322            $("#loading").show();
1323        },
1324        success: function (response) {
1325            if (response.status === 0) {
1326                response.message.map(function (message) {
1327                    toastr.error(message);
1328                });
1329            } else {
1330                location.href = response.redirect
1331                    ? response.redirect
1332                    : $("#route-checkout-details").data("url");
1333            }
1334        },
1335        complete: function () {
1336            $("#loading").hide();
1337        },
1338    });
1339}
1340
1341function orderSummaryStickyFunction() {
1342    try {
1343        const stickyElement = $(".bottom-sticky3");
1344        const offsetElement = $(".__cart-total_sticky .proceed_to_next_button");
1345
1346        const elementOffset = offsetElement.offset().top;
1347        const scrollTop = $(window).scrollTop();
1348        if (scrollTop >= elementOffset - $(window).height() + 50) {
1349            stickyElement.addClass("stick");
1350            $(".floating-btn-grp").removeClass("style-2");
1351        } else {
1352            stickyElement.removeClass("stick");
1353            $(".floating-btn-grp").addClass("style-2");
1354        }
1355    } catch (e) { }
1356}
1357
1358$(window).on("resize", orderSummaryStickyFunction);
1359$(window).on("scroll", orderSummaryStickyFunction);
1360
1361function cartListQuantityUpdateInit() {
1362    $(".action-update-cart-quantity").on("click", function () {
1363        let cartId = $(this).data("cart-id");
1364        let productId = $(this).data("product-id");
1365        let action = $(this).data("action");
1366        let event = $(this).data("event");
1367        updateCartQuantity(cartId, productId, action, event);
1368    });
1369
1370    $(".action-update-cart-quantity-list").on("click", function () {
1371        let minimumOrderQuantity = $(this).data("minimum-order");
1372        let key = $(this).data("cart-id");
1373        let increment = $(this).data("increment");
1374        let event = $(this).data("event");
1375        updateCartQuantityList(minimumOrderQuantity, key, increment, event);
1376    });
1377
1378    $(".action-change-update-cart-quantity-list").on("change", function () {
1379        let minimumOrderQuantity = $(this).data("minimum-order");
1380        let key = $(this).data("cart-id");
1381        let increment = $(this).data("increment");
1382        let event = $(this).data("event");
1383        updateCartQuantityList(minimumOrderQuantity, key, increment, event);
1384    });
1385
1386    $(".action-update-cart-quantity-list-mobile").on("click", function () {
1387        let minimumOrderQuantity = $(this).data("minimum-order");
1388        let key = $(this).data("cart-id");
1389        let increment = $(this).data("increment");
1390        let event = $(this).data("event");
1391        updateCartQuantityListMobile(
1392            minimumOrderQuantity,
1393            key,
1394            increment,
1395            event
1396        );
1397    });
1398
1399    $(".action-change-update-cart-quantity-list-mobile").on(
1400        "change",
1401        function () {
1402            let minimumOrderQuantity = $(this).data("minimum-order");
1403            let key = $(this).data("cart-id");
1404            let increment = $(this).data("increment");
1405            let event = $(this).data("event");
1406            updateCartQuantityListMobile(
1407                minimumOrderQuantity,
1408                key,
1409                increment,
1410                event
1411            );
1412        }
1413    );
1414
1415    $(document).ready(function () {
1416        $(".cart_information").each(function () {
1417            let allShopItemsInChecked = true;
1418            $(this)
1419                .find(".shop-item-check")
1420                .each(function () {
1421                    if (!$(this).prop("checked")) {
1422                        allShopItemsInChecked = false;
1423                        return false;
1424                    }
1425                });
1426            $(this)
1427                .find(".shop-head-check")
1428                .prop("checked", allShopItemsInChecked);
1429        });
1430    });
1431
1432    $(".shop-head-check").on("change", function () {
1433        $(this)
1434            .parents(".cart_information")
1435            .find(".shop-item-check")
1436            .prop("checked", this.checked);
1437    });
1438
1439    $(".shop-item-check").on("change", function () {
1440        var allChecked = true;
1441        $(this)
1442            .parents(".cart_information")
1443            .find(".shop-item-check")
1444            .each(function () {
1445                if (!$(this).prop("checked")) {
1446                    allChecked = false;
1447                    return false;
1448                }
1449            });
1450        $(this)
1451            .parents(".cart_information")
1452            .find(".shop-head-check")
1453            .prop("checked", allChecked);
1454    });
1455
1456    $(".shop-head-check-desktop").on("change", function () {
1457        getCartSelectCartItemsCheckedValues(
1458            '.cart_information input[type="checkbox"].shop-item-check-desktop'
1459        );
1460    });
1461
1462    $(".shop-head-check-mobile").on("change", function () {
1463        getCartSelectCartItemsCheckedValues(
1464            '.cart_information input[type="checkbox"].shop-item-check-mobile'
1465        );
1466    });
1467
1468    $(".shop-item-check-desktop").on("change", function () {
1469        getCartSelectCartItemsCheckedValues(
1470            '.cart_information input[type="checkbox"].shop-item-check-desktop'
1471        );
1472    });
1473
1474    $(".shop-item-check-mobile").on("change", function () {
1475        getCartSelectCartItemsCheckedValues(
1476            '.cart_information input[type="checkbox"].shop-item-check-mobile'
1477        );
1478    });
1479
1480    function getCartSelectCartItemsCheckedValues(elementSelector) {
1481        let checkedValues = [];
1482        $(elementSelector).each(function () {
1483            if ($(this).prop("checked")) {
1484                checkedValues.push($(this).val());
1485            }
1486        });
1487        getCartSelectCartItemsRequest(checkedValues);
1488    }
1489
1490    function getCartSelectCartItemsRequest(checkedValues) {
1491        $.ajaxSetup({
1492            headers: {
1493                "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
1494            },
1495        });
1496        $.ajax({
1497            url: $("#get-cart-select-cart-items").data("route"),
1498            type: "POST",
1499            data: {
1500                ids: checkedValues,
1501            },
1502            beforeSend: function () {
1503                $("#loading").show();
1504            },
1505            success: function (response) {
1506                $("#cart-summary").empty().html(response.htmlView);
1507                toastr.success(response.message);
1508                cartListQuantityUpdateInit();
1509                setShippingIdFunctionCartDetails();
1510                $('[data-toggle="tooltip"]').tooltip();
1511                actionCheckoutFunctionInit();
1512                couponCode();
1513                updateNavCart();
1514            },
1515            complete: function () {
1516                $("#loading").hide();
1517            },
1518        });
1519    }
1520}
1521
1522cartListQuantityUpdateInit();
1523
1524function actionCheckoutFunctionInit() {
1525    $(".action-checkout-function").on("click", function () {
1526        let getRoute = $("#route-action-checkout-function").data("route");
1527        if (getRoute && getRoute.toString() === "shop-cart") {
1528            checkoutFromCartList();
1529        } else if (getRoute && getRoute.toString() === "checkout-details") {
1530            checkoutFromShipping();
1531        } else if (getRoute && getRoute.toString() === "checkout-payment") {
1532            checkoutFromPayment();
1533        }
1534    });
1535
1536    $(".action-set-shipping-id").on("change", function () {
1537        let cartGroupId = $(this).data("product-id");
1538        let id = $(this).val();
1539        setShippingId(id, cartGroupId);
1540    });
1541}
1542
1543actionCheckoutFunctionInit();
1544
1545function removeFromCart(key) {
1546    $.post(
1547        $("#route-cart-remove").data("url"),
1548        {
1549            _token: $('meta[name="_token"]').attr("content"),
1550            key: key,
1551        },
1552        function (response) {
1553            $("#cod-for-cart").hide();
1554            updateNavCart();
1555            $("#cart-summary").empty().html(response.data);
1556            couponCode();
1557            toastr.info(
1558                $("#message-item-has-been-removed-from-cart").data("text"),
1559                {
1560                    CloseButton: true,
1561                    ProgressBar: true,
1562                }
1563            );
1564            let segment_array = window.location.pathname.split("/");
1565            let segment = segment_array[segment_array.length - 1];
1566            if (
1567                segment === "checkout-payment" ||
1568                segment === "checkout-details"
1569            ) {
1570                location.reload();
1571            }
1572        }
1573    );
1574}
1575
1576function updateNavCart(afterUpdate) {
1577    $.post(
1578        $("#route-cart-nav-cart").data("url"),
1579        {
1580            _token: $('meta[name="_token"]').attr("content"),
1581        },
1582        function (response) {
1583            $("#cart_items").html(response.data);
1584            cartListQuantityUpdateInit();
1585            if (typeof afterUpdate === "function") {
1586                afterUpdate();
1587            }
1588        }
1589    );
1590}
1591
1592function cartQuantityInitialize() {
1593    // off/on with a namespace: this runs again on every quick-view open, and
1594    // the plain .click() bindings used to stack — N opens meant a single tap
1595    // moved the quantity N+1 times.
1596    $(".btn-number").off("click.kqty").on("click.kqty", function (e) {
1597        e.preventDefault();
1598        let fieldName = $(this).attr("data-field");
1599        let type = $(this).attr("data-type");
1600        let productType = $(this).data("producttype");
1601        let input = $("input[name='" + fieldName + "']");
1602        let productContainer = $(this).closest(
1603            ".product-cart-option-container"
1604        );
1605        let currentVal = parseInt(productContainer.find(".input-number").val());
1606        if (!isNaN(currentVal)) {
1607            if (type == "minus") {
1608                if (
1609                    currentVal >
1610                    productContainer.find(".input-number").attr("min")
1611                ) {
1612                    productContainer
1613                        .find(".input-number")
1614                        .val(currentVal - 1)
1615                        .change();
1616                }
1617                if (
1618                    parseInt(productContainer.find(".input-number").val()) ==
1619                    productContainer.find(".input-number").attr("min")
1620                ) {
1621                    $(this).attr("disabled", true);
1622                }
1623            } else if (type == "plus") {
1624                if (
1625                    currentVal <
1626                    productContainer.find(".input-number").attr("max") ||
1627                    productType === "digital"
1628                ) {
1629                    productContainer
1630                        .find(".input-number")
1631                        .val(currentVal + 1)
1632                        .change();
1633                } else {
1634                    Swal.fire({
1635                        icon: "error",
1636                        title: $("#message-cart").data("text"),
1637                        text: $("#message-sorry-stock-limit-exceeded").data(
1638                            "text"
1639                        ),
1640                    });
1641                    productContainer
1642                        .find(".btn-number")
1643                        .val(productContainer.find(".btn-number").attr("max"));
1644                    productContainer.find(".btn-number").attr("disabled", true);
1645                }
1646
1647                if (
1648                    parseInt(input.val()) ==
1649                    productContainer.find(".input-number").attr("max") &&
1650                    productType === "physical"
1651                ) {
1652                    $(this).attr("disabled", true);
1653                }
1654            }
1655        } else {
1656            productContainer.find(".input-number").val(0);
1657        }
1658    });
1659
1660    $(".input-number").off("focusin.kqty").on("focusin.kqty", function () {
1661        $(this).data("oldValue", $(this).val());
1662    });
1663
1664    $(".input-number").off("change.kqty").on("change.kqty", function () {
1665        let productType = $(this).data("producttype");
1666        let minValue = parseInt($(this).attr("min"));
1667        let maxValue = parseInt($(this).attr("max"));
1668        let valueCurrent = parseInt($(this).val());
1669        let name = $(this).attr("name");
1670        let productContainer = $(this).closest(
1671            ".product-cart-option-container"
1672        );
1673        if (valueCurrent >= minValue) {
1674            $(
1675                ".btn-number[data-type='minus'][data-field='" + name + "']"
1676            ).removeAttr("disabled");
1677        } else {
1678            Swal.fire({
1679                icon: "error",
1680                title: $("#message-cart").data("text"),
1681                text: $("#message-minimum-order-quantity-cannot-less-than").data("text")+ " "+ minValue,
1682            });
1683            $(".input-number").val($(".input-number").attr("min"));
1684        }
1685        if (productType === "digital" || valueCurrent <= maxValue) {
1686            $(".btn-number[data-type='plus'][data-field='" + name + "']"
1687            ).removeAttr("disabled");
1688        } else {
1689            Swal.fire({
1690                icon: "error",
1691                title: $("#message-cart").data("text"),
1692                text: $("#message-sorry-stock-limit-exceeded").data("text"),
1693            });
1694            productContainer
1695                .find(".input-number")
1696                .val(productContainer.find(".input-number").attr("max"));
1697        }
1698    });
1699
1700    $(".input-number").keydown(function (e) {
1701        if (
1702            $.inArray(e.keyCode, [46, 8, 9, 27, 13, 190]) !== -1 ||
1703            (e.keyCode == 65 && e.ctrlKey === true) ||
1704            (e.keyCode >= 35 && e.keyCode <= 39)
1705        ) {
1706            return;
1707        }
1708        if (
1709            (e.shiftKey || e.keyCode < 48 || e.keyCode > 57) &&
1710            (e.keyCode < 96 || e.keyCode > 105)
1711        ) {
1712            e.preventDefault();
1713        }
1714    });
1715}
1716
1717function debounce(func, delay) {
1718    let debounceTimer;
1719    return function () {
1720        let context = this;
1721        let args = arguments;
1722        clearTimeout(debounceTimer);
1723        debounceTimer = setTimeout(() => func.apply(context, args), delay);
1724    };
1725}
1726let currentPriceRequest = null;
1727const debouncedGetVariantPrice = debounce(getVariantPrice, 300);
1728
1729$(".add-to-cart-details-form input").on("input change", () => {
1730    debouncedGetVariantPrice(".add-to-cart-details-form");
1731});
1732
1733$(".add-to-cart-sticky-form input").on("input change", () => {
1734    debouncedGetVariantPrice(".add-to-cart-sticky-form");
1735});
1736
1737
1738
1739function updateQuantity(key, element) {
1740    $.post(
1741        $("#route-cart-updateQuantity").data("url"),
1742        {
1743            _token: $('meta[name="_token"]').attr("content"),
1744            key: key,
1745            quantity: element.value,
1746        },
1747        function (data) {
1748            updateNavCart();
1749            $("#cart-summary").empty().html(data);
1750            couponCode();
1751        }
1752    );
1753}
1754
1755function updateCartQuantity(cart_id, product_id, action, event) {
1756    let remove_url = $("#route-cart-remove").data("url");
1757    let update_quantity_url = $("#route-cart-updateQuantity-guest").data("url");
1758    let token = $('meta[name="_token"]').attr("content");
1759    let product_qyt =
1760        parseInt($(`.cartQuantity${cart_id}`).val()) + parseInt(action);
1761    let cart_quantity_of = $(`.cartQuantity${cart_id}`);
1762    let segment_array = window.location.pathname.split("/");
1763    let segment = segment_array[segment_array.length - 1];
1764
1765    if (cart_quantity_of.val() > cart_quantity_of.data("current-stock")) {
1766        cartItemRemoveFunction(remove_url, token, cart_id, segment);
1767        return false;
1768    }
1769
1770    if (cart_quantity_of.val() == 0) {
1771        toastr.info($(".cannot_use_zero").data("text"), {
1772            CloseButton: true,
1773            ProgressBar: true,
1774        });
1775        cart_quantity_of.val(cart_quantity_of.data("min"));
1776    } else if (
1777        cart_quantity_of.val() == cart_quantity_of.data("min") &&
1778        event == "minus"
1779    ) {
1780        cartItemRemoveFunction(remove_url, token, cart_id, segment);
1781    } else {
1782        if (cart_quantity_of.val() < cart_quantity_of.data("min")) {
1783            let min_value = cart_quantity_of.data("min");
1784            toastr.error(
1785                $("#message-minimum-order-quantity-cannot-less-than").data(
1786                    "text"
1787                ) +
1788                " " +
1789                min_value
1790            );
1791            cart_quantity_of.val(min_value);
1792            updateCartQuantity(cart_id, product_id, action, event);
1793        } else {
1794            $(`.cartQuantity${cart_id}`).html(product_qyt);
1795            $.post(
1796                update_quantity_url,
1797                {
1798                    _token: token,
1799                    key: cart_id,
1800                    product_id: product_id,
1801                    quantity: product_qyt,
1802                },
1803                function (response) {
1804                    if (response["status"] == 0) {
1805                        toastr.error(response["message"]);
1806                    } else {
1807                        toastr.success(response["message"]);
1808                    }
1809                    $('.product-exist-in-cart-list[name="key"]').val(
1810                        response.in_cart_key
1811                    );
1812                    response["qty"] <= 1
1813                        ? $(`.quantity__minus${cart_id}`).html(
1814                            '<i class="fi fi-rr-trash-outlined text-danger fs-10"></i>'
1815                        )
1816                        : $(`.quantity__minus${cart_id}`).html(
1817                            '<i class="tio-remove fs-10"></i>'
1818                        );
1819
1820                    $(`.cartQuantity${cart_id}`).val(response["qty"]);
1821                    $(`.cartQuantity${cart_id}`).html(response["qty"]);
1822                    $(`.cart_quantity_multiply${cart_id}`).html(
1823                        response["qty"]
1824                    );
1825                    $(".cart_total_amount").html(response.total_price);
1826                    $(".cart-total-price").html(response.total_price);
1827                    $(`.discount_price_of_${cart_id}`).html(
1828                        response["discount_price"]
1829                    );
1830                    $(`.quantity_price_of_${cart_id}`).html(
1831                        response["quantity_price"]
1832                    );
1833                    $(`.total_discount`).html(response["total_discount_price"]);
1834                    $(`.free_delivery_amount_need`).html(
1835                        response.free_delivery_status.amount_need
1836                    );
1837                    if (response.free_delivery_status.amount_need <= 0) {
1838                        $(".amount-fill-up").removeClass("d-none");
1839                        $(".amount-need-to-fill-up").addClass("d-none");
1840                    } else {
1841                        $(".amount-fill-up").addClass("d-none");
1842                        $(".amount-need-to-fill-up").removeClass("d-none");
1843                    }
1844                    const progressBar = document.querySelector(".progress-bar");
1845                    if (progressBar) {
1846                        progressBar.style.width =
1847                            response.free_delivery_status.percentage + "%";
1848                    }
1849                    if (response["qty"] == cart_quantity_of.data("min")) {
1850                        cart_quantity_of
1851                            .parent()
1852                            .find(".quantity__minus")
1853                            .html(
1854                                '<i class="fi fi-rr-trash-outlined text-danger fs-10"></i>'
1855                            );
1856                    } else {
1857                        cart_quantity_of
1858                            .parent()
1859                            .find(".quantity__minus")
1860                            .html('<i class="tio-remove fs-10"></i>');
1861                    }
1862                    if (
1863                        segment === "shop-cart" ||
1864                        segment === "checkout-payment" ||
1865                        segment === "checkout-details"
1866                    ) {
1867                        location.reload();
1868                    }
1869                }
1870            );
1871        }
1872    }
1873}
1874
1875function cartItemRemoveFunction(remove_url, token, cart_id, segment) {
1876    $.post(
1877        remove_url,
1878        {
1879            _token: token,
1880            key: cart_id,
1881        },
1882        function (response) {
1883            updateNavCart();
1884            toastr.info(response.message, {
1885                CloseButton: true,
1886                ProgressBar: true,
1887            });
1888            getUpdateProductAddUpdateCartBtn(response);
1889            if (
1890                segment === "shop-cart" ||
1891                segment === "checkout-payment" ||
1892                segment === "checkout-details"
1893            ) {
1894                location.reload();
1895            }
1896        }
1897    );
1898}
1899
1900function getUpdateProductAddUpdateCartBtn(response) {
1901    try {
1902        let productInfo = $(".product-generated-variation-code");
1903        let productVariantExist = false;
1904
1905        response?.cartList?.map(function (item, index) {
1906            if (
1907                productInfo.data("product-id") == item?.id &&
1908                productInfo.val() == item?.variant
1909            ) {
1910                productVariantExist = true;
1911            }
1912        });
1913
1914        if (!productVariantExist) {
1915            let actionAddToCartBtn = $(".product-add-to-cart-button");
1916            actionAddToCartBtn.html(actionAddToCartBtn.data("add"));
1917            $('.product-exist-in-cart-list[name="key"]').val("");
1918        }
1919    } catch (e) { }
1920}
1921
1922$(".add-to-cart-details-form").on("submit", function (event) {
1923    event.preventDefault();
1924});
1925
1926// The debounced input/change bindings above are the only variant_price
1927// triggers; a second, un-debounced pair used to fire here as well, sending
1928// two requests for every option or quantity change.
1929
1930let checkFirstTimeVariant = true;
1931function getVariantPrice(formSelector = ".add-to-cart-details-form") {
1932    $(".btn-number").attr("disabled", false);
1933    if (checkValidityForVariantPrice(formSelector)) {
1934        $.ajaxSetup({
1935            headers: {
1936                "X-CSRF-TOKEN": $('meta[name="_token"]').attr("content"),
1937            },
1938        });
1939
1940        if (currentPriceRequest) {
1941            currentPriceRequest.abort();
1942        }
1943
1944        currentPriceRequest = $.ajax({
1945            type: "POST",
1946            url: $("#route-cart-variant-price").data("url"),
1947            data: $(formSelector).serializeArray().concat([
1948                {
1949                    name: "is_first_check",
1950                    value: checkFirstTimeVariant ? 1 : 0
1951                }
1952            ]),
1953            beforeSend: function () {
1954                $(".btn-number").attr("disabled", true);
1955            },
1956            success: function (response) {
1957                if (formSelector === ".add-to-cart-sticky-form" || checkFirstTimeVariant) {
1958                    checkFirstTimeVariant = false;
1959                }
1960                updateProductDetailsTopSection(".add-to-cart-details-form", response);
1961                updateProductDetailsBottomSection(".add-to-cart-sticky-form", response);
1962                applyVariantStockLimit(response);
1963                if (response?.discount_amount > 0) {
1964                    if (response?.discount_type === "flat") {
1965                        $(formSelector).find(".discounted_badge").html(`${response?.discount}`);
1966                    } else {
1967                        $(formSelector).find(".discounted_badge").html(`- ${response?.discount}`);
1968                    }
1969                    $(formSelector).find(".discounted-badge-element").removeClass("d-none");
1970                } else {
1971                    $(formSelector).find(".discounted-badge-element").addClass("d-none");
1972                }
1973
1974                setTimeout(() => {
1975                    $(".btn-number").attr("disabled", false);
1976                }, 1000)
1977            },
1978            complete: function () {
1979                setTimeout(() => {
1980                    $(".btn-number").attr("disabled", false);
1981                }, 3000)
1982            },
1983            error: function () {
1984                currentPriceRequest = null;
1985            },
1986        });
1987    }
1988}
1989
1990
1991/**
1992 * Re-limit the quantity box to the stock of the variant the customer just chose.
1993 *
1994 * The page renders max="{{ $product->current_stock }}" — the product's TOTAL stock across every
1995 * variant. So on a product with 8 small and 2 large, choosing "large" still offered up to 10. The
1996 * server does refuse it (CartManager checks the variant's own qty), so nothing oversells; the cost
1997 * is that the page invites a quantity it is about to reject, and the customer only finds out after
1998 * pressing Add to cart.
1999 *
2000 * The variant response already carries the right number — it was simply never applied. Digital
2001 * products report 100 rather than a stock level, which is the existing convention and is left alone.
2002 */
2003function applyVariantStockLimit(response) {
2004    var available = parseInt(response?.quantity);
2005    if (isNaN(available)) {
2006        return;
2007    }
2008
2009    $(".product-details-cart-qty").each(function () {
2010        var $input = $(this);
2011        $input.attr("max", available);
2012
2013        // Clamp a quantity that was valid for the previous variant but is not for this one, so the
2014        // box can never sit on a value the server will reject.
2015        var current = parseInt($input.val());
2016        var minimum = parseInt($input.attr("min")) || 1;
2017        if (!isNaN(current) && current > available) {
2018            $input.val(available > 0 ? Math.max(minimum, available) : minimum);
2019        }
2020    });
2021}
2022
2023$(".product-details-cart-qty").on("keypress keyup input", function (event) {
2024    if (parseInt($(this).val()) > $(this).attr("max")) {
2025        event.preventDefault();
2026        $(this).val($(this).attr("min") ?? 1);
2027        return false;
2028    }
2029});
2030
2031$(".product-quantity-minus").on("click", function () {
2032    $(this).attr("disabled", true);
2033});
2034
2035$(".product-quantity-plus").on("click", function () {
2036    $(this).attr("disabled", true);
2037});
2038
2039function checkValidityForVariantPrice(formSelector) {
2040    return (
2041        $(formSelector).find("input[name=quantity]").val() > 0 &&
2042        checkAddToCartValidity(formSelector)
2043    );
2044}
2045
2046let isBottomSectionUpdated = false;
2047
2048function updateProductDetailsBottomSection(formSelector, response) {
2049    let productDetailsStickySection = $(".product-details-sticky-section");
2050    $(".product-bottom-section-price").text(response?.price);
2051
2052    $(formSelector).find(".product-details-cart-qty").val(response?.in_cart_quantity).attr("max", response?.quantity);
2053
2054    productDetailsStickySection.find(".discounted-unit-price").html(response?.discounted_unit_price);
2055    productDetailsStickySection.find(".product-total-unit-price").html(response?.discount_amount > 0 ? response?.total_unit_price : "");
2056    productDetailsStickySection.find(".product-details-sticky-color-name").html(response?.color_name ? `(${response?.color_name})` : "");
2057
2058    productDetailsStickySection.find(".product-generated-variation-code").val(response?.variation_code);
2059    productDetailsStickySection.find(".product-generated-variation-text").text(response?.variation_code);
2060
2061    if (response?.discount_amount > 0) {
2062        productDetailsStickySection.find(".discounted_badge").html(`- ${response?.discount}`);
2063        productDetailsStickySection.find(".discounted-badge-element").removeClass("d-none");
2064    } else {
2065        productDetailsStickySection.find(".discounted-badge-element").addClass("d-none");
2066    }
2067    let actionAddToCartBtn = $(formSelector).find(".product-add-to-cart-button");
2068     let topAddToCartBtn = $('.add-to-cart-details-form').find(".product-add-to-cart-button");
2069    if (response?.in_cart_status === 1) {
2070        $(formSelector).find('.product-exist-in-cart-list[name="key"]').val(response?.in_cart_key);
2071        actionAddToCartBtn.html(actionAddToCartBtn.data("update"));
2072        topAddToCartBtn.html(topAddToCartBtn.data("update"));
2073    } else {
2074        $(formSelector).find('.product-exist-in-cart-list[name="key"]').val(response?.in_cart_key);
2075        actionAddToCartBtn.html(actionAddToCartBtn.data("add"));
2076    }
2077    if (response?.product_type?.toString() === "physical") {
2078        let productRestockRequestButton = $(formSelector).find(
2079            ".product-restock-request-button"
2080        );
2081        if (response?.quantity <= 0) {
2082            $(formSelector).find(".product-restock-request-section").show();
2083            productRestockRequestButton.removeAttr("disabled");
2084            $(formSelector).find(".product-add-and-buy-section").hide().removeClass("d-flex");
2085        } else {
2086            $(formSelector).find(".product-restock-request-section").hide();
2087            $(formSelector).find(".product-add-and-buy-section").show().addClass("d-flex");
2088        }
2089        if (response?.restock_request_status) {
2090            productRestockRequestButton.html(
2091                productRestockRequestButton.data("requested")
2092            );
2093            productRestockRequestButton.attr("disabled", true);
2094        } else {
2095            productRestockRequestButton.html(
2096                productRestockRequestButton.data("default")
2097            );
2098        }
2099    }
2100}
2101
2102function updateProductDetailsTopSection(formSelector, response) {
2103    $(formSelector).find(".product-details-chosen-price-section").removeClass("d-none");
2104    $(formSelector).find(".product-details-chosen-price-amount").html(response?.price);
2105
2106
2107    $(formSelector).find(".product-details-cart-qty").attr("max", response?.quantity);
2108
2109    if (response?.product_type?.toString() === "physical") {
2110        let productRestockRequestButton = $(formSelector).find(".product-restock-request-button");
2111        if (response?.quantity <= 0) {
2112            $(formSelector).find(".product-restock-request-section").show();
2113            productRestockRequestButton.removeAttr("disabled");
2114            $(formSelector).find(".product-add-and-buy-section").hide().removeClass("d-flex");
2115        } else {
2116            $(formSelector).find(".product-restock-request-section").hide();
2117            $(formSelector).find(".product-add-and-buy-section").show().addClass("d-flex");
2118        }
2119        if (response?.restock_request_status) {
2120            productRestockRequestButton.html(productRestockRequestButton.data("requested"));
2121            productRestockRequestButton.attr("disabled", true);
2122        } else {
2123            productRestockRequestButton.html(productRestockRequestButton.data("default"));
2124        }
2125    }
2126
2127    $(formSelector).find(".product-details-cart-qty").val(response?.in_cart_quantity);
2128    $(formSelector).find(".product-generated-variation-code").val(response?.variation_code);
2129    $(formSelector).find(".product-generated-variation-text").text(response?.variation_code);
2130
2131    $(formSelector).find(".discounted-unit-price").html(response?.discounted_unit_price);
2132    $(formSelector).find(".product-total-unit-price").html(response?.discount_amount > 0 ? response?.total_unit_price : "");
2133
2134    let actionAddToCartBtn = $(formSelector).find(".product-add-to-cart-button");
2135    if (response?.in_cart_status === 1) {
2136        $(formSelector).find('.product-exist-in-cart-list[name="key"]').val(response?.in_cart_key);
2137        actionAddToCartBtn.html(actionAddToCartBtn.data("update"));
2138    } else {
2139        $(formSelector).find('.product-exist-in-cart-list[name="key"]').val(response?.in_cart_key);
2140        actionAddToCartBtn.html(actionAddToCartBtn.data("add"));
2141    }
2142
2143    if (
2144        $(formSelector).find(".product-details-cart-qty").attr("min") <
2145        parseFloat($(formSelector).find(".product-details-cart-qty").val())
2146    ) {
2147        setTimeout(() => {
2148            $(formSelector).find(".btn-number[data-type='minus'][data-field='quantity']").removeAttr("disabled");
2149        }, 1000);
2150    } else {
2151        $(formSelector).find(".btn-number[data-type='minus'][data-field='quantity']").attr("disabled", true);
2152    }
2153}
2154document.addEventListener('change', function(e){
2155    const t = e.target;
2156    if (!t.matches('input[type="radio"][name="color"], input[type="radio"][name^="choice_"]')) return;
2157
2158    const val = (t.value || '').toLowerCase();
2159    const name = t.name;
2160    const isSticky = t.id && t.id.startsWith('sticky-');
2161
2162    let selector;
2163    if (isSticky) {
2164        selector = 'input[type="radio"][name="' + name + '"]:not([id^="sticky-"])';
2165    } else {
2166        selector = 'input[id^="sticky-"][name="' + name + '"]';
2167    }
2168    let match = Array.from(document.querySelectorAll(selector)).find(i => (i.value || '').toLowerCase() === val);
2169    if (!match && name === "color" && !isSticky) {
2170        const code = val.replace('#','');
2171        match = document.querySelector('input[id^="sticky-"][id$="-color-' + code + '"]');
2172    }
2173    if (match) match.checked = true;
2174});
2175function checkAddToCartValidity(formSelector = ".add-to-cart-details-form") {
2176    var names = {};
2177    $(formSelector)
2178        .find("input:radio")
2179        .each(function () {
2180            names[$(this).attr("name")] = true;
2181        });
2182    var count = 0;
2183    $.each(names, function () {
2184        count++;
2185    });
2186
2187    if ($(formSelector).find("input:radio:checked").length == count) {
2188        return true;
2189    }
2190    return false;
2191}
2192
2193function updateFlashDealProgressBar() {
2194    let getFlashDealsTime = $("#storage-flash-deals").data("value");
2195    const current_time_stamp = new Date().getTime();
2196    const start_date = new Date(getFlashDealsTime).getTime();
2197    const countdownElement = document.querySelector(".cz-countdown");
2198    try {
2199        const getEndTime = countdownElement.data("countdown");
2200        const endTime = new Date(getEndTime).getTime();
2201        let time_progress =
2202            ((current_time_stamp - start_date) / (endTime - start_date)) * 100;
2203        const progress_bar = document.querySelector(".flash-deal-progress-bar");
2204        progress_bar.style.width = time_progress + "%";
2205    } catch (e) { }
2206}
2207
2208$(".image-preview-before-upload").on("change", function () {
2209    let getElementId = $(this).data("preview");
2210    $(getElementId).attr("src", window.URL.createObjectURL(this.files[0]));
2211    $(getElementId).removeClass("d-none");
2212    $(getElementId)
2213        .closest(".custom_upload_input")
2214        .find(".placeholder-image")
2215        .css("opacity", "0");
2216});
2217
2218$(document).on("ready", function () {
2219    if ($(".image-preview-before-upload").length) {
2220        $(".image-preview-before-upload").each(function () {
2221            if ($(this).data("image")) {
2222                let getElementId = $(this).data("preview");
2223                $(getElementId).attr("src", $(this).data("image"));
2224                $(getElementId).removeClass("d-none");
2225                $(getElementId)
2226                    .closest(".custom_upload_input")
2227                    .find(".placeholder-image")
2228                    .css("opacity", "0");
2229            }
2230        });
2231    }
2232});
2233
2234$("#vendor-remember-input-checked").on("change", function () {
2235    if ($(this).is(":checked")) {
2236        $("#apply").removeAttr("disabled");
2237    } else {
2238        $("#apply").attr("disabled", "disabled");
2239    }
2240});
2241
2242$("#exampleInputPassword, #exampleRepeatPassword").on("keyup", function () {
2243    let password = $("#exampleInputPassword").val();
2244    let passwordRepeat = $("#exampleRepeatPassword").val();
2245    if (password != "" && passwordRepeat != "") {
2246        if (password.toString() === passwordRepeat.toString()) {
2247            $(".pass").hide();
2248        } else {
2249            $(".pass").show();
2250        }
2251    } else {
2252        $(".pass").hide();
2253    }
2254});
2255
2256$(".alert-insufficient-loyalty-point").on("click", function () {
2257    let message = $(this).data("insufficient-point");
2258    toastr.error(message);
2259});
2260
2261/*
2262 * Which network a share button is for, taken from the endpoint it posts to.
2263 *
2264 * Every share button in the shop went through this one handler and sent the bare canonical URL, so
2265 * a share that arrived without a Referer — which is most of them, from a messaging app — came back
2266 * as (direct) and the share buttons looked like they produced nothing.
2267 */
2268function shareNetworkOf(endpoint) {
2269    let host = String(endpoint || "").split("/")[0].toLowerCase();
2270
2271    if (host.indexOf("facebook") !== -1) return "facebook";
2272    if (host.indexOf("twitter") !== -1 || host === "x.com") return "t
2272witter";
2273    if (host.indexOf("linkedin") !== -1) return "linkedin";
2274    if (host.indexOf("whatsapp") !== -1) return "whatsapp";
2275    if (host.indexOf("telegram") !== -1 || host === "t.me") return "telegram";
2276    if (host.indexOf("pinterest") !== -1) return "pinterest";
2277    if (host.indexOf("reddit") !== -1) return "reddit";
2278
2279    return host.split(".")[0] || "social";
2280}
2281
2282/* Tag a link this shop is handing out, without touching one that is already tagged or foreign. */
2283function taggedShareUrl(rawUrl, network) {
2284    let parsed;
2285
2286    try {
2287        parsed = new URL(rawUrl, window.location.origin);
2288    } catch (error) {
2289        return rawUrl;
2290    }
2291
2292    if (parsed.origin !== window.location.origin) {
2293        return rawUrl;
2294    }
2295
2296    // A referral link already says where it came from, and that is the more specific truth.
2297    if (!parsed.searchParams.has("utm_source")) {
2298        parsed.searchParams.set("utm_source", network);
2299        parsed.searchParams.set("utm_medium", "social");
2300        parsed.searchParams.set("utm_campaign", "share_button");
2301    }
2302
2303    return parsed.toString();
2304}
2305
2306$(document).on("click", ".share-on-social-media", function (e) {
2307    e.preventDefault();
2308    let social = $(this).data("social-media-name");
2309    let url = taggedShareUrl($(this).data("action"), shareNetworkOf(social));
2310    let width = 600,
2311        height = 400,
2312        left = (screen.width - width) / 2,
2313        top = (screen.height - height) / 2;
2314
2315    window.open(
2316        "https://" + social + encodeURIComponent(url),
2317        "Popup",
2318        "toolbar=0,status=0,width=" +
2319        width +
2320        ",height=" +
2321        height +
2322        ",left=" +
2323        left +
2324        ",top=" +
2325        top
2326    );
2327});
2328
2329
2330var directionFromSession = $("#direction-from-session").data("value");
2331directionFromSession = directionFromSession ? directionFromSession : "ltr";
2332
2333const themeDirection = $("html").attr("dir");
2334
2335function renderOwlCarouselSilder() {
2336    var sync1 = $("#sync1");
2337    var sync2 = $("#sync2");
2338    var thumbnailItemClass = ".owl-item";
2339    var slides = sync1
2340        .owlCarousel({
2341            startPosition: 12,
2342            items: 1,
2343            loop: false,
2344            margin: 0,
2345            mouseDrag: true,
2346            touchDrag: true,
2347            pullDrag: false,
2348            scrollPerPage: true,
2349            autoplayHoverPause: false,
2350            nav: false,
2351            dots: false,
2352            rtl: themeDirection && themeDirection.toString() === "rtl",
2353        })
2354        .on("changed.owl.carousel", syncPosition);
2355
2356    function syncPosition(el) {
2357        var owl_slider = $(this).data("owl.carousel");
2358        var loop = owl_slider.options.loop;
2359
2360        if (loop) {
2361            var count = el.item.count - 1;
2362            var current = Math.round(el.item.index - el.item.count / 2 - 0.5);
2363            if (current < 0) {
2364                current = count;
2365            }
2366            if (current > count) {
2367                current = 0;
2368            }
2369        } else {
2370            var current = el.item.index;
2371        }
2372
2373        var owl_thumbnail = sync2.data("owl.carousel");
2374        var itemClass = "." + owl_thumbnail.options.itemClass;
2375
2376        var thumbnailCurrentItem = sync2
2377            .find(itemClass)
2378            .removeClass("synced")
2379            .eq(current);
2380        thumbnailCurrentItem.addClass("synced");
2381
2382        if (!thumbnailCurrentItem.hasClass("active")) {
2383            var duration = 500;
2384            sync2.trigger("to.owl.carousel", [current, duration, true]);
2385        }
2386    }
2387
2388    var thumbs = sync2
2389        .owlCarousel({
2390            startPosition: 12,
2391            items: 4,
2392            loop: false,
2393            margin: 10,
2394            autoplay: false,
2395            nav: false,
2396            dots: false,
2397            rtl: themeDirection && themeDirection.toString() === "rtl",
2398            responsive: {
2399                576: {
2400                    items: 4,
2401                },
2402                768: {
2403                    items: 4,
2404                },
2405                992: {
2406                    items: 4,
2407                },
2408                1200: {
2409                    items: 5,
2410                },
2411                1400: {
2412                    items: 5,
2413                },
2414            },
2415            onInitialized: function (e) {
2416                var thumbnailCurrentItem = $(e.target)
2417                    .find(thumbnailItemClass)
2418                    .eq(this._current);
2419                thumbnailCurrentItem.addClass("synced");
2420            },
2421        })
2422        .on("click", thumbnailItemClass, function (e) {
2423            e.preventDefault();
2424            var duration = 500;
2425            var itemIndex = $(e.target).parents(thumbnailItemClass).index();
2426            sync1.trigger("to.owl.carousel", [itemIndex, duration, true]);
2427        })
2428        .on("changed.owl.carousel", function (el) {
2429            var number = el.item.index;
2430            var owl_slider = sync1.data("owl.carousel");
2431            owl_slider.to(number, 500, true);
2432        });
2433    sync1.owlCarousel();
2434}
2435
2436renderOwlCarouselSilder();
2437
2438function findCountryObject(data) {
2439    return data.find((obj) => obj.types && obj.types.includes("country"));
2440}
2441
2442$(".close-element-onclick-by-data").on("click", function () {
2443    $($(this).data("selector")).slideUp("slow").fadeOut("slow");
2444});
2445$(".password-check").on("keyup keypress change click", function () {
2446    let password = $(this).val();
2447    let passwordError = $(".password-error");
2448    let passwordErrorMessage = $("#password-error-message");
2449    switch (true) {
2450        case password.length < 8:
2451            passwordError
2452                .html(passwordErrorMessage.data("max-character"))
2453                .removeClass("d-none");
2454            break;
2455        case !/[a-z]/.test(password):
2456            passwordError
2457                .html(passwordErrorMessage.data("lowercase-character"))
2458                .removeClass("d-none");
2459            break;
2460        case !/[A-Z]/.test(password):
2461            passwordError
2462                .html(passwordErrorMessage.data("uppercase-character"))
2463                .removeClass("d-none");
2464            break;
2465        case !/\d/.test(password):
2466            passwordError
2467                .html(passwordErrorMessage.data("number"))
2468                .removeClass("d-none");
2469            break;
2470        case !/[@.#$!%*?&]/.test(password):
2471            passwordError
2472                .html(passwordErrorMessage.data("symbol"))
2473                .removeClass("d-none");
2474            break;
2475        default:
2476            passwordError.addClass("d-none").empty();
2477    }
2478});
2479
2480function setEqualHeight(slides) {
2481    let maxHeight = 0;
2482
2483    slides.forEach((slide) => {
2484        slide.style.height = "";
2485        if (slide.offsetHeight > maxHeight) {
2486            maxHeight = slide.offsetHeight;
2487        }
2488    });
2489
2490    slides.forEach((slide) => {
2491        slide.style.height = maxHeight + "px";
2492    });
2493}
2494
2495$(".footer-slider").owlCarousel({
2496    margin: 10,
2497    items: 3,
2498    // responsiveClass: true,
2499    nav: false,
2500    dots: false,
2501    loop: false,
2502    autoplay: false,
2503    rtl: themeDirection && themeDirection.toString() === "rtl",
2504    autoHeight: true,
2505    responsive: {
2506        768: {
2507            items: $(".footer-slider")?.data('item') ?? 4,
2508            margin: 40,
2509        },
2510    },
2511});
2512
2513$(".footer-top-slider").owlCarousel({
2514    margin: 20,
2515    items: 2,
2516    nav: false,
2517    dots: false,
2518    loop: false,
2519    autoplay: false,
2520    responsiveClass: true,
2521    rtl: themeDirection && themeDirection.toString() === "rtl",
2522    autoHeight: true,
2523    responsive: {
2524        500: {
2525            items: 3,
2526        },
2527        768: {
2528            items: 4,
2529        },
2530    },
2531});
2532// $(".footer-top-slider").each(function(){
2533//     let maxItems = $(this).data('slide-items');
2534//     $(this).owlCarousel({
2535//         autoplay: true,
2536//         margin: 20,
2537//         nav: true,
2538//         navText:
2539//             directionFromSession === "rtl"
2540//                 ? [
2541//                     "<i class='czi-arrow-right'></i>",
2542//                     "<i class='czi-arrow-left'></i>",
2543//                 ]
2544//                 : [
2545//                     "<i class='czi-arrow-left'></i>",
2546//                     "<i class='czi-arrow-right'></i>",
2547//                 ],
2548//         dots: false,
2549//         autoplayHoverPause: true,
2550//         rtl: directionFromSession === "rtl",
2551
2552//         responsive: {
2553//             500: {
2554//                 items: 3,
2555//                 loop: maxItems > 3
2556//             },
2557//             768: {
2558//                 items: 4,
2559//                 loop: maxItems > 4
2560//             },
2561//         },
2562//     });
2563// })
2564
2565function sameHeight() {
2566    setEqualHeight(
2567        document.querySelectorAll(
2568            ".footer-slider-container .footer-slider .owl-item"
2569        )
2570    );
2571    setEqualHeight(document.querySelectorAll(".footer-top-slider .owl-item"));
2572}
2573
2574sameHeight();
2575
2576$(window).on("resize", sameHeight);
2577
2578$(".promotional-banner-slider").owlCarousel({
2579    margin: 20,
2580    items: 1,
2581    nav: true,
2582    dots: false,
2583    loop: true,
2584    rtl: themeDirection && themeDirection.toString() === "rtl",
2585    responsive: {
2586        768: {
2587            items: 2,
2588            nav: true,
2589            dots: false,
2590            loop: true,
2591        },
2592    },
2593});
2594
2595function playAudio() {
2596    document.getElementById("myAudio").play();
2597}
2598
2599$(window).on("load", function () {
2600    $(".upload-file__input").on("change", function () {
2601        if (this.files && this.files[0]) {
2602            let reader = new FileReader();
2603            let img = $(this)
2604                .siblings(".upload-file__img")
2605                .find("img")
2606                .removeAttr("hidden");
2607            $(this)
2608                .siblings(".upload-file__img")
2609                .find(".temp-img-box")
2610                .remove();
2611
2612            reader.onload = function (e) {
2613                img.attr("src", e.target.result);
2614            };
2615
2616            reader.readAsDataURL(this.files[0]);
2617        }
2618    });
2619});
2620
2621function downloadFileUsingFileUrl(url) {
2622    fetch(url)
2623        .then((response) => response.blob())
2624        .then((blob) => {
2625            const filename = url.substring(url.lastIndexOf("/") + 1);
2626            const blobUrl = window.URL.createObjectURL(new Blob([blob]));
2627            const link = document.createElement("a");
2628            link.href = blobUrl;
2629            link.setAttribute("download", filename);
2630            document.body.appendChild(link);
2631            link.click();
2632            link.parentNode.removeChild(link);
2633        })
2634        .catch((error) => console.error("Error downloading file:", error));
2635}
2636
2637$(".getDownloadFileUsingFileUrl").on("click", function () {
2638    let getLink = $(this).data("file-path");
2639    downloadFileUsingFileUrl(getLink);
2640});
2641$(".sidebar-overlay").on("click", function () {
2642    $(".cz-sidebar").removeClass("show active");
2643});
2644
2645
2646$(".otp-login-btn").on("click", function () {
2647    $(this).addClass("d-none");
2648    $(".manual-login-btn").removeClass("d-none");
2649    $(".manual-login-items").addClass("d-none");
2650    $(".otp-login-items").removeClass("d-none");
2651    $(".phone-input-with-country-picker").attr("required", true);
2652    $(".auth-email-input").attr("required", false);
2653    $(".auth-password-input").attr("required", false);
2654    $(".auth-login-type-input").val("otp-login");
2655});
2656
2657$(".manual-login-btn").on("click", function () {
2658    $(this).addClass("d-none");
2659    $(".otp-login-btn").removeClass("d-none");
2660    $(".otp-login-items").addClass("d-none");
2661    $(".manual-login-items").removeClass("d-none");
2662    $(".phone-input-with-country-picker").attr("required", false);
2663    $(".auth-email-input").attr("required", true);
2664    $(".auth-password-input").attr("required", true);
2665    $(".auth-login-type-input").val("manual-login");
2666});
2667
2668$(".customer-centralize-login-form").on("submit", async function (event) {
2669    event.preventDefault();
2670
2671    $.ajax({
2672        url: $(this).attr("action"),
2673        method: $(this).attr("method"),
2674        data: $(this).serialize(),
2675        beforeSend: function () {
2676            $("#loading").show();
2677        },
2678        success: function (response) {
2679            responseManager(response);
2680        },
2681        complete: function () {
2682            $("#loading").hide();
2683        },
2684    });
2685});
2686
2687function responseManager(response) {
2688    if (response.status === "success") {
2689        if (response.message) {
2690            toastr.success(response.message);
2691        }
2692        if (response?.redirectRoute) {
2693            location.href = response.redirectRoute;
2694        } else if (response?.redirect_url) {
2695            location.href = response?.redirect_url;
2696        }
2697    } else if (response.status === "error") {
2698        if (response.message) {
2699            toastr.error(response.message);
2700        }
2701    } else if (response.status === "warning") {
2702        if (response.message) {
2703            toastr.warning(response.message);
2704        }
2705    }
2706
2707    if (response.errors) {
2708        for (let index = 0; index < response.errors.length; index++) {
2709            toastr.error(response.errors[index].message, {
2710                CloseButton: true,
2711                ProgressBar: true,
2712            });
2713        }
2714    } else if (response.error) {
2715        toastr.error(response.error, {
2716            CloseButton: true,
2717            ProgressBar: true,
2718        });
2719    }
2720
2721    if (response?.reload && !response?.redirectRoute && !response?.redirect_url) {
2722        location.reload();
2723    }
2724}
2725
2726$(".clean-phone-input-value").on("input", function () {
2727    $(this).val($(this).val().replace(/\s/g, ""));
2728});
2729
2730function productRestockStockLimitStatus(response) {
2731    let mainElement = $(".product-restock-stock-alert");
2732    mainElement.find(".title").html(response?.title);
2733    mainElement.find(".image").attr("width", 50).attr("src", response?.image);
2734    mainElement.find(".message").html(response?.body);
2735    mainElement.find(".product-link").removeAttr("data-link");
2736    mainElement.find(".product-link").attr("data-link", response?.route);
2737    mainElement.addClass("active");
2738    setTimeout(() => {
2739        mainElement.removeClass("active");
2740    }, 100000);
2741}
2742
2743$(".product-restock-stock-close").on("click", function () {
2744    $(".product-restock-stock-alert").removeClass("active");
2745});
2746
2747$('.only-integer-input-field').on("keypress keyup change", function (event) {
2748    let inputValue = $(this).val();
2749    if (event.type === "keypress" && (event.which < 48 || event.which > 57) && event.which !== 46) {
2750        event.preventDefault();
2751    }
2752    if ((inputValue.match(/\./g) || []).length > 1) {
2753        $(this).val(inputValue.slice(0, inputValue.lastIndexOf('.')));
2754    }
2755    $(this).val(inputValue.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1'));
2756});
2757
2758$('.form-loading-button-form').on('submit', function () {
2759    $(this).find('[type="submit"]').addClass('active-loading').attr('disabled', true);
2760    $(this).find('.form-cancel-button').attr('disabled', true);
2761});
2762
2763//  ---- tooltip control fr chatting
2764function isElementVisibleInContainer($el, $container) {
2765    const el = $el[0];
2766    const container = $container[0];
2767
2768    const elRect = el.getBoundingClientRect();
2769    const containerRect = container.getBoundingClientRect();
2770
2771    return (
2772        elRect.top >= containerRect.top &&
2773        elRect.bottom <= containerRect.bottom
2774    );
2775}
2776
2777function updateTooltipsBasedOnVisibility() {
2778    try {
2779        const $container = $('#chatting-messages-section');
2780        $container.find('[data-toggle="tooltip"]').each(function () {
2781            const $el = $(this);
2782            const isVisible = isElementVisibleInContainer($el, $container);
2783
2784            const tooltipInstance = bootstrap.Tooltip.getInstance(this);
2785
2786            if (isVisible) {
2787                if (!tooltipInstance) {
2788                    new bootstrap.Tooltip(this);
2789                }
2790            } else {
2791                if (tooltipInstance) {
2792                    tooltipInstance.dispose();
2793                }
2794            }
2795        });
2796    } catch (e) {
2797    }
2798}
2799
2800$(document).ready(function () {
2801    updateTooltipsBasedOnVisibility();
2802
2803    $('#chatting-messages-section').on('scroll', function () {
2804        updateTooltipsBasedOnVisibility();
2805    });
2806
2807    // ---- swipper slider and zoom
2808    function initSliderWithZoom() {
2809        $(".easyzoom").each(function () {
2810            $(this).easyZoom();
2811        });
2812
2813        new Swiper(".quickviewSlider2", {
2814            slidesPerView: 1,
2815            spaceBetween: 10,
2816            loop: false,
2817            thumbs: {
2818                swiper: new Swiper(".quickviewSliderThumb2", {
2819                    spaceBetween: 10,
2820                    slidesPerView: 'auto',
2821                    watchSlidesProgress: true,
2822                    navigation: {
2823                        nextEl: ".swiper-quickview-button-next",
2824                        prevEl: ".swiper-quickview-button-prev",
2825                    },
2826                }),
2827            },
2828        });
2829    }
2830    initSliderWithZoom();
2831});
2832
2833// --- Text Descrition toggle bases on char limit ---
2834$(function () {
2835    let seeMoreText = $('#see-more-less').data('see-more') || 'See More';
2836    let seeLessText = $('#see-more-less').data('see-less') || 'See Less';
2837
2838    $('.review-wrapper').each(function () {
2839
2840        let wrapper = $(this);
2841        let textEl = wrapper.find('.review-des');
2842        let button = wrapper.find('.see_more_btn');
2843        let limit = parseInt(wrapper.attr('data-char-limit')) || 150;
2844
2845        let fullText = $.trim(textEl.text());
2846
2847        if (fullText.length <= limit) return;
2848
2849        let shortText = fullText.substring(0, limit) + '...';
2850
2851        textEl.data('full', fullText);
2852        textEl.data('short', shortText);
2853
2854        textEl.text(shortText);
2855        button.text(seeMoreText).removeClass('d-none');
2856    });
2857
2858
2859    $(document).on('click', '.see_more_btn', function () {
2860
2861        let btn = $(this);
2862        let wrapper = btn.closest('.review-wrapper');
2863        let textEl = wrapper.find('.review-des');
2864
2865        if (btn.hasClass('open')) {
2866            textEl.text(textEl.data('short'));
2867            btn.removeClass('open').text(seeMoreText);
2868        } else {
2869            textEl.text(textEl.data('full'));
2870            btn.addClass('open').text(seeLessText);
2871        }
2872
2873    });
2874
2875});
2876
2877document.addEventListener("keydown", function (event) {
2878    const input = event.target;
2879
2880    if (!input.classList.contains("only-number-input-with-decimal-point")) {
2881        return;
2882    }
2883    if (
2884        event.key === "Backspace" ||
2885        event.key === "Delete" ||
2886        event.key === "ArrowLeft" ||
2887        event.key === "ArrowRight" ||
2888        event.key === "Tab"
2889    ) {
2890        return;
2891    }
2892    if (event.key === "." && input.value.includes(".")) {
2893        event.preventDefault();
2894        return;
2895    }
2896    if (!/^[0-9.]$/.test(event.key)) {
2897        event.preventDefault();
2898    }
2899});

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.