PageSourceSearch

https://kultmopeds.de/templates/NOVA/js/jtl.evo.js?v=1.2.3

js kultmopeds.de collected 2026-09-25 13:22:01 UTC 49,011 bytes, 1,256 lines download raw bytes

1(function () {
2    'use strict';
3
4    if (!$.evo) {
5        $.evo = {};
6    }
7
8    var EvoClass = function() {};
9
10    EvoClass.prototype = {
11        options: {
12            captcha: {},
13            scrollSearch: '.smoothscroll-top-search'
14        },
15
16        constructor: EvoClass,
17
18        generateSlickSlider: function() {
19            let self = this;
20
21            const observer = new window.IntersectionObserver(entries => {
22                for (const entry of entries) {
23                    if (entry.isIntersecting) {
24                        let mainNode = $(entry.target);
25                        mainNode.removeClass('slick-lazy');
26                        if (!mainNode.hasClass('slick-initialized')) {
27                            mainNode.find('.product-wrapper').removeClass('mx-auto ml-auto-util mr-auto');
28                            self.initSlick(mainNode, mainNode.data('slick-type'), mainNode.data('display-counts'));
29                            mainNode.find('.slick-active a:first-child').attr({
30                                'tabindex': '-1'
31                            });
32
33                        }
34                    }
35                }
36            }, {
37                root: null,
38                threshold: 0.1, // set offset 0.1 means trigger if atleast 10% of element in viewport
39            })
40
41            document.querySelectorAll('.slick-lazy').forEach(function(slickItem) {
42                observer.observe(slickItem)
43            });
44
45            document.querySelectorAll('.slick-lazy').forEach(function(slickItem) {
46                let startX;
47                let supportsPassive = false;
48                try {
49                    let opts = Object.defineProperty({}, 'passive', {
50                        get: function() {
51                            supportsPassive = true;
52                        }
53                    });
54                    window.addEventListener("testPassive", null, opts);
55                    window.removeEventListener("testPassive", null, opts);
56                } catch (e) {}
57
58                slickItem.addEventListener('touchstart', function (e) {
59                    startX = e.changedTouches[0].pageX;
60
61                },supportsPassive ? { passive: true } : false);
62                slickItem.addEventListener('touchmove', function (e) {
63                    let mainNode = $(this);
64                    if (!mainNode.hasClass('slick-initialized')
65                        && Math.abs(startX - e.changedTouches[0].pageX) > 80
66                    ) {
67                        mainNode.removeClass('slick-lazy');
68                        mainNode.find('.product-wrapper').removeClass('mx-auto ml-auto-util mr-auto');
69                        self.initSlick(mainNode, mainNode.data('slick-type'), mainNode.data('display-counts'));
70                        let slickOptions = mainNode.slick('getSlick');
71                        if(slickOptions.slideCount > mainNode.slick('slickGetOption', 'slidesToShow')) {
72                            let goTo;
73                            $.each(slickOptions.originalSettings.responsive, function (key, value) {
74                                if (value.breakpoint === slickOptions.activeBreakpoint
75                                    && value.settings.slidesToShow !== undefined
76                                ) {
77                                    goTo = value.settings.slidesToShow;
78                                }
79                            });
80                            if (goTo === undefined) {
81                                goTo = slickOptions.originalSettings.slidesToScroll
82                            }
83                            mainNode.slick('slickGoTo', goTo || 2);
84                        }
85                    }
86                }, supportsPassive ? { passive: true } : false);
87            });
88        },
89
90        initSlick: function (node, sliderType, displayCounts = '') {
91            displayCounts = displayCounts.split(',');
92            displayCounts = [
93                parseInt(displayCounts[0]) || 2,
94                parseInt(displayCounts[1]) || 3,
95                parseInt(displayCounts[2]) || 5,
96                parseInt(displayCounts[3]) || 7,
97            ];
98            let sliderOptions = {
99                'box-slider' : {
100                    rows:           0,
101                    arrows:         false,
102                    lazyLoad:       'ondemand',
103                    slidesToShow:   1,
104                    slidesToScroll: 1,
105                    mobileFirst:    true,
106                    responsive: [
107                        {
108                            breakpoint: 992,
109                            settings: {
110                                arrows: true,
111                            }
112                        }
113                    ]
114                },
115                'slider-half' : {
116                    rows:         0,
117                    arrows:       false,
118                    lazyLoad:     'ondemand',
119                    mobileFirst:    true,
120                    slidesToShow: 2,
121                    slidesToScroll: 2,
122                    responsive:   [
123                        {
124                            breakpoint: 992,
125                            settings: {
126                                arrows: true,
127                            }
128                        },
129                        {
130                            breakpoint: 1300,
131                            settings: {
132                                slidesToShow: 3,
133                                slidesToScroll: 3,
134                                arrows: true,
135                            }
136                        }
137                    ]
138                },
139                'slider-three' : {
140                    rows:         0,
141                    arrows:       false,
142                    lazyLoad:     'ondemand',
143                    mobileFirst:    true,
144                    slidesToShow: 1,
145                    slidesToScroll: 1,
146                    responsive:   [
147                        {
148                            breakpoint: 768,
149                            settings: {
150                                slidesToShow: 2,
151                                slidesToScroll: 2,
152                            }
153                        },
154                        {
155                            breakpoint: 992,
156                            settings: {
157                                arrows: true,
158                            }
159                        },
160                        {
161                            breakpoint: 1300,
162                            settings: {
163                                arrows: true,
164                                slidesToShow: 3,
165                                slidesToScroll: 3,
166                            }
167                        }
168                    ]
169                },
170                'product-slider' : {
171                    rows:           0,
172                    arrows:         false,
173                    lazyLoad:       'ondemand',
174                    slidesToShow:   displayCounts[0] || 2,
175                    slidesToScroll: displayCounts[0] || 2,
176                    mobileFirst:    true,
177                    responsive:     [
178                        {
179                            breakpoint: 768,
180                            settings: {
181                                slidesToShow: displayCounts[1] || 3,
182                                slidesToScroll: displayCounts[1] || 3,
183                            }
184                        },
185                        {
186                            breakpoint: 992,
187                            settings: {
188                                slidesToShow: displayCounts[2] || 5,
189                                slidesToScroll: displayCounts[2] || 5,
190                                arrows: true,
191                            }
192                        },
193                        {
194                            breakpoint: 1300,
195                            settings: {
196                                slidesToShow: displayCounts[3] || 7,
197                                slidesToScroll: displayCounts[3] || 7,
198                                arrows: true,
199                            }
200                        }
201                    ]
202                },
203                'news-slider' : {
204                    rows:           0,
205                    slidesToShow:   1,
206                    slidesToScroll: 1,
207                    arrows:         false,
208                    infinite:       false,
209                    lazyLoad:       'ondemand',
210                    mobileFirst:    true,
211                    responsive:     [
212                        {
213                            breakpoint: 768,
214                            settings: {
215                                slidesToShow: 2,
216                                slidesToScroll: 2,
217                            }
218                        },
219                        {
220                            breakpoint: 992,
221                            settings: {
222                                slidesToShow:3,
223                                slidesToScroll: 3,
224                                arrows: true
225                            }
226                        },
227                        {
228                            breakpoint: 1300,
229                            settings: {
230                                slidesToShow:5,
231                                slidesToScroll: 5,
232                                arrows: true
233                            }
234                        }
235                    ]
236                },
237                'freegift' : {
238                    rows:         0,
239                    slidesToShow:   3,
240                    slidesToScroll: 3,
241                    arrows:   false,
242                    infinite: false,
243                    responsive: [
244                        {
245                            breakpoint: 768,
246                            settings: {
247                                slidesToShow: 2,
248                                slidesToScroll: 2,
249                            }
250                        },
251                        {
252                            breakpoint: 992,
253                            settings: {
254                                arrows: true
255                            }
256                        }
257                    ]
258                },
259                'gallery' : {
260                    rows:     0,
261                    lazyLoad: 'ondemand',
262                    infinite: true,
263                    dots:     false,
264                    arrows:   true,
265                    speed: 500,
266                    fade: true,
267                    cssEase: 'linear',
268                    asNavFor: '#gallery_preview',
269                    responsive:     [
270                        {
271                            breakpoint: 992,
272                            settings: {
273                                dots: true
274                            }
275                        }
276                    ]
277                },
278                'gallery_preview' : {
279                    rows:           0,
280                    lazyLoad:       'ondemand',
281                    slidesToShow:   5,
282                    slidesToScroll: 1,
283                    asNavFor:       '#gallery',
284                    dots:           false,
285                    arrows:         true,
286                    focusOnSelect:  true,
287                    responsive:     [
288                        {
289                            breakpoint: 768,
290                            settings:   {
291                                slidesToShow: 4,
292                                slidesToScroll: 1,
293                            }
294                        },
295                        {
296                            breakpoint: 576,
297                            settings: {
298                                slidesToShow: 3,
299                                slidesToScroll: 1,
300                            }
301                        }
302                    ]
303                }
304            };
305            if ($('#content').hasClass('col-lg-9')) {
306                sliderOptions['news-slider']['slidesToShow'] = 2;
307            }
308            if (sliderType === 'gallery_preview') {
309                sliderType = 'gallery';
310                node = $('#gallery');
311            }
312            if (sliderType === 'gallery') {
313                $('.js-gallery-images').removeClass('d-none');
314                $('.slick-inital-arrow').remove();
315                $('.initial-slick-dots').remove();
316                $('#gallery_preview').slick(sliderOptions['gallery_preview']);
317            }
318
319            return node.slick(sliderOptions[sliderType]);
320        },
321
322        scrollStuff: function() {
323            var breakpoint = 0,
324                pos,
325                sidePanel = $('#sidepanel_left');
326
327            if(sidePanel.length) {
328                breakpoint = sidePanel.position().top + sidePanel.hiddenDimension('height');
329            }
330
331            pos = breakpoint - $(this).scrollTop();
332
333            if ($(this).scrollTop() > 200 && !$('#to-top').hasClass('active')) {
334                $('#to-top').addClass('active');
335            } else if($(this).scrollTop() < 200 && $('#to-top').hasClass('active')) {
336                $('#to-top').removeClass('active');
337            }
338
339            if ($(window).width() > 768) {
340                var $document = $(document),
341                    $element = $('.navbar-fixed-top'),
342                    className = 'nav-closed';
343
344                $document.scroll(function() {
345                    $element.toggleClass(className, $document.scrollTop() >= 150);
346                });
347
348            }
349        },
350
351        productTabsPriceFlow: function() {
352            var dateFormat = 'DD.MM.YYYY';
353            if ($('html').attr('lang') !== 'de') {
354                dateFormat = 'MM/DD/YYYY';
355            }
356            var chartOptions = {
357                responsive:       true,
358                scaleBeginAtZero: false,
359                aspectRatio:3,
360                tooltips: {
361                    callbacks: {
362                        label: function (tooltipItem, data) {
363                            var label = window.chartDataTooltip;
364                            label += Math.round(tooltipItem.yLabel * 100) / 100;
365                            label += ' '+window.chartDataCurrency;
366                            return label;
367                        }
368                    }
369                },
370                scales: {
371                    xAxes: [{
372                        type: 'time',
373                        time: {
374                            parser: 'DD.MM.YYYY',
375                            // round: 'day'
376                            tooltipFormat: dateFormat
377                        },
378                        display: false
379                    }],
380                }
381            };
382            if (typeof window.priceHistoryChart !== 'undefined' && window.priceHistoryChart === null) {
383                window.priceHistoryChart = new Chart(window.ctx, {
384                    type: 'line',
385                    data: window.chartData,
386                    options: chartOptions
387                });
388            }
389        },
390
391        tooltips: function() {
392            $('[data-toggle="tooltip"]').tooltip();
393        },
394
395        bootlint: function() {
396            (function(){
397                var p = window.alert;
398                var s = document.createElement("script");
399                window.alert = function() {
400                    console.info(arguments);
401                };
402                s.onload = function() {
403                    bootlint.showLintReportForCurrentDocument([]);
404                    window.alert = p;
405                };
406                s.src = "https://maxcdn.bootstrapcdn.com/bootlint/latest/bootlint.min.js";
407                document.body.appendChild(s);
408            })();
409        },
410
411        showNotify: function(options) {
412            eModal.alert({
413                size: 'xl',
414                buttons: false,
415                title: options.title,
416                message: options.text,
417                keyboard: true,
418                tabindex: -1})
419                .then(
420                 function() {
421                    $.evo.generateSlickSlider();
422                }
423            );
424        },
425
426        popupDep: function() {
427            $('#main-wrapper').on('click', '.popup-dep', function(e) {
428                var id    = '#popup' + $(this).attr('id'),
429                    title = $(this).attr('title'),
430                    html  = $(id).html();
431                eModal.alert({
432                    message: html,
433                    title: title,
434                    keyboard: true,
435                    buttons: false,
436                    tabindex: -1})
437                    .then(
438                        function () {
439                            //the modal just copies all the html.. so we got duplicate IDs which confuses recaptcha
440                            var recaptcha = $('.tmp-modal-content .g-recaptcha');
441                            if (recaptcha.length === 1) {
442                                var siteKey = recaptcha.data('sitekey'),
443                                    newRecaptcha = $('<div />');
444                                if (typeof  siteKey !== 'undefined') {
445                                    //create empty recapcha div, give it a unique id and delete the old one
446                                    newRecaptcha.attr('id', 'popup-recaptcha').addClass('g-recaptcha form-group');
447                                    recaptcha.replaceWith(newRecaptcha);
448                                    grecaptcha.render('popup-recaptcha', {
449                                        'sitekey' : siteKey,
450                                        'callback' : 'captcha_filled'
451
452                                    });
453                                }
454                            }
455                            addValidationListener();
456                            $('.g-recaptcha-response').attr('required', true);
457                        }
458                    );
459                return false;
460            });
461        },
462
463        popover: function() {
464            /*
465             * <a data-toggle="popover" data-ref="#popover-content123">Click me</a>
466             * <div id="popover-content123" class="popover">content here</div>
467             */
468            $('[data-toggle="popover"]').popover({
469                html: true,
470                sanitize: false,
471                content: function() {
472                    var ref = $(this).attr('data-ref');
473                    return $(ref).html();
474                }
475            });
476        },
477
478        smoothScrollToAnchor: function(href, pushToHistory) {
479            var anchorRegex = /^#[\w\-]+$/;
480            if (!anchorRegex.test(href)) {
481                return false;
482            }
483
484            var target, targetOffset;
485            target = $('#' + href.slice(1));
486
487            if (target.length > 0) {
488                // scroll below the static megamenu
489                var nav         = $('#jtl-nav-wrapper.sticky-top');
490                var fixedOffset = nav.length > 0 ? nav.outerHeight() : 0;
491
492                targetOffset = target.offset().top - fixedOffset - parseInt(target.css('margin-top'));
493                $('html, body').animate({scrollTop: targetOffset});
494
495                if (pushToHistory) {
496                    history.pushState({}, document.title, location.pathname + href);
497                }
498
499                return true;
500            }
501
502            return false;
503        },
504
505        smoothScroll: function() {
506            var supportHistory = (history && history.pushState) ? true : false;
507            var that = this;
508
509            this.smoothScrollToAnchor(location.hash, false);
510            $(document).delegate('a[href^="#"]', 'click', function(e) {
511                var elem = e.target;
512                if (!e.isDefaultPrevented()) {
513                    // only runs if no other click event is fired
514                    if (that.smoothScrollToAnchor(elem.getAttribute('href'), supportHistory)) {
515                        e.preventDefault();
516                    }
517                }
518            });
519        },
520
521        initSkipToScroll: function() {
522            // set focus on skip-to links
523            let links = $('.btn-skip-to');
524            var that = this;
525
526            links.on('click', function(e) {
527                let url    = new URL(e.target.href);
528                let target = url.hash;
529
530                that.smoothScrollToAnchor(target, false);
531                $(target).focus();
532            });
533        },
534
535        initScrollSearchEvent: function() {
536            this.destroyScrollSearchEvent();
537            let lastScroll       = 0,
538                $scrollTopSearch = $(this.options.scrollSearch);
539            if ($scrollTopSearch.length) {
540                $(document).on('scroll.search', function () {
541                    let newScroll = $(this).scrollTop();
542                    if (newScroll < lastScroll) {
543                        if ($(window).scrollTop() > 100) {
544                            $scrollTopSearch.removeClass('d-none');
545                        } else {
546                            $scrollTopSearch.addClass('d-none');
547                        }
548                    } else {
549                        $scrollTopSearch.addClass('d-none');
550                    }
551                    lastScroll = newScroll;
552                });
553            }
554        },
555
556        destroyScrollSearchEvent: function() {
557            $(this.options.scrollSearch).addClass('d-none');
558            $(document).off('scroll.search');
559        },
560
561        initScrollEvents: function() {
562            this.initScrollSearchEvent();
563
564            //scroll top button
565            let toTopbuttonVisible     = false,
566                $toTopbutton           = $('.smoothscroll-top'),
567                toTopbuttonActiveClass = 'show';
568
569            function scrolltoTop() {
570                $(window).scrollTop(0);
571            }
572
573            function handleVisibilityTopButton() {
574                let currentPosition = $(window).scrollTop();
575                if (currentPosition > 800) {
576                    if (!toTopbuttonVisible) {
577                        $toTopbutton.addClass(toTopbuttonActiveClass);
578                        toTopbuttonVisible = true;
579                    }
580                } else if (toTopbuttonVisible) {
581                    toTopbuttonVisible = false;
582                    $toTopbutton.removeClass(toTopbuttonActiveClass)
583                }
584            }
585
586            if ($toTopbutton.length) {
587                $(window).on('scroll', handleVisibilityTopButton);
588                $toTopbutton.on('click', scrolltoTop);
589                handleVisibilityTopButton();
590            }
591        },
592
593        resetForParallax: function() {
594            $(window).trigger('resize').trigger('scroll');
595        },
596
597        addCartBtnAnimation: function() {
598            var animating = false;
599
600            initCustomization();
601
602            function initCustomization() {
603                var addToCartBtn = $('#add-to-cart button[type="submit"]'),
604                    form         = $('#buy_form');
605                //detect click on the add-to-cart button
606                form.on('submit', function(e) {
607                    if(!animating ) {
608                        //animate if not already animating
609                        animating =  true;
610
611                        addToCartBtn.addClass('is-added').find('path').eq(0).animate({
612                            //draw the check icon
613                            'stroke-dashoffset':0
614                        }, 300, function(){
615                            setTimeout(function(){
616                                addToCartBtn.removeClass('is-added').find('span.btn-basket-check').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
617                                    //wait for the end of the transition to reset the check icon
618                                    addToCartBtn.find('path').eq(0).css('stroke-dashoffset', '19.79');
619                                    animating =  false;
620                                });
621
622                                if( $('.no-csstransitions').length > 0 ) {
623                                    // check if browser doesn't support css transitions
624                                    addToCartBtn.find('path').eq(0).css('stroke-dashoffset', '19.79');
625                                    animating =  false;
626                                }
627                            }, 600);
628                        });
629                    }
630                });
631            }
632
633        },
634
635        checkout: function() {
636            // show only the first submit button (i.g. the button from payment plugin)
637            var $submits = $('#checkout-shipping-payment')
638                .closest('form')
639                .find('button[type="submit"]');
640            $submits.addClass('d-none');
641            $submits.first().removeClass('d-none');
642
643            $('input[name="Versandart"]', '#checkout-shipping-payment').on('change', function() {
644                var id    = parseInt($(this).val());
645                var $form = $(this).closest('form');
646                if (isNaN(id)) {
647                    return;
648                }
649
650                $form.find('fieldset, button[type="submit"]')
651                    .attr('disabled', true);
652
653                var urlInstance = null;
654                if ($form.length === 1 && $form.attr('action') !== undefined) {
655                    urlInstance = new URL($form.attr('action'));
656                    urlInstance.searchParams.append('kVersandart', '' + id);
657                }
658                var url = urlInstance === null
659                    ? $('#jtl-io-path').data('path') + '/bestellvorgang.php?kVersandart=' + id
660                    : urlInstance.href;
661                $.evo.loadContent(url, function() {
662                    $.evo.checkout();
663                }, null, true);
664            });
665
666            $('#country').on('change', function (e) {
667                var val = $(this).find(':selected').val();
668
669                $.evo.io().call('checkDeliveryCountry', [val], {}, function (error, data) {
670                    var $shippingSwitch = $('#checkout_register_shipping_address');
671
672                    if (data.response) {
673                        $shippingSwitch.removeAttr('disabled');
674                        $shippingSwitch.parent().removeClass('d-none');
675                    } else {
676                        $shippingSwitch.attr('disabled', true);
677                        $shippingSwitch.parent().addClass('d-none');
678                        if ($shippingSwitch.prop('checked')) {
679                            $shippingSwitch.prop('checked', false);
680                            $('#select-shipping-address').collapse('show');
681                        }
682                    }
683                });
684            });
685        },
686
687        loadContent: function(url, callback, error, animation, wrapper) {
688            var that        = this;
689            var $wrapper    = (typeof wrapper === 'undefined' || wrapper.length === 0) ? $('#result-wrapper') : $(wrapper);
690            var ajaxOptions = {data: 'isAjax'};
691            if (animation) {
692                $wrapper.addClass('loading');
693            }
694
695            that.trigger('load.evo.content', { url: url });
696
697            $.ajax(url, ajaxOptions).done(function(html) {
698                var $data = $(html);
699                if (animation) {
700                    $data.addClass('loading');
701                }
702                $wrapper.replaceWith($data);
703                $wrapper = $data;
704                if (typeof callback === 'function') {
705                    callback();
706                }
707            })
708            .fail(function() {
709                if (typeof error === 'function') {
710                    error();
711                }
712            })
713            .always(function() {
714                $wrapper.removeClass('loading');
715                that.trigger('contentLoaded'); // compatibility
716                that.trigger('loaded.evo.content', { url: url });
717            });
718        },
719
720        startSpinner: function (target) {
721            target = target || $('body');
722            if ($('.jtl-spinner').length === 0) {
723                target.append('<div class="jtl-spinner"><i class="fa fa-spinner fa-pulse"></i></div>');
724            }
725        },
726
727        stopSpinner: function () {
728            $('.jtl-spinner').remove();
729        },
730
731        trigger: function(event, args) {
732            $(document).trigger('evo:' + event, args);
733            return this;
734        },
735
736        error: function() {
737            if (console && console.error) {
738                if (1 in arguments && arguments[1] === 'abort') {
739                    console.info(arguments);
740                } else {
741                    console.error(arguments);
742                }
743            }
744        },
745
746        addInactivityCheck: function(wrapper, timeoutMS = 500, stopEnter = false) {
747            var timeoutID,
748                that = this,
749                currentBox;
750
751            setup();
752
753            function setup() {
754                $(wrapper + ' .form-counter input, ' + wrapper + ' .choose_quantity input').on('change',resetTimer);
755                $(wrapper + ' .form-counter .btn-decrement, ' + wrapper + ' .form-counter .btn-increment')
756                    .on('click keydown',resetTimer)
757                    .on('touchstart',resetTimer,{passive: true});
758                if (stopEnter) {
759                    $(wrapper + ' input.quantity').on('keypress', function (e) {
760                        if (e.key === 'Enter') {
761                            return false;
762                        } else {
763                            resetTimer(e);
764                        }
765                    });
766                }
767            }
768
769            function startTimer() {
770                timeoutID = window.setTimeout(goInactive, timeoutMS);
771            }
772
773            function resetTimer(e) {
774                // prevents form submit on navigating via tab-key
775                if (e.keyCode !== 9) {
776                    if (wrapper === '#wl-items-form') {
777                        currentBox = $(e.target).closest('.productbox-inner');
778                    }
779                    if (timeoutID == undefined) {
780                        startTimer();
781                    }
782                    window.clearTimeout(timeoutID);
783
784                    startTimer();
785                }
786            }
787
788            function goInactive() {
789                if (wrapper === '#cart-form') {
790                    $(wrapper).submit();
791                } else if (wrapper === '#wl-items-form') {
792                    that.updateWishlistItem(currentBox);
793                }
794            }
795        },
796
797        updateWishlistItem: function($wrapper) {
798            let formID   = 'wl-items-form';
799            $.evo.extended().startSpinner($wrapper);
800            $.evo.io().call(
801                'updateWishlistItem',
802                [
803                    parseInt($('#' + formID + ' input[name="kWunschliste"]').val()),
804                    $.evo.io().getFormValues(formID)
805                ],
806                $(this) , function(error, data) {
807                    $.evo.extended().stopSpinner();
808                    $wrapper.removeClass('loading');
809                });
810        },
811
812        fixStickyElements: function() {
813            var sticky    = '.cart-summary';
814            var navHeight = $('#jtl-nav-wrapper').outerHeight(true);
815            navHeight = navHeight === undefined ? 0 : parseInt(navHeight + 40);
816            $(sticky).css('top', navHeight);
817        },
818
819        setWishlistVisibilitySwitches: function() {
820            $('.wl-visibility-switch').on('change', function () {
821                $.evo.io().call(
822                    'setWishlistVisibility',
823                    [$(this).data('wl-id'), $(this).is(":checked"), $('.
823jtl_token').val()],
824                    $(this),
825                    function(error, data) {
826                    if (error) {
827                        return;
828                    }
829                    var $wlPrivate    = $('span[data-switch-label-state="private-' + data.response.wlID + '"]'),
830                        $wlPublic     = $('span[data-switch-label-state="public-' + data.response.wlID + '"]'),
831                        $wlURLWrapper = $('#wishlist-url-wrapper'),
832                        $wlURL        = $('#wishlist-url');
833                    if (data.response.state) {
834                        $wlPrivate.addClass('d-none');
835                        $wlPublic.removeClass('d-none');
836                        $wlURLWrapper.removeClass('d-none');
837                        $wlURL.val($wlURL.data('static-route') + data.response.url)
838                    } else {
839                        $wlPrivate.removeClass('d-none');
840                        $wlPublic.addClass('d-none');
841                        $wlURLWrapper.addClass('d-none');
842                    }
843                });
844            });
845        },
846
847        setDeliveryAdressDefaultSwitches: function() {
848            $('.la-default-switch').on('change', function () {
849                let input = $(this);
850                $('.la-default-switch').each(function() {
851                    if (input.attr('id') !== $(this).attr('id')) {
852                        $(this).prop('checked', false);
853                    } else {
854                        $(this).prop('checked', true);
855                    }
856                });
857                $.evo.io().call(
858                    'setDeliveryaddressDefault',
859                    [$(this).data('la-id'), $('.jtl_token').val()],
860                    $(this), function(error, data) {
861                        if (error) {
862                            return;
863                        }
864                        if (!data.response.result) {
865                            input.prop('checked', false);
866                        }
867                    }
868                );
869            });
870        },
871
872        initEModals: function () {
873            $('.author-modal').on('click', function (e) {
874                e.preventDefault();
875                let modalID = $(this).data('target');
876                eModal.alert({
877                    title: $(modalID).attr('title'),
878                    message: $(modalID).html(),
879                    buttons: false
880                });
881            });
882        },
883
884        initPriceSlider: function ($wrapper, redirect) {
885            let priceRange      = $wrapper.find('[data-id="js-price-range"]').val(),
886                priceRangeID    = $wrapper.find('[data-id="js-price-range-id"]').val(),
887                priceRangeMin   = 0,
888                priceRangeMax   = $wrapper.find('[data-id="js-price-range-max"]').val(),
889                currentPriceMin = priceRangeMin,
890                currentPriceMax = priceRangeMax,
891                $priceRangeFrom = $("#" + priceRangeID + "-from"),
892                $priceRangeTo = $("#" + priceRangeID + "-to"),
893                $priceSlider = document.getElementById(priceRangeID);
894
895            if($priceSlider === null) {
896                return;
897            }
898
899            if (priceRange) {
900                let priceRangeMinMax = priceRange.split('_');
901                currentPriceMin = priceRangeMinMax[0];
902                currentPriceMax = priceRangeMinMax[1];
903                $priceRangeFrom.val(currentPriceMin);
904                $priceRangeTo.val(currentPriceMax);
905            }
906            noUiSlider.create($priceSlider, {
907                start: [parseInt(currentPriceMin), parseInt(currentPriceMax)],
908                connect: true,
909                range: {
910                    'min': parseInt(priceRangeMin),
911                    'max': parseInt(priceRangeMax)
912                },
913                step: 1,
914                format: {
915                    to: function (value) {
916                        return parseInt(value);
917                    },
918                    from: function (value) {
919                        return parseInt(value);
920                    }
921                },
922                handleAttributes: [
923                    { 'aria-label': 'lower' },
924                    { 'aria-label': 'upper' },
925                ],
926            });
927            $priceSlider.noUiSlider.on('change', function (values, handle) {
928                setTimeout(function(){
929                    $.evo.redirectToNewPriceRange(values[0] + '_' + values[1], redirect, $wrapper);
930                },0);
931            });
932            $priceSlider.noUiSlider.on('update', function (values, handle) {
933                $priceRangeFrom.val(values[0]);
934                $priceRangeTo.val(values[1]);
935            });
936            $('.price-range-input').on('change', function () {
937                let prFrom = parseInt($priceRangeFrom.val()),
938                    prTo = parseInt($priceRangeTo.val());
939                $.evo.redirectToNewPriceRange(
940                    (prFrom > 0 ? prFrom : priceRangeMin) + '_' + (prTo > 0 ? prTo : priceRangeMax),
941                    redirect,
942                    $wrapper
943                );
944            });
945        },
946
947        initFilters: function (href) {
948            let $wrapper = $('.js-collapse-filter');
949            $('#submitMobileFilters').addClass('disabled');
950            $.evo.extended().startSpinner($wrapper);
951
952            $.ajax(href, {data: {'useMobileFilters':1}})
953                .done(function(data) {
954                    $wrapper.html(data);
955                    $.evo.initPriceSlider($wrapper, false);
956                    $.evo.initItemSearch('filter');
957                })
958                .always(function() {
959                    $('#submitMobileFilters').removeClass('disabled');
960                    $.evo.extended().stopSpinner();
961                });
962        },
963
964        initFilterEvents: function() {
965            let initiallized = false;
966            $('#js-filters').on('click', function() {
967                if (!initiallized) {
968                    $.evo.initFilters(window.location.href);
969                    initiallized = true;
970                }
971            });
972        },
973
974        redirectToNewPriceRange: function (priceRange, redirect, $wrapper) {
975            let currentURL  = window.location.href;
976            if (!redirect) {
977                currentURL  = $wrapper.find('[data-id="js-price-range-url"]').val();
978            }
979            let redirectURL = $.evo.updateURLParameter(
980                currentURL,
981                'pf',
982                priceRange
983            );
984            if (redirect) {
985                window.location.href = redirectURL;
986            } else {
987                $.evo.initFilters(redirectURL);
988            }
989        },
990
991        updateURLParameter: function (url, param, paramVal) {
992            let newAdditionalURL = '',
993                tempArray        = url.split('?'),
994                baseURL          = tempArray[0],
995                additionalURL    = tempArray[1],
996                temp             = '';
997            if (additionalURL) {
998                tempArray = additionalURL.split('&');
999                for (let i=0; i<tempArray.length; i++){
1000                    if(tempArray[i].split('=')[0] != param){
1001                        newAdditionalURL += temp + tempArray[i];
1002                        temp = '&';
1003                    }
1004                }
1005            }
1006
1007            return baseURL + '?' + newAdditionalURL + temp + param + '=' + paramVal;
1008        },
1009
1010        updateReviewHelpful: function(item) {
1011            let formData = $.evo.io().getFormValues('reviews-list');
1012            formData[item.prop('name')] = '';
1013            formData['reviewID'] = item.data('review-id');
1014
1015            $.evo.io().call(
1016                'updateReviewHelpful',
1017                [formData],
1018                $(this) , function(error, data) {
1019                    if (error) {
1020                        return;
1021                    }
1022                    let review = data.response.review;
1023
1024                    $('[data-review-id="' + review.kBewertung + '"]').removeClass('on-list');
1025                    item.addClass('on-list');
1026                    $('[data-review-count-id="hilfreich_' + review.kBewertung + '"]').html(review.nHilfreich);
1027                    $('[data-review-count-id="nichthilfreich_' + review.kBewertung + '"]').html(review.nNichtHilfreich);
1028                });
1029        },
1030
1031        initReviewHelpful: function() {
1032            $('.js-helpful').on('click', function (e) {
1033                e.preventDefault();
1034                $.evo.extended().updateReviewHelpful($(this));
1035            });
1036        },
1037
1038        initWishlist: function() {
1039            let wlFormID = '#wl-items-form';
1040            if ($(wlFormID).length) {
1041                $.evo.extended().addInactivityCheck(wlFormID, 300, true);
1042                $('.js-update-wl').on('change', function () {
1043                    $.evo.extended().updateWishlistItem($(this).closest('.productbox-inner'));
1044                });
1045                $(window).on('resize', function () {
1046                    setWishlistItemheights();
1047                });
1048                setWishlistItemheights();
1049            }
1050            function setWishlistItemheights() {
1051                $('.product-list').children().each(function() {
1052                    $(this).css('height', window.innerWidth > globals.breakpoints.xl ? $(this).height() : 'unset');
1053                });
1054            }
1055        },
1056
1057        initPaginationEvents: function() {
1058            $('.pagination-wrapper select').on('change', function () {
1059                this.form.submit();
1060            });
1061        },
1062
1063        initItemSearch: function(context) {
1064            let searchWrapper  = '.' + context + '-search-wrapper',
1065                searchInput    = '.' + context + '-search',
1066                itemValue      = '.' + context + '-item-value',
1067                item           = '.' + context + '-item',
1068                clear          = '.form-clear',
1069                inputSelected  = 'input-group-selected',
1070                $searchWrapper = $(searchWrapper);
1071
1072            if ($searchWrapper.length === 0) {
1073                return;
1074            }
1075            $searchWrapper.each((i, itemWrapper) => {
1076                $(itemWrapper).find(searchInput).on('input', function () {
1077                    filterSearch($(itemWrapper));
1078                    $(itemWrapper).find('.collapse').collapse('show');
1079                }).on('keydown', e => {
1080                    if (e.key === 'Escape') {
1081                        e.stopPropagation();
1082                    }
1083                });
1084            });
1085            $(searchWrapper + ' ' + clear).on('click', function() {
1086                $(this).prev().val('');
1087                $(this).addClass('d-none');
1088                filterSearch($(this).closest(searchWrapper));
1089            });
1090            $(searchInput).on('focusin', function() {
1091                $(this).closest(searchWrapper).addClass(inputSelected);
1092            }).on('focusout', function() {
1093                $(this).closest(searchWrapper).removeClass(inputSelected);
1094            });
1095
1096            function filterSearch (itemWrapper) {
1097                let searchTerm = itemWrapper.find(searchInput).val().toLowerCase();
1098                itemWrapper.find(itemValue).each((i, itemTMP) => {
1099                    itemTMP = $(itemTMP);
1100                    let text = itemTMP.text().toLowerCase();
1101                    if (text.indexOf(searchTerm) === -1) {
1102                        itemTMP.closest(item).hide();
1103                    } else {
1104                        itemTMP.closest(item).show();
1105                    }
1106                    if (searchTerm.length === 0) {
1107                        itemWrapper.find(clear).addClass('d-none');
1108                    } else {
1109                        itemWrapper.find(clear).removeClass('d-none');
1110                    }
1111                });
1112            }
1113        },
1114
1115        initSliders: function() {
1116            let wrapper  = '.js-slider-wrapper',
1117                buttonF  = '.js-btn-slider-sf',
1118                buttonB  = '.js-btn-slider-sb',
1119                items    = '.js-slider-items';
1120
1121            $(wrapper).each(function (e) {
1122                let $buttonF   = $(this).find(buttonF),
1123                    $buttonB   = $(this).find(buttonB),
1124                    $items     = $(this).find(items);
1125
1126                $buttonF.on('click', function () {
1127                    $items.animate(
1128                        { scrollLeft: $items.scrollLeft() + $items.width() },
1129                        300,
1130                        'swing',
1131                        function () {
1132                            checkButtonDisable($buttonB, $buttonF, $items);
1133                        });
1134                });
1135                $buttonB.on('click', function () {
1136                    $items.animate(
1137                        { scrollLeft: $items.scrollLeft() - $items.width() },
1138                        300,
1139                        'swing',
1140                        function () {
1141                            checkButtonDisable($buttonB, $buttonF, $items);
1142                        });
1143                });
1144                $items.on('touchend', function (e) {
1145                    checkButtonDisable($buttonB, $buttonF, $items);
1146                });
1147            });
1148
1149            function checkButtonDisable($buttonB, $buttonF, $items) {
1150                let currentScroll = $items.scrollLeft();
1151                if (currentScroll <= 1) {
1152                    $buttonB.prop('disabled', true);
1153                } else {
1154                    $buttonB.prop('disabled', false);
1155                }
1156                if (currentScroll >= $items[0].scrollWidth - $items.width()) {
1157                    $buttonF.prop('disabled', true);
1158                } else {
1159                    $buttonF.prop('disabled', false);
1160                }
1161            }
1162        },
1163
1164        initSwatchFocus: function($wrapper) {
1165            $('.swatches-image>input, .swatches-text>input', $wrapper).on('focusin', function () {
1166                $(this).parent('label').addClass('focus');
1167            }).on('focusout', function () {
1168                $(this).parent('label').removeClass('focus');
1169            });
1170        },
1171
1172        registerImageHover: function($wrapper) {
1173            $(window).on("load resize", function() {
1174                let productWrapper = $('.product-wrapper');
1175                $.each(productWrapper, function() {
1176                    // Skip if element is inside a closed collapse.
1177                    let collapse = $(this).closest('.collapse');
1178                    if (collapse.length === 0 || collapse.hasClass('show')) {
1179                        let boxHeight = $(this).height()
1180                        $(this).height(boxHeight);
1181                    }
1182                })
1183            })
1184        },
1185
1186        /**
1187         * $.evo.extended() is deprecated, please use $.evo instead
1188         */
1189        extended: function() {
1190            return $.evo;
1191        },
1192
1193        register: function() {
1194            this.productTabsPriceFlow();
1195            this.generateSlickSlider();
1196            setTimeout(() => {
1197                $('.nav-tabs').tabdrop();
1198            }, 200);
1199            this.tooltips();
1200            this.popupDep();
1201            this.popover();
1202            this.addCartBtnAnimation();
1203            this.checkout();
1204            if ($('body').data('page') == 3) {
1205                this.addInactivityCheck('#cart-form',500,true);
1206            }
1207            this.fixStickyElements();
1208            this.setWishlistVisibilitySwitches();
1209            this.setDeliveryAdressDefaultSwitches();
1210            this.initEModals();
1211            $.evo.article().initConfigListeners();
1212            this.initScrollEvents();
1213            this.initSkipToScroll();
1214            this.initReviewHelpful();
1215            this.initWishlist();
1216            this.initPaginationEvents();
1217            this.initFilterEvents();
1218            this.initItemSearch('filter');
1219            this.initSliders();
1220            this.initSwatchFocus();
1221            this.registerImageHover();
1222            this.wireUpPRGLinks();
1223        },
1224
1225        wireUpPRGLinks()
1226        {
1227            for (const prgLink of document.querySelectorAll('[data-prg-href]')) {
1228                prgLink.addEventListener('click', e => {
1229                    e.preventDefault();
1230                    let targetUrl = atob(prgLink.dataset.prgHref);
1231                    let urlInput = document.createElement('input');
1232                    let virtualForm = document.createElement('form');
1233                    document.body.append(virtualForm);
1234                    urlInput.name = 'prgTargetUrl';
1235                    urlInput.value = targetUrl;
1236                    virtualForm.action = window.jtlShopBaseUrl + '/prg';
1237                    virtualForm.method = 'post';
1238                    virtualForm.append(urlInput);
1239                    virtualForm.submit();
1240                });
1241            }
1242        },
1243    };
1244
1245    $(document).ready(function () {
1246        $.evo.register();
1247    });
1248
1249    // PLUGIN DEFINITION
1250    // =================
1251    $.evo = new EvoClass();
1252})(jQuery);
1253
1254function g_recaptcha_callback() {
1255    $.evo.renderCaptcha();
1256}

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.