1/* ÐбÑий клиенÑÑкий Ñлой ÑайÑа: бÑÑгеÑ-менÑ, мобилÑнÑе ÑикÑÑ, ÑипогÑаÑика, ÑкоÑÑ. 2 ÐодклÑÑаеÑÑÑ Ð½Ð° вÑÐµÑ ÑÑÑаниÑÐ°Ñ (лендинги, блог, ÑÑ-ÑÑÑаниÑÑ). */ 3(function () { 4 var lastToggle = 0; 5 var LINKS = [ 6 ['ÐÑзÑÐ²Ñ Ð¸ аналиÑика', '/otzyvy/'], 7 ['ÐопÑоÑÑ', '/voprosy/'], 8 ['ЧаÑÑ', '/chaty/'], 9 ['ТаÑиÑÑ', '/#pricing'], 10 ['Ðлог', '/blog/'], 11 ]; 12 13 /* ---------------- бÑÑÐ³ÐµÑ (вне дизайн-ÑанÑайма) ---------------- */ 14 function buildNav() { 15 if (document.getElementById('blBurger')) return; 16 17 var btn = document.createElement('button'); 18 btn.type = 'button'; 19 btn.id = 'blBurger'; 20 btn.className = 'bl-burger'; 21 btn.setAttribute('aria-label', 'ÐенÑ'); 22 btn.innerHTML = '<span></span><span></span><span></span>'; 23 24 var panel = document.createElement('nav'); 25 panel.id = 'blPanel'; 26 panel.className = 'bl-mnav'; 27 LINKS.forEach(function (l) { 28 var a = document.createElement('a'); 29 a.href = l[1]; 30 a.textContent = l[0]; 31 panel.appendChild(a); 32 }); 33 var demo = document.createElement('a'); 34 demo.href = 'https://t.me/BlaberHELLO_bot'; 35 demo.target = '_blank'; 36 demo.rel = 'noopener'; 37 demo.textContent = 'Ðемо'; 38 demo.className = 'bl-mnav-demo'; 39 panel.appendChild(demo); 40 var cta = document.createElement('a'); 41 cta.href = 'https://my.blaber.ai/'; 42 cta.target = '_blank'; 43 cta.rel = 'noopener'; 44 cta.textContent = 'ÐодклÑÑиÑÑ Ð±ÐµÑплаÑно'; 45 cta.className = 'bl-mnav-cta'; 46 panel.appendChild(cta); 47 48 document.body.appendChild(btn); 49 document.body.appendChild(panel); 50 51 btn.addEventListener('click', function (e) { 52 e.preventDefault(); 53 e.stopPropagation(); 54 var now = Date.now(); 55 if (now - lastToggle < 450) return; 56 lastToggle = now; 57 document.documentElement.classList.toggle('bl-open'); 58 }); 59 panel.addEventListener('click', function (e) { 60 if (e.target.closest('a')) document.documentElement.classList.remove('bl-open'); 61 }); 62 } 63 64 /* ---------------- мобилÑнÑе ÑикÑÑ Ð²ÑÑÑÑки ---------------- */ 65 function fixFlexRows() { 66 if (window.innerWidth > 760) return; 67 var vw = window.innerWidth; 68 document.querySelectorAll('div,section').forEach(function (el) { 69 if (el.id === 'blPanel' || el.id === 'blBurger') return; 70 if (el.closest('[style*="animation"]')) return; 71 var cs;
72 try { cs = getComputedStyle(el); } catch (e) { return; } 73 if (cs.display !== 'flex' || cs.flexDirection !== 'row' || cs.flexWrap === 'wrap') return; 74 if (cs.animationName && cs.animationName !== 'none') return; 75 var kids = el.children; 76 for (var i = 0; i < kids.length; i++) { 77 var r = kids[i].getBoundingClientRect(); 78 if (r.right > vw + 4 || r.width > vw - 24) { el.classList.add('bl-fixwrap'); break; } 79 } 80 }); 81 } 82 83 function freezeSvg() { 84 if (window.innerWidth > 760) return; 85 document.querySelectorAll('svg animate, svg animateTransform').forEach(function (a) { a.remove(); }); 86 } 87 88 /* ---------------- ÑипогÑаÑика ---------------- 89 1) знак пÑÐµÐ¿Ð¸Ð½Ð°Ð½Ð¸Ñ Ð½Ðµ наÑÐ¸Ð½Ð°ÐµÑ ÑÑÑÐ¾ÐºÑ (Ñклеиваем Ñ Ð¿ÑедÑдÑÑим ÑлеменÑом); 90 2) пÑедлоги/ÑоÑÐ·Ñ Ð½Ðµ виÑÑÑ Ð² конÑе ÑÑÑоки (неÑазÑÑвнÑй пÑобел поÑле Ð½Ð¸Ñ ). */ 91 var SHORT_WORDS = ('а,и,но,да,или,либо,ÑÑо,как,где,кÑо,Ñей,бÑ,ли,же,не,ни,в,во,на,по,за,из,иÑ,к,ко,Ñ,Ñо,Ñ,о,об,обо,оÑ,оÑо,до,' 92 + 'длÑ,пÑи,пÑо,над,под,без,ÑеÑез,междÑ,пеÑед,около,поÑле,вмеÑÑо,кÑоме,Ñади,ÑквозÑ,ÑÑеди,благодаÑÑ,' 93 + 'ÑÑо,ÑÑоÑ,ÑÑа,ÑÑи,ÑоÑ,Ñа,Ñе,мÑ,вÑ,он,она,они,Ñ,Ð¸Ñ ,его,еÑ,ваÑ,ваÑа,ваÑи,наÑ,наÑа,наÑи').split(','); 94 var SHORT_RE = new RegExp('(^|[\\s(«"â-])(' + SHORT_WORDS.join('|') + ')\\s+', 'gi'); 95 var PUNCT_RE = /^[\s]*[,.;:!?%â¦Â»)]/; 96 var SKIP_TAGS = { SCRIPT: 1, STYLE: 1, TEXTAREA: 1, INPUT: 1, CODE: 1, PRE: 1, SVG: 1, NOSCRIPT: 1 }; 97 98 function typography(root) { 99 var walker = document.createTreeWalker(root || document.body, NodeFilter.SHOW_TEXT, { 100 acceptNode: function (n) { 101 if (!n.nodeValue || !n.nodeValue.trim()) return NodeFilter.FILTER_REJECT; 102 var p = n.parentNode; 103 while (p && p !== document.body) { 104 if (SKIP_TAGS[p.nodeName] || p.classList && p.classList.contains('bl-typo-done')) return NodeFilter.FILTER_REJECT; 105 p = p.parentNode; 106 } 107 return NodeFilter.FILTER_ACCEPT; 108 } 109 }); 110 var nodes = [], n; 111 while ((n = walker.nextNode())) nodes.push(n); 112 113 nodes.forEach(function (node) { 114 // 1) знак пÑÐµÐ¿Ð¸Ð½Ð°Ð½Ð¸Ñ ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле ÑлеменÑа â пÑиклеиваем к Ð½ÐµÐ¼Ñ 115 var prev = node.previousSibling; 116 if (prev && prev.nodeType === 1 && PUNCT_RE.test(node.nodeValue)) { 117 var m = node.nodeValue.match(/^[\s]*([,.;:!?%â¦Â»)]+)/); 118 if (m && !prev.classList.contains('bl-glued')) { 119 var punct = m[1]; 120 node.nodeValue = node.nodeValue.slice(m[0].length); 121 var wrap = document.createElement('span'); 122 wrap.className = 'bl-glued'; 123 wrap.style.whiteSpace = 'nowrap'; 124 prev.parentNode.insertBefore(wrap, prev); 125 wrap.appendChild(prev); 126 wrap.appendChild(document.createTextNode(punct)); 127 } 128 } 129 // 2) коÑоÑкие Ñлова липнÑÑ Ðº ÑледÑÑÑÐµÐ¼Ñ 130 var v = node.nodeValue; 131 var nv = v.replace(SHORT_RE, function (all, before, word) { return before + word + ' '; }); 132 if (nv !== v) node.nodeValue = nv; 133 }); 134 } 135 136 /* ---------------- ÑкоÑÑ (#pricing и пÑоÑие) ---------------- */ 137 function scrollToHash(hash, smooth) { 138 if (!hash || hash.length < 2) return false; 139 var el; 140 try { el = document.querySelector(hash); } catch (e) { return false; } 141 if (!el) return false; 142 var top = el.getBoundingClientRect().top + window.pageYOffset - 90; 143 // далеко â пÑÑгаем ÑÑÐ°Ð·Ñ (Ð¿Ð»Ð°Ð²Ð½Ð°Ñ Ð¿ÑокÑÑÑка на 15 000px длиÑÑÑ Ð²ÐµÑноÑÑÑ) 144 var far = Math.abs(top - window.pageYOffset) > 2500; 145 window.scrollTo({ top: top, behavior: (smooth && !far) ? 'smooth' : 'auto' }); 146 return true; 147 } 148 149 function initAnchors() { 150 // клик по ÑÑÑлке Ñ ÑкоÑем на ÑÑой же ÑÑÑаниÑе â плавнÑй ÑкÑолл без пеÑезагÑÑзки 151 document.addEventListener('click', function (e) { 152 var a = e.target.closest && e.target.closest('a[href*="#"]'); 153 if (!a) return; 154 var href = a.getAttribute('href') || ''; 155 var parts = href.split('#'); 156 if (parts.length < 2 || !parts[1]) return; 157 var path = parts[0] || location.pathname; 158 if (path !== location.pathname && path !== '/' + location.pathname.replace(/^\//, '')) { 159 if (!(path === '/' && location.pathname === '/')) return; // дÑÑÐ³Ð°Ñ ÑÑÑаниÑа â обÑÑнÑй пеÑÐµÑ Ð¾Ð´ 160 } 161 if (scrollToHash('#' + parts[1], true)) { 162 e.preventDefault(); 163 history.replaceState(null, '', '#' + parts[1]); 164 document.documentElement.classList.remove('bl-open'); 165 } 166 }, true); 167 168 // пÑиÑли по ÑÑÑлке Ñ ÑкоÑем: дизайн-ÑанÑайм доÑиÑовÑÐ²Ð°ÐµÑ ÐºÐ¾Ð½ÑÐµÐ½Ñ â ждÑм ÑÐµÐ»Ñ 169 if (location.hash) { 170 var tries = 0; 171 var t = setInterval(function () { 172 tries += 1; 173 if (scrollToHash(location.hash, false) || tries > 30) clearInterval(t); 174 }, 200); 175 } 176 } 177 178 var debounceT = null;
179 function runAll() { buildNav(); fixFlexRows(); freezeSvg(); typography(); } 180 function debounced() { clearTimeout(debounceT); debounceT = setTimeout(runAll, 350); } 181 182 if (document.readyState === 'loading') { 183 document.addEventListener('DOMContentLoaded', function () { runAll(); initAnchors(); }); 184 } else { 185 runAll(); initAnchors(); 186 } 187 window.addEventListener('load', debounced); 188 window.addEventListener('resize', debounced); 189 try { new MutationObserver(debounced).observe(document.body, { childList: true, subtree: true }); } catch (e) {} 190})();
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.