PageSourceSearch

https://dinastiy.ru/local/templates/dinastiy/script/script_modified.js?v=1168627947

js dinastiy.ru collected 2026-09-28 13:31:01 UTC 28,151 bytes, 783 lines download raw bytes

1if (function() {
2    if (document.querySelector(".js-main-slider")) {
3        new Swiper(".js-main-slider", {
4            init: !0,
5            speed: 1200,
6            slidesPerView: 1,
7            loop: !1,
8            parallax: !0,
9            autoHeight: !0,
10            direction: "horizontal",
11            watchOverflow: !0,
12            autoplay: {
13                delay: 5000,
14            },
15            pagination: {
16                el: ".js-main-slider-pagination",
17                clickable: !0
18            },
19            navigation: {
20                nextEl: ".js-main-slider-arrow-right",
21                prevEl: ".js-main-slider-arrow-left"
22            }
23        })
24    }
25    if (document.querySelector(".js-reviews-slider")) {
26        new Swiper(".js-reviews-slider", {
27            breakpoints: {
28                320: {
29                    spaceBetween: 32
30                },
31                1480: {
32                    spaceBetween: 36
33                }
34            },
35            speed: 1200,
36            slidesPerView: "auto",
37            loop: !1,
38            parallax: !0,
39            direction: "horizontal",
40            watchOverflow: !0,
41            navigation: {
42                nextEl: ".js-reviews-slider-arrow-right",
43                prevEl: ".js-reviews-slider-arrow-left"
44            }
45        })
46    }
47    if (document.querySelector(".js-news-element-slider")) {
48        new Swiper(".js-news-element-slider", {
49            init: !0,
50            speed: 1e3,
51            slidesPerView: 1,
52            loop: !1,
53            parallax: !0,
54            autoHeight: !0,
55            direction: "horizontal",
56            watchOverflow: !0,
57            spaceBetween: 20,
58            pagination: {
59                el: ".js-news-slider-pagination",
60                clickable: !0
61            },
62            navigation: {
63                nextEl: ".js-news-slider-arrow-right",
64                prevEl: ".js-news-slider-arrow-left"
65            }
66        })
67    }
68}(), GLightbox({
69    touchNavigation: !0,
70    loop: !0,
71    autoplayVideos: !0
72}), function() {
73    function e(e) {
74        let t = this.querySelectorAll("input, select, textarea"),
75            n = [];
76
77        function o(e) {
78            e.hasAttribute("data-req") && n.push(e)
79        }
80
81        function i(e) {
82            e.classList.contains("error") && e.classList.remove("error")
83        }
84
85        function s(e, t, o) {
86            o.test(t) ? i(e) : n.push(e)
87        }
88        t.forEach((function(e) {
89            let t;
90alert("yes");
91            switch (t = e.hasAttribute("type") ? e.getAttribute("type") : e.getAttribute("data-type"), t) {
92                case "text":
93                    if ("" == e.value) o(e);
94                    else {
95                        let t;
96                        switch (e.getAttribute("data-content")) {
97                            case "surname":
98                            case "name":
99                                t = new RegExp("^[a-zа-яё -]{1,}$", "i"), s(e, e.value, t);
100                                break;
101                            case "phone":
102                                t = new RegExp("^[0-9-()+]{7,}$"), s(e, e.value, t);
103                                break;
104                            case "date":
105                                t = new RegExp("^[0-9]{1,4}[.]{1}[0-9]{1,4}[.]{1}[0-9]{1,4}$"), s(e, e.value, t);
106                                break;
107                            case "mail":
108                                t = new RegExp("^[a-z0-9_-]{1,}@{1}[a-z]{1,}[.]{1}[a-z]{3}$", "i"), s(e, e.value, t)
109                        }
110                    }
111                    break;
112                case "textarea":
113                    "" == e.value ? o(e) : i(e);
114                    break;
115                case "checkbox":
116                    e.checked ? i(e) : o(e)
117            }
118        }
118)), n.length && (e.preventDefault(), n.forEach((function(e) {
119            e.classList.contains("error") || e.classList.add("error")
120        })))
121    }
122  /*  document.querySelector("form.form.js__form") && document.querySelectorAll("form.form.js__form").forEach((function(t) {
123        t.addEventListener("submit", e)
124    })); */
125    let t = document.querySelectorAll(".js-imask-phone"),
126        n = {
127            mask: "+{7}(000)000-00-00",
128            lazy: !1
129        };
130    for (let e = 0; e < t.length; e++) {
131        IMask(t[e], n)
132    }
133    let o = document.querySelectorAll(".js-imask-date"),
134        i = {
135            mask: Date,
136            lazy: !1,
137            min: new Date(1930, 0, 1),
138            max: new Date(2030, 0, 1)
139        };
140    for (let e = 0; e < o.length; e++) {
141        IMask(o[e], i)
142    }
143}(), function() {
144    function e() {
145        let e = document.querySelector("[data-popup=" + this.getAttribute("data-popup-for") + "]");
146        e && (document.body.classList.add("js-popup-is-open"), e.classList.add("js-active-popup"))
147    }
148
149    function t() {
150        if (document.querySelector(".js-active-popup")) {
151            document.querySelector(".js-active-popup").classList.remove("js-active-popup");
152        }
153        document.body.classList.remove("js-popup-is-open");
154    }
155    document.body.addEventListener("click", (function(e) {
156        e.target.classList.contains("js-close-popup") && t()
157    }));
158
159    document.querySelectorAll(".js-popup-button").forEach(function(t) {
160        t.addEventListener("click", e);
161    });
162
163    // document.querySelector(".js-popup-button") && document.querySelector(".js-close-popup-button") && (document.querySelectorAll(".js-popup-button").forEach((function(t) {
164    //     t.addEventListener("click", e)
165    // }));
166
167    document.querySelectorAll(".js-close-popup-button").forEach((function(e) {
168        e.addEventListener("click", t)
169    }))
170}(), document.getElementById("map-1")) {
171function init_bk() {
172    let e = new ymaps.Map("map-1", {
173            center: [56.831886, 60.62048],
174            zoom: 15,
175            //controls: []
176        }),
177        t = new ymaps.Placemark([56.831886, 60.62048], {
178            hintContent: "",
179            balloonContent: ""
180        }, {
181            iconLayout: "default#image",
182            iconImageHref: "/local/templates/dinastiy/images/pin.png",
183            iconImageSize: [32, 37],
184            iconImageOffset: [-16, -37],
185            cursor: 'grab',
186        });
187    e.geoObjects.add(t)
188}
189// ymaps.ready(init)
190
191
192
193}
194
195
196
197
198
199
200/*
201if (document.querySelectorAll(".ymaps-map")) {
202let elems = document.querySelectorAll(".ymaps-map");
203
204for( var i = 0; i < elems.length; ++i ) {
205    let coord_lat = elems[i].dataset.lat;
206    let coord_lon = elems[i].dataset.lon;
207    let k = elems[i].dataset.id;
208    //let k = i+1;
209    ymaps.ready(function() {
210        let e = new ymaps.Map(("map-"+k), {
211                center: [coord_lat, coord_lon],
212                zoom: 15,
213                //controls: []
214            }),
215            t = new ymaps.Placemark([coord_lat, coord_lon], { //[56.795475, 60.624631]
216                hintContent: "",
217                balloonContent: ""
218            }, {
219                iconLayout: "default#image",
220                iconImageHref: "/local/templates/dinastiy/images/pin.png",
221                iconImageSize: [32, 37],
222                iconImageOffset: [-16, -37],
223                cursor: 'grab',
224            });
225        e.geoObjects.add(t);
226    });
227}
228}*/
229
230if (document.querySelectorAll(".ymaps-map")) {
231ymaps.ready(function() {
232    let elems = document.querySelectorAll(".ymaps-map");
233    for( var i = 0; i < elems.length; ++i ) {
234        let coord_lat = elems[i].dataset.lat;
235        let coord_lon = elems[i].dataset.lon;
236        let k = elems[i].dataset.id;
237
238        let e = new ymaps.Map(("map-"+k), {
239                center: [coord_lat, coord_lon],
240                zoom: 15,
241                //controls: []
242            }),
243            t = new ymaps.Placemark([coord_lat, coord_lon], { //[56.795475, 60.624631]
244                hintContent: "",
245                balloonContent: ""
246            }, {
247                iconLayout: "default#image",
248                iconImageHref: "/local/templates/dinastiy/images/pin.png",
249                iconImageSize: [32, 37],
250                iconImageOffset: [-16, -37],
251                cursor: 'grab',
252            });
253        e.geoObjects.add(t);
254    }
255});
256}
257
258
259
260
261/*
262if (document.getElementById("map-20")) {
263function init() {
264    let e = new ymaps.Map("map-20", {
265            center: [56.795475, 60.624631],
266            zoom: 15,
267            //controls: []
268        }),
269        t = new ymaps.Placemark([56.795475, 60.624631], {
270            hintContent: "",
271            balloonContent: ""
272        }, {
273            iconLayout: "default#image",
274            iconImageHref: "/local/templates/dinastiy/images/pin.png",
275            iconImageSize: [32, 37],
276            iconImageOffset: [-16, -37],
277            cursor: 'grab',
278        });
279    e.geoObjects.add(t)
280}
281ymaps.ready(init)
282}*/
283! function() {
284let e = document.querySelectorAll(".js-tabs");
285if (e)
286    for (let n = 0; n < e.length; n++) {
287        new t(e[n])
288    }
289
290function t(e) {
291    let t = e.querySelectorAll("[data-tab]");
292    if (t)
293        for (let o = 0; o < t.length; o++) t[o].addEventListener("click", n.bind(null, e, t[o]));
294    o(e.querySelector(".tabs__item--active").firstElementChild, e)
295}
296
297function n(e, t) {
298    e.querySelector(".tabs__item--active").classList.remove("tabs__item--active"), t.parentElement.classList.add("tabs__item--active"), o(t, e)
299}
300
301function o(e, t) {
302    let n = document.querySelector("[data-tabs-content=" + t.getAttribute("data-tabs") + "]");
303    if (n) {
304        let t = n.querySelectorAll("[data-tab-content]");
305        if ("all" == e.getAttribute("data-tab"))
306            for (let e = 0; e < t.length; e++) t[e].classList.contains("js-content-is-hidden") && t[e].classList.remove("js-content-is-hidden");
307        else
308            for (let n = 0; n < t.length; n++) t[n].getAttribute("data-tab-content").includes(e.getAttribute("data-tab")) ? t[n].classList.contains("js-content-is-hidden") && t[n].classList.remove("js-content-is-hidden") : t[n].classList.contains("js-content-is-hidden") || t[n].classList.add("js-content-is-hidden")
309    }
310}
311}(),
312function() {
313let e = document.querySelector(".header");
314if (window.addEventListener("scroll", (function() {
315        window.pageYOffset > 1 ? e.classList.add("header__fixed") : e.classList.remove("header__fixed")
316    })), document.querySelector(".js-service-menu")) {
317    let e = document.querySelector(".js-service-menu"),
318        t = document.querySelector(".service__info-hero"),
319        n = window.pageYOffset + e.getBoundingClientRect().top;
320    document.documentElement.clientWidth > 1479 && window.addEventListener("scroll", (function() {
321        window.pageYOffset > n - 91 ? (e.classList.add("service__menu--fixed"), t.classList.add("service__info-hero--position")) : (e.classList.remove("service__menu--fixed"), t.classList.remove("service__info-hero--position"))
322    })) && window.addEventListener("DOMContentLoaded", (function() {
323        window.pageYOffset > n - 91 ? (e.classList.add("service__menu--fixed"), t.classList.add("service__info-hero--position")) : (e.classList.remove("service__menu--fixed"), t.classList.remove("service__info-hero--position"))
324    }))
325}
326}(),
327function() {
328let e = document.querySelectorAll(".js-choices-dependent");
329if (e)
330    for (let t = 0; t < e.length; ++t) serviceChoices = new Choices(e[t], {
331        silent: !1,
332        shouldSort: false,
333       shouldSortItems: false,
334        searchEnabled: !1,
335        resetScrollPosition: !0,
336        classNames: {
337            containerOuter: "choices",
338            containerInner: "choices__inner",
339            item: "choices__item"
340        }
341    })
342}(),
343function() {
344let e = document.querySelectorAll(".js-bubble-hover");
345e && e.forEach(e => {
346    e.addEventListener("mouseenter", n), e.addEventListener("mouseleave", (function() {
347        t = !0
348    }))
349});
350let t = !0;
351
352function n(e) {
353    if (!t) return;
354    t = !1;
355    let n = this.offsetWidth;
356    this.offsetWidth > this.offsetHeight && (n = this.offsetHeight);
357    let o = document.createElement("div");
358    o.className = "bubble-container", o.style.width = n + "px", o.style.height = n + "px", o.style.left = e.clientX - this.getBoundingClientRect().left - n / 2 + "px", o.style.top = e.clientY - this.getBoundingClientRect().top - n / 2 + "px";
359    let i = document.createElement("div");
360    i.className = "bubble", o.append(i), this.prepend(o), setTimeout((function() {
361        o.remove()
362    }), 500)
363}
364}(), document.addEventListener( "DOMContentLoaded", function() {			
365[].forEach.call(document.querySelectorAll('a[data-al]'), function(el){
366            var href = el.getAttribute('data-al');
367            if (href) {
368                el.setAttribute('href', href);
369            }
370})
371}),
372function() {
373    function e(e) {
374        let n = {};
375        n.theme = e.getAttribute("data-for");
376        let o = document.querySelectorAll(".js-filtered-content");
377        if (o)
378            for (let e = 0; e < o.length; e++)
379                if (o[e].getAttribute("data-content") == n.theme) {
380                    n.for = o[e];
381                    break
382                } let i = e.querySelector(".js-choice");
383        t(i, n.for), i.addEventListener("change", t.bind(null, i, n.for))
384    }
385
386    function t(e, t) {
387        let n = t.querySelectorAll("[data-filter-group]");
388        if (n) switch (e.value) {
389            case "all-branches":
390                for (let e = 0; e < n.length; e++) n[e].classList.contains("js-content-is-hidden") && n[e].classList.remove("js-content-is-hidden");
391                break;
392            default:
393                for (let t = 0; t < n.length; t++) {
394                    let o = !1,
395                        i = n[t].getAttribute("data-filter-group").split(" ");
396                    for (let t = 0; t < i.length; t++) i[t] == e.value && (o = !0);
397                    switch (o) {
398                        case !0:
399                            n[t].classList.contains("js-content-is-hidden") && n[t].classList.remove("js-content-is-hidden");
400                            break;
401                        case !1:
402                            n[t].classList.contains("js-content-is-hidden") || n[t].classList.add("js-content-is-hidden")
403                    }
404                }
405        }
406    }
407    let n = document.querySelectorAll(".js-select-filter");
408    if (n)
409        for (let t = 0; t < n.length; t++) {
410            new e(n[t])
411        }
412}(), document.querySelectorAll(".js-accordion-open").forEach((function(e) {
413    e.addEventListener("click", (function(e) {
414        e.preventDefault();
415        let t = e.target;
416        t.closest(".js-accordion-open") && t.closest(".js-accordion").classList.toggle("opened")
417    }))
418})),
419function() {
420    function e(e) {
421        let n = document.querySelector("[data-anchor=" + e.getAttribute("data-target") + "]");
422        n && e.addEventListener("click", (function(e) {
423            e.preventDefault(), t || function e(n) {
424                t = !0;
425                Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight);
426                let o = window.pageYOffset + n.getBoundingClientRect().top;
427                if (o > window.pageYOffset) {
428                    let i = o - window.pageYOffset - 200;
429                    i > 60 ? (window.scrollTo(0, window.pageYOffset + 60), setTimeout((function() {
430                        e(n)
431                    }), 15)) : (window.scrollTo(0, window.pageYOffset + i), t = !1)
432                } else {
433                    let i = window.pageYOffset - o + 200;
434                    i > 60 ? (window.scrollTo(0, window.pageYOffset - 60), setTimeout((function() {
435                        e(n)
436                    }), 15)) : (window.scrollTo(0, window.pageYOffset - i), t = !1)
437                }
438            }(n)
439        }))
440    }
441    let t = !1;
442    let n = document.querySelectorAll(".js-scroll-button");
443    if (n)
444        for (let t = 0; t < n.length; t++) {
445            new e(n[t])
446        }
447}(),
448// document.querySelector(".js-close-cookie") && document.body.classList.contains("js-cookie-is-show") && document.querySelector(".js-close-cookie").addEventListener("click", (function() {
449//     console.log(1);
450//     setCookie('cookie', 'close');
451//     document.body.classList.remove("js-cookie-is-show");
452// }));
453
454
455(function reviewText() { //вставка текста отзыва в попап отзыва
456if(document.querySelector(".review__button")){
457    const reviewBtns = document.querySelectorAll(".review__button");
458    reviewBtns.forEach((i) => i.addEventListener("click", function(){
459        const wrap = i.parentElement;
460        const name = wrap.querySelector(".review__author").innerHTML;
461        const date = wrap.querySelector(".review__date").innerHTML;
462        const text = wrap.querySelector(".review__description").innerHTML;
463        const popup = document.querySelector(".review-text-popup");
464        const popupName = popup.querySelector(".review__author");
465        const popupDate = popup.querySelector(".review__date");
466        const popupText = popup.querySelector(".review__description");
467        popupName.innerHTML = name;
468        popupDate.innerHTML = date;
469        popupText.innerHTML = text;
470    }));
471}
472})();
473
474function setCookie(name, value) {
475const expires = new Date(Date.now() + 86400e3 * 365 * 10);
476
477let options = {
478    path: '/',
479    expires: expires,
480};
481if (options.expires instanceof Date) {
482  options.expires = options.expires.toUTCString();
483}
484let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
485for (let optionKey in options) {
486  updatedCookie += "; " + optionKey;
487  let optionValue = options[optionKey];
488  if (optionValue !== true) {
489    updatedCookie += "=" + optionValue;
490  }
491}
492document.cookie = updatedCookie;
493}
494function getCookie(name) {
495let matches = document.cookie.match(new RegExp(
496  "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
497));
498return matches ? decodeURIComponent(matches[1]) : undefined;
499}
500
501(function cookieCheck() {
502if (getCookie("cookie") == "close") {
503document.body.classList.remove("js-cookie-is-show");
504} else {
505document.body.classList.add("js-cookie-is-show");
506if (
507  document.querySelector(".js-close-cookie") &&
508  document.body.classList.contains("js-cookie-is-show")
509) {
510  document
511    .querySelector(".js-close-cookie")
512    .addEventListener("click", function () {
513      setCookie("cookie", "close");
514      document.body.classList.remove("js-cookie-is-show");
515    });
516}
517}
518})();
519
520
521document.querySelectorAll('a[href^="#"]').forEach(link=>{
522link.addEventListener('click', function(){
523    event.preventDefault();
524    let anchor = link.attributes.href.textContent
525    let pos = document.querySelector(`${anchor}`).getBoundingClientRect().top + document.documentElement.scrollTop;
526    // console.log(pos)
527    window.scrollTo({
528        top: pos - 140,
529        behavior: 'smooth'
530    });
531})
532})
533
534if (!!document.querySelectorAll('.js-service-description-with-opener').length){
535let block = document.querySelector('.js-service-description-with-opener')
536if (block.clientHeight > 300) {
537    block.classList.add('js-hidden');
538}
539document.querySelector('.service__description-opener').addEventListener('click', function(){
540    block.classList.toggle('js-opened')
541})
542} 
543
544new isvek.Bvi({
545target: '.bvi-btn',
546});
547
548document.querySelectorAll('.bvi-btn').forEach(button=>{
549button.addEventListener('click', function(){
550    window.scrollTo({top: 0, behavior: 'smooth'})
551})
552})
553
554if(document.querySelector(".main-slider__tag-right")){
555document.querySelectorAll('.main-slider__tag-right').forEach(el=>{
556    el.querySelector('.main-slider__tag-right-button').addEventListener('click', function(){
557        el.classList.toggle('opened')
558        if (el.classList.contains('copied')) {
559            el.classList.remove('copied')
560        }
561    })
562    el.querySelector('.main-slider__tag-copy').addEventListener('click', function(){
563        
564        navigator.clipboard.writeText(el.querySelector('.main-slider__tag-text').textContent);
565        el.classList.add('copied')
566    })
567    
568})
569}
570
571function getServicesList(){
572
573const request = new XMLHttpRequest();
574const url = "/ajax/services_list.php";
575const params = "";
576
577request.open("POST", url, true);
578request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
579request.addEventListener("readystatechange", () => {
580
581    if (request.readyState === 4 && request.status === 200) {
582
583        let serviceList = document.querySelector('.select_container_services-options');
584        let arrServicesName = JSON.parse(request.responseText);
585
586        arrServicesName.forEach(serviceName => {
587            let newOption = new Option(serviceName);
588            serviceList.append(newOption);
589        })
590        document.querySelectorAll('select.select_container_services-options').forEach(el=>{const choices = new Choices(el)})
591
592    }
593});
594
595request.send(params);
596
597}
598setTimeout(getServicesList(), 1000);
599
600
601
602// добавлено 22.11.2023
603// change tabs in page doctors
604(function(){
605document.querySelectorAll('.reception-at-clinic__tab').forEach(tab => {
606    tab.addEventListener('click', e => {
607        let id = tab.getAttribute('data-id');
608        document.querySelectorAll('.reception-at-clinic__tab').forEach(tab => {
609            tab.classList.remove('is-active');
610        });
611        document.querySelectorAll('.reception-at-clinic__tab-content').forEach(content => {
612            content.classList.remove('is-active');
613        });
614        tab.classList.add('is-active');
615        document.querySelector(`.reception-at-clinic__tab-content[data-id='${id}']`).classList.add('is-active');
616    });
617});
618})();
619
620
621(function(){
622document.addEventListener("keyup", (e) => {
623    if (e.key === "Escape") {
624        if(document.querySelector('.popup__close-button')) {
625            document.querySelector('.popup__close-button').click();
626        }
627
628    }
629});
630})();
631
632document.addEventListener('DOMContentLoaded', () => {
633
634const blockReview = document.querySelector('.reviews');
635if (blockReview) {
636
637    const reviews = blockReview.querySelectorAll('.review');
638    reviews.forEach(review => {
639        const description = review.querySelector('.review__description');
640        if (getCountLetters(description) < 170) {
641            review.querySelector('.review__button').style.display = 'none';
642        }
643
644    });
645
646    function getCountLetters(value) {
647        return value.textContent.trim().length;
648    }
649
650}
651
652if (!!document.querySelector('.diseases')) {
653    let block = document.querySelector('.diseases')
654    let button = document.querySelector('.js-diseases-show-more')
655    let children = 0;
656
657    if (document.querySelectorAll('.diseases__item').length < 10) {
658        block.classList.add('inline')
659    }
660    document.querySelectorAll('.diseases__list .diseases__block-list').forEach(list=>{
661        for (let i = 0; i < 5; i++) {
662            if (!!list.querySelector('.diseases__item:not(.show)') && children < 5) {
663                list.closest('.diseases__block').classList.add('show')
664                list.closest('.diseases__list-col').classList.add('show')
665                list.querySelector('.diseases__item:not(.show)').classList.add('show');
666                children++
667            }
668        }
669    })
670    button.addEventListener('click', function(){
671        block.classList.toggle('opened') 
672    })
673}
674
675    if (!!document.querySelector('.prices__search')) {
676        let searchInput = document.querySelector('.prices__search');
677        let groups = Array.from(document.querySelectorAll('.prices__items'));
678
679        let LOOKALIKES = {
680            'а': 'a', 'А': 'A',
681            'в': 'b', 'В': 'B',
682            'е': 'e', 'Е': 'E',
683            'к': 'k', 'К': 'K',
684            'м': 'm', 'М': 'M',
685            'н': 'h', 'Н': 'H',
686            'о': 'o', 'О': 'O',
687            'р': 'p', 'Р': 'P',
688            'с': 'c', 'С': 'C',
689            'т': 't', 'Т': 'T',
690            'х': 'x', 'Х': 'X',
691            'у': 'y', 'У': 'Y',
692            'і': 'i', 'І': 'I'
693        };
694
695        let ENDINGS = [
696            'иями', 'ями', 'иях', 'ями', 'иям', 'ией', 'ием',
697            'ого', 'его', 'ому', 'ему', 'ыми', 'ими',
698            'ая', 'яя', 'ое', 'ее', 'ые', 'ие', 'ых', 'их', 'ым', 'им', 'ом', 'ем',
699            'ов', 'ев', 'ей', 'ой', 'ый', 'ию', 'ия', 'ии', 'ий',
700            'а', 'я', 'ы', 'и', 'е', 'о', 'у', 'ю', 'ь'
701        ].sort((a, b) => b.length - a.length);
702
703        function normalize(str) {
704            return str.toLowerCase().trim().split('').map(ch => (LOOKALIKES[ch] ? LOOKALIKES[ch].toLowerCase() : ch)).join('');
705        }
706
707        function stem(word) {
708            for (let ending of ENDINGS) {
709                if (word.length - ending.length >= 3 && word.endsWith(ending)) {
710                    return word.slice(0, word.length - ending.length);
711                }
712            }
713            return word;
714        }
715
716        // Разбиваем по ЛЮБОМУ символу, который не буква и не цифра
717        // (скобки, звёздочки, слэши, дефисы, кавычки, знаки пунктуации и т.д. — всё считается разделителем)
718        function tokenize(str) {
719            return normalize(str)
720                .split(/[^a-zа-яё0-9]+/iu)
721                .filter(Boolean);
722        }
723
724        function wordMatches(queryToken, targetToken) {
725            // Ищем частичное совпадение в любом месте слова, а не только в начале —
726            // это решает случай "биоревитализация" внутри "(биоревитализация)"
727            if (targetToken.includes(queryToken)) return true;
728            if (stem(queryToken) === stem(targetToken)) return true;
729            return false;
730        }
731
732        function itemMatchesQuery(queryTokens, nameTokens, normalizedCode) {
733            return queryTokens.every(qToken => {
734                let matchesName = nameTokens.some(nToken => wordMatches(qToken, nToken));
735                let matchesCode = normalizedCode.includes(qToken);
736                return matchesName || matchesCode;
737            });
738        }
739
740        function filterPrices() {
741            let rawQuery = searchInput.value.trim();
742            let queryTokens = tokenize(rawQuery);
743
744            groups.forEach(group => {
745                let items = Array.from(group.querySelectorAll('.prices__item'));
746                let visibleCount = 0;
747
748                items.forEach(item => {
749                    let nameEl = item.querySelector('.prices__item-name');
750                    let codeEl = item.querySelector('.prices__item-code');
751
752                    let nameTokens = nameEl ? tokenize(nameEl.textContent) : [];
753                    let normalizedCode = codeEl ? normalize(codeEl.textContent) : '';
754
755                    let isMatch =
756                        queryTokens.length === 0 ||
757                        itemMatchesQuery(queryTokens, nameTokens, normalizedCode);
758
759                    item.style.display = isMatch ? '' : 'none';
760                    if (isMatch) visibleCount++;
761                });
762
763                let groupHeading = group.querySelector('.prices__items-heading-2');
764                let groupSubHeading = group.querySelector('.prices__items-heading');
765
766                group.style.display = visibleCount === 0 ? 'none' : '';
767                if (groupHeading) {
768                    groupHeading.style.display = visibleCount === 0 ? 'none' : '';
769                }
770                if (groupSubHeading) {
771                    groupSubHeading.style.display = visibleCount === 0 ? 'none' : '';
772                }
773            });
774        }
775
776        let debounceTimer;
777        searchInput.addEventListener('input', function () {
778            clearTimeout(debounceTimer);
779            debounceTimer = setTimeout(filterPrices, 150);
780        });
781    }
782
783});

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.