PageSourceSearch

https://aspro-rus.ru/local/templates/aspro/js/custom.js?178593981234541

js aspro-rus.ru collected 2026-10-01 14:10:32 UTC 34,541 bytes, 1,079 lines download raw bytes

1$(function () {
2  $(document).on('click', '.js-remove-compare', function () {
3    let params = {
4      'id': $(this).data('prod'),
5      "action": "DELETE_FROM_COMPARE_LIST"
6    };
7
8    $.get("/local/ajax/compare/addToCompare.php", params, function (response) {
9      updateSmallCompare();
10    });
11  });
12
13  $(document).on('click', '.js-add2compare', function () {
14    let params = { 'id': $(this).data('prod') };
15    if ($(this).hasClass('active')) {
16      params["action"] = "DELETE_FROM_COMPARE_LIST" ;
17    } else {
18      params["action"] = "ADD_TO_COMPARE_LIST";
19    }
20
21    $(this).toggleClass('active');
22
23    $.get("/local/ajax/compare/addToCompare.php", params, function (response) {
24      updateSmallCompare()
25    });
26  });
27
28  $(document).on('click', '.js-add2favorite', function () {
29    let isFavPage = $(this).data("fav-page");
30    let $this = $(this);
31    $this.toggleClass('active');
32
33    let fType = '';
34    if ($this.hasClass('active')) {
35      fType = 'add';
36    } else {
37      fType = 'del';
38    }
39
40    $.post("/local/ajax/favorite.php", {
41      "fid": $this.data('prod'),
42      'type': fType
43    }, function (data) {
44      if (isFavPage == "1" && fType == 'del') {
45        const $list = $this.closest('.js-list');
46
47        $this.closest(".js-item").remove();
48
49        if (!$list.find(".js-item").length) {
50          location.reload();
51        }
52      }
53
54      if (fType == 'add') {
55        ym(88897647, 'reachGoal', 'addToFavorite');
56      }
57      updateSmallFavorits();
58    }, "json");
59  });
60
61  $('.js--form-validate-order-element').on('submit', function (e) {
62    e.preventDefault();
63
64    var $this = $(this);
65    var action = $this.attr('action');
66
67    if (!action) {
68      console.log('У формы отсутствует атрибут action, не знаю куда посылать данные');
69      return false;
70    };
71
72    if ( validation.verificationFields($this) ) {
73      console.log('form well done.');
74
75      if (e.target.classList.contains('order-element')) {
76        var formData = new FormData($this[0]);
77        $.ajax({
78          'type': "POST",
79          'enctype': 'multipart/form-data',
80          'dataType': "json",
81          'url': '/local/components/custom/feedback/templates/.default/ajax.php',
82          'data': formData,
83          'processData': false,
84          'contentType': false,
85          'cache': false,
86          success: function (data) {
87            console.log("SUCCESS : ", data);
88
89            if(data.error == 1) {
90
91            }
92            if (data.success == 1) {
93              // validation.resetForm($this);
94              $.modal.close();
95            }
96          },
97          error: function (e) {
98            console.log("ERROR : ", e);
99          }
100        });
101      }
102
103      validation.resetForm($this);
104    };
105
106    return false;
107  });
108
109
110  $(document).on("click",".js-download", function(){
111    if (typeof ym === 'function') {
112      ym(88897647,'reachGoal','download_files');
113    }
114  });
115
116  $(document).on("click",".js-download", function(){
117    if (typeof ym === 'function') {
118      ym(88897647,'reachGoal','download_files');
119    }
120  });
121
122  $(document).on("click", ".jsCatalogAsproItem object a.bitem__footer", function(){
123    if (typeof ym === 'function') {
124      ym(88897647,'reachGoal','addToCart');
125    }
126  });
127  $(document).on("click", ".js-add2cart", function(){
128    if (typeof ym === 'function') {
129      ym(88897647,'reachGoal','addToCart');
130    }
131  });
132
133
134
135  $(document).on('click', '.js-add2cartItem', function(){
136    let prod = $(this).data('prod');
137    let count = 1;
138    let block = $(this);
139    console.log("wewewewe3333333");
140    $.post("/local/ajax/add2cartItem.php", {prod:prod, count:count}, function(data){
141      console.log(data);
142      console.log(data.result);
143      if(data.result == 1) {
144        // block.text('В корзине');
145        // setTimeout(function () {
146        //   block.html('<svg class="icon icon--24"><use xlink:href="#icon-plus"></use></svg>Купить');
147        // }, 2000);
148
149        console.log(window.location.href);
150        console.log(window.location.pathname);
151
152        BX.onCustomEvent('OnBasketChange');
153
154        if (window.location.pathname == "/personal/cart/") {
155          $.ajax({
156            url: window.location.pathname,
157            context: document.body,
158            data: {AJAX_REQUEST: 'Y'},
159            success: function (data2) {
160              $('#basket-main-container').html(data2);
161            }
162          });
163        }
164      }
165  }, "json");
166  });
167
168
169  $('#header-search a.js-header-search-to-page').click(function(event){
170    event.preventDefault(); // Предотвращаем стандартное поведение ссылки
171    var query = $('#header-search input[name="q"]').val();
171 // Получаем значение из input с name="q"
172    var newUrl = '/search/';
173    if (query.length >= 2) {
174      newUrl += '?q=' + query; // Формируем новую ссылку с параметром q, если длина строки >= 2
175    }
176    window.location.href = newUrl; // Осуществляем переход по новой ссылке
177  });
178
179
180
181
182    load_more = false;
183    $(window).scroll(function(){
184      //$(document).on('click', '.load_more', function(){
185      if($(".load_more").length && !load_more){
186        var targetContainer = $('.js-list'),          //  Контейнер, в котором хранятся элементы
187            url =  $('.load_more').attr('data-url'),    //  URL, из которого будем брать элементы
188            offset_button = $(".load_more").offset();
189        if (url !== undefined && $(this).scrollTop() >= offset_button.top - $(window).height()) {
190          load_more = true;
191          $.ajax({
192            type: 'GET',
193            url: url,
194            dataType: 'html',
195            success: function(data){
196
197              //  Удаляем старую навигацию
198              $('.load_more').remove();
199
200              var elements = $(data).find('.js-item'),  //  Ищем элементы
201                  pagination = $(data).find('.load_more');//  Ищем навигацию
202
203              targetContainer.append(elements);   //  Добавляем посты в конец контейнера
204              targetContainer.append(pagination); //  добавляем навигацию следом
205              load_more = false;
206              $(window).trigger('resize');
207            }
208          })
209        }
210      }
211    });
212
213    $(document).on('click', ".js-catalog-sort", function(){
214      console.log("url = ", document.location.pathname+document.location.search);
215      let url = document.location.pathname+document.location.search;
216      let targetContainer = $('.js-list');
217
218      let sort = $(this).val();
219      console.log('sort = ', sort);
220
221      $.ajax({
222        type: 'GET',
223        url: url,
224        dataType: 'html',
225        data: {'sort':sort},
226        success: function(data){
227
228          //  Удаляем старую навигацию
229          $('.load_more').remove();
230
231          var elements = $(data).find('.js-item'),  //  Ищем элементы
232              pagination = $(data).find('.load_more');//  Ищем навигацию
233
234          targetContainer.html(elements);   //  Добавляем посты в конец контейнера
235          targetContainer.parent().append(pagination); //  добавляем навигацию следом
236          load_more = false;
237          $(window).trigger('resize');
238        }
239      })
240    });
241
242
243
244
245  // Hero slider buttons visibility
246  var $heroContainer = $('#hero-slider .swiper-container');
247  var $heroNextButton = $('#hero-slider .swiper-button-next');
248  var $heroPrevButton = $('#hero-slider .swiper-button-prev');
249
250  $heroNextButton.on('mouseover', function() {
251    $heroContainer.addClass('show-buttons');
252  });
253
254  $heroContainer.on('mouseout', function() {
255    $heroContainer.removeClass('show-buttons');
256  });
257
258  $heroContainer.on('mouseover', function() {
259    $heroContainer.addClass('show-buttons');
260  });
261
262  $heroContainer.on('mouseout', function() {
263    $heroContainer.removeClass('show-buttons');
264  });
265
266  $heroPrevButton.on('mouseover', function() {
267    $heroContainer.addClass('show-buttons');
268  });
269
270  $heroPrevButton.on('mouseout', function() {
271    $heroContainer.removeClass('show-buttons');
272  });
273
274  // Hits slider buttons visibility
275  var $hitsContainer = $('#hits-slider .swiper-container');
276  var $hitsNextButton = $('#hits-slider .swiper-button-next');
277  var $hitsPrevButton = $('#hits-slider .swiper-button-prev');
278
279  $hitsNextButton.on('mouseover', function() {
280    $hitsContainer.addClass('show-buttons');
281  });
282
283  $hitsContainer.on('mouseout', function() {
284    $hitsContainer.removeClass('show-buttons');
285  });
286
287  $hitsContainer.on('mouseover', function() {
288    $hitsContainer.addClass('show-buttons');
289  });
290
291  $hitsContainer.on('mouseout', function() {
292    $hitsContainer.removeClass('show-buttons');
293  });
294
295  $hitsPrevButton.on('mouseover', function() {
296    $hitsContainer.addClass('show-buttons');
297  });
298
299  $hitsPrevButton.on('mouseout', function() {
300    $hitsContainer.removeClass('show-buttons');
301  });
302
303
304  $(document).on("click", "#geo-drop .js--popover-close", function() {
305    // console.log('geo-drop = 1');
306    $("#geo-btn.js-toggle-element").trigger("click");
307    // $(".js-toggle-element-allow-close-all").trigger("toggle-element");
308    // $.modal.close();
309  });
310  $(document).on("toggle-element", "#geo-drop", function (e) {
311    // console.log('geo-drop = 2');
312  });
313
314
315  const swiperWow = '.wow_image__list';
316  if(swiperWow){
317    const swiperMedia = () => new Swiper(swiperWow, {
318      slidesPerView: 1,
319      loop: true,
320      start: 1,
321      autoplay: {
322        delay: 1500,
323      },
324      speed: 400,
325      allowTouchMove:false,
326    });
327    swiperMedia();
328  }
329
330  // Hits slider initialization
331  const hitsSliderContainer = document.querySelector('.hits-swiper-container');
332  if (hitsSliderContainer) {
333    const hitsSwiper = new Swiper(hitsSliderContainer, {
334      slidesPerView: 4,
335      spaceBetween: 16,
336      slidesPerGroup: 3,
337      speed: 600,
338      freeMode: "true",
339      loop: false,
340      navigation: {
341        nextEl: '#hits-slider .swiper-button-next',
342        prevEl: '#hits-slider .swiper-button-prev',
343      },
344      breakpoints: {
345        320: {
346          slidesPerView: 1,
347          spaceBetween: 12
348        },
349        768: {
350          slidesPerView: 2,
351          spaceBetween: 16
352        },
353        1024: {
354          slidesPerView: 3,
355          spaceBetween: 16
356        },
357        1280: {
358          slidesPerView: 4,
359          spaceBetween: 16
360        }
361      },
362      on: {
363        init: function() {
364          // Добавляем класс show-buttons при наведении
365          const container = this.$el;
366          container.on('mouseenter', function() {
367            container.addClass('show-buttons');
368          });
369          container.on('mouseleave', function() {
370            container.removeClass('show-buttons');
371          });
372        }
373      }
374    });
375  }
376
377});
378
379function in_array(value, array) {
380  for (let i = 0; i < array.length; i++) {
381    if (value == array[i]) return true;
382  }
383  return false;
384}
385
386function updateSmallFavorits() {
387  $.post("/local/ajax/getCntFavorites.php", function (data) {
388    const cnt = data.result?.cnt || 0;
389
390    if (cnt > 0) $('#favCnt').html(cnt);
391    else $('#favCnt').html('');
392  }, "json");
393}
394
395function updateSmallCompare() {
396  $.post("/local/ajax/getCntCompare.php", function (data) {
397    if (data.cnt > 0) $('#compareCnt').html(data.cnt);
398    else $('#compareCnt').html('');
399  }, "json");
400}
401
402// document.addEventListener('DOMContentLoaded', function() {
403//   const oldVersionSite = document.querySelector('.old-version-site');
404//   const link = oldVersionSite.querySelector('a');
405//
406//   if (window.innerWidth <= 768) {
407//     oldVersionSite.addEventListener('click', function(event) {
408//       if (!oldVersionSite.classList.contains('expanded')) {
409//         event.preventDefault();
410//         oldVersionSite.classList.add('expanded');
411//       } else {
412//         link.click();
413//       }
414//     });
415//   }
416// });
417
418$('#header-phone').on('click', function(event) {
419  event.stopPropagation();
420});
421
422$(document).on("click", ".js-user-consent-input", function() {
423  if(!$(this).is(':checked'))
424  {
425    $(this).addClass("error");
426  }
427  else if($(this).is(':checked'))
428  {
429    $(this).removeClass("error");
430  }
431});
432
433function fixHeroSliders() {
434    const sliderIds = ['hero-slider', 'hero-slider-mob', 'hits-slider'];
435
436    sliderIds.forEach(sliderId => {
437        const container = document.querySelector(`#${sliderId} .swiper-container`);
438        if (!container) return;
439
440        // Проверка видимости
441        const rect = container.getBoundingClientRect();
442        if (rect.width === 0 || rect.height === 0) return;
443
444        if (!container.swiper) return;
445
446        const swiper = container.swiper;
447
448        // обновляем размеры слайдов
449        swiper.update();
450
451        // оставляем активный слайд видимым
452        swiper.slideTo(swiper.realIndex, 0);
453
454        // обновляем картинки через customUpdateSliderMain, если есть
455        if (typeof customUpdateSliderMain === 'function') {
456            customUpdateSliderMain();
457        }
458    });
459}
460
461window.addEventListener('resize', fixHeroSliders);
462window.addEventListener('orientationchange', function() {
463    setTimeout(fixHeroSliders, 300);
464});
465document.addEventListener('DOMContentLoaded', fixHeroSliders);
466
467 // Автоматическое переключение карты на город при поиске
468$(function() {
469  var mapSearchTimeout;
470  $('body').on('input change', '.js--map-info-search-input', function(e){
471    var $input = $(this);
472    var val = $input.val().trim().toLowerCase();
473
474    clearTimeout(mapSearchTimeout);
475
476    if (val.length >= 2) {
477      mapSearchTimeout = setTimeout(function() {
478        var $activeTab = $('.map-info__tab.active');
479        var $items = $activeTab.find('.js--map-placemark-item');
480
481        var $filteredItems = $items.filter(function(ind, el) {
482          var text = $(el).find('.cities__item-btn-txt').text().toLowerCase();
483          return text.includes(val);
484        });
485
486        // Автоматически переключаемся на город, когда остается только один уникальный в результате поиска
487        if ($filteredItems.length > 0) {
488          // Собираем уникальные названия городов
489          var uniqueCities = {};
490          $filteredItems.each(function() {
491            var cityName = $(this).find('.cities__item-btn-txt').text().toLowerCase().trim();
492            if (!uniqueCities[cityName]) {
493              uniqueCities[cityName] = $(this);
494            }
495          });
496
497          // Переключаемся только если остался один уникальный город
498          var uniqueCityNames = Object.keys(uniqueCities);
499          if (uniqueCityNames.length === 1) {
500            var $firstFilteredItem = uniqueCities[uniqueCityNames[0]];
501            var $placemarkInfo = $firstFilteredItem.find('.js--map-placemark-info').first();
502
503            if ($placemarkInfo.length > 0) {
504              var lat = $placemarkInfo.data('lat');
505              var lon = $placemarkInfo.data('lon');
506              var myMap = $('#mapShops').data('map');
507
508              if (myMap && lat && lon) {
509                myMap.balloon.close();
510                myMap.setZoom(10);
511                myMap.panTo([lat, lon], {
512                  flying: true
513                });
514              }
515            }
516          }
517        }
518      }, 250);
519    }
520  });
521});
522
523// Функция для установки высоты затемнений слайдера по высоте bitem__bg
524function setSimilarSliderOverlayHeight() {
525    const sliders = document.querySelectorAll('.slider--similar-item, .slider--actions');
526
527    sliders.forEach(slider => {
528        const swiperContainer = slider.querySelector('.swiper-container');
529        const bitemBg = slider.querySelector('.bitem__bg');
530
531        if (swiperContainer && bitemBg) {
532            const height = bitemBg.offsetHeight;
533            // Устанавливаем CSS переменную для высоты
534            swiperContainer.style.setProperty('--overlay-height', height + 'px');
535        }
536    });
537}
538
539// Обновляем высоту при загрузке, ресайзе и после инициализации слайдеров
540document.addEventListener('DOMContentLoaded', setSimilarSliderOverlayHeight);
541window.addEventListener('resize', setSimilarSliderOverlayHeight);
542window.addEventListener('load', setSimilarSliderOverlayHeight);
543
544// Если используется Swiper, обновляем после инициализации
545if (typeof Swiper !== 'undefined') {
546    document.addEventListener('DOMContentLoaded', function() {
547        setTimeout(setSimilarSliderOverlayHeight, 500);
548    });
549}
550
551// Функция для синхронизации высоты вертикального блока с высотой изображения статьи
552function syncArticleSidebarHeight() {
553    const articleImg = document.querySelector('.blog-article--img.blog-article--img-rounded.mt-0');
554    const verticalBg = document.querySelector('.bitem__bg.bitem__bg--vertical');
555
556    if (articleImg && verticalBg) {
557        const imgHeight = articleImg.offsetHeight;
558        verticalBg.style.height = imgHeight + 'px';
559    }
560}
561
562// Обновляем высоту при различных событиях
563document.addEventListener('DOMContentLoaded', syncArticleSidebarHeight);
564window.addEventListener('load', syncArticleSidebarHeight);
565window.addEventListener('resize', syncArticleSidebarHeight);
566
567// Дополнительное обновление с небольшой задержкой для подгрузки изображений
568if (document.readyState === 'loading') {
569    document.addEventListener('DOMContentLoaded', function() {
570        setTimeout(syncArticleSidebarHeight, 300);
571        setTimeout(syncArticleSidebarHeight, 1000);
572    });
573} else {
574    setTimeout(syncArticleSidebarHeight, 300);
575    setTimeout(syncArticleSidebarHeight, 1000);
576}
577
578////////////////////////////////////////////////////////////
579document.addEventListener("DOMContentLoaded", function () {
580
581  const TEL_SELECTOR = "[data-mask=tel]";
582  const BAD_SELECTOR = ".js--reg-input-tel";
583
584  // console.log("[tel-fix] init");
585
586  // ==============================
587  // 1️⃣ ОТКЛЮЧАЕМ ЛОМАЮЩИЙ input HANDLER
588  // ==============================
589  try {
590    $("body").off("input", BAD_SELECTOR);
591    // console.log("[tel-fix] bad input handler disabled");
592  } catch(e) {}
593
594  // ==============================
595  // 2️⃣ ЗАЩИТА ОТ ВНЕШНЕЙ .val() ПЕРЕЗАПИСИ
596  // ==============================
597  const originalVal = $.fn.val;
598
599  $.fn.val = function(value) {
600    // setter
601    if (arguments.length && this.is(TEL_SELECTOR)) {
602      const el = this[0];
603
604      // если input под управлением Inputmask — не даём ломать value
605      if (el && el.inputmask) {
606        return this;
607      }
608    }
609
610    return originalVal.apply(this, arguments);
611  };
612
613  // console.log("[tel-fix] jQuery .val protected");
614
615  // ==============================
616  // 3️⃣ ПЕРЕИНИЦИАЛИЗАЦИЯ INPUTMASK
617  // ==============================
618  function reinitMask() {
619    $(TEL_SELECTOR).each(function () {
620      const $input = $(this);
621
622      try { $input.inputmask("remove"); } catch(e) {}
623
624      $input.inputmask({
625        mask: "+7 (999) 999-99-99",
626        clearIncomplete: true,
627        showMaskOnHover: false,
628        showMaskOnFocus: true,
629        placeholder: "_",
630        inputmode: "tel"
631      });
632    });
633
634    // console.log("[tel-fix] mask reinit");
635  }
636
637  reinitMask();
638
639  // ==============================
640  // 4️⃣ ПЕРЕЗАПУСК ПРИ MODAL / AJAX (BITRIX)
641  // ==============================
642  $(document).on("modal:open shown.bs.modal ajaxComplete", function () {
643    reinitMask();
644  });
645
646});
647
648$(function() {
649  mapInitShops();
650
651  recalculateBlockPaddingsWhenNotificationPresent();
652
653  // Корректируем sticky-секцию после того, как скомпилированный JS установил top
654  setTimeout(adjustStickyTopForNotification, 200);
655  $(window).on('scroll', adjustStickyTopForNotificationThrottled);
656  $(window).on('resize', adjustStickyTopForNotificationThrottled);
657});
658function mapInitShops(){
659  var inputTimeout;
660
661  console.log("mapShops", $('#mapShops'));
662  if ( $('#mapShops').length ) {
663
664    // Перемещаем карту в другое место на мобилке
665    if ( window.matchMedia("(max-width: 767px)").matches ) {
666      $('#mapShops').appendTo($('.map-wrap-mobile'));
667    }
668
669    ymaps.ready(initMap);
670
671    function initMap() {
672      var centerCoor = [55.7522, 37.6156]; //Москва
673
674      $('#mapShops').data('map', new ymaps.Map("mapShops", {
675        center: centerCoor,
676        zoom: 5,
677        controls: [],
678      }));
679
680      var myMap = $('#mapShops').data('map');
681
682      var MyBalloonLayout = ymaps.templateLayoutFactory.createClass(
683          '<div class="map-balloon">' +
684          '$[[options.contentLayout]]' +
685          '</div>', {
686
687            build: function () {
688              this.constructor.superclass.build.call(this);
689
690              this._$element = $('.map-balloon', this.getParentElement());
691
692              this.applyElementOffset();
693            },
694
695            clear: function () {
696              this.constructor.superclass.clear.call(this);
697            },
698
699            onSublayoutSizeChange: function () {
700              MyBalloonLayout.superclass.onSublayoutSizeChange.apply(this, arguments);
701
702              if(!this._isElement(this._$element)) {
703                return;
704              }
705
706              this.applyElementOffset();
707
708              this.events.fire('shapechange');
709            },
710
711            applyElementOffset: function () {
712              var arrowH = 12; // Высота стрелочки балуна
713
714              this._$element.css({
715                left: -(this._$element[0].offsetWidth / 2),
716                top: -(this._$element[0].offsetHeight + arrowH)
717              });
718            },
719
720            getShape: function () {
721              if(!this._isElement(this._$element)) {
722                return MyBalloonLayout.superclass.getShape.call(this);
723              }
724
725              var position = this._$element.position();
726              var arrowH   = 12; // Высота стрелочки балуна
727
728              return new ymaps.shape.Rectangle(new ymaps.geometry.pixel.Rectangle([
729                [position.left, position.top], [
730                  position.left + this._$element[0].offsetWidth,
731                  position.top + this._$element[0].offsetHeight + arrowH
732                ]
733              ]));
734            },
735
736            _isElement: function (element) {
737              return element && element[0];
738            }
739          }
740      );
741
742      var MyBalloonContentLayout = ymaps.templateLayoutFactory.createClass(
743          '<h3 class="map-balloon__title">$[properties.balloonTitle]</h3>' +
744          '<div class="map-balloon__desc">$[properties.balloondesc]</div>'
745      );
746
747      // Закрываем балун по клику на карте
748      myMap.events.add('click', function (e) {
749        myMap.balloon.close();
750      });
751
752      // Собираем все маркеры с активного таба
753      $('.map-info__tab.active .js--map-placemark-info').each(function(){
754        var $t  = $(this);
755        var data   = {
756          coords  : [$t.data('lat'), $t.data('lon')],
757          title   : $t.data('balloon-title'),
758          desc    : $t.data('balloon-desc'),
759          type    : $t.data('type'),
760          isHidden: $t.data('hidden')
761        }
762
763        createMapPin(data);
764      });
765
766      // Если в хеше были координаты
767      if ( location.hash ) {
768        let hash   = location.hash;
769        let YMhash = hash.split("?").filter((el)=>el.includes('YM-'));
770
771        if ( YMhash.length ) {
772          YMhash = YMhash[0].replace('YM-', '');
773
774          let lat  = +YMhash.split('_')[0].replace('lat=', '');
775          let long = +YMhash.split('_')[1].replace('long=', '');
776
777          myMap.setZoom(10);
778
779          myMap.panTo([lat, long], {
780            flying: true
781          });
782        }
783      }
784
785      function createMapPin(data){
786        var placemark = new ymaps.Placemark(data.coords, {
787          balloonTitle: data.title,
788          balloondesc: data.desc
789        }, {
790          iconLayout: 'default#image',
791          iconImageHref: './svg/icon-map-pin-v2.svg',
792          iconImageSize: [24, 27],
793          iconImageOffset: [-12, -27],
794          balloonShadow: false,
795          balloonLayout: MyBalloonLayout,
796          balloonContentLayout: MyBalloonContentLayout,
797          balloonPanelMaxMapArea: 0
798        });
799
800        myMap.geoObjects.add(placemark);
801      }
802    };
803
804    function reInitMap() {
805      // console.log('map = ', $('#map'));
806      if ( $('#mapShops').data('map') ) {
807        $('#mapShops').data('map').destroy();
808        initMap();
809      }
810    };
811
812    $('.map-info__nav').on('tab-changed', function(){
813      // console.log('tab-changed: ', this);
814      var $activeTab = $('.map-info__tab.active');
815      var $items     = $activeTab.find('.js--map-placemark-item');
816      var $searchInp = $activeTab.find('.js--map-info-search-input');
817      var $errorMsg  = $activeTab.find('.map-info__content-msg');
818
819      // console.log('$activeTab = ', $activeTab);
820      // console.log('$items = ', $items);
821      // console.log('$searchInp = ', $searchInp);
822      // console.log('$errorMsg = ', $errorMsg);
823      reInitMap();
824      if ( $('#delivery-map').length ) {
825        reInitDeliveryMap();
826      }
827      if ( $('#delivery-map-2').length ) {
828        reInitDeliveryMap2()
829      }
830
831      $items.filter('.cities__item_top').removeClass('hidden');
832      $searchInp.val('');
833      $errorMsg.removeClass('active');
834    });
835
836    // Фильтруем список
837    $('body').on('input change', '.js--map-info-search-input', function(e){
838      var $t         = $(this);
839      var val        = $t.val().trim().toLowerCase();
840      var $activeTab = $('.map-info__tab.active');
841      var $items     = $activeTab.find('.js--map-placemark-item');
842      var $errorMsg  = $activeTab.find('.map-info__content-msg');
843
844      clearTimeout(inputTimeout);
845
846      if ( val.length >= 2 ) {
847
848        inputTimeout = setTimeout(() => {
849
850          var $filteredItems = $items.filter(function(ind, el) {
851            var text = $(el).find('.cities__item-btn-txt').text().toLowerCase();
852
853            return text.includes(val);
854          });
855
856          $filteredItems.removeClass('hidden');
857          $items.not($filteredItems).addClass('hidden');
858
859          ( !$items.not('.hidden').length ) ? $errorMsg.addClass('active') : $errorMsg.removeClass('active');
860        }, 200);
861      }
862
863      if ( val == "" ) {
864        $errorMsg.removeClass('active');
865        $items.removeClass('hidden');
866      }
867    });
868
869    // Клик по кнопке -посмотреть все-
870    $('body').on('click', '.js--map-info-show-full-btn', function(e){
871      e.preventDefault();
872
873      gotoObject($('#contacts-general-list-c'));
874    });
875
876    // Клик по информации на итемах около карты
877    $('body').on('click', '.js--map-placemark-info', function(e){
878      var $t      = $(this);
879      var lat     = $t.data('lat');
880      var lon     = $t.data('lon');
881      var myMap   = $('#mapShops').data('map');
882
883      if ( !myMap || !lat || !lon ) return;
884
885      myMap.balloon.close();
886      myMap.setZoom(10);
887
888      myMap.panTo([lat, lon], {
889        flying: true
890      });
891    });
892  };
893
894  if ( $('#delivery-map').length ) {
895    ymaps.ready(initDeliveryMap);
896
897    function initDeliveryMap() {
898      var centerCoor = [55.7522, 37.6156]; //Москва
899
900      $('#delivery-map').data('map', new ymaps.Map("delivery-map", {
901        center: centerCoor,
902        zoom: 5,
903        controls: [],
904      }));
905
906      var myMap = $('#delivery-map').data('map');
907    };
908
909    function reInitDeliveryMap() {
910      if ( $('#deliverymap').data('map') ) {
911        $('#deliverymap').data('map').destroy();
912        initDeliveryMap();
913      }
914    };
915  }
916
917  if ( $('#delivery-map-2').length ) {
918    ymaps.ready(initDeliveryMap2);
919
920    function initDeliveryMap2() {
921      var centerCoor = [55.7522, 37.6156]; //Москва
922
923      $('#delivery-map-2').data('map', new ymaps.Map("delivery-map-2", {
924        center: centerCoor,
925        zoom: 5,
926        controls: [],
927      }));
928
929      var myMap = $('#delivery-map-2').data('map');
930    };
931
932    function reInitDeliveryMap2() {
933      if ( $('#deliverymap-2').data('map') ) {
934        $('#deliverymap-2').data('map').destroy();
935        initDeliveryMap2();
936      }
937    };
938  }
939
940  if ( $('#address-map').length ) {
941    ymaps.ready(initAdressMap);
942
943    function initAdressMap() {
944      var centerCoor    = [55.7522, 37.6156]; //Москва
945      var $addressInput = $('.js--address-input');
946      var myPlacemark;
947      var myMap;
948
949      $('#address-map').data('map', new ymaps.Map('address-map', {
950        center: centerCoor,
951        zoom: 5,
952        controls: ['zoomControl', 'searchControl', 'fullscreenControl']
953      }, {
954        searchControlProvider: 'yandex#map',
955        yandexMapDisablePoiInteractivity: true
956      }));
957
958      var myMap = $('#address-map').data('map');
959
960      // Слушаем клик на карте.
961      myMap.events.add('click', function (e) {
962        var coords = e.get('coords');
963
964        // Если метка уже создана – просто передвигаем ее.
965        if (myPlacemark) {
966          myPlacemark.geometry.setCoordinates(coords);
967        }
968        // Если нет – создаем.
969        else {
970          myPlacemark = createPlacemark(coords);
971          myMap.geoObjects.add(myPlacemark);
972          // Слушаем событие окончания перетаскивания на метке.
973          myPlacemark.events.add('dragend', function () {
974            getAddress(myPlacemark.geometry.getCoordinates());
975          });
976        }
977        getAddress(coords);
978      });
979
980      // Создание метки.
981      function createPlacemark(coords) {
982        return new ymaps.Placemark(coords, {}, {
983          iconLayout: 'default#image',
984          iconImageHref: './svg/icon-map-pin-v2.svg',
985          iconImageSize: [24, 27],
986          iconImageOffset: [-12, -27]
987        });
988      }
989
990      // Определяем адрес по координатам (обратное геокодирование).
991      function getAddress(coords) {
992        ymaps.geocode(coords).then(function (res) {
993          var firstGeoObject = res.geoObjects.get(0);
994          var address        = firstGeoObject.getAddressLine();
995
996          $addressInput.val(address);
997        });
998      }
999    };
1000  }
1001}
1002
1003// Отмена анимации .small-top-notification при переключении меню
1004window.toggleMenu = function(el) {
1005  const $target = $(".js-menu-switcher-target");
1006  $target.toggleClass("menu-overlay-active");
1007
1008  if ($target.hasClass("menu-overlay-active")) {
1009    if (window.matchMedia("(max-width: 767px)").matches) {
1010      if (typeof addBodyFixedOverflow === 'function') {
1011        addBodyFixedOverflow();
1012      }
1013      $('.foot-fix-menu__btn.js-menu-switcher').addClass("active");
1014    }
1015    // $smNotification.slideUp(200); // Отменено
1016  } else {
1017    if (window.matchMedia("(max-width: 767px)").matches) {
1018      if (typeof removeBodyFixedOverflow === 'function') {
1019        removeBodyFixedOverflow();
1020      }
1021      $('.foot-fix-menu__btn.js-menu-switcher').removeClass('active');
1022    }
1023    /* // Отменено
1024    setTimeout(function() {
1025        $smNotification.slideDown(200);
1026    }, 400);
1027    */
1028  }
1029};
1030/* пересчитать отступы блоков, когда уведомление присутствует */
1031recalculateBlockPaddingsWhenNotificationPresent = function() {
1032  let blockNotification = $(".small-top-notification");
1033  let isNotif =  (blockNotification.length > 0) ? true : false;
1034
1035  if(isNotif) {
1036    $(".small-top-notification ~ header.header").css({"top": blockNotification.outerHeight()+"px"});
1037  }
1038
1039  // Также корректируем sticky-секцию сразу после загрузки
1040  adjustStickyTopForNotification();
1041};
1042
1043/**
1044 * Корректирует CSS-свойство top для плавающей секции
1045 * .section--sticky.js-goto-offset с учётом высоты .small-top-notification.
1046 *
1047 * Скомпилированный JS (build-noncritical.js) рассчитывает top только
1048 * от высоты header'а. Здесь мы добавляем высоту уведомления.
1049 */
1050function adjustStickyTopForNotification() {
1051  var $sticky = $('.section--sticky.js-goto-offset.mobile-hide');
1052  if (!$sticky.length) return;
1053
1054  var $header = $('header.header');
1055  var headerHeight = $header.length ? $header.outerHeight(true) : 0;
1056  var $notification = $('.small-top-notification');
1057  var notificationHeight = $notification.length ? $notification.outerHeight(true) : 0;
1058
1059  var expectedTop = headerHeight + notificationHeight;
1060  var currentTop = parseInt($sticky.css('top'), 10);
1061
1062  // Обновляем только если значение изменилось (избегаем лишних перерисовок)
1063  if (currentTop !== expectedTop && !isNaN(currentTop)) {
1064    $sticky.css('top', expectedTop + 'px');
1065  }
1066
1067  // Обновляем CSS-переменные для возможного использования в стилях
1068  document.documentElement.style.setProperty('--notification-height', notificationHeight + 'px');
1069  document.documentElement.style.setProperty('--header-height', headerHeight + 'px');
1070}
1071
1072// Throttled-версия для scroll/resize
1073var adjustStickyTopForNotificationThrottled = function() {
1074  if (adjustStickyTopForNotification._rafId) return;
1075  adjustStickyTopForNotification._rafId = requestAnimationFrame(function() {
1076    adjustStickyTopForNotification._rafId = null;
1077    adjustStickyTopForNotification();
1078  });
1079};

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.