PageSourceSearch

https://my.alyans-auto.ru/cabinet/assets/new/scripts/script.js?version=1785763126

js alyans-auto.ru collected 2026-09-24 10:22:00 UTC 62,974 bytes, 2,067 lines download raw bytes

1if (window.Selectize) {
2  Selectize.define('plugin_a', function () {
3    var self = this
4
5    const POSITION = {
6      top: 'top',
7      bottom: 'bottom',
8    }
9
10    self.positionDropdown = (function () {
11      return function () {
12        const $control = this.$control
13        const offset =
14          this.settings.dropdownParent === 'body'
15            ? $control.offset()
16            : $control.position()
17        offset.top += $control.outerHeight(true)
18
19        const dropdownHeight = this.$dropdown.prop('scrollHeight') + 5
20        const controlPosTop = this.$control.get(0).getBoundingClientRect().top
21        const wrapperHeight = this.$wrapper.height()
22        const controlPosBottom = self.$control
23          .get(0)
24          .getBoundingClientRect().bottom
25        const position =
26          controlPosTop + dropdownHeight + wrapperHeight > window.innerHeight &&
27          controlPosBottom - dropdownHeight - wrapperHeight >= 0
28            ? POSITION.top
29            : POSITION.bottom
30        const w =
31          this.$wrapper[0].style.width !== 'fit-content'
32            ? this.settings.dropdownParent === 'body'
33              ? 'max-content'
34              : '100%'
35            : 'max-content'
36        const styles = {
37          width: w,
38          minWidth: $control.outerWidth(true),
39          left: offset.left,
40        }
41
42        if (position === POSITION.top) {
43          const styleToAdd = { bottom: offset.top, top: 'unset' }
44
45          if (this.settings.dropdownParent === 'body') {
46            styleToAdd.top =
47              offset.top -
48              this.$dropdown.outerHeight(true) -
49              $control.outerHeight(true)
50            styleToAdd.bottom = 'unset'
51          }
52          Object.assign(styles, styleToAdd)
53          this.$dropdown.addClass('selectize-position-top')
54          this.$control.addClass('selectize-position-top')
55        } else {
56          Object.assign(styles, { top: offset.top, bottom: 'unset' })
57          this.$dropdown.removeClass('selectize-position-top')
58          this.$control.removeClass('selectize-position-top')
59        }
60
61        if (
62          this.settings.dropdownParent !== 'body' &&
63          w === 'max-content' &&
64          $control.outerWidth(true) >= this.$dropdown.outerWidth(true)
65        ) {
66          w = '100%'
67        }
68        this.$dropdown.css(styles)
69      }
70    })()
71  })
72}
73
74const loader =
75  '<div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div>'
76
77if ($('input[data-mask="phone"]').length) {
78  $('input[data-mask="phone"]').inputmask('mask', {
79    mask: '+7(*99) 999-99-99',
80    clearIncomplete: true,
81    showMaskOnHover: true,
82    showMaskOnFocus: false,
83    definitions: { '*': { validator: '[0-69]' } },
84  })
85}
86
87// * Отпарвка формы с просьбой о помощи
88$('body').on('submit', '.sos-screen__form', function (e) {
89  e.preventDefault()
90  const form = $(this)
91  const route = form.attr('action')
92  let btn = form.find('button.sos-screen__form-submit')
93  let btnOld = btn.html()
94
95  let validateSelect = false
96  let validateInputs = false
97  let validateInputsPass = 0
98  let validatSelectPass = 0
99  let validatSelectCount = form.find('select.validate-select').length
100  let validateInputsCount = form.find('.validate-input').length
101  let validateCheckbox = false
102
103  form.find('.validate-input').each(function () {
104    const element = $(this)
105
106    if (!element.val().length) {
107      element.addClass('validate-error')
108      validateInputsPass--
109    }
110
111    if (
112      element.attr('data-mask') === 'phone' &&
113      element.val().replace(/\D+/g, '').length < 10
114    ) {
115      element.addClass('validate-error')
116      validateInputsPass--
117    }
118
119    validateInputsPass++
120  })
121
122  form.find('select.validate-select').each(function () {
123    const element = $(this)
124    if (!element.val()) {
125      element.data('selectize').$wrapper[0].classList.add('validate-error')
126      validatSelectPass--
127    }
128    validatSelectPass++
129  })
130
131  if (validatSelectPass >= validatSelectCount) validateSelect = true
132  else validateSelect = false
133
134  if (validateInputsPass >= validateInputsCount) validateInputs = true
135  else validateInputs = false
136
137  if (form.find('.form__agree input[type="checkbox"]').is(':checked')) {
138    form
139      .find('.form__agree input[type="checkbox"]')
140      .removeClass('validate-error')
141    validateCheckbox = true
142  } else {
143    form.find('.form__agree input[type="checkbox"]').addClass('validate-error')
144    validateCheckbox = false
145  }
146
147  if (validateSelect && validateInputs && validateCheckbox) {
148    btn
149      .addClass('disable')
150      .css('width', btn.outerWidth() + 'px')
151      .css('height', btn.outerHeight() + 'px')
152      .html(loader)
153    const data = {
154      sosService: form.find('select.validate-select[name="sos-problem]').val(),
155      sosComment: form.find('.validate-select[name="sos-comment"]').val(),
156      sosPhone: form.find('.validate-select[name="sos-phone"]').val(),
157    }
158
159    $.ajax({
160      url: route,
161      method: 'GET',
162      data: data,
163      success() {
164        btn.html(btnOld)
165        form.trigger('reset')
166        form.find('select.validate-select').get(0).selectize.clear()
167      },
168      error() {
169        btn.html(btnOld)
170      },
171    })
172  }
173})
174
175$('body').on('focus click change', '.validate-error', function () {
176  $(this).removeClass('validate-error')
177  $(this).parent().find('.form-error-message').remove()
178})
179
180// * Классы для модалки помошь на дороге
181
182const CLASS = {
183  screenHide: 'sos-screen_hidden',
184  screenShow: 'sos-screen_shown',
185  screenReturnShow: 'sos-modal__return_shown',
186  sosModalShow: 'sos-modal_shown',
187  sosModalVisible: 'sos-modal_visible',
188}
189
190// * Показывает форму отправки о помоще на дороге
191function showScreen2() {
192  $('.sos-screen_first')
193    .addClass(CLASS.screenHide)
194    .removeClass(CLASS.screenShow)
195  $('.sos-screen_second')
196    .addClass(CLASS.screenShow)
197    .removeClass(CLASS.screenHide)
198  $('.sos-modal__return').addClass(CLASS.screenReturnShow)
199}
200
201function hideScreen2() {
202  $('.sos-screen_first')
203    .removeClass(CLASS.screenShow)
204    .removeClass(CLASS.screenHide)
205  $('.sos-screen_second')
206    .removeClass(CLASS.screenHide)
207    .removeClass(CLASS.screenShow)
208  $('.sos-modal__return').removeClass(CLASS.screenReturnShow)
209
210  $('.sos-screen__form').trigger('reset')
211}
212
213$('body').on('click', '.sos-screen__clarify', function () {
214  showScreen2()
215})
216
217$('body').on('click', '.sos-modal__return', function () {
218  hideScreen2()
219})
220
221function showSosModal() {
222  $('.sos-modal').addClass(CLASS.sosModalShow)
223  setTimeout(() => {
224    $('.sos-modal').addClass(CLASS.sosModalVisible)
225  }, 0)
226}
227
228function hideSosModal() {
229  $('.sos-modal').removeClass(CLASS.sosModalVisible)
230  setTimeout(() => {
231    $('.sos-modal').removeClass(CLASS.sosModalShow)
232    hideScreen2()
233  }, 300)
234}
235
236$('.header-sos').on('click', function (e) {
237  showSosModal()
238})
239
240$('.sos-modal__close').on('click', function () {
241  hideSosModal()
242})
243
244// * Скрывает модалки при клике вне блока
245$(document).mouseup(function (e) {
246  let isFocus = false
247  $('.form__inp').each(function () {
248    if ($(this).is(':focus')) isFocus = true
249  })
250
251  let sosTarget = $('.header-sos, .sos-container')
252
253  if (
254    !isFocus &&
255    !sosTarget.is(e.target) &&
256    sosTarget.has(e.target).length === 0
257  ) {
258    hideSosModal()
259  }
260
261  let lkTarget = $('.lk-modal__container, .profile-lk__phone-change')
262
263  if (
264    !isFocus &&
265    !lkTarget.is(e.target) &&
266    lkTarget.has(e.target).length === 0
267  ) {
268    hideViews()
269  }
270})
271
272// * Подсвечивает звезды при ховере
273$('.star').on('mouseenter', function () {
274  const element = $(this)
275  const elementIndex = element.index()
276  if (!$('.stars').hasClass('star_selected')) {
277    $('.star').removeClass('active')
278    $('.star').each(function (index) {
279      if (index <= elementIndex) {
280        $(this).addClass('active')
281      }
282    })
283  } else {
284    $('.star').removeClass('active active_old')
285    $('.star').each(function (index) {
286      if (index < Number($('.stars').attr('data-score-selected'))) {
287        $(this).addClass('active_old')
288      }
289      if (index <= elementIndex) {
290        $('.star').removeClass('active_old')
291        $(this).addClass('active')
292      }
293    })
294  }
295})
296
297// * ставит активный звезду
298$('.star').on('click', function () {
299  const element = $(this)
300  const elementIndex = element.index()
301  const selectedScore = element.attr('data-score')
302  $('.star').removeClass('active')
303  $('.star').each(function (index) {
304    if (index <= elementIndex) {
305      $(this).addClass('active')
306    }
307  })
308  $('.stars').addClass('star_selected')
309  $('.stars').attr('data-score-selected', selectedScore)
310  $('input.survey-score').val(selectedScore)
311
312  $('.star').removeClass('active_old')
313})
314
315//  * Возвращает в изначальное состояние звезд при покидании области
316$('.stars').on('mouseleave', function () {
317  const element = $(this)
318  $('.star').removeClass('active')
319
320  if (element.hasClass('star_selected')) {
321    const selectedScore = element.attr('data-score-selected')
322    const lastStarIndex = $('.star[data-score="' + selectedScore + '"]').index()
323
324    $('.star').each(function (index) {
325      if (index <= lastStarIndex) {
326        $(this).addClass('active')
327      }
328    })
329  }
330  $('.star').removeClass('active_old')
331})
332
333// * Функция для подъема плейсходера
334function upFlyPlacholder() {
335  $('.fly-input').each(function () {
336    if ($(this).val().length) {
337      $(this).closest('.fly-label').addClass('focused')
338    } else {
339      $(this).closest('.fly-label').removeClass('focused')
340    }
341  })
342}
343
344$('.fly-input').on('blur', function () {
345  if ($(this).val().length) {
346    $(this).closest('.fly-label').addClass('focused')
347  } else {
348    $(this).closest('.fly-label').removeClass('focused')
349  }
350})
351
352upFlyPlacholder()
353
354// * Показывает поле для ввода текста при выборе пункта "другое"
355$('body').on(
356  'change',
357  '.custom-checkbox input, .custom-radio input',
358  function () {
359    const elemеnt = $(this)
360    elemеnt
361      .closest('.survey-block_action')
362      .find('.custom-checkbox input:checked, .custom-radio input:checked')
363      .each(function () {
364        if (!['Другое', 'Другая', 'Другие'].includes($(this).val())) {
365          $(this)
366            .closest('.survey-block_action')
367            .find('.survey-block__shown-comment').length
368            ? ($(this)
369                .closest('.survey-block_action')
370                .find(
371                  '.survey-block__shown-comment input, .survey-block__shown-comment textarea',
372                )
373                .val(''),
374              upFlyPlacholder(),
375              $(this)
376                .closest('.survey-block_action')
377                .find('.survey-block__shown-comment')
378                .addClass('survey-block__hidden-comment')
379                .removeClass('survey-block__shown-comment'))
380            : null
381        } else {
382          $(this)
383            .closest('.survey-block_action')
384            .find('.survey-block__hidden-comment').length
385            ? $(this)
386                .closest('.survey-block')
387                .find('.survey-block__hidden-comment')
388                .removeClass('survey-block__hidden-comment')
389                .addClass('survey-block__shown-comment')
390            : null
391        }
392      })
393  },
394)
395
396// * Добавляет ошибки
397function addErrorMessage(params) {
398  const message = params['message'] ? params['message'] : null
399  const elem = params['element'] ? params['element'] : null
400  const position = params['position'] ? params['position'] : 'top'
401  const className = params['className'] ? params['className'] : null
402
403  const error = document.createElement('div')
404  error.className = 'error'
405  className !== null ? error.classList.add(className) : null
406  error.textContent = message !== null ? message : 'Ошибка'
407  if (elem === null || elem === undefined || elem === 'undefined')
408    return new Error('Не указан элемент')
409
410  switch (position) {
411    case 'top':
412      elem.before(error)
413      break
414    case 'bottom':
415      elem.after(error)
416      break
417    case 'inner':
418      elem.append(error)
419      break
420  }
421}
422
423// * Валидация и Отправка формы опросника
424
425$('.survey-form').on('submit', function (e) {
426  e.preventDefault()
427  const form = $(this)
428  const blocks = form.find('.survey-block_action')
429  const blocksCount = blocks.length
430
431  let btn = form.find('button.survey-submit')
432  let btnOld = btn.html()
433
434  let validPass = 0
435  let data = {}
436  let items = []
437
438  blocks.each(function () {
439    const element = $(this)
440    element
441      .find('.survey-block__inner')
442      .find('.survey-block__inner-error')
443      .remove()
444
445    if (
446      element.find('.custom-radio input, .custom-checkbox input').length &&
447      !element
448        .find('.custom-radio input, .custom-checkbox input')
449        .is(':checked')
450    ) {
451      validPass--
452      element.find('.custom-radio input').length
453        ? addErrorMessage({
454            message: 'Выберите пункт',
455            position: 'inner',
456            element: element.find('.survey-block__inner'),
457            className: 'survey-block__inner-error',
458          })
459        : element.find('.custom-checkbox input').length
460          ? addErrorMessage({
461              message: 'Выберите один из пунктов',
462              position: 'inner',
463              element: element.find('.survey-block__inner'),
464              className: 'survey-block__inner-error',
465            })
466          : null
467    } else {
468      data[
469        element
470          .find('.custom-radio input:checked, .custom-checkbox input:checked')
471          .attr('name')
472      ] = element
473        .find('.custom-radio input:checked, .custom-checkbox input:checked')
474        .val()
475    }
476
477    if (
478      element.find('.custom-radio input, .custom-checkbox input').is(':checked')
479    ) {
480      $(this)
481        .find('.custom-radio input, .custom-checkbox input')
482        .each(function () {
483          if (
484            $(this).is(':checked') &&
485            ['Другое', 'Другая', 'Другие'].includes($(this).val()) &&
486            !element.find('.fly-label .fly-input').val().length
487          ) {
488            validPass--
489            addErrorMessage({
490              message: 'Напишите пару слов',
491              position: 'inner',
492              element: element.find('.survey-block__inner'),
493              className: 'survey-block__inner-error',
494            })
495          } else if (
496            $(this).is(':checked') &&
497            ['Другое', 'Другая', 'Другие'].includes($(this).val()) &&
498            element.find('.fly-label .fly-input').val().length
499          ) {
500            items.push(element.find('.fly-label .fly-input').val())
501          } else if ($(this).is(':checked')) {
502            items.push($(this).val())
503          }
504        })
505      data[element.find('.fly-label .fly-input').attr('name')] = items
506      items = []
507    }
508
509    if (element.find('.survey-score').length) {
510      if (!element.find('.survey-score').val().length) {
511        validPass--
512        addErrorMessage({
513          message: 'Выберите оценку',
514          position: 'inner',
515          element: element.find('.survey-block__inner'),
516          className: 'survey-block__inner-error',
517        })
518      } else {
519        data[element.find('.survey-score').attr('name')] = element
520          .find('.survey-score')
521          .val()
522      }
523    }
524
525    if (element.find('.comment-block').length) {
526      if (!element.find('.comment-block').val().length) {
527        validPass--
528        addErrorMessage({
529          message: 'Напишите пару слов',
530          position: 'inner',
531          element: element.find('.survey-block__inner'),
532          className: 'survey-block__inner-error',
533        })
534      } else {
535        data[element.find('.comment-block').attr('name')] = element
536          .find('.comment-block')
537          .val()
538      }
539    }
540    validPass++
541  })
542
543  if (!form.find('.form__agree input[type="checkbox"]').is(':checked')) {
544    validPass--
545    addErrorMessage({
546      message: 'Примите соглашение',
547      position: 'bottom',
548      element: form.find('.form__agree'),
549      className: 'survey-block__inner-error',
550    })
551  }
552
553  if (validPass >= blocksCount) {
554    btn
555      .addClass('disable')
556      .css('width', btn.outerWidth() + 'px')
557      .css('height', btn.outerHeight() + 'px')
558      .html(loader)
559    $.ajax({
560      url: '/',
561      type: 'GET',
562      data: data,
563      success() {
564        btn.html(btnOld)
565        form.trigger('reset')
566      },
567      error() {
568        btn.html(btnOld)
569      },
570    })
571  }
572})
573
574//  * Удаление ошибок в опроснике
575$('.survey-form input, .survey-form textarea, .survey-form .star').on(
576  'change input blur click',
577  function (e) {
578    $(this)
579      .closest('.survey-block_action, .survey-bottom')
580      .find('.survey-block__inner-error')
581      .remove()
582  },
583)
584
585// * Слайдер для срочных услуг
586if ($('.profile-uservices__slider-v1').length) {
587  const slidesPerView =
588    $('.profile-uservices__slider-v1').find('.swiper-slide').length > 2
589      ? 2.08
590      : 2
591  $(
592    '.profile-uservices__slider-v1 .swiper-button-next, .profile-uservices__slider-v1 .swiper-button-prev',
593  )
594    .removeClass('in')
595    .removeClass('out')
596
597  new Swiper('.profile-uservices__slider-v1', {
598    slidesPerView: 'auto',
599    spaceBetween: 10,
600    breakpoints: {
601      600: {
602        slidesPerView: slidesPerView,
603      },
604    },
605    navigation: {
606      nextEl: '.swiper-button-next',
607      prevEl: '.swiper-button-prev',
608    },
609  })
610}
611
612// * Слайдер для услуг и сервиса
613if ($('.profile-uservices__slider-v2').length) {
614  $(
615    '.profile-uservices__slider-v2 .swiper-button-next, .profile-uservices__slider-v2 .swiper-button-prev',
616  )
617    .removeClass('in')
618    .removeClass('out')
619
620  new Swiper('.profile-uservices__slider-v2', {
621    slidesPerView: 'auto',
622    spaceBetween: 10,
623    navigation: {
624      nextEl: '.swiper-button-next',
625      prevEl: '.swiper-button-prev',
626    },
627  })
628}
629
630// Слайдер со спецприложениями
631if ($('.profile__specials-slider').length) {
632  $(
633    '.profile__specials-slider .swiper-button-next, .profile__specials-slider .swiper-button-prev',
634  )
635    .removeClass('in')
636    .removeClass('out')
637  new Swiper('.profile__specials-slider', {
638    direction: 'horizontal',
639    spaceBetween: 10,
640    slidesPerView: 'auto',
641    navigation: {
642      nextEl: '.swiper-button-next',
643      prevEl: '.swiper-button-prev',
644    },
645    speed: 600,
646  })
647}
648
649// * Функция для копирования в буфер обмена
650function copyToClipboard(copyText) {
651  if (navigator.clipboard) {
652    navigator.clipboard.writeText(copyText).then(() => {
653      $('.profile-points__friend-copy').addClass('copied').text('Скопировано')
654      setTimeout(() => {
655        $('.profile-points__friend-copy')
656          .removeClass('copied')
657          .text('Скопировать')
658      }, 2000)
659    })
660  }
661}
662
663// * Копирование в буфер ссылки для приглашения
664$('.profile-points__friend .profile-points__friend-copy').on(
665  'click',
666  function () {
667    const text = $(this)
668      .parent()
669      .children('.profile-points__friend-field')
670      .val()
671      .trim()
672    copyToClipboard(text)
673  },
674)
675
676Selectize.define('multi_deselect', function () {
677  const self = this
678
679  self.onOptionSelect = (function () {
680    return function (e) {
681      if (e.preventDefault) {
682        e.preventDefault()
683        e.stopPropagation()
684      }
685      const $target = $(e.currentTarget)
686      const value = $target.attr('data-value')
687      if (/mouseup/.test(e.type) || /touchstart/.test(e.type)) {
688        if (self.getValue().includes(value) && $target.hasClass('selected')) {
689          self.removeItem(value)
690          self.refreshOptions(false)
691        } else {
692          self.addItem(value, true)
693          self.refreshOptions(false)
694        }
695      }
696      return
697    }
698  })()
699
700  self.setup = (function () {
701    const original = self.setup
702    return function () {
703      original.apply(self, arguments)
704      self.$dropdown.off(
705        'mouseup click mousedown',
706        '[data-selectable]',
707        function () {
708          return self.onOptionSelect.apply(self, arguments)
709        },
710      )
711      self.$dropdown.on('mouseup', '[data-selectable]', function (e) {
712        if (e.type === 'mouseup') {
713          self.onOptionSelect.apply(self, arguments)
714        }
715      })
716    }
717  })()
718})
719
720Selectize.define('custom_dropdowm', function () {
721  const self = this
722  self.onMouseDown = (function () {
723    const original = self.onMouseDown
724    return function (e) {
725      const $target = $(e.currentTarget)
726      console.log(e.currentTarget)
727      if (
728        $target.hasClass('dropdown-active') ||
729        $(e.target).closest('.selectize-input').hasClass('dropdown-active')
730      ) {
731        // if (self.isOpen) {
732        self.close()
733      } else {
734        self.open()
735      }
736    }
737  })()
738  self.onClick = (function (e) {
739    const original = self.onMouseDown
740    return function (e) {}
741  })()
742  self.setup = (function () {
743    const original = self.setup
744    return function (e) {
745      original.apply(self, arguments)
746      self.$control_input.on({
747        click: function (e) {
748          if (
749            $(e.target).closest('.selectize-input').hasClass('dropdown-active')
750          ) {
751            self.close()
752          } else {
753            self.open()
754          }
755        },
756      })
757    }
758  })()
759})
760
761//запрос к беку / изменения
762async function request(data) {
763  $.ajax({
764    url: '/?cabinet',
765    type: 'POST',
766    data,
767    success: async function (response) {
768      Swal.fire({
769        position: 'top-end',
770        icon: 'success',
771        title: response.description,
772        showConfirmButton: false,
773        timer: 1500,
774      })
775      console.log(response)
776      return response
777    },
778    error: async function (jqXHR, exception) {
779      Swal.fire({
780        position: 'top-end',
781        icon: 'error',
782        title: 'Ошибка изменения данных',
783        showConfirmButton: false,
784        timer: 1500,
785      })
786      console.log(exception)
787      return exception
788    },
789  })
790}
791
792var specialBrands = []
793var specialSalons = []
794var specialSelectSort = []
795
796// спец. предложения - выбор бренда
797if ($('.special-modal__brand').length) {
798  $('.special-modal__brand')[0].selectize
799    ? $('.special-modal__brand')[0].selectize.destroy()
800    : null
801
802  $('.special-modal__brand').selectize({
803    onInitialize: function (e) {
804      const specialBrands = $('#special-brand').val()
805      dialerSort(specialBrands, 'onInitialize')
806    },
807    onItemAdd: function (e) {
808      const specialBrands = $('#special-brand').val()
809      specialBrands.push(e)
810      dialerSort(specialBrands)
811    },
812    onItemRemove: function (e) {
813      const specialBrands = $('#special-brand').val()
814      dialerSort(specialBrands)
815    },
816    hideSelected: false,
817    closeAfterSelect: false,
818    openOnFocus: true,
819    openOnFocus: false,
820    plugins: {
821      multi_deselect: {},
822      remove_button: {
823        title: 'Удалить',
824      },
825    },
826  })
827}
828
829$('body').on('change', '#hiddenDealers', function () {
830  dialerSort($('#special-brand').val())
831})
832
833//сортировка ДЦ - бренд + выбраннее ранее ДЦ
834function dialerSort(brands, onInitialize) {
835  specialSelectSort = specialSelect
836  // если ничего не выбрано
837  if (!brands || brands.length === 0) {
838    $('#special-personal .profile__special-item').removeClass('hidden')
839  } else {
840    // если выбран бренд то сортировка
841    if ($('#hiddenDealers').is(':checked')) specialSelectSort = []
842    const currentDealers = $('#special-dialer').val()
843
844    $('#special-personal .profile__special-item').addClass('hidden')
845    specialSelect.find(function (item) {
846      if (brands.indexOf(item.brand) !== -1) {
847        $(
848          `#special-personal .profile__special-item[data-brand='${item.brand}']`,
849        ).removeClass('hidden')
850        !currentDealers.length
851          ? ''
852          : currentDealers.indexOf(item.value) !== -1
853            ? (item.selected = true)
854            : ''
855        if ($('#hiddenDealers').is(':checked')) specialSelectSort.push(item)
856      }
857    })
858  }
859
860  dealerForm()
861
862  if (!onInitialize) {
863    const userID = $('#user_ID').val()
864    const name = 'special_brand'
865    const value = brands.length > 0 ? brands.join(',') : ''
866    const action = 'edit'
867    const requestData = { userID, action, name, value }
868
869    if (userID) request(requestData)
870  }
871}
872
873//спецпредложения - сортировка по ДЦ
874function salonSort(salons, onInitialize) {
875  // если ничего не выбрано
876  if (!salons || salons.length === 0) {
877    $('#special-personal .profile__special-item').removeClass('specialHidden')
878  } else {
879    $('#special-personal .profile__special-item').addClass('specialHidden')
880    salons.find((e) => {
881      $(`#special-personal .profile__special-item`).each(function (i) {
882        if ($(this).hasClass(e)) $(this).removeClass('specialHidden')
883      })
884    })
885  }
886
887  if (!onInitialize) {
888    const userID = $('#user_ID').val()
889    const name = 'special_dealer'
890    const value = salons.length > 0 ? salons.join(',') : ''
891    const action = 'edit'
892    const requestData = { userID, action, name, value }
893
894    if (userID) request(requestData)
895  }
896
897  specialFIX()
898}
899
900//исправление бага с кривым выбором
901function specialFIX() {
902  const elements = $('#special-personal .profile__special-item')
903  if (elements.is(':visible') === false) {
904    $('#specialErrors')
905      .html('Нет предложений с такими параметрами, измените настройки фильтра')
906      .fadeIn()
907    $('#special-personal .profile__special-item').removeClass('specialHidden')
908  } else {
909    $('#specialErrors').html('').fadeOut()
910  }
911}
912
913//форма со списком ДЦ
914function dealerForm() {
915  if ($('.special-modal__dialer')[0].selectize) {
916    var openElement = true
917    $('.special-modal__dialer')[0].selectize.destroy()
918  }
919
920  const dialerSelect = $('.special-modal__dialer').selectize({
921    onInitialize: function () {
922      if (openElement) {
923        var that = this
924        this.$control.on('mousedown', function () {
925          if (that.isOpen) that.close()
926          else that.open()
927        })
928      }
929      const specialSalons = $('#special-dialer').val()
930      salonSort(specialSalons, 'onInitialize')
931    },
932    onItemAdd: function (e) {
933      const specialSalons = $('#special-dialer').val()
934      specialSalons.push(e)
935      salonSort(specialSalons)
936    },
937    onItemRemove: function (e) {
938      const specialSalons = $('#special-dialer').val()
939      salonSort(specialSalons)
940    },
941    persist: false,
942    maxItems: null,
943    valueField: 'value',
944    labelField: 'description',
945    searchField: ['value', 'description'],
946    options: specialSelectSort,
947    hideSelected: false,
948    openOnFocus: false,
949    plugins: {
950      multi_deselect: {},
951      remove_button: {
952        title: 'Удалить',
953      },
954    },
955    render: {
956      item: function (item, escape) {
957        return `
958			<div class="item">
959				${escape(item.value)}
960			</div>`
961      },
962      option: function (item, escape) {
963        const label = item.value || item.value
964        const description = item.description ? item.description : null
965        const image = item.image ? item.image : null
966        const real_address = item.real_address ? item.real_address : null
967
968        return `
969				<div class="special-option option ">
970					<img class="special-option__image" src="${escape(image)}" alt="">
971						<div class="special-option__info">
972							<div class="special-option__title">${escape(label)}</div>
973							<div class="special-option__subtitle">
974              ${escape(description)}
975              <br>
976              ${escape(real_address)}
977              </div>
978						</div>
979				</div>`
980      },
981    },
982  })
983
984  const dialerSelectSelectize = dialerSelect[0].selectize
985
986  const dialerSelectSelected = specialSelectSort.map((item) => {
987    if (item.selected) return item.value
988  })
989
990  dialerSelectSelectize.setValue(dialerSelectSelected)
991  dialerSelectSelectize.refreshItems()
992}
993
994$('select').each(function () {
995  const select = $(this)[0].selectize
996  if (select) {
997    // if (select && select.settings.mode === 'multi') {
998    select.$control.on('click', function (e) {
999      e.preventDefault()
1000      e.stopPropagation()
1001      if (select.settings.mode === 'multi' && select.isOpen) {
1002        select.close()
1003      } else if (select.settings.mode === 'multi' && !select.isOpen) {
1004        select.open()
1005      }
1006    })
1007  }
1008})
1009
1010if ($('.auto-modal__select').length) {
1011  $('.auto-modal__select').each(function () {
1012    const selectize = $(this)[0].selectize
1013
1014    if (selectize) {
1015      selectize.destroy()
1016
1017      const newSelect = $(this).selectize({
1018        openOnFocus: false,
1019        valueField: 'value',
1020        labelField: 'value',
1021        plugins: {
1022          custom_dropdowm: {},
1023        },
1024      })
1025
1026      newSelect[0].selectize.clear()
1027    }
1028  })
1029}
1030
1031$('.form__inp').each(function () {
1032  if ($(this).val().length)
1033    $(this).parent().find('.form__label').addClass('act')
1034  else $(this).parent().find('.form__label').removeClass('act')
1035})
1036
1037$('.form__inp').on('focus', function (e) {
1038  $(this).parent().removeClass('error')
1039  $('.form-errors').find('.form__error').remove()
1040})
1041
1042// * Только числа
1043$(document).on('input keyup paste', '[data-numeric]', function () {
1044  $(this).val($(this).val().replace(/\D/, ''))
1045})
1046
1047// * Форма для получения кода
1048$('.restore-password').on('submit', function (e) {
1049  e.preventDefault()
1050  const form = $(this)
1051  const route = form.attr('action')
1052  const button = form.find('button.form__but')
1053  const buttonOld = button.html()
1054  form.find('.form-errors').find('.form__error').remove()
1055
1056  if (!form.find('.form__inp').val().length) {
1057    form.find('.form__item').addClass('error')
1058    !form.find('.form-errors').find('.form__error').length
1059      ? form
1060          .find('.form-errors')
1061          .append(
1062            '<div class="form__error form__error_active">Введите номер телефона</div>',
1063          )
1064      : null
1065    return
1066  }
1067
1068  if (form.find('.form__inp').val().replace(/\D+/g, '').length < 10) {
1069    form.find('.form__item').addClass('error')
1070    !form.find('.form-errors').find('.form__error').length
1071      ? form
1072          .find('.form-errors')
1073          .append(
1074            '<div class="form__error form__error_active">Некорректный номер телефона</div>',
1075          )
1076      : null
1077    return
1078  }
1079
1080  button.html(loader)
1081
1082  $.ajax({
1083    url: route,
1084    data: { phone: form.find('.form__inp').val().replace(/\D+/g, '') },
1085    type: 'GET',
1086    success(data) {
1087      button.html(buttonOld)
1088      form.addClass('form-style_hidden')
1089      $('.code-form').attr('data-code', 1234)
1090      $('.code-form').attr('data-phone', form.find('.form__inp').val())
1091      $('.code-form').removeClass('form-style_hidden')
1092      $('.code-form').find('.restore-phone').text(form.find('.form__inp').val())
1093      codeResendTimer(3, $('.code-form').find('.login__reminder-timer-counter'))
1094    },
1095    error(error) {
1096      button.html(buttonOld)
1097      !form.find('.form-errors').find('.form__error').length
1098        ? form
1099            .find('.form-errors')
1100            .append(
1101              `<div class="form__error form__error_active">${JSON.stringify(
1102                error,
1103              )}</div>`,
1104            )
1105        : null
1106    },
1107  })
1108})
1109
1110// * Форма для отправки запроса на новый пароль
1111
1112$('.code-form').on('submit', function (e) {
1113  e.preventDefault()
1114  const form = $(this)
1115  const route = form.attr('action')
1116  const button = form.find('button.form__but')
1117  const buttonOld = button.html()
1118  const code = form.attr('data-code')
1119  form.find('.form-errors').find('.form__error').remove()
1120
1121  if (!form.find('.form__inp').val().length) {
1122    form.find('.form__item').addClass('error')
1123    !form.find('.form-errors').find('.form__error').length
1124      ? form
1125          .find('.form-errors')
1126          .append(
1127            '<div class="form__error form__error_active">Введите код подтверждения</div>',
1128          )
1129      : null
1130    return
1131  }
1132
1133  if (code !== form.find('.form__inp').val().trim()) {
1134    form.find('.form__item').addClass('error')
1135    !form.find('.form-errors').find('.form__error').length
1136      ? form
1137          .find('.form-errors')
1138          .append(
1139            '<div class="form__error form__error_active">Код подтверждения введен неверно</div>',
1140          )
1141      : null
1142    return
1143  }
1144
1145  button.html(loader)
1146
1147  $.ajax({
1148    url: route,
1149    data: {
1150      phone: $('.restore-password')
1151        .find('.form__inp')
1152        .val()
1153        .replace(/\D+/g, ''),
1154      query: 'restore',
1155    },
1156    type: 'GET',
1157    success(data) {
1158      button.html(buttonOld)
1159      form.addClass('form-style_hidden')
1160      $('.restore-confirm-modal').removeClass('form-style_hidden')
1161    },
1162    error(error) {
1163      !form.find('.form-errors').find('.form__error').length
1164        ? form
1165            .find('.form-errors')
1166            .append(
1167              `<div class="form__error form__error_active">${JSON.stringify(
1168                error,
1169              )}</div>`,
1170            )
1171        : null
1172      button.html(buttonOld)
1173    },
1174  })
1175})
1176
1177// * Форма для повторного получения кода в смс
1178$('.login__reminder-resend').on('click', function () {
1179  var element = $(this)
1180  $('.form__lk').find('.form__error').html('').hide()
1181  const token = $('.g-recaptcha-response').val()
1182  $.ajax({
1183    url: '/?action=send_sms_code',
1184    data: {
1185      phone: element.closest('form').attr('data-phone').replace(/\D+/g, ''),
1186      'g-recaptcha-response': token,
1187      cabinet_csrf: element.closest('form').find('input[name="cabinet_csrf"]').val(),
1188    },
1189    type: 'POST',
1190    success(response) {
1191      if ((response.status && response.status === 'error') || response === '') {
1192        form.find('.login__error').addClass('act')
1193        form.find('.login__item').addClass('error')
1194        form
1195          .find('.form__error')
1196          .text(
1197            response && response.description
1198              ? response.description
1199              : 'Неизвестная ошибка',
1200          )
1201          .show()
1202      } else {
1203        element.hide()
1204        element
1205          .closest('.login__reminder')
1206          .find('.login__reminder-timer')
1207          .show()
1208        codeResendTimer(
1209          300,
1210          element
1211            .closest('.login__reminder')
1212            .find('.login__reminder-timer-counter'),
1213        )
1214      }
1215    },
1216    error(error) {
1217      !$('.code-form').find('.form-errors').find('.form__error').length
1218        ? $('.code-form')
1219            .find('.form-errors')
1220            .append(
1221              `<div class="form__error form__error_active">
1222							${JSON.stringify(error)}</div>`,
1223            )
1224        : null
1225    },
1226  })
1227})
1228
1229function codeResendTimer(timer, element) {
1230  var time_redir = timer
1231  element.text(time_redir)
1232  let timer_redir = setInterval(function () {
1233    if (time_redir !== 0) {
1234      time_redir--
1235      element.text(time_redir)
1236    } else {
1237      element.closest('.login__reminder').find('.login__reminder-timer').hide()
1238      element.closest('.login__reminder').find('.login__reminder-resend').show()
1239      clearInterval(timer_redir)
1240    }
1241  }, 1000)
1242}
1243
1244// отправка кода через смс соощение
1245$('.form__lk').submit(function (e) {
1246  e.preventDefault()
1247  const form = $(this)
1248  const button = $(this).find('.form__but')
1249  const buttonOld = button.html()
1250  var phone = $('#authFormPhone').val()
1251  var user_name = $('#user_name').val()
1252  var user_surname = $('#user_surname').val()
1253  var user_patronymic = $('#user_patronymic').val()
1254
1255  if (!form.find('input').val()) {
1256    form.find('.form__inp').addClass('error')
1257    return false
1258  }
1259  if (
1260    $(this).find('input[data-mask=phone]').length &&
1261    $(this).find('input[data-mask=phone]').val().replace(/\D+/g, '').length !==
1262      11
1263  ) {
1264    $(this).find('.form__error').text('Некорректный номер').show()
1265    $(this).find('input[data-mask=phone]').addClass('error')
1266    return false
1267  }
1268
1269  if (!button.hasClass('disable')) {
1270    button.removeAttr('style')
1271    button
1272      .addClass('disable')
1273      .css('width', button.outerWidth() + 'px')
1274      .css('height', button.outerHeight() + 'px')
1275      .html(loader)
1276
1277    $.ajax({
1278      url: '/?action=send_sms_code',
1279      type: 'POST',
1280      data: form.serialize(),
1281      success: function (response) {
1282        if (
1283          (response.status && response.status === 'error') ||
1284          response === ''
1285        ) {
1286          form.find('.login__error').addClass('act')
1287          form.find('.login__item').addClass('error')
1288          form
1289            .find('.form__error')
1290            .text(
1291              response && response.description
1292                ? response.description
1293                : 'Неизвестная ошибка',
1294            )
1295            .show()
1296          button.removeClass('disable').html(buttonOld)
1297        } else {
1298          $(this).find('.form__error').html('').hide()
1299
1300          if (form.hasClass('profile__form-inner')) {
1301            opensuccess2()
1302          }
1303
1304          if (response.result === 'success' && response.message) {
1305            $('.login__subtitle').html(response.message)
1306            $('.login-verification-phone').html(phone)
1307            $('#authFormCode').focus()
1308          }
1309
1310          form.trigger('reset')
1311          form.find('.login__error').removeClass('act')
1312          form.find('.form__label').removeClass('act')
1313          button.removeClass('disable').html(buttonOld)
1314
1315          form.addClass('form-style_hidden')
1316          $('.code-verification').attr('data-phone', phone)
1317          $('.code-verification').attr('data-name', user_name)
1318          $('.code-verification').attr('data-surname', user_surname)
1319          $('.code-verification').attr('data-patronymic', user_patronymic)
1320          $('.code-verification').removeClass('form-style_hidden')
1321          codeResendTimer(
1322            300,
1323            $('.code-verification').find('.login__reminder-timer-counter'),
1324          )
1325        }
1326      },
1327      error: function (response) {
1328        console.log(response)
1329        form.find('.login__error').addClass('act')
1330        form.find('.login__item').addClass('error')
1331        form
1332          .find('.form__error')
1333          .text(
1334            response.description
1335              ? response.description
1336              : 'проверка безопасности...',
1337          )
1338          .show()
1339        button.removeClass('disable').html(buttonOld)
1340        // повторная отправка TODO: костыль
1341        $('.but.butred.login__but.form__but').click()
1342      },
1343    })
1344  }
1345})
1346
1347// * Верификация с помощью номера
1348$('.code-verification').on('submit', function (e) {
1349  e.preventDefault()
1350  const form = $(this)
1351  const route = form.attr('action')
1352  const button = form.find('button.form__but')
1353  const buttonOld = button.html()
1354  const code = $('#authFormCode').val()
1355  const phone = $('.login-verification-phone').html()
1356  const rememberMe = $('#rememberMe').attr('checked') === 'checked' ? 1 : 0
1357  const token = $('.g-recaptcha-response').val()
1358  const cabinetCsrf = form.find('input[name="cabinet_csrf"]').val()
1359
1360  if (!phone || !code) return false
1361
1362  form.find('.form-errors').find('.form__error').remove()
1363
1364  if (!form.find('.form__inp').val().length) {
1365    form.find('.form__item').addClass('error')
1366    !form.find('.form-errors').find('.form__error').length
1367      ? form
1368          .find('.form-errors')
1369          .append(
1370            '<div class="form__error form__error_active">Введите код подтверждения</div>',
1371          )
1372      : null
1373    return
1374  }
1375
1376  button.html(loader)
1377
1378  $.ajax({
1379    url: route,
1380    data: {
1381      phone: phone,
1382      code: code,
1383      'g-recaptcha-response': token,
1384      cabinet_csrf: cabinetCsrf,
1385    },
1386    type: 'POST',
1387    success(response) {
1388      console.log(response)
1389      if (response.result === 'error') {
1390        button.html(buttonOld)
1391        form.find('.form__item').addClass('error')
1392        !form.find('.form-errors').find('.form__error').length
1393          ? form
1394              .find('.form-errors')
1395              .append(
1396                '<div class="form__error form__error_active">' +
1397                  response.message +
1398                  '</div>',
1399              )
1400          : null
1401        return
1402      }
1403
1404      if (response.result === 'success') {
1405        // console.log(response)
1406        var yandex_client_ID = localStorage.getItem('yandex_client_ID')
1407        var user_name = $('.code-verification').attr('data-name')
1408        var user_surname = $('.code-verification').attr('data-surname')
1409        var user_patronymic = $('.code-verification').attr('data-patronymic')
1410        var site_name = $('.code-verification').attr('data-site')
1411        var data = {
1412          name: response.data.user.name,
1413          surname: response.data.user.surname,
1414          patronymic: response.data.user.patronymic,
1415          phone: response.data.user.phone,
1416          access_token: response.data.token.access_token,
1417          expires_in: response.data.token.expires_in,
1418          remember_me: rememberMe,
1419          yandex_client_ID: yandex_client_ID ? yandex_client_ID : '',
1420          user_name: user_name ? user_name : '',
1421          user_surname: user_surname ? user_surname : '',
1422          user_patronymic: user_patronymic ? user_patronymic : '',
1423          site_name: site_name ? site_name : '',
1424          redirect: $('#redirect').val() ? $('#redirect').val() : '',
1425          cabinet_csrf: cabinetCsrf,
1426        }
1427        $.ajax({
1428          url: '/?create_user',
1429          type: 'POST',
1430          data: data,
1431          success: function (response2) {
1432            console.log('авторизация и переход в личный кабинет...')
1433            response.data.user
1434              ? localStorage.setItem(
1435                  'cabinetUser',
1436                  JSON.stringify(response.data.user),
1437                )
1438              : ''
1439            response.data.token
1440              ? localStorage.setItem(
1441                  'cabinetToken',
1442                  JSON.stringify(response.data.token),
1443                )
1444              : ''
1445            let searchParams = new URLSearchParams(window.location.search)
1446            !searchParams.has('debug')
1447              ? window.location.replace(response2.redirect)
1448              : console.log(response2)
1449          },
1450          error: function (jqXHR, exception) {
1451            var msg = ''
1452            if (jqXHR.status === 0) {
1453              msg = 'Not connect.\n Verify Network.'
1454            } else if (jqXHR.status == 404) {
1455              msg = 'Requested page not found. [404]'
1456            } else if (jqXHR.status == 500) {
1457              msg = 'Internal Server Error [500].'
1458            } else if (exception === 'parsererror') {
1459              msg = 'Requested JSON parse failed.'
1460            } else if (exception === 'timeout') {
1461              msg = 'Time out error.'
1462            } else if (exception === 'abort') {
1463              msg = 'Ajax request aborted.'
1464            } else {
1465              msg = 'Uncaught Error.\n' + jqXHR.responseText
1466            }
1467            console.log(msg)
1468          },
1469        })
1470      }
1471    },
1472    error(error) {
1473      form.find('.login__error').addClass('act')
1474      form.find('.login__item').addClass('error')
1475      form
1476        .find('.form__error')
1477        .text(
1478          response.description
1479            ? response.description
1480            : 'проверка безопасности...',
1481        )
1482        .show()
1483      button.html(buttonOld)
1484      // повторная отправка TODO: костыль
1485      $('.but.butred.login__but.form__but').click()
1486    },
1487  })
1488})
1489
1490// * Поднимает или отпускает подсказку 2
1491$('.form__inp').each(function () {
1492  if ($(this).val().length)
1493    $(this).parent().find('.form__label').addClass('act')
1494  else $(this).parent().find('.form__label').removeClass('act')
1495})
1496
1497$('.auto-modal__select[name="auto_brand"]').on('change', function () {
1498  return false
1499  const element = $(this)
1500  const value = element.val().trim()
1501  const modelSelect = element
1502    .closest('.auto-modal__form')
1503    .find('.auto-modal__select[name="auto_model"]')
1504    .get(0).selectize
1505  $.ajax({
1506    url: '/new/scripts/models.json',
1507    type: 'GET',
1508    data: {
1509      brand: value,
1510    },
1511    dataType: 'json',
1512    success(data) {
1513      modelSelect.clearOptions()
1514      modelSelect.unlock()
1515      modelSelect.enable()
1516      modelSelect.addOption(data)
1517      modelSelect.refreshOptions(false)
1518      modelSelect.refreshState()
1519    },
1520    error(error) {},
1521  })
1522})
1523
1524$('.auto-modal__form').on('submit', function (e) {
1525  e.preventDefault()
1526  const form = $(this)
1527  const validateSelect = form.find('select.validate-select')
1528  const validateInput = form.find('.validate-input')
1529  const validateSelectCount = validateSelect.length
1530  const validateInputCount = validateInput.length
1531  const date = new Date()
1532  const curruntYear = date.getFullYear()
1533  const button = form.find('button')
1534  const buttonOld = button.html()
1535  const route = form.attr('action')
1536  let validateSelectPass = 0
1537  let valdiateInputPass = 0
1538  const data = {}
1539
1540  validateInput.each(function () {
1541    const $this = $(this)
1542
1543    if (!$this.val().length) {
1544      valdiateInputPass--
1545      $this.addClass('validate-error')
1546      !$this.parent().find('.form-error-message').length
1547        ? addErrorMessage({
1548            message: 'Заполните поле',
1549            position: 'bottom',
1550            element: $this,
1551            className: 'form-error-message',
1552          })
1553        : null
1554    }
1555    if ($this.attr('name') === 'auto-born') {
1556      if ($this.val().trim().length !== 4) {
1557        valdiateInputPass--
1558        $this.addClass('validate-error')
1559        !$this.parent().find('.form-error-message').length
1560          ? addErrorMessage({
1561              message: 'Некорректная длина',
1562              position: 'bottom',
1563              element: $this,
1564              className: 'form-error-message',
1565            })
1566          : null
1567      }
1568
1569      if (Number($this.val()) < 1900 || Number($this.val()) > curruntYear) {
1570        valdiateInputPass--
1571        $this.addClass('validate-error')
1572        !$this.parent().find('.form-error-message').length
1573          ? addErrorMessage({
1574              message: 'Некорректная дата',
1575              position: 'bottom',
1576              element: $this,
1577              className: 'form-error-message',
1578            })
1579          : null
1580      }
1581    }
1582    valdiateInputPass++
1583  })
1584
1585  validateSelect.each(function () {
1586    const $this = $(this)
1587    if (!$this.val().trim().length) {
1588      validateSelectPass--
1589      $this.parent().find('.selectize-control').addClass('validate-error')
1590      !$this.parent().find('.form-error-message').length
1591        ? addErrorMessage({
1592            message: 'Выберите пункт',
1593            position: 'inner',
1594            element: $this.parent(),
1595            className: 'form-error-message',
1596          })
1597        : null
1598    }
1599    validateSelectPass++
1600  })
1601
1602  if (
1603    validateSelectPass >= validateSelectCount &&
1604    valdiateInputPass >= validateInputCount
1605  ) {
1606    button.html(loader)
1607    validateSelect.each(function () {
1608      data[$(this)[0].name] = $(this).val()
1609    })
1610    validateInput.each(function () {
1611      data[$(this)[0].name] = $(this).val()
1612    })
1613
1614    $.ajax({
1615      url: route,
1616      data: data,
1617      type: 'GET',
1618      success(data) {
1619        button.html(buttonOld)
1620        form.trigger('reset')
1621        validateSelect.each(function () {
1622          $(this)[0].selectize.clear()
1623        })
1624      },
1625      error() {},
1626    })
1627  }
1628})
1629
1630$('body').on('click', '.auto-modal .close, .close-modal', function () {
1631  const $this = $(this)
1632
1633  $this.parent().find('form').trigger('reset')
1634
1635  $this
1636    .parent()
1637    .find('select')
1638    .each(function () {
1639      $(this)[0].selectize.clear()
1640    })
1641})
1642
1643// * Плавающий блок каталога на главной странице
1644const sliders = document.querySelectorAll('.selectize-control .selectize-input')
1645
1646sliders.forEach((slider) => {
1647  if (slider) {
1648    let isDown = false
1649    let startX
1650    let scrollLeft
1651
1652    slider.addEventListener('mousedown', (e) => {
1653      isDown = true
1654      slider.classList.add('active')
1655      startX = e.pageX - slider.offsetLeft
1656      scrollLeft = slider.scrollLeft
1657    })
1658    slider.addEventListener('mouseleave', () => {
1659      isDown = false
1660      slider.classList.remove('active')
1661    })
1662    slider.addEventListener('mouseup', () => {
1663      isDown = false
1664      slider.classList.remove('active')
1665    })
1666    slider.addEventListener('mousemove', (e) => {
1667      if (!isDown) return
1668      e.preventDefault()
1669      const x = e.pageX - slider.offsetLeft
1670      const walk = (x - startX) * 1 //scroll-fast
1671      slider.scrollLeft = scrollLeft - walk
1672    })
1673  }
1674})
1675
1676let scrollOld = 0
1677const profileLeft = document.querySelector('.profile__left ')
1678const aside = document.querySelector('.profile__left-inner')
1679const profileMain = document.querySelector('.profile__inner')
1680const asideRemainder = aside ? window.innerHeight - aside.offsetHeight : null
1681
1682function ScrollAside() {
1683  if (!aside) return
1684  if (window.innerWidth < 1000 || window.innerHeight > aside.offsetHeight) {
1685    $('.profile__left-inner').removeAttr('style')
1686    return
1687  }
1688  if (aside.offsetHeight * 1.5 > profileLeft.offsetHeight) return
1689  let scrollCurrent = window.scrollY
1690
1691  if (scrollCurrent > scrollOld) {
1692    if (
1693      window.scrollY + window.innerHeight >=
1694      profileMain.offsetTop + profileMain.offsetHeight + 20
1695    ) {
1696      aside.style.position = 'relative'
1697      aside.style.top =
1698        profileMain.offsetTop +
1699        profileMain.offsetHeight -
1700        aside.offsetHeight -
1701        profileLeft.offsetTop +
1702        'px'
1703      aside.style.transform = `translateY(0)`
1704      aside.style.transition = 'transform 0ms ease'
1705      return
1706    }
1707    if (window.scrollY > profileLeft.offsetTop) {
1708      aside.style.position = 'fixed'
1709      aside.style.top = '0'
1710      aside.style.transform = `translateY(${asideRemainder - 20}px)`
1711      aside.style.transition = 'transform 500ms ease'
1712    }
1713  } else {
1714    if (window.scrollY <= profileLeft.offsetTop) {
1715      aside.style.position = 'relative'
1716      aside.style.top = '0'
1717      aside.style.transform = `translateY(0)`
1718      return
1719    }
1720    if (
1721      window.scrollY <=
1722      profileLeft.offsetTop + profileLeft.offsetHeight - aside.offsetHeight
1723    ) {
1724      aside.style.position = 'fixed'
1725      aside.style.top = '0'
1726      aside.style.transform = `translateY(20px)`
1727      aside.style.transition = 'transform 300ms ease'
1728      console.log(
1729        window.scrollY,
1730        profileLeft.offsetTop +
1731          profileLeft.offsetHeight -
1732          aside.offsetHeight +
1733          60,
1734      )
1735    }
1736  }
1737
1738  scrollOld = scrollCurrent
1739}
1740
1741window.addEventListener('DOMContentLoaded', () => {
1742  ScrollAside()
1743})
1744window.addEventListener('scroll', () => {
1745  ScrollAside()
1746})
1747window.addEventListener('resize', () => {
1748  ScrollAside()
1749})
1750
1751function initCameraModalMenuSlider() {
1752  return function () {
1753    const el = $('.camera-modal__menu')
1754    if (el.length) {
1755      const cameraModalMenuSliderOptions = {
1756        slidesPerView: 'auto',
1757      }
1758      el.each(function (i) {
1759        if (el.get(i).swiper === undefined) {
1760          new Swiper(el.get(i), cameraModalMenuSliderOptions).slideTo(0)
1761        }
1762      })
1763    }
1764  }
1765}
1766
1767const initCameraModalMenuSliderF = initCameraModalMenuSlider()
1768initCameraModalMenuSliderF()
1769
1770$('body').on('click', '.camera-modal__menu-item', function () {
1771  const element = $(this)
1772  const link = element.data('url')
1773  element
1774    .closest('.camera-modal__inner')
1775    .find('.camera-modal__menu-item')
1776    .removeClass('camera-modal__menu-item_active')
1777  element.addClass('camera-modal__menu-item_active')
1778
1779  element
1780    .closest('.camera-modal__inner')
1781    .find('.camera-modal__video')
1782    .attr('src', link)
1783})
1784
1785$('body').on('click', '.service-camera__item', function () {
1786  const id = $(this).attr('data-modal')
1787  const modal = $('.camera-modal[data-modal="' + id + '"]')
1788  modal
1789    .find('.camera-modal__menu-item')
1790    .removeClass('camera-modal__menu-item_active')
1791  modal
1792    .find('.camera-modal__menu-item')
1793    .eq(0)
1794    .addClass('camera-modal__menu-item_active')
1795  const link = modal.find('.camera-modal__menu-item').eq(0).data('url')
1796  modal.find('.camera-modal__video').attr('src', link)
1797  initCameraModalMenuSliderF()
1798})
1799
1800$('body').on('click', '.profile-lk__field-change', function () {
1801  const element = $(this)
1802  if (!element.hasClass('profile-lk__field-confirm')) {
1803    element.addClass('profile-lk__field-confirm')
1804    element.text('Сохранить')
1805    element
1806      .parent()
1807      .find('.profile-lk__field-placeholder')
1808      .addClass('profile-lk__field-placeholder_hidden')
1809    element
1810      .parent()
1811      .find('.profile-lk__field-input')
1812      .addClass('profile-lk__field-input_shown')
1813    element.closest('.profile-lk__row').addClass('profile-lk__row_active')
1814  } else {
1815    element.removeClass('profile-lk__field-confirm')
1816    element.text('Изменить')
1817    element
1818      .parent()
1819      .find('.profile-lk__field-placeholder')
1820      .removeClass('profile-lk__field-placeholder_hidden')
1821    element
1822      .parent()
1823      .find('.profile-lk__field-input')
1824      .removeClass('profile-lk__field-input_shown')
1825    element.closest('.profile-lk__row').removeClass('profile-lk__row_active')
1826  }
1827})
1828
1829if ($('input[name="user-born"]').length) {
1830  $('input[name="user-born"]').inputmask({
1831    mask: '99.99.9999',
1832  })
1833}
1834
1835$('body').on('click', '.lk-modal__close', function () {
1836  const closeButton = $(this)
1837  hideViews()
1838})
1839
1840const lkCLASS = {
1841  view_hidden: 'lk-modal__view_hidden',
1842  view_active: 'lk-modal__view_active',
1843  modal_shown: 'lk-modal_shown',
1844  modal_visible: 'lk-modal_visible',
1845}
1846
1847function hideViews() {
1848  hidChangeProfileModal()
1849  $('.lk-modal__view')
1850    .removeClass('lk-modal__view_active')
1851    .not(':first-child')
1852    .addClass('lk-modal__view_hidden')
1853  $('.lk-modal__view').eq(0).addClass('lk-modal__view_active')
1854}
1855
1856// $('body').on('click', '.sos-screen__clarify', function () {
1857// 	showScreen2();
1858// });
1859
1860// $('body').on('click', '.sos-modal__return', function () {
1861// 	hideViews();
1862// });
1863
1864function showChangeProfileModal() {
1865  $('.lk-modal').addClass(lkCLASS.modal_shown)
1866  setTimeout(() => {
1867    $('.lk-modal').addClass(lkCLASS.modal_visible)
1868  }, 0)
1869}
1870
1871function hidChangeProfileModal() {
1872  $('.lk-modal').removeClass(lkCLASS.modal_visible)
1873  setTimeout(() => {
1874    $('.lk-modal').removeClass(lkCLASS.modal_shown)
1875  }, 300)
1876}
1877
1878$('.profile-lk__phone-change').on('click', function (e) {
1879  const phoneNumber = $(this)
1880    .closest('.profile-lk__field')
1881    .find('.profile-lk__field-input')
1882    .val()
1883  $('.lk-modal__view').eq(0).find('.lk-modal__phone-place').text(phoneNumber)
1884  showChangeProfileModal()
1885})
1886
1887$('.lk-modal__get-code').on('submit', function (e) {
1888  e.preventDefault()
1889  const form = $(this)
1890  let button = form.find('button')
1891  let buttonOld = button.html()
1892  button
1893    .addClass('disable')
1894    .css('width', button.outerWidth() + 'px')
1895    .css('height', button.outerHeight() + 'px')
1896    .html(loader)
1897  $.ajax({
1898    url: form.attr('action'),
1899    data: {
1900      phone: form.find('.lk-modal__phone-place').text(),
1901      cabinet_csrf: $('#cabinet_csrf').val(),
1902    },
1903    success(data) {
1904      button.html(buttonOld)
1905      form.addClass(lkCLASS.view_hidden).removeClass(lkCLASS.view_active)
1906      form.next().removeClass(lkCLASS.view_hidden).addClass(lkCLASS.view_active)
1907      form
1908        .next()
1909        .find('.lk-modal__phone-place')
1910        .text(form.find('.lk-modal__phone-place').text())
1911      form
1912        .next()
1913        .attr('data-phone', form.find('.lk-modal__phone-place').text())
1914        .attr('data-code', 1234)
1915      codeResendTimer(3, form.next().find('.login__reminder-timer-counter'))
1916    },
1917    error() {
1918      button.html(buttonOld)
1919    },
1920  })
1921})
1922
1923$('.lk-modal__confirm-code').on('submit', function (e) {
1924  e.preventDefault()
1925  const form = $(this)
1926  let button = form.find('button')
1927  let buttonOld = button.html()
1928  if (!form.find('input').val()) {
1929    form.find('input').addClass('validate-error')
1930    addErrorMessage({
1931      message: 'Введите код',
1932      position: 'bottom',
1933      element: form.find('input'),
1934      className: 'survey-block__inner-error',
1935    })
1936    return
1937  }
1938  if (form.attr('data-code') !== form.find('input').val()) {
1939    form.find('input').addClass('validate-error')
1940    addErrorMessage({
1941      message: 'Неверный код',
1942      position: 'bottom',
1943      element: form.find('input'),
1944      className: 'survey-block__inner-error',
1945    })
1946    return
1947  }
1948  button
1949    .addClass('disable')
1950    .css('width', button.outerWidth() + 'px')
1951    .css('height', button.outerHeight() + 'px')
1952    .html(loader)
1953  $.ajax({
1954    url: form.attr('action'),
1955    data: { code: form.attr('data-code') },
1956    success(data) {
1957      button.html(buttonOld)
1958      form.addClass(lkCLASS.view_hidden).removeClass(lkCLASS.view_active)
1959      form.next().removeClass(lkCLASS.view_hidden).addClass(lkCLASS.view_active)
1960    },
1961    error() {
1962      button.html(buttonOld)
1963    },
1964  })
1965})
1966
1967$('.lk-modal__set-phone').on('submit', function (e) {
1968  e.preventDefault()
1969  const form = $(this)
1970  let button = form.find('button')
1971  let buttonOld = button.html()
1972
1973  if (!form.find('input').val().replace(/\D+/g, '')) {
1974    form.find('input').addClass('validate-error')
1975    addErrorMessage({
1976      message: 'Введите номер телефона',
1977      position: 'bottom',
1978      element: form.find('input'),
1979      className: 'survey-block__inner-error',
1980    })
1981    return
1982  }
1983
1984  if (form.find('input').val().replace(/\D+/g, '').length < 10) {
1985    form.find('input').addClass('validate-error')
1986    addErrorMessage({
1987      message: 'Некорректный номер телефона',
1988      position: 'bottom',
1989      element: form.find('input'),
1990      className: 'survey-block__inner-error',
1991    })
1992    return
1993  }
1994  button
1995    .addClass('disable')
1996    .css('width', button.outerWidth() + 'px')
1997    .css('height', button.outerHeight() + 'px')
1998    .html(loader)
1999
2000  $.ajax({
2001    url: form.attr('action'),
2002    data: {
2003      phone: form.find('input').val().replace(/\D+/g, ''),
2004      cabinet_csrf: $('#cabinet_csrf').val(),
2005    },
2006    success(data) {
2007      button.html(buttonOld)
2008      form.addClass(lkCLASS.view_hidden).removeClass(lkCLASS.view_active)
2009      form.next().removeClass(lkCLASS.view_hidden).addClass(lkCLASS.view_active)
2010      form.next().find('.lk-modal__phone-place').text(form.find('input').val())
2011      form
2012        .next()
2013        .attr('data-phone', form.find('input').val())
2014        .attr('data-code', 1234)
2015      codeResendTimer(3, form.next().find('.login__reminder-timer-counter'))
2016    },
2017    error() {
2018      button.html(buttonOld)
2019    },
2020  })
2021})
2022
2023$('.lk-modal__confirm-phonecode').on('submit', function (e) {
2024  e.preventDefault()
2025  const form = $(this)
2026  let button = form.find('button')
2027  let buttonOld = button.html()
2028  if (!form.find('input').val()) {
2029    form.find('input').addClass('validate-error')
2030    addErrorMessage({
2031      message: 'Введите код',
2032      position: 'bottom',
2033      element: form.find('input'),
2034      className: 'survey-block__inner-error',
2035    })
2036    return
2037  }
2038  if (form.attr('data-code') !== form.find('input').val()) {
2039    form.find('input').addClass('validate-error')
2040    addErrorMessage({
2041      message: 'Неверный код',
2042      position: 'bottom',
2043      element: form.find('input'),
2044      className: 'survey-block__inner-error',
2045    })
2046    return
2047  }
2048  button
2049    .addClass('disable')
2050    .css('width', button.outerWidth() + 'px')
2051    .css('height', button.outerHeight() + 'px')
2052    .html(loader)
2053  $.ajax({
2054    url: form.attr('action'),
2055    data: { code: form.attr('data-code') },
2056    success(data) {
2057      button.html(buttonOld)
2058    },
2059    error() {
2060      button.html(buttonOld)
2061    },
2062  })
2063})
2064
2065$('.lk-modal__view-input').on('change input blur click', function (e) {
2066  $(this).closest('form').find('.error').remove()
2067})

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.