1/* Direct Telegram contact, 2026-09-15. */ 2(() => { 3 'use strict'; 4 function init() { 5 if (document.getElementById('ruservice-telegram')) return; 6 const style = document.createElement('style'); 7 style.textContent = ` 8 #ruservice-telegram{position:fixed;right:24px;bottom:calc(24px + env(safe-area-inset-bottom,0px));z-index:9990;display:flex;align-items:center;gap:12px;width:max-content;max-width:calc(100vw - 32px);padding:0;margin:0;border:0;background:transparent;text-decoration:none;color:#333;font:16px/1.3 Arial,sans-serif;isolation:isolate} 9 #ruservice-telegram .tg-label{position:relative;padding:12px 17px;border-radius:16px;background:#fff;color:#333;box-shadow:0 3px 16px #0002;white-space:nowrap} 10 #ruservice-telegram .tg-label:after{content:'';position:absolute;right:-6px;top:calc(50% - 6px);width:12px;height:12px;background:#fff;transform:rotate(45deg)} 11 #ruservice-telegram .tg-icon{display:grid;place-items:center;flex:none;width:64px;height:64px;border-radius:50%;background:#399cda;box-shadow:0 6px 24px #173f6526;transition:transform .16s,background .16s} 12 #ruservice-telegram svg{display:block;width:35px;height:35px;fill:#fff} 13 #ruservice-telegram:hover .tg-icon{background:#2389c8;transform:translateY(-2px)} 14 #ruservice-telegram:focus-visible{outline:3px solid #145f91;outline-offset:6px;border-radius:18px} 15 #ruservice-telegram[hidden]{display:none!important} 16 @media(max-width:600px){#ruservice-telegram{right:16px;gap:10px;font-size:14px}#ruservice-telegram .tg-icon{width:56px;height:56px}#ruservice-telegram svg{width:31px;height:31px}#ruservice-telegram .tg-label{padding:10px 13px}} 17 @media(prefers-reduced-motion:reduce){#ruservice-telegram .tg-icon{transition:none}} 18 @media print{#ruservice-telegram{display:none!important}} 19 `; 20 document.head.appendChild(style); 21 const link = document.createElement('a'); 22 link.id = 'ruservice-telegram'; 23 link.href = 'https://t.me/RuSrvice'; 24 link.target = '_blank'; 25 link.rel = 'noopener noreferrer'; 26 link.setAttribute('aria-label', 'ÐапиÑаÑÑ Ð½Ð°Ð¼ в Telegram â @RuSrvice'); 27 link.innerHTML = '<span class="tg-label">ÐапиÑаÑÑ Ð½Ð°Ð¼</span><span class="tg-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21.4 3.6 18.1 20c-.25 1.15-.9 1.43-1.83.9l-5-3.69-2.4 2.32c-.27.27-.5.5-1.02.5l.36-5.1 9.28-8.39c.4-.36-.09-.56-.63-.2L5.4 13.57.47 12.03c-1.07-.33-1.1-1.07.23-1.6L20 3c.9-.33 1.67.2 1.4.6Z"/></svg></span>'; 28 document.body.appendChild(link); 29 let fixed = []; 30 let pending = false; 31 function collect() { 32 fixed = [...document.body.querySelectorAll('*')].filter(el => 33 el !== link && !link.contains(el) && getComputedStyle(el).position === 'fixed'); 34 } 35 function place() { 36 pending = false; 37 const visibleModal = [...document.querySelectorAll('dialog[open], [aria-modal="true"]:not([aria-hidden="true"])')].some(el => 38 el.getBoundingClientRect().height > 0 && el.checkVisibility({checkOpacity:true,checkVisibilityCSS:true})); 39 link.hidden = !!visibleModal; 40 if (visibleModal) return; 41 const base = innerWidth <= 600 ? 16 : 24; 42 let bottom = base; 43 const box = link.getBoundingClientRect(); 44 for (let pass = 0; pass < 3; pass++) { 45 for (const el of fixed) { 46 const r = el.getBoundingClientRect(); 47 const css = getComputedStyle(el); 48 if (!r.width || !r.height || css.visibility === 'hidden' || css.display === 'none' || css.opacity === '0') continue; 49 if (r.height > innerHeight * .65 || r.top < innerHeight * .3) continue; 50 if (r.right <= box.left - 8 || r.left >= box.right + 8) continue; 51 const top = innerHeight - bottom - box.height; 52 if (r.bottom > top - 12 && r.top < innerHeight - bottom + 12) bottom = Math.max(bottom, innerHeight - r.top + 12); 53 } 54 }
55 const value = `calc(${bottom}px + env(safe-area-inset-bottom, 0px))`; 56 if (link.style.bottom !== value) link.style.bottom = value; 57 } 58 function schedule() { if (!pending) { pending = true; requestAnimationFrame(place); } } 59 collect(); 60 new MutationObserver(records => { 61 if (records.every(r => r.target === link || link.contains(r.target))) return; 62 if (records.some(r => r.type === 'childList')) collect(); 63 schedule(); 64 }).observe(document.body, {subtree:true,childList:true,attributes:true,attributeFilter:['class','hidden','aria-hidden','open','style']}); 65 window.addEventListener('resize', () => { collect(); schedule(); }, {passive:true}); 66 window.addEventListener('scroll', schedule, {passive:true}); 67 window.addEventListener('load', () => { collect(); schedule(); }, {once:true}); 68 schedule(); 69 } 70 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init, {once:true}); 71 else init(); 72})();
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.