1$(document).ready(function() { 2 function getAutoplayConfig() { 3 return { 4 delay: 7000, 5 disableOnInteraction: false, 6 pauseOnMouseEnter: true 7 }; 8 } 9 10 function getSliderOriginalCount(selector) { 11 var $slider = $(selector); 12 13 if (!$slider.length) { 14 return 0; 15 } 16 17 return $slider.find('.swiper-wrapper > .swiper-slide').not('.swiper-slide-duplicate').length; 18 } 19 20 function getLoopConfig(selector, minSlides) { 21 var count = getSliderOriginalCount(selector); 22 var shouldLoop = count >= (minSlides || 2); 23 24 return { 25 loop: shouldLoop, 26 rewind: !shouldLoop 27 }; 28 } 29 30 var topBannerLoopConfig = getLoopConfig('.top-banner__slider', 2); 31 32 new Swiper('.top-banner__slider', { 33 autoplay: topBannerLoopConfig.loop ? getAutoplayConfig() : false, 34 loop: topBannerLoopConfig.loop, 35 rewind: topBannerLoopConfig.rewind, 36 slidesPerView: 1, 37 effect: 'slide', 38 pagination: { 39 el: '.top-banner__pagination', 40 clickable: true 41 }, 42 navigation: { 43 nextEl: '.top-banner__button--next', 44 prevEl: '.top-banner__button--prev' 45 } 46 }); 47 48 var possibilitiesLoopConfig = getLoopConfig('.possibilities-slider', 2); 49 50 new Swiper('.possibilities-slider', { 51 autoplay: possibilitiesLoopConfig.loop ? { 52 delay: 2000, 53 disableOnInteraction: false, 54 pauseOnMouseEnter: true 55 } : false, 56 loop: possibilitiesLoopConfig.loop, 57 rewind: possibilitiesLoopConfig.rewind, 58 watchOverflow: true, 59 slidesPerView: 'auto', 60 spaceBetween: 20, 61 pagination: { 62 el: '.possibilities .swiper-pagination', 63 clickable: true 64 }, 65 navigation: { 66 nextEl: '.possibilities-nav__button--next', 67 prevEl: '.possibilities-nav__button--prev' 68 }, 69 breakpoints: { 70 0: { 71 slidesPerView: 'auto', 72 spaceBetween: 12 73 }, 74 768: { 75 slidesPerView: 'auto', 76 spaceBetween: 20 77 } 78 } 79 }); 80 81 var $historySlider = $('.history-slider'); 82 83 if ($historySlider.length) { 84 var historyOriginalCount = parseInt($historySlider.attr('data-history-original-count'), 10) || getSliderOriginalCount('.history-slider'); 85 var historyShouldLoop = historyOriginalCount > 1; 86 87 new Swiper('.history-slider', { 88 autoplay: historyShouldLoop ? getAutoplayConfig() : false, 89 loop: historyShouldLoop, 90 rewind: !historyShouldLoop, 91 watchOverflow: true, 92 slidesPerView: 2, 93 slidesPerGroup: 1, 94 spaceBetween: 35, 95 pagination: { 96 el: '.history .swiper-pagination', 97 clickable: true 98 }, 99 navigation: { 100 nextEl: '.history-nav__button--next', 101 prevEl: '.history-nav__button--prev' 102 }, 103 breakpoints: { 104 0: { 105 slidesPerView: 1, 106 spaceBetween: 16 107 }, 108 768: { 109 slidesPerView: 2, 110 spaceBetween: 35 111 } 112 } 113 }); 114 } 115 116 var changesLoopConfig = getLoopConfig('.changes-slider', 2); 117 118 new Swiper('.changes-slider', { 119 autoplay: changesLoopConfig.loop ? getAutoplayConfig() : false, 120 loop: changesLoopConfig.loop, 121 rewind: changesLoopConfig.rewind, 122 slidesPerView: 1, 123 spaceBetween: 30, 124 autoHeight: true, 125 pagination: { 126 el: '.changes .swiper-pagination', 127 clickable: true 128 }, 129 navigation: { 130 nextEl: '.changes-nav__button--next', 131 prevEl: '.changes-nav__button--prev' 132 } 133 }); 134 135 var implementationSwiper = null; 136 137 138 function toggleImplementationSwiper() { 139 if (window.innerWidth > 767) { 140 if (!implementationSwiper) { 141 implementationSwiper = new Swiper('.implementation-slider', { 142 autoplay: { 143 delay: 7000, 144 disableOnInteraction: false, 145 pauseOnMouseEnter: true, 146 stopOnLastSlide: true 147 }, 148 loop: false, 149 rewind: false, 150 slidesPerView: 'auto', 151 spaceBetween: 24, 152 pagination: { 153 el: '.implementation .swiper-pagination', 154 clickable: true 155 }, 156 navigation: { 157 nextEl: '.implementation-nav__button--next', 158 prevEl: '.implementation-nav__button--prev' 159 } 160 }); 161 } 162 } else if (implementationSwiper) { 163 implementationSwiper.destroy(true, true); 164 implementationSwiper = null; 165 } 166 } 167 168 toggleImplementationSwiper(); 169 170 $(window).on('resize', function() { 171 toggleImplementationSwiper(); 172 }); 173 174 var clientsLoopConfig = getLoopConfig('.clients-slider', 5); 175 176 new Swiper('.clients-slider', { 177 autoplay: clientsLoopConfig.loop ? { 178 delay: 1000, 179 disableOnInteraction: false, 180 pauseOnMouseEnter: true 181 } : false, 182 loop: clientsLoopConfig.loop, 183 rewind: clientsLoopConfig.rewind, 184 slidesPerView: 3.9, 185 spaceBetween: 30, 186 pagination: { 187 el: '.clients .swiper-pagination', 188 clickable: true 189 }, 190 navigation: { 191 nextEl: '.clients-nav__button--next', 192 prevEl: '.clients-nav__button--prev' 193 }, 194 breakpoints: { 195 0: { 196 slidesPerView: 1.12, 197 spaceBetween: 12 198 }, 199 768: { 200 slidesPerView: 3.9, 201 spaceBetween: 30 202 } 203 } 204 }); 205
206 var benefitsSwiper = null; 207 208 function toggleBenefitsSwiper() { 209 if (window.innerWidth <= 767) { 210 if (!benefitsSwiper) { 211 var benefitsLoopConfig = getLoopConfig('.benefits-slider', 2); 212 213 benefitsSwiper = new Swiper('.benefits-slider', { 214 autoplay: benefitsLoopConfig.loop ? getAutoplayConfig() : false, 215 loop: benefitsLoopConfig.loop, 216 rewind: benefitsLoopConfig.rewind, 217 slidesPerView: 'auto', 218 spaceBetween: 20, 219 freeMode: false 220 }); 221 } 222 } else if (benefitsSwiper) { 223 benefitsSwiper.destroy(true, true); 224 benefitsSwiper = null; 225 } 226 } 227 228 toggleBenefitsSwiper(); 229 230 $(window).on('resize', function() { 231 toggleBenefitsSwiper(); 232 }); 233 234 $('.tabs-items a').on('click', function(e) { 235 e.preventDefault(); 236 var $tab = $(this); 237 var tabName = $tab.data('tab'); 238 var tabTitle = $tab.data('title'); 239 240 $tab.addClass('active').siblings().removeClass('active'); 241 $('.tabs-selected span').text(tabTitle); 242 $('.tabs-content__item').removeClass('active'); 243 $('.tabs-content__item[data-tab-content="' + tabName + '"]').addClass('active'); 244 }); 245 246 $('.accordion__trigger').on('click', function() { 247 var $item = $(this).closest('.accordion__item'); 248 var $accordion = $item.closest('.accordion'); 249 250 if ($item.hasClass('active')) { 251 return; 252 } 253 254 $accordion.find('.accordion__item').removeClass('active').find('.accordion__text').slideUp(200); 255 $item.addClass('active').find('.accordion__text').slideDown(200); 256 }); 257 258 var reviewsLoopConfig = getLoopConfig('.reviews-slider', 2); 259 260 new Swiper('.reviews-slider', { 261 autoplay: reviewsLoopConfig.loop ? getAutoplayConfig() : false, 262 loop: reviewsLoopConfig.loop, 263 rewind: reviewsLoopConfig.rewind, 264 slidesPerView: 'auto', 265 spaceBetween: 12, 266 pagination: { 267 el: '.reviews-block .swiper-pagination', 268 clickable: true 269 }, 270 navigation: { 271 nextEl: '.reviews-nav__button--next', 272 prevEl: '.reviews-nav__button--prev' 273 } 274 }); 275 276 $('.mobile-header__menu-btn').on('click', function() { 277 var isOpen = $('body').toggleClass('mobile-menu-open').hasClass('mobile-menu-open'); 278 $(this).attr('aria-expanded', isOpen ? 'true' : 'false'); 279 $('.mobile-menu').attr('aria-hidden', isOpen ? 'false' : 'true'); 280 }); 281 282 function closeMobileSubmenu() { 283 $('.mobile-submenu').removeClass('active').attr('aria-hidden', 'true'); 284 } 285 286 $('.mobile-menu__close').on('click', function() { 287 $('body').removeClass('mobile-menu-open'); 288 $('.mobile-header__menu-btn').attr('aria-expanded', 'false'); 289 $('.mobile-menu').attr('aria-hidden', 'true'); 290 closeMobileSubmenu(); 291 }); 292 293 $('.js-mobile-submenu-open').on('click', function(e) { 294 if ($(window).width() > 767) { 295 return; 296 } 297 e.preventDefault(); 298 var target = $(this).data('submenu'); 299 closeMobileSubmenu(); 300 $('#' + target).addClass('active').attr('aria-hidden', 'false'); 301 }); 302 303 $('.js-mobile-submenu-back').on('click', function() { 304 closeMobileSubmenu(); 305 }); 306 307 308 $('.mobile-menu a').on('click', function(e) { 309 if ($(window).width() <= 767 && !$(this).hasClass('js-mobile-submenu-open')) { 310 $('body').removeClass('mobile-menu-open'); 311 $('.mobile-header__menu-btn').attr('aria-expanded', 'false'); 312 $('.mobile-menu').attr('aria-hidden', 'true'); 313 closeMobileSubmenu(); 314 } 315 }); 316 317 function newDentalFormatPhoneNumber(value) { 318 var digits = String(value || '').replace(/\D/g, ''); 319 if (!digits.length) { 320 return ''; 321 } 322 if (digits.charAt(0) === '8') { 323 digits = '7' + digits.slice(1); 324 } 325 if (digits.charAt(0) !== '7') { 326 digits = '7' + digits; 327 } 328 digits = digits.slice(0, 11); 329 var result = '+7'; 330 if (digits.length >= 2) { 331 result += ' (' + digits.slice(1, 4); 332 if (digits.length >= 5) { 333 result += ') ' + digits.slice(4, 7); 334 if (digits.length >= 8) { 335 result += '-' + digits.slice(7, 9); 336 if (digits.length >= 10) { 337 result += '-' + digits.slice(9, 11); 338 } 339 } 340 } 341 } 342 return result; 343 } 344 345 function newDentalApplyPhoneMask(input, withValidation) { 346 if (!input || input.dataset.maskApplied === '1') { 347 return; 348 } 349 350 function validatePhone() { 351 if (!withValidation) { 352 return true; 353 } 354 var digits = input.value.replace(/\D/g, ''); 355 if (digits.length !== 11) { 356 input.classList.add('phone-error'); 357 return false;
358 } 359 input.classList.remove('phone-error'); 360 return true; 361 } 362 363 input.addEventListener('focus', function() { 364 if (!input.value) { 365 input.value = '+7'; 366 } 367 }); 368 369 input.addEventListener('input', function(e) { 370 var oldValue = e.target.value; 371 var cursorPos = e.target.selectionStart || 0; 372 var newValue = newDentalFormatPhoneNumber(oldValue); 373 if (oldValue !== newValue) { 374 e.target.value = newValue; 375 var digitsBefore = oldValue.slice(0, cursorPos).replace(/\D/g, '').length; 376 var newCursorPos = 0; 377 var digitCount = 0; 378 for (var i = 0; i < newValue.length; i++) { 379 if (digitCount >= digitsBefore) { 380 break; 381 } 382 if (/\d/.test(newValue[i])) { 383 digitCount++; 384 } 385 newCursorPos = i + 1; 386 } 387 if (typeof e.target.setSelectionRange === 'function') { 388 e.target.setSelectionRange(newCursorPos, newCursorPos); 389 } 390 } 391 validatePhone(); 392 }); 393 394 input.addEventListener('blur', function() { 395 if (input.value.replace(/\D/g, '').length < 4) { 396 input.value = ''; 397 } 398 validatePhone(); 399 }); 400 401 if (input.value) { 402 input.value = newDentalFormatPhoneNumber(input.value); 403 } 404 405 input.dataset.maskApplied = '1'; 406 input._newDentalValidatePhone = validatePhone; 407 } 408 409 function newDentalInjectRecaptcha(siteToken, callback) { 410 if (!siteToken) { 411 if (typeof callback === 'function') { 412 callback(false); 413 } 414 return; 415 } 416 417 if (window.grecaptcha && typeof window.grecaptcha.execute === 'function') { 418 if (typeof callback === 'function') { 419 callback(true); 420 } 421 return; 422 } 423 424 var existing = document.querySelector('script[data-demo-recaptcha="1"]'); 425 if (existing) { 426 existing.addEventListener('load', function() { 427 if (typeof callback === 'function') { 428 callback(true); 429 } 430 }, {once: true}); 431 existing.addEventListener('error', function() { 432 if (typeof callback === 'function') { 433 callback(false); 434 } 435 }, {once: true}); 436 return; 437 } 438 439 var script = document.createElement('script'); 440 script.src = 'https://www.google.com/recaptcha/api.js?render=' + encodeURIComponent(siteToken); 441 script.async = true; 442 script.defer = true; 443 script.setAttribute('data-demo-recaptcha', '1'); 444 script.onload = function() { 445 if (typeof callback === 'function') { 446 callback(true); 447 } 448 }; 449 script.onerror = function() { 450 if (typeof callback === 'function') { 451 callback(false); 452 } 453 }; 454 document.head.appendChild(script); 455 } 456 457 function newDentalRefreshRecaptchaToken(form, done) { 458 if (!form) { 459 if (typeof done === 'function') { 460 done(false); 461 } 462 return; 463 } 464 465 var tokenField = form.querySelector('[name="recaptcha_response"]'); 466 var siteToken = form.getAttribute('data-recaptcha-site-key') || ''; 467 if (!tokenField || !siteToken) { 468 if (typeof done === 'function') { 469 done(false); 470 } 471 return; 472 } 473 474 newDentalInjectRecaptcha(siteToken, function(ok) { 475 if (!ok || !window.grecaptcha || typeof window.grecaptcha.ready !== 'function') { 476 if (typeof done === 'function') { 477 done(false); 478 } 479 return; 480 } 481 482 window.grecaptcha.ready(function() { 483 window.grecaptcha.execute(siteToken, {action: 'form_send'}).then(function(token) { 484 tokenField.value = token || ''; 485 if (typeof done === 'function') { 486 done(!!token); 487 } 488 }).catch(function() { 489 if (typeof done === 'function') { 490 done(false); 491 } 492 }); 493 }); 494 }); 495 } 496 497 function newDentalInitManagedForms() { 498 var selector = '.investor-form--bitrix, .dp-form--presentation, .dp-form--clients, .dp-form--clients-secondary, .dp-form--blue-section'; 499 500 document.querySelectorAll(selector).forEach(function(form) { 501 if (form.dataset.newDentalFormReady === '1') { 502 return; 503 } 504 505 var phoneField = form.querySelector('.js-phone-mask, .phone-mask-field'); 506 if (phoneField) { 507 newDentalApplyPhoneMask(phoneField, form.classList.contains('investor-form--bitrix') || form.classList.contains('dp-form--presentation')); 508 } 509 510 newDentalRefreshRecaptchaToken(form); 511 512 form.addEventListener('submit', function(e) { 513 if (phoneField && typeof phoneField._newDentalValidatePhone === 'function' && !phoneField._newDentalValidatePhone()) { 514 e.preventDefault(); 515 phoneField.focus(); 516 return; 517 } 518 519 var tokenField = form.querySelector('[name="recaptcha_response"]'); 520 var siteToken = form.getAttribute('data-recaptcha-site-key') || ''; 521 if (!tokenField || tokenField.value || !siteToken) { 522 return; 523 } 524 525 e.preventDefault(); 526 newDentalRefreshRecaptchaToken(form, function(ok) { 527 if (ok) { 528 form.submit(); 529 } 530 }); 531 }); 532 533 form.dataset.newDentalFormReady = '1'; 534 }); 535 536 if (window.BX && typeof BX.addCustomEvent === 'function' && !window.newDentalAjaxFormsBound) { 537 BX.addCustomEvent('onAjaxSuccess', function() { 538 document.querySelectorAll(selector).forEach(function(form) { 539 newDentalRefreshRecaptchaToken(form); 540 }); 541 }); 542 window.newDentalAjaxFormsBound = true; 543 } 544 } 545 546 function newDentalInitWhoLikesModal() { 547 document.querySelectorAll('[data-who-likes-root="1"]').forEach(function(root) { 548 if (root.dataset.whoLikesReady === '1') { 549 return; 550 } 551 552 var modalId = root.getAttribute('id') ? root.getAttribute('id') + '-modal' : ''; 553 var modal = modalId ? document.getElementById(modalId) : null; 554 if (!modal) { 555 return; 556 } 557 558 var modalImage = modal.querySelector('.who-likes-modal__image'); 559 var closeModal = function() { 560 modal.classList.remove('is-open'); 561 modal.setAttribute('aria-hidden', 'true'); 562 document.body.classList.remove('who-likes-modal-open'); 563 if (modalImage) { 564 modalImage.setAttribute('src', ''); 565 } 566 }; 567 568 root.addEventListener('click', function(event) { 569 var hotspot = event.target.closest('.who-likes-visual__hotspot'); 570 if (!hotspot || !root.contains(hotspot) || !modalImage) { 571 return; 572 } 573 574 var imageSrc = hotspot.getAttribute('data-modal-image'); 575 if (!imageSrc) { 576 return; 577 } 578 579 modalImage.setAttribute('src', imageSrc); 580 modal.classList.add('is-open'); 581 modal.setAttribute('aria-hidden', 'false'); 582 document.body.classList.add('who-likes-modal-open'); 583 }); 584 585 modal.addEventListener('click', function(event) { 586 if (event.target.closest('[data-who-likes-close="true"]')) { 587 closeModal(); 588 } 589 }); 590 591 document.addEventListener('keydown', function(event) { 592 if (event.key === 'Escape' && modal.classList.contains('is-open')) { 593 closeModal(); 594 } 595 }); 596 597 root.dataset.whoLikesReady = '1'; 598 }); 599 } 600 601 function newDentalInitFooterModal() {
602 var overlay = document.querySelector('.new-dental-overlay'); 603 if (!overlay || overlay.dataset.modalReady === '1') { 604 return; 605 } 606 607 var body = document.body; 608 var formModal = overlay.querySelector('[data-modal="modal1"]'); 609 var videoModal = overlay.querySelector('[data-modal="video"]'); 610 var videoFrameBox = videoModal ? videoModal.querySelector('.modal__frame') : null; 611 var titleNode = formModal ? formModal.querySelector('.modal-title') : null; 612 var defaultTitle = titleNode ? (titleNode.getAttribute('data-title-standart') || titleNode.textContent) : ''; 613 614 function closestNode(node, selector) { 615 while (node && node !== document) { 616 if (node.matches && node.matches(selector)) { 617 return node; 618 } 619 node = node.parentNode; 620 } 621 return null; 622 } 623 624 function closeModal() { 625 overlay.classList.remove('active'); 626 if (formModal) { 627 formModal.classList.remove('active'); 628 } 629 if (videoModal) { 630 videoModal.classList.remove('active'); 631 } 632 if (videoFrameBox) { 633 videoFrameBox.innerHTML = ''; 634 } 635 body.classList.remove('lock'); 636 if (titleNode) { 637 titleNode.innerHTML = defaultTitle; 638 } 639 } 640 641 function openFormModal(trigger) { 642 if (!formModal) { 643 return; 644 } 645 if (titleNode) { 646 titleNode.innerHTML = trigger && trigger.getAttribute('data-modal-title') ? trigger.getAttribute('data-modal-title') : defaultTitle; 647 } 648 overlay.classList.add('active'); 649 formModal.classList.add('active'); 650 if (videoModal) { 651 videoModal.classList.remove('active'); 652 } 653 body.classList.add('lock'); 654 var modalForm = formModal.querySelector('.modal-form'); 655 if (modalForm) { 656 modalForm.setAttribute('data-recaptcha-site-key', overlay.getAttribute('data-recaptcha-site-key') || ''); 657 newDentalRefreshRecaptchaToken(modalForm); 658 } 659 } 660 661 function buildVideoFrame(trigger) { 662 if (!trigger || !trigger.dataset || !trigger.dataset.video) { 663 return null; 664 } 665 if (trigger.dataset.video.includes('vk.com')) { 666 var videoParts = trigger.dataset.video.split('video'); 667 if (!videoParts[1]) { 668 return null; 669 } 670 var idVideo = videoParts[1].split('_'); 671 var vkFrame = document.createElement('iframe'); 672 vkFrame.setAttribute('title', 'Vk video player'); 673 vkFrame.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share'); 674 vkFrame.setAttribute('allowfullscreen', ''); 675 vkFrame.setAttribute('src', 'https://vk.com/video_ext.php?oid=' + idVideo[0] + '&id=' + idVideo[1] + '&hd=2&autoplay=1'); 676 return vkFrame; 677 } 678 if (trigger.dataset.video.includes('rutube.ru')) { 679 var rutubeParts = trigger.dataset.video.split('video'); 680 if (!rutubeParts[1]) { 681 return null; 682 } 683 var rutubeFrame = document.createElement('iframe'); 684 rutubeFrame.setAttribute('title', 'Rutube video player'); 685 rutubeFrame.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share'); 686 rutubeFrame.setAttribute('allowfullscreen', ''); 687 rutubeFrame.setAttribute('src', 'https://rutube.ru/play/embed' + rutubeParts[1]); 688 return rutubeFrame; 689 } 690 var re = /(?:embed\/|v=|youtu\.be\/|youtube\.com\/user\/\S+#\S+\/\S+\/\S+\/\S+)([^"&?\/\s]{11})/i; 691 var match = trigger.dataset.video.match(re); 692 var youtubeId = match && match[1] ? match[1] : (trigger.dataset.video.length === 11 ? trigger.dataset.video : null); 693 if (!youtubeId) { 694 return null; 695 } 696 var youtubeFrame = document.createElement('iframe'); 697 youtubeFrame.setAttribute('title', 'YouTube video player'); 698 youtubeFrame.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share'); 699 youtubeFrame.setAttribute('allowfullscreen', ''); 700 youtubeFrame.setAttribute('src', 'https://www.youtube.com/embed/' + youtubeId); 701 return youtubeFrame; 702 } 703 704 function openVideoModal(trigger) { 705 if (!videoModal || !videoFrameBox) { 706 return; 707 } 708 var frame = buildVideoFrame(trigger); 709 if (!frame) { 710 return; 711 } 712 videoFrameBox.innerHTML = ''; 713 videoFrameBox.appendChild(frame); 714 overlay.classList.add('active'); 715 videoModal.classList.add('active'); 716 if (formModal) { 717 formModal.classList.remove('active'); 718 } 719 body.classList.add('lock'); 720 } 721 722 var modalForm = formModal ? formModal.querySelector('.modal-form') : null; 723 if (modalForm) { 724 modalForm.setAttribute('data-recaptcha-site-key', overlay.getAttribute('data-recaptcha-site-key') || ''); 725 newDentalRefreshRecaptchaToken(modalForm); 726 } 727 728 document.addEventListener('click', function(event) { 729 var formTrigger = closestNode(event.target, '[data-btn="modal1"]'); 730 if (formTrigger) { 731 event.preventDefault(); 732 openFormModal(formTrigger); 733 return; 734 } 735 var videoTrigger = closestNode(event.target, '[data-btn="video"]'); 736 if (videoTrigger) { 737 event.preventDefault(); 738 openVideoModal(videoTrigger); 739 return; 740 } 741 if (!overlay.classList.contains('active')) { 742 return; 743 } 744 if (closestNode(event.target, '[data-close]')) { 745 event.preventDefault(); 746 closeModal(); 747 return; 748 }
749 if (!closestNode(event.target, '.new-dental-overlay .modal')) { 750 closeModal(); 751 } 752 }); 753 754 document.addEventListener('keydown', function(event) { 755 if (event.key === 'Escape' && overlay.classList.contains('active')) { 756 closeModal(); 757 } 758 }); 759 760 if (overlay.getAttribute('data-reopen-after-post') === '1' || overlay.querySelector('.new-dental-form-errors') || overlay.querySelector('.form-note') || overlay.querySelector('.errortext')) { 761 openFormModal(); 762 } 763 764 overlay.dataset.modalReady = '1'; 765 } 766 767 newDentalInitManagedForms(); 768 newDentalInitWhoLikesModal(); 769 newDentalInitFooterModal(); 770 771 var pricingMatrixRaw = $('.pricing').first().attr('data-pricing-matrix'); 772 var pricingMatrix = {}; 773 774 if (pricingMatrixRaw) { 775 try { 776 pricingMatrix = JSON.parse(pricingMatrixRaw); 777 } catch (e) { 778 pricingMatrix = {}; 779 } 780 } 781 782 pricingMatrix = pricingMatrix && Object.keys(pricingMatrix).length ? pricingMatrix : { 783 basic: { 784 "1-2": { "default": 9880, "6": 9386, "12": 8892, "60": 8892 }, 785 "3-4": { "default": 13180, "6": 12521, "12": 11862, "60": 11862 }, 786 "5+": { "default": 15380, "6": 14611, "12": 13842, "60": 13842 } 787 }, 788 pro: { 789 "1-2": { "default": 10980, "6": 10980, "12": 10980, "60": 10980 }, 790 "3-4": { "default": 22600, "6": 21470, "12": 18080, "60": 15820 }, 791 "5+": { "default": 33200, "6": 31540, "12": 26560, "60": 23240 } 792 } 793 }; 794 795 var pricingState = { 796 size: '1-2', 797 term: '12' 798 }; 799 var pricingAddonState = {}; 800 801 function normalizePricingValue(value) { 802 if (typeof value === 'number') { 803 return value; 804 } 805 806 var parsedValue = parseInt(String(value).replace(/[^\d-]/g, ''), 10); 807 return isNaN(parsedValue) ? 0 : parsedValue; 808 } 809 810 function formatPricingValue(value) { 811 return normalizePricingValue(value).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' '); 812 } 813 814 function setAddonState(addonKey, isActive) { 815 addonKey = String(addonKey); 816 817 pricingAddonState[addonKey] = !!isActive; 818 819 $('[data-pricing-addon-toggle][data-addon-key="' + addonKey + '"]').each(function() { 820 var $button = $(this); 821 $button.toggleClass('is-active', !!isActive); 822 $button.attr('aria-pressed', isActive ? 'true' : 'false'); 823 $button.find('.tariff-addon__icon').text(isActive ? 'â' : '+'); 824 }); 825 826 $('[data-pricing-addon-item][data-addon-key="' + addonKey + '"]').toggleClass('is-active', !!isActive); 827 828 $('[data-pricing-mobile-addon-toggle][data-addon-key="' + addonKey + '"]').each(function() { 829 var $button = $(this); 830 $button.toggleClass('is-active', !!isActive); 831 $button.attr('aria-pressed', isActive ? 'true' : 'false'); 832 $button.find('.pricing-mobile-addon__icon').text(isActive ? 'â' : '+'); 833 }); 834 835 $('[data-pricing-mobile-addon-item][data-addon-key="' + addonKey + '"]').toggleClass('is-active', !!isActive); 836 } 837 838 function getBasicAddonsTotal() { 839 var total = 0; 840 841 $.each(pricingAddonState, function(addonKey, isActive) { 842 if (!isActive) { 843 return; 844 } 845 846 var $control = $('[data-pricing-addon-toggle][data-addon-key="' + addonKey + '"], [data-pricing-mobile-addon-toggle][data-addon-key="' + addonKey + '"]').first(); 847 total += normalizePricingValue($control.data('addon-price')); 848 }); 849 850 return total; 851 } 852 853 function getPricingValue(tariffCode) { 854 if (!pricingMatrix[tariffCode] || !pricingMatrix[tariffCode][pricingState.size]) { 855 return 0; 856 } 857 858 var sizeData = pricingMatrix[tariffCode][pricingState.size]; 859 var baseValue = 0; 860 861 if (typeof sizeData[pricingState.term] !== 'undefined') { 862 baseValue = normalizePricingValue(sizeData[pricingState.term]); 863 } else if (typeof sizeData['default'] !== 'undefined') { 864 baseValue = normalizePricingValue(sizeData['default']); 865 } 866 867 if (tariffCode === 'basic') { 868 baseValue += getBasicAddonsTotal(); 869 } 870 871 return baseValue; 872 } 873 874 function updatePricing() { 875 var basicValue = getPricingValue('basic'); 876 var proValue = getPricingValue('pro'); 877 878 $('[data-pricing-basic-mobile]').text('Ð¾Ñ ' + formatPricingValue(basicValue) + ' â½/меÑ'); 879 $('[data-pricing-pro-mobile]').text('Ð¾Ñ ' + formatPricingValue(proValue) + ' â½/меÑ'); 880 $('[data-pricing-basic-mobile-bottom]').text('Ð¾Ñ ' + formatPricingValue(basicValue) + ' ⽠в меÑ'); 881 $('[data-pricing-basic-desktop]').text('Ð¾Ñ ' + formatPricingValue(basicValue) + ' ⽠в меÑ'); 882 $('[data-pricing-pro-desktop]').text('Ð¾Ñ ' + formatPricingValue(proValue) + ' ⽠в меÑ'); 883 } 884 885 $('[data-pricing-term]').on('click', function() { 886 var $button = $(this); 887 var isActive = $button.hasClass('active'); 888 889 $('[data-pricing-term]').removeClass('active'); 890 891 if (isActive) { 892 $button.addClass('active'); 893 pricingState.term = $button.data('pricing-term').toString(); 894 updatePricing(); 895 return; 896 } 897 898 $button.addClass('active'); 899 pricingState.term = $button.data('pricing-term').toString(); 900 updatePricing(); 901 }); 902 903 $('[data-pricing-size]').on('click', function() { 904 var $button = $(this); 905 906 $('[data-pricing-size]').removeClass('active'); 907 $button.addClass('active'); 908 909 pricingState.size = $button.data('pricing-size').toString(); 910 updatePricing(); 911 }); 912 913 $('[data-pricing-addon-toggle], [data-pricing-mobile-addon-toggle]').each(function() { 914 var addonKey = String($(this).data('addon-key')); 915 if (typeof pricingAddonState[addonKey] === 'undefined') { 916 pricingAddonState[addonKey] = $(this).hasClass('is-active'); 917 } 918 }); 919 920 $('[data-pricing-addon-toggle]').on('click', function() { 921 var $button = $(this); 922 setAddonState($button.data('addon-key'), !$button.hasClass('is-active')); 923 updatePricing(); 924 }); 925 926 $('[data-pricing-mobile-addon-toggle]').on('click', function(e) { 927 e.preventDefault(); 928 e.stopPropagation(); 929 930 var $button = $(this); 931 setAddonState($button.data('addon-key'), !$button.hasClass('is-active')); 932 updatePricing(); 933 }); 934 935 $('[data-pricing-mobile-addons-toggle]').on('click', function() { 936 var $button = $(this); 937 var $panel = $('#' + $button.attr('aria-controls')); 938 var isOpen = $button.hasClass('is-open'); 939 940 $button.toggleClass('is-open', !isOpen); 941 $button.attr('aria-expanded', isOpen ? 'false' : 'true'); 942 943 if (isOpen) {
944 $panel.stop(true, true).slideUp(200, function() { 945 $panel.prop('hidden', true); 946 }); 947 return; 948 } 949 950 $panel.prop('hidden', false).hide().stop(true, true).slideDown(200); 951 }); 952 953 $.each(pricingAddonState, function(addonKey, isActive) { 954 setAddonState(addonKey, isActive); 955 }); 956 957 updatePricing(); 958 959 $('.faq-item__head').on('click', function() { 960 var $item = $(this).closest('.faq-item'); 961 if ($item.hasClass('active')) { 962 $item.removeClass('active'); 963 $item.find('.faq-item__body').slideUp(200); 964 $(this).attr('aria-expanded', 'false'); 965 return; 966 } 967 $('.faq-item').removeClass('active').find('.faq-item__body').slideUp(200); 968 $('.faq-item__head').attr('aria-expanded', 'false'); 969 $item.addClass('active'); 970 $item.find('.faq-item__body').slideDown(200); 971 $(this).attr('aria-expanded', 'true'); 972 }); 973 974 var $topBannerModal = $('.top-banner-modal'); 975 var $topBannerModalImage = $('.top-banner-modal__image'); 976 977 function closeTopBannerModal() { 978 $topBannerModal.removeClass('is-open').attr('aria-hidden', 'true'); 979 $('body').removeClass('top-banner-modal-open'); 980 $topBannerModalImage.attr('src', ''); 981 } 982 983 $('.top-banner__hotspot').on('click', function() { 984 var imageSrc = $(this).data('modal-image'); 985 if (!imageSrc) { 986 return; 987 } 988 989 $topBannerModalImage.attr('src', imageSrc); 990 $topBannerModal.addClass('is-open').attr('aria-hidden', 'false'); 991 $('body').addClass('top-banner-modal-open'); 992 }); 993 994 $('.top-banner-modal__close, .top-banner-modal__overlay').on('click', function() { 995 closeTopBannerModal(); 996 }); 997 998 $(document).on('keydown', function(e) { 999 if (e.key === 'Escape' && $topBannerModal.hasClass('is-open')) { 1000 closeTopBannerModal(); 1001 } 1002 }); 1003 1004 function initStickyHeaderBottom() { 1005 var $headerBottom = $('.js-header-bottom').first(); 1006 var $placeholder = $('.header__bottom-placeholder').first(); 1007 1008 if (!$headerBottom.length || !$placeholder.length) { 1009 return; 1010 } 1011 1012 var stickyTop = 0; 1013 var stickyStart = 0; 1014 1015 function getAdminOffset() { 1016 var $adminPanel = $('#bx-panel'); 1017 if ($adminPanel.length && $adminPanel.is(':visible')) { 1018 return $adminPanel.outerHeight(); 1019 } 1020 return 0; 1021 } 1022 1023 function disableSticky() { 1024 $headerBottom.removeClass('header__bottom--fixed').css('top', ''); 1025 $placeholder.hide().height(0); 1026 } 1027 1028 function recalcSticky() { 1029 if ($(window).width() <= 767) { 1030 disableSticky(); 1031 return; 1032 } 1033 1034 stickyTop = getAdminOffset(); 1035 1036 var wasFixed = $headerBottom.hasClass('header__bottom--fixed'); 1037 if (wasFixed) { 1038 $headerBottom.removeClass('header__bottom--fixed').css('top', ''); 1039 } 1040 1041 $placeholder.hide().height(0); 1042 stickyStart = $headerBottom.offset().top - stickyTop; 1043 1044 if (wasFixed) { 1045 updateSticky(); 1046 } 1047 } 1048 1049 function updateSticky() { 1050 if ($(window).width() <= 767) { 1051 disableSticky(); 1052 return; 1053 } 1054 1055 var shouldFix = $(window).scrollTop() >= stickyStart; 1056 1057 if (shouldFix) { 1058 $placeholder.show().height($headerBottom.outerHeight()); 1059 $headerBottom.addClass('header__bottom--fixed').css('top', stickyTop + 'px'); 1060 } else { 1061 disableSticky(); 1062 } 1063 } 1064 1065 recalcSticky(); 1066 updateSticky(); 1067 1068 $(window).on('scroll.stickyHeaderBottom', updateSticky); 1069 $(window).on('resize.stickyHeaderBottom orientationchange.stickyHeaderBottom', function() { 1070 recalcSticky(); 1071 updateSticky(); 1072 }); 1073 } 1074 1075 initStickyHeaderBottom(); 1076 1077 function initMetrikaRecordKeys() { 1078 var selector = [ 1079 '.dp-form input:not([type="hidden"]):not([type="password"]):not([type="file"])', 1080 '.dp-form textarea', 1081 '.dp-form select', 1082 '.investor-form--bitrix input:not([type="hidden"]):not([type="password"]):not([type="file"])', 1083 '.investor-form--bitrix textarea', 1084 '.investor-form--bitrix select' 1085 ].join(','); 1086 1087 document.querySelectorAll(selector).forEach(function(field) { 1088 field.classList.add('ym-record-keys'); 1089 }); 1090 } 1091 1092 initMetrikaRecordKeys(); 1093 //calltouch 1094 (function(w,d,n,c){w.CalltouchDataObject=n;w[n]=function(){w[n]["callbacks"].push(arguments)};if(!w[n]["callbacks"]){w[n]["callbacks"]=[]}w[n]["loaded"]=false;if(typeof c!=="object"){c=[c]}w[n]["counters"]=c;for(var i=0;i<c.length;i+=1){p(c[i])}function p(cId){var a=d.getElementsByTagName("script")[0],s=d.createElement("script"),i=function(){a.parentNode.insertBefore(s,a)},m=typeof Array.prototype.find === 'function',n=m?"init-min.js":"init.js";s.async=true;s.src="https://mod.calltouch.ru/"+n+"?id="+cId;if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",i,false)}else{i()}}})(window,document,"ct","x5ca8qhp"); 1095 1096 Element.prototype.matches || (Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector), Element.prototype.closest || (Element.prototype.closest = function (e) { for (var t = this; t;) { if (t.matches(e)) return t; t = t.parentElement } return null }); 1097 var ct_get_val = function (form, selector) { if (!!form.querySelector(selector)) { return form.querySelector(selector).value; console.log(form.querySelector(selector)) } else { return ''; } }; 1098 function SendCalltouch(t_el) { 1099 if (t_el.closest('form [type="submit"]')) { 1100 try { 1101 var form = t_el.closest('form'); 1102 var fio = ct_get_val(form, 'input[name="form_text_1"], input[name="form_text_7"], input[placeholder*="имÑ"]'); 1103 var phoneNumber = ct_get_val(form, 'input[type="tel"]'); 1104 var email = ct_get_val(form, 'input[name*="email"]'); 1105 var subject = 'ÐаÑвка Ñ ' + location.hostname; 1106 var ct_site_id = 51456; 1107 var ct_data = { 1108 fio: fio, 1109 phoneNumber: phoneNumber, 1110 email: email, 1111 subject: subject, 1112 requestUrl: location.href, 1113 sessionId: window.call_value 1114 }; 1115 var post_data = Object.keys(ct_data).reduce(function (a, k) { if (!!ct_data[k]) { a.push(k + '=' + encodeURIComponent(ct_data[k])); } return a }, []).join('&'); 1116 var CT_URL = 'https://api.calltouch.ru/calls-service/RestAPI/requests/' + ct_site_id + '/register/';
1117 var ct_valid = !!phoneNumber && phoneNumber.replace(/[^0-9]/gim, '').length > 9; 1118 if (ct_valid && !window.ct_snd_flag) { 1119 console.log('ÐÑпÑавлено в Calltouch', ct_data); 1120 window.ct_snd_flag = 1; setTimeout(function () { window.ct_snd_flag = 0; }, 15000); 1121 var request = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 1122 request.open("POST", CT_URL, true); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 1123 request.send(post_data); 1124 } 1125 } catch (e) { console.log(e); } 1126 } 1127 } 1128 document.addEventListener('click', function (e) { SendCalltouch(e.target) }); 1129 //calltouch 1130});
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.