1// Ðогика лендинга /app: 3D-ÑÑена геÑоÑ, Ð¶Ð¸Ð²Ð°Ñ Ð»ÐµÐ½Ñа пиÑем, гÑаÑик оÑÑÑÑов, 2// ÑаÑкÑÑваÑÑиеÑÑ ÐºÐ°ÑÑоÑки нагÑад и видео, пеÑеклÑÑаÑÐµÐ»Ñ ÑемÑ. 3// ÐеÑенеÑено из пÑоÑоÑипа design/app-landing/prototype.html без Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ. 4 5// ÐагÑÐ°Ð´Ñ Ð¸ видео Ð»ÐµÐ¶Ð°Ñ Ð¾ÑделÑнÑм ÑедакÑиÑÑемÑм Ñайлом (landing-static.js), 6// вÑÑ Ð¾ÑÑалÑное ÑеÑÐ²ÐµÑ ÐºÐ»Ð°Ð´ÑÑ Ð² RF_SNAPSHOT пÑÑмо в ÑазмеÑке. Сводим в один обÑекÑ, 7// ÑÑÐ¾Ð±Ñ Ð½Ð¸Ð¶Ðµ по ÐºÐ¾Ð´Ñ Ð¸ÑÑоÑник даннÑÑ Ð±Ñл один. 8(function () { 9 var S = window.RF_SNAPSHOT = window.RF_SNAPSHOT || {}; 10 var T = window.RF_APP_STATIC || {}; 11 if (!S.awards) S.awards = T.awards || []; 12 if (!S.videos) S.videos = T.videos || []; 13})(); 14 15(function(){ 16 var root=document.getElementById('mock-d'); 17 18 /* ---------- год и ÑÑаÑÑÑÑ ÑÐ¸Ñ ---------- 19 СÑаÑÑÑÑ Ð²ÑнеÑÐµÐ½Ñ Ð² даннÑе: в Ð±Ð¾Ñ Ð¸Ñ Ð¾ÑдаÑÑ /apk/app-latest.json ÑÑдом Ñ Ð²ÐµÑÑией, 20 Ñак ÑÑо поÑле Ñелиза доÑÑаÑоÑно попÑавиÑÑ json â вÑÑÑÑÐºÑ ÑÑогаÑÑ Ð½Ðµ нÑжно. */ 21 (function(){ 22 var y=document.getElementById('d-year'); 23 if(y) y.textContent=new Date().getFullYear(); 24 25 /* СÑаÑÑÑÑ Ð¿ÑÐ¸Ñ Ð¾Ð´ÑÑ Ñ ÑеÑвеÑа из /apk/app-latest.json. ÐаÑиÑого запаÑного набоÑа 26 здеÑÑ Ð½ÐµÑ Ð½Ð°Ð¼ÐµÑенно: он молÑа ÑÑÑаÑÐµÐ²Ð°ÐµÑ Ð¿Ð¾Ñле Ñелиза и вÑÑÑ ÑеловекÑ. */ 27 var features=(window.RF_SNAPSHOT&&RF_SNAPSHOT.features)||{}; 28 var WORDS={ 29 released:{ios:'РабоÑÐ°ÐµÑ Ð² App Store', android:'РабоÑÐ°ÐµÑ Ð² Google Play и RuStore', cls:'on'}, 30 testing: {ios:'iOS â в ÑеÑÑиÑовании', android:'Android â в ÑеÑÑиÑовании', cls:'test'}, 31 planned: {ios:'iOS â в ÑабоÑе', android:'Android â в ÑабоÑе', cls:'soon'} 32 }; 33 root.querySelectorAll('.feat-state[data-feat]').forEach(function(el){ 34 var st=(features[el.dataset.feat]||{})[el.dataset.platform]; 35 var w=WORDS[st]; 36 if(!w){ el.remove(); return; } /* ÑÑаÑÑÑа Ð½ÐµÑ â не вÑдÑмÑваем, пÑоÑÑо не показÑваем */ 37 el.textContent=w[el.dataset.platform]; 38 el.className='feat-state '+w.cls; 39 }); 40 })(); 41 42 /* ---------- кнопка «навеÑÑ Â» ---------- */ 43 (function(){ 44 var btn=document.getElementById('d-totop'); 45 if(!btn) return; 46 function upd(){ 47 var on=scrollY>600; 48 btn.dataset.on=on?'1':'0'; 49 btn.hidden=!on&&btn.dataset.on!=='1'?false:false; /* деÑжим в поÑоке: ÑкÑÑваем пÑозÑаÑноÑÑÑÑ */ 50 } 51 btn.hidden=false; upd(); 52 addEventListener('scroll',upd,{passive:true}); 53 btn.addEventListener('click',function(){ 54 scrollTo({top:0,behavior:matchMedia('(prefers-reduced-motion: reduce)').matches?'auto':'smooth'}); 55 }); 56 })(); 57 58 /* ---------- демонÑÑÑаÑÐ¸Ñ Ð¾Ñложенного пожеÑÑÐ²Ð¾Ð²Ð°Ð½Ð¸Ñ ---------- 59 ТекÑÑÑ Ð²Ð·ÑÑÑ Ð¸Ð· docs/deferred_donations_texts.md: важно, ÑÑо денÑги не ÑпиÑанÑ. */ 60 (function(){ 61 var txt=document.getElementById('d-demo'); 62 if(!txt) return; 63 var demo=txt.closest('.demo'), bar=demo.querySelector('.demo-bar i'); 64 var steps=[ 65 {t:'ÐÐµÑ ÑвÑзи Ñ ÑеÑвеÑом', cls:'', w:'0%'}, 66 {t:'Ð¡Ð¾Ñ Ñанено на ÑÑом ÑелеÑоне · 500 â½', cls:'saved', w:'45%'}, 67 {t:'ÐенÑги не ÑпиÑанÑ, напомним пÑи ÑвÑзи', cls:'saved', w:'70%'}, 68 {t:'СвÑÐ·Ñ Ð¿Ð¾ÑвилаÑÑ â пожеÑÑвование оÑпÑавлено', cls:'sent', w:'100%'} 69 ]; 70 var i=0, calm=matchMedia('(prefers-reduced-motion: reduce)').matches; 71 function show(){ 72 var st=steps[i]; 73 txt.textContent=st.t; 74 demo.className='demo'+(st.cls?' '+st.cls:''); 75 bar.style.width=st.w; 76 i=(i+1)%steps.length; 77 } 78 show(); 79 if(calm) return; 80 var timer=null; 81 var io=new IntersectionObserver(function(es){ 82 if(es[0].isIntersecting){ if(!timer) timer=setInterval(show,2600); } 83 else if(timer){ clearInterval(timer); timer=null; } 84 },{threshold:.4}); 85 io.observe(demo); 86 })();
87 88 /* ---------- нагÑадÑ: каÑÑоÑка ÑазвоÑаÑиваеÑÑÑ Ð²Ð½Ð¸Ð· ---------- */ 89 (function(){ 90 var host=document.getElementById('d-awards'), list=(window.RF_SNAPSHOT||{}).awards||[]; 91 if(!host) return; 92 host.innerHTML=list.map(function(a,i){ 93 return '<article class="aw" data-open="0" tabindex="0" role="button" aria-expanded="false">'+ 94 '<div class="cover"><img src="'+a.c+'" alt=""></div>'+ 95 '<div class="head"><span class="yr">'+a.y+'</span><h3>'+a.t+'</h3><p>'+a.n+'</p>'+ 96 '<span class="more">+</span></div>'+ 97 '<div class="fold"><div><p>'+a.txt+'</p>'+ 98 '<a href="'+a.u+'" target="_blank" rel="noopener">ЧиÑаÑÑ Ð½Ð¾Ð²Ð¾ÑÑÑ <span>â</span></a></div></div>'+ 99 '</article>'; 100 }).join(''); 101 host.addEventListener('click',function(e){ 102 if(e.target.closest('a')) return; /* ÑÑÑлка внÑÑÑи ÑабоÑÐ°ÐµÑ ÐºÐ°Ðº ÑÑÑлка */ 103 var card=e.target.closest('.aw'); if(!card) return; 104 var open=card.dataset.open!=='1'; 105 card.dataset.open=open?'1':'0'; 106 card.setAttribute('aria-expanded',open?'true':'false'); 107 }); 108 host.addEventListener('keydown',function(e){ 109 if(e.key!=='Enter'&&e.key!==' ') return; 110 var card=e.target.closest('.aw'); if(!card) return; 111 e.preventDefault(); card.click(); 112 }); 113 })(); 114 115 /* ---------- видео: каÑÑоÑка ÑазвоÑаÑиваеÑÑÑ Ð¸ подгÑÑÐ¶Ð°ÐµÑ Ð¿Ð»ÐµÐµÑ ---------- */ 116 (function(){ 117 var host=document.getElementById('d-videos'), list=(window.RF_SNAPSHOT||{}).videos||[]; 118 if(!host) return; 119 var PLAY='<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg>'; 120 host.innerHTML=list.map(function(v){ 121 return '<article class="aw vid" data-open="0" data-id="'+v.id+'" tabindex="0" role="button" aria-expanded="false">'+ 122 '<div class="cover"><img src="'+v.c+'" alt="" loading="lazy">'+ 123 '<span class="play" aria-hidden="true">'+PLAY+'</span><span class="dur">'+v.d+'</span></div>'+ 124 '<div class="head"><span class="yr">Ðзен</span><h3>'+v.t+'</h3><p>'+v.n+'</p>'+ 125 '<span class="more">+</span></div>'+ 126 '<div class="fold"><div><div class="frame"></div><p>'+v.txt+'</p>'+ 127 '<a href="https://dzen.ru/video/watch/'+v.w+'" target="_blank" rel="noopener">ÐÑкÑÑÑÑ Ð½Ð° Ðзене <span>â</span></a>'+ 128 '</div></div></article>'; 129 }).join(''); 130 function set(card,open){ 131 card.dataset.open=open?'1':'0'; 132 card.setAttribute('aria-expanded',open?'true':'false'); 133 var frame=card.querySelector('.frame'); 134 if(open){ 135 if(!frame.firstChild){ 136 var f=document.createElement('iframe'); 137 f.src='https://dzen.ru/embed/'+card.dataset.id+'?from_block=partner&from=zen&mute=0&autoplay=1&tv=0'; 138 f.setAttribute('allow','autoplay; fullscreen; accelerometer; gyroscope; picture-in-picture; encrypted-media'); 139 f.setAttribute('allowfullscreen',''); 140 f.setAttribute('scrolling','no'); 141 f.setAttribute('title',card.querySelector('h3').textContent); 142 frame.appendChild(f); 143 } 144 } else { 145 frame.innerHTML=''; /* закÑÑли â звÑк Ð·Ð°Ð¼Ð¾Ð»ÐºÐ°ÐµÑ */ 146 } 147 } 148 host.addEventListener('click',function(e){ 149 if(e.target.closest('a')||e.target.closest('iframe')) return; 150 var card=e.target.closest('.vid'); if(!card) return; 151 var open=card.dataset.open!=='1'; 152 if(open) Array.prototype.forEach.call(host.querySelectorAll('.vid[data-open="1"]'),function(c){ set(c,false); }); 153 set(card,open); 154 }); 155 host.addEventListener('keydown',function(e){ 156 if(e.key!=='Enter'&&e.key!==' ') return; 157 var card=e.target.closest('.vid'); if(!card) return; 158 e.preventDefault(); card.click(); 159 }); 160 })(); 161 162 /* ---------- Ñели ЯндекÑ.ÐеÑÑики ---------- 163 РанÑÑе ÑÑо жило в jQuery-бандле MobileAppLanding/main.js, коÑоÑÑй оÑÑÑда ÑбÑан. 164 СÑÑÑÑик Ð¿Ð¾Ð´Ð½Ð¸Ð¼Ð°ÐµÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ CountersTop, здеÑÑ ÑолÑко оÑпÑавка Ñели. */ 165 (function(){ 166 function goal(name){
167 try{ 168 if(window.yaCounter33497798) window.yaCounter33497798.reachGoal(name); 169 else if(window.ym) window.ym(33497798,'reachGoal',name); 170 }catch(e){} 171 } 172 function ga(cat,act){ try{ if(window.ga) window.ga('send','event',cat,act); }catch(e){} } 173 document.addEventListener('click',function(e){ 174 var el=e.target.closest && e.target.closest('.js-metrika,.js-ga'); 175 if(!el) return; 176 if(el.dataset.metrikaGoal) goal(el.dataset.metrikaGoal); 177 if(el.dataset.gaCategory) ga(el.dataset.gaCategory,el.dataset.gaAction); 178 }); 179 })(); 180 181 /* ---------- гÑаÑик на веÑÑ ÑкÑан ---------- */ 182 (function(){ 183 var btn=document.getElementById('d-fullscreen'); 184 if(!btn) return; 185 var box=btn.closest('.chart'); 186 btn.addEventListener('click',function(){ 187 if(document.fullscreenElement){ document.exitFullscreen(); return; } 188 if(box.requestFullscreen) box.requestFullscreen(); 189 else if(box.webkitRequestFullscreen) box.webkitRequestFullscreen(); 190 }); 191 document.addEventListener('fullscreenchange',function(){ 192 btn.firstChild.nodeValue=document.fullscreenElement?'СвеÑнÑÑÑ ':'ÐÑкÑÑÑÑ Ð½Ð° полнÑй ÑкÑан '; 193 }); 194 })(); 195 196 /* ---------- «СкаÑаÑÑ» в Ñапке ---------- 197 ÐÑли Ñеловек и Ñак навеÑÑ Ñ, пÑокÑÑÑиваÑÑ Ð½ÐµÐºÑда â кнопка кажеÑÑÑ Ñломанной. 198 Тогда вмеÑÑо пÑокÑÑÑки один Ñаз подÑвеÑиваем Ñами кнопки магазинов. */ 199 (function(){ 200 var stores=document.getElementById('d-stores'); 201 if(!stores) return; 202 root.querySelectorAll('[data-scroll-to-stores]').forEach(function(link){ 203 link.addEventListener('click',function(e){ 204 var box=stores.getBoundingClientRect(); 205 /* «Ðидно» â ÑÑо видно Ñеликом и не из-под Ñапки: еÑли веÑÑ Ð½Ð¸Ð¹ ÑÑд кнопок 206 накÑÑÑ Ð»Ð¸Ð¿ÐºÐ¾Ð¹ навигаÑией, ÑеÑÑнее домоÑаÑÑ ÑÑÑаниÑÑ, Ñем моÑгаÑÑ Ð¿Ð¾Ð´ÑвеÑкой. */ 207 var navH=(root.querySelector('.nav')||{offsetHeight:0}).offsetHeight; 208 var visible=box.top>=navH && box.bottom<=innerHeight; 209 if(!visible) return; /* обÑÑÐ½Ð°Ñ Ð¿ÑокÑÑÑка по ÑкоÑÑ */ 210 e.preventDefault(); 211 stores.classList.remove('look'); 212 void stores.offsetWidth; /* пеÑезапÑÑк анимаÑии */ 213 stores.classList.add('look'); 214 }); 215 }); 216 stores.addEventListener('animationend',function(){ stores.classList.remove('look'); },true); 217 })(); 218 219 /* ---------- подпиÑка: пÑовеÑка адÑеÑа ---------- 220 ÐÑежнÑÑ ÑÑÑаниÑа /app показÑвала оÑÐ¸Ð±ÐºÑ Ð¿ÑÑмо на кнопке и не давала оÑпÑавиÑÑ 221 ÑоÑÐ¼Ñ Ñ Ð¼ÑÑоÑом. ТÑÑ Ñо же Ñамое, ÑолÑко без jQuery. РегÑлÑÑка мÑгÑе ÑÑаÑой: 222 Ñа не пÑопÑÑкала адÑеÑа Ñ Ð´ÐµÑиÑом в домене (my-mail.ru), а ÑÑо обÑÑнÑе адÑеÑа. */ 223 (function(){ 224 var form=document.getElementById('subscribtion_form'); 225 if(!form) return; 226 var email=form.querySelector('.js-subs-email'), btn=form.querySelector('.js-subs-button'); 227 if(!email||!btn) return; 228 229 var RE=/^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/; 230 231 function check(){ 232 var v=email.value.trim(); 233 var state = !v ? 'idle' : (RE.test(v) ? 'ok' : 'bad'); 234 btn.textContent=btn.dataset[state]; 235 btn.disabled=(state!=='ok'); 236 btn.className='js-subs-button'+(state==='ok'?'':' '+state); 237 email.classList.toggle('bad',state==='bad'); 238 } 239 240 email.addEventListener('input',check); 241 email.addEventListener('change',check); /* подÑÑановка из авÑÐ¾Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ */ 242 check(); /* бÑаÑÐ·ÐµÑ Ð¼Ð¾Ð³ заполниÑÑ Ð¿Ð¾Ð»Ðµ заÑанее */ 243 })();
244 245 /* ---------- мобилÑное Ð¼ÐµÐ½Ñ ---------- */ 246 (function(){ 247 var btn=document.getElementById('d-burger'), sheet=document.getElementById('d-menu'); 248 if(!btn||!sheet) return; 249 function set(open){ 250 btn.setAttribute('aria-expanded',open?'true':'false'); 251 sheet.dataset.open=open?'1':'0'; 252 sheet.hidden=!open; 253 } 254 set(false); 255 btn.addEventListener('click',function(){ set(btn.getAttribute('aria-expanded')!=='true'); }); 256 sheet.addEventListener('click',function(e){ if(e.target.tagName==='A') set(false); }); 257 addEventListener('keydown',function(e){ if(e.key==='Escape') set(false); }); 258 /* ÑÑли Ñ Ñзкого ÑкÑана â Ð¿Ð°Ð½ÐµÐ»Ñ Ð±Ð¾Ð»ÑÑе не нÑжна */ 259 matchMedia('(min-width:701px)').addEventListener('change',function(e){ if(e.matches) set(false); }); 260 })(); 261 262 /* ---------- веÑÑÐ¸Ñ APK ---------- 263 Ð Ð±Ð¾Ñ ÑÑо Ð´ÐµÐ»Ð°ÐµÑ apkVersion.js: fetch('/apk/app-latest.json') и Ñе же клаÑÑÑ js-apk-*. 264 ÐдеÑÑ Ð¼Ð°Ð½Ð¸ÑеÑÑ Ð²ÑиÑ, ÑÑÐ¾Ð±Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° показÑвала наÑÑоÑÑÑÑ ÑбоÑкÑ. */ 265 (function(){ 266 var data={versionName:'4.3.50465',date:'2026-08-19',url:'https://im.rusfond.ru/pics/site/apk/Rusfond-latest.apk'}; 267 var MON=['ÑнваÑÑ','ÑевÑалÑ','маÑÑа','апÑелÑ','маÑ','иÑнÑ','иÑлÑ','авгÑÑÑа','ÑенÑÑбÑÑ','окÑÑбÑÑ','ноÑбÑÑ','декабÑÑ']; 268 root.querySelectorAll('.js-apk-link').forEach(function(link){ 269 link.setAttribute('href',data.url); 270 link.setAttribute('download','Rusfond-'+data.versionName+'.apk'); 271 var v=link.querySelector('.js-apk-version'); 272 if(v) v.textContent=data.versionName; 273 }); 274 var d=new Date(data.date+'T00:00:00'); 275 root.querySelectorAll('.js-apk-note').forEach(function(n){ 276 n.textContent='Файл Ð´Ð»Ñ Android Ð¾Ñ '+d.getDate()+' '+MON[d.getMonth()]+' '+d.getFullYear()+ 277 ' года â еÑли недоÑÑÑÐ¿Ð½Ñ Ð¼Ð°Ð³Ð°Ð·Ð¸Ð½Ñ Ð¿Ñиложений'; 278 }); 279 })(); 280 281 /* ---------- ÑÑÑÑÑик пиÑем: пÑавилÑное Ñклонение ---------- */ 282 (function(){ 283 var el=document.getElementById('d-count'); 284 if(!el) return; 285 var n=(window.RF_SNAPSHOT&&RF_SNAPSHOT.total)||kids.length; 286 var t=n%100, u=n%10, word; 287 if(t>10&&t<20) word='пиÑем'; 288 else if(u===1) word='пиÑÑмо'; 289 else if(u>=2&&u<=4) word='пиÑÑма'; 290 else word='пиÑем'; 291 el.textContent='Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ð² пÑиложениÑÑ '+n+' '+word+' Ñ Ð¿ÑоÑÑбой о помоÑи'; 292 })();
293 294 /* ---------- ÑаÑÑ Ð² ÑÑаÑÑÑ-баÑе: наÑÑоÑÑее вÑÐµÐ¼Ñ ---------- */ 295 (function(){ 296 var el=document.getElementById('d-clock'); 297 if(!el) return; 298 function tick(){ 299 var d=new Date(); 300 el.textContent=d.getHours()+':'+String(d.getMinutes()).padStart(2,'0'); 301 } 302 tick(); 303 setTimeout(function(){ tick(); setInterval(tick,60000); }, (60-new Date().getSeconds())*1000); 304 })(); 305 306 /* ---------- пÑокÑÑÑка пеÑеÑаÑкиванием ---------- 307 Ðивой Ð¼Ð°ÐºÐµÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ веÑÑи ÑÐµÐ±Ñ ÐºÐ°Ðº ÑкÑан: ÑпиÑок ÑÑнеÑÑÑ Ð¼ÑÑÑÑ, полки â вбок. */ 308 function dragScroll(el,axis){ 309 var down=false,moved=false,sx=0,sy=0,l0=0,t0=0; 310 el.style.cursor='grab'; 311 /* ÐнÑÑÑи полок Ð»ÐµÐ¶Ð°Ñ ÑÑÑлки Ñ ÐºÐ°ÑÑинками, и бÑаÑÐ·ÐµÑ Ð½Ð° Ð½Ð¸Ñ Ð·Ð°Ð¿ÑÑÐºÐ°ÐµÑ ÑобÑÑвенное 312 пеÑеÑаÑкивание: кÑÑÑÐ¾Ñ ÑÐ²Ð¾Ð´Ð¸Ñ Ð¿ÑизÑак ÑÑÑлки, Ð½Ð°Ñ pointermove не пÑÐ¸Ñ Ð¾Ð´Ð¸Ñ, а по 313 оÑпÑÑÐºÐ°Ð½Ð¸Ñ ÑÑабаÑÑÐ²Ð°ÐµÑ Ð¿ÐµÑÐµÑ Ð¾Ð´. ÐоÑÑÐ¾Ð¼Ñ Ð½Ð°ÑивнÑй drag глÑÑим. */ 314 el.addEventListener('dragstart',function(e){ e.preventDefault(); }); 315 316 el.addEventListener('pointerdown',function(e){ 317 if(e.button) return; 318 down=true; moved=false; sx=e.clientX; sy=e.clientY; 319 l0=el.scrollLeft; t0=el.scrollTop; 320 el.style.cursor='grabbing'; el.style.userSelect='none'; 321 }); 322 addEventListener('pointermove',function(e){ 323 if(!down) return; 324 var dx=e.clientX-sx, dy=e.clientY-sy; 325 if(Math.abs(dx)+Math.abs(dy)>4) moved=true; 326 if(axis!=='y') el.scrollLeft=l0-dx; 327 if(axis!=='x') el.scrollTop=t0-dy; 328 },{passive:true}); 329 addEventListener('pointerup',function(){ 330 if(!down) return; 331 down=false; el.style.cursor='grab'; el.style.userSelect=''; 332 }); 333 /* поÑÑнÑли â знаÑÐ¸Ñ Ð»Ð¸ÑÑали, а не оÑкÑÑвали каÑÑоÑÐºÑ */ 334 el.addEventListener('click',function(e){ 335 if(moved){ e.preventDefault(); e.stopPropagation(); } 336 },true); 337 } 338 339 /* ---------- Ñема: ÑолнÑе и лÑна ---------- 340 СÑаÑÑÑем Ð¾Ñ Ð²ÑбоÑа зÑиÑÐµÐ»Ñ (ÑÑамп на докÑменÑе или ÑиÑÑÐµÐ¼Ð½Ð°Ñ Ð½Ð°ÑÑÑойка), 341 далÑÑе запоминаем ÑÑÑной вÑбоÑ. */ 342 var themeHooks=[]; 343 function currentTheme(){ return root.getAttribute('data-theme')||'dark'; } 344 (function(){ 345 var saved=null; 346 try{ saved=localStorage.getItem('rf-app-theme'); }catch(e){} 347 var host=document.documentElement; 348 349 /* СÑÑаниÑа по ÑмолÑÐ°Ð½Ð¸Ñ ÑÑÐ¼Ð½Ð°Ñ â Ñак она вÑглÑÐ´Ð¸Ñ Ð´Ð¾Ñоже, и ÑÑо ÑеÑение, 350 а не Ñледование за ÑиÑÑемой. ÐалÑÑе Ñеловек вÑбиÑÐ°ÐµÑ ÑолнÑем или лÑной, 351 и вÑÐ±Ð¾Ñ Ð·Ð°Ð¿Ð¾Ð¼Ð¸Ð½Ð°ÐµÑÑÑ. СÑамп на докÑменÑе Ñважаем: его ÑÑÐ°Ð²Ð¸Ñ Ð¾ÐºÑÑжение, 352 внÑÑÑи коÑоÑого ÑÑÑаниÑа Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾ÑкÑÑÑа. */ 353 function auto(){ 354 var stamp=host.getAttribute('data-theme'); 355 if(stamp==='light'||stamp==='dark') return stamp; 356 return 'dark'; 357 } 358 function apply(mode,announce){ 359 root.setAttribute('data-theme',mode==='light'?'light':'dark'); 360 if(announce) themeHooks.forEach(function(fn){ fn(currentTheme()); }); 361 } 362 /* Ð¡Ð¾Ñ ÑанÑннÑй вÑбоÑ, ÑовпавÑий Ñ Ñемой по ÑмолÑаниÑ, Ñ ÑаниÑÑ Ð½ÐµÐ·Ð°Ñем. */ 363 if(saved===auto()){ saved=null; try{ localStorage.removeItem('rf-app-theme'); }catch(e){} } 364 365 apply(saved||auto(),false); 366 367 function follow(){ if(!saved) apply(auto(),true); } 368 if(window.MutationObserver){ 369 new MutationObserver(follow).observe(host,{attributes:true,attributeFilter:['data-theme']}); 370 } 371 372 var btn=document.getElementById('d-theme'); 373 btn.addEventListener('click',function(){
374 var next=currentTheme()==='light'?'dark':'light'; 375 if(next===auto()){ /* веÑнÑлиÑÑ Ðº Ñеме по ÑмолÑÐ°Ð½Ð¸Ñ â помниÑÑ Ð½ÐµÑего */ 376 saved=null; try{ localStorage.removeItem('rf-app-theme'); }catch(e){} 377 } else { 378 saved=next; try{ localStorage.setItem('rf-app-theme',next); }catch(e){} 379 } 380 apply(next,true); 381 }); 382 })(); 383 384 /* ---------- Ð¶Ð¸Ð²Ð°Ñ Ð»ÐµÐ½Ñа пиÑем ---------- 385 Ð Ð±Ð¾Ñ ÑÑда пÑÐ¸Ñ Ð¾Ð´Ð¸Ñ /api/please-help-destitutes (ÑÐ¾Ñ Ð¶Ðµ ÑндпоинÑ, ÑÑо и ÑейÑаÑ), 386 здеÑÑ â ÑеалÑнÑе пиÑÑма Ñ ÑайÑа, ÑÑÐ¾Ð±Ñ Ð²ÑÑÑÑка пÑовеÑÑлаÑÑ Ð½Ð° наÑÑоÑÑÐ¸Ñ Ð´Ð»Ð¸Ð½Ð°Ñ ÑÑÑок. */ 387 var SNAP=window.RF_SNAPSHOT||{kids:[],programs:[]}; 388 var kids=SNAP.kids.map(function(k){ 389 return {n:(k.first+' '+k.last).trim(), d:k.diag, s:k.need, u:k.url, p:k.photo, r:k.region, 390 deferred:!!k.deferred}; 391 }); 392 /* благодаÑноÑÑи: mobile.rusfond.ru/api/v1/destitutes/parent-gratitudes/videos, 393 обложка â og:image ÑÑÑаниÑÑ Ð¿Ð»ÐµÐµÑа, Ñем же пÑÑÑм, ÑÑо беÑÑÑ Ð¿Ñиложение */ 394 var thanks=(SNAP.thanks||[]).map(function(t){ return {n:t.n,u:t.u,c:t.cover,note:t.note}; }); 395 /* пÑогÑаммÑ: mobile.rusfond.ru/api/v1/programs â Ñе же обложки и ÑÑÑлки, ÑÑо в пÑиложении */ 396 var programs=(SNAP.programsV2||[]).map(function(p2){ 397 return {t:p2.t, d:p2.d, u:p2.u, c:p2.c}; 398 }); 399 function esc(t){return t.replace(/[&<>]/g,function(c){return {'&':'&','<':'<','>':'>'}[c];});} 400 /* ÐиÑем в ленÑе ÑÑолÑко же, ÑколÑко наÐ
400·ÑÐ²Ð°ÐµÑ ÑÑÑÑÑик в Ñапке, â Ñо еÑÑÑ Ð²Ñе оÑкÑÑÑÑе. 401 ФоÑогÑаÑии за пÑеделами пеÑвÑÑ ÐºÐ°ÑÑоÑек гÑÑзим лениво: ÑпиÑок веÑÑикалÑнÑй, до Ð½Ð¸Ñ 402 еÑÑ Ð½Ð°Ð´Ð¾ доÑкÑоллиÑÑ, и в оÑлиÑие Ð¾Ñ Ð³Ð¾ÑизонÑалÑной полки благодаÑноÑÑей Ð»ÐµÐ½Ð¸Ð²Ð°Ñ 403 загÑÑзка здеÑÑ Ð½Ð¸Ñего не ломаеÑ. */ 404 var EAGER_PHOTOS=6; 405 function kidCard(k,i){ 406 var lazy=i>=EAGER_PHOTOS? ' loading="lazy" decoding="async"' : ''; 407 var face=k.p? '<img src="'+k.p+'" alt=""'+lazy+'>' : esc(k.n.charAt(0)); 408 return '<a class="kid" href="'+k.u+'" target="_blank" rel="noopener" title="'+esc(k.n)+', '+esc(k.r)+'">'+ 409 /* У ÑÐµÑ , кого назвал Ð±Ð°Ð½Ð½ÐµÑ Ð¾Ñложенного пожеÑÑвованиÑ, вмеÑÑо галоÑки ÑаÑÑ: 410 плаÑÑж ждÑÑ Ð¿Ð¾Ð´ÑвеÑждениÑ, а не завеÑÑÑн. ÐÑÑжок и ÑÐ²ÐµÑ Ñе же â в пÑиложении 411 оÑделÑной ÑаÑкÑаÑки Ñ ÑÑой меÑки неÑ, а ÑÑÑаниÑа показÑÐ²Ð°ÐµÑ Ñо, ÑÑо еÑÑÑ. 412 ЦиÑеÑÐ±Ð»Ð°Ñ Ñавен заÑемнÑÐ½Ð½Ð¾Ð¼Ñ ÐºÑÑÐ¶ÐºÑ Ð¿Ð¾Ð´ ним, а не галоÑке: маленÑкий 413 диÑкообÑазнÑй ÑиÑеÑÐ±Ð»Ð°Ñ Ð½Ð° плиÑке в 22 ÑоÑки пÑоÑÑо не ÑиÑалÑÑ. */ 414 '<span class="ph2">'+face+'<em>'+ 415 (k.deferred 416 ? '<svg class="cl" viewBox="0 0 14 14" aria-hidden="true"><circle cx="7" cy="7" r="6.1"/><path d="M7 3.8v3.2l2.3 1.5"/></svg>' 417 : '<svg viewBox="0 0 14 14" aria-hidden="true"><path d="M3.2 7.4 5.9 10 10.8 4.2"/></svg>')+ 418 '</em></span>'+ 419 '<span class="info">'+ 420 '<span class="nm">'+esc(k.n)+'</span>'+ 421 '<span class="dg">'+esc(k.d)+'</span>'+ 422 '<span class="need">Ðе Ñ Ð²Ð°ÑÐ°ÐµÑ <b>'+esc(k.s)+'</b></span>'+ 423 '</span>'+ 424 '<span class="chev">âº</span></a>'; 425 } 426 var feed=document.getElementById('d-feed'),html=''; 427 kids.forEach(function(k,i){ 428 html+=kidCard(k,i); 429 if(i===2){ 430 html+='<div class="shelf"><h5>ÐлагодаÑноÑÑи</h5><div class="rail">'+ 431 thanks.map(function(t){ 432 /* ÐадÑÑ Ð¸Ð· видео ÑÑжÑлÑе (100â200 ÐÐ), а ÑÑÑаниÑа в ÑÑÐ¾Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð·Ð°Ð½ÑÑа 433 3D-ÑÑеной, и Safari оÑкладÑÐ²Ð°ÐµÑ Ð¸Ñ Ð·Ð°Ð³ÑÑзкÑ: плиÑка ÑÑÐ¾Ð¸Ñ Ð¿ÑÑÑой, пока 434 Ñеловек ÐµÑ Ð½Ðµ ÑÑонеÑ. ÐоÑÑÐ¾Ð¼Ñ Ð³ÑÑзим вÑе ÑÑÐ°Ð·Ñ Ð¸ Ñ Ð²ÑÑоким пÑиоÑиÑеÑом â 435 Ð»ÐµÐ½Ð¸Ð²Ð°Ñ Ð·Ð°Ð³ÑÑзка в гоÑизонÑалÑной полке Ð´ÐµÐ»Ð°ÐµÑ Ð·Ð°Ð»Ð¸Ð¿Ð°Ð½Ð¸Ðµ ÑолÑко замеÑнее. 436 ÐиÑÑÑ ÐºÐ°ÑÑÐ¸Ð½ÐºÑ ÑбиÑаем: под ней оÑÑаÑÑÑÑ ÑÑÐ¼Ð½Ð°Ñ Ð¿Ð»Ð¸Ñка Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑебÑнка. */ 437 var bg=t.c? '<img src="'+t.c+'" alt="" decoding="async" fetchpriority="high"'+ 438 ' onerror="this.remove()">' : ''; 439 return '<a class="thx" href="'+t.u+'" target="_blank" rel="noopener">'+bg+ 440 '<b><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 7.5 17 12l-8 4.5z"/></svg></b>'+ 441 '<span class="who">'+esc(t.n)+'</span></a>';}).join('')+'</div></div>'; 442 } 443 if(i===5){ 444 html+='<div class="shelf"><h5>ÐÑогÑаммÑ</h5><div class="rail">'+ 445 programs.map(function(p){ 446 var cov=p.c? '<img src="'+p.c+'" alt="">' : ''; 447 return '<a class="prg" href="'+p.u+'" target="_blank" rel="noopener"><span class="im">'+cov+'</span>'+ 448 '<span class="tx"><b>'+esc(p.t)+'</b><span>'+esc(p.d)+'</span></span></a>'; 449 }).join('')+'</div></div>'; 450 } 451 }); 452 feed.innerHTML=html; 453 dragScroll(feed,'y'); 454 [].slice.call(root.querySelectorAll('.shelf .rail')).forEach(function(r){ dragScroll(r,'x'); }); 455 /* ÑÑÐ¼Ð¼Ñ Ð² ленÑе Ñоже подгонÑÑÑÑÑ, Ñм. блок подгонки ниже */ 456 457 /* ---------- ÑÐ²ÐµÑ Ð²ÐµÐ´ÑÑ Ð¿Ð¾ Ñазделам ---------- */ 458 var tones={indigo:'108,123,255',mint:'53,214,164',amber:'255,194,92',violet:'169,139,255'}; 459 var links=[].slice.call(root.querySelectorAll('.nav a.l')); 460 var secs=[].slice.call(root.querySelectorAll('section[data-accent]')); 461 function paint(sec){ 462 var rgb=tones[sec.dataset.accent]||tones.indigo; 463 root.style.setProperty('--a','rgb('+rgb+')'); 464 root.style.setProperty('--a-soft','rgba('+rgb+',.17)'); 465 links.forEach(function(l){l.dataset.on=(l.dataset.sec===sec.id)?'1':'0';}); 466 } 467 if('IntersectionObserver' in window){ 468 var io=new IntersectionObserver(function(es){
469 es.forEach(function(e){ if(e.isIntersecting) paint(e.target); }); 470 },{rootMargin:'-45% 0px -45% 0px'}); 471 secs.forEach(function(s){io.observe(s);}); 472 } 473 474 /* пÑогÑеÑÑ ÑÑÐµÐ½Ð¸Ñ â ÑолбÑк Ð´Ð»Ñ Ð±ÑаÑзеÑов без scroll-timeline */ 475 var prog=document.getElementById('d-prog'); 476 if(!(CSS.supports&&CSS.supports('animation-timeline','scroll()'))){ 477 var tick=function(){ 478 var h=document.documentElement.scrollHeight-innerHeight; 479 prog.style.width=(h>0?(scrollY/h*100):0)+'%'; 480 }; 481 addEventListener('scroll',tick,{passive:true}); tick(); 482 } 483 484 /* подÑвеÑка акÑивного пеÑиода */ 485 root.querySelectorAll('.chip').forEach(function(c){ 486 c.addEventListener('click',function(){ 487 root.querySelectorAll('.chip').forEach(function(x){x.dataset.on='0';}); 488 c.dataset.on='1'; 489 }); 490 }); 491 492 /* ---------- подгонка длиннÑÑ ÑÑмм ---------- 493 clamp() Ð·Ð½Ð°ÐµÑ ÑолÑко ÑиÑÐ¸Ð½Ñ Ð¾ÐºÐ½Ð°, а не Ð´Ð»Ð¸Ð½Ñ ÑÑÑоки: еÑли ÑÑмма вÑÑаÑÑÐµÑ Ð½Ð° ÑазÑÑд, 494 ÐºÐµÐ³Ð»Ñ ÑжимаеÑÑÑ Ñовно наÑÑолÑко, ÑÑÐ¾Ð±Ñ ÑиÑло влезло Ñеликом. Ðи пеÑеноÑа, ни обÑезки. */ 495 (function(){ 496 var MIN=13; /* ниже не опÑÑкаемÑÑ: ÑиÑÑа должна оÑÑаваÑÑÑÑ ÑиÑÑой */ 497 function avail(box){ 498 var cs=getComputedStyle(box); 499 return box.clientWidth-parseFloat(cs.paddingLeft)-parseFloat(cs.paddingRight); 500 } 501 function fit(n){ 502 var box=n.parentElement; 503 if(!box||!box.clientWidth) return; 504 n.style.fontSize=''; /* возвÑаÑаем ÐºÐµÐ³Ð»Ñ Ð¸Ð· CSS и меÑÑем Ð¾Ñ Ð½ÐµÐ³Ð¾ */ 505 var max=parseFloat(getComputedStyle(n).fontSize), space=avail(box), w=n.scrollWidth; 506 if(w>space) n.style.fontSize=Math.max(MIN,Math.floor(max*space/w*10)/10)+'px'; 507 } 508 function all(){
509 [].slice.call(root.querySelectorAll('.fg .n, .kid .need b')).forEach(fit); 510 } 511 root.fitNumbers=all; 512 all(); 513 if(document.fonts&&document.fonts.ready) document.fonts.ready.then(all); 514 addEventListener('resize',function(){ clearTimeout(all.t); all.t=setTimeout(all,120); },{passive:true}); 515 })(); 516 517 /* ---------- плиÑки ÑиÑÑ: пÑожекÑÐ¾Ñ Ð¸ кÑÐ¸Ð²Ð°Ñ ÑоÑÑа ---------- */ 518 (function(){ 519 var calm2=matchMedia('(prefers-reduced-motion: reduce)').matches; 520 [].slice.call(root.querySelectorAll('.fg')).forEach(function(fg,idx){ 521 var c=document.createElement('canvas'); c.className='spark'; c.setAttribute('aria-hidden','true'); 522 fg.appendChild(c); 523 var ctx=c.getContext('2d'), w=0,h=0, pts=[], grow=0, raf=0, tone; 524 var tones=[[108,123,255],[53,214,164],[255,194,92],[169,139,255]]; 525 tone=tones[idx%tones.length]; 526 function size(){ 527 var d=Math.min(devicePixelRatio||1,2); 528 w=fg.clientWidth; h=fg.clientHeight; 529 c.width=Math.round(w*d); c.height=Math.round(h*d); 530 ctx.setTransform(d,0,0,d,0,0); 531 pts=[]; var seed=idx*97+13; 532 for(var i=0;i<=30;i++){ 533 seed=(seed*1103515245+12345)%2147483648; 534 var noise=(seed/2147483648-.5)*.14; 535 var v=Math.pow(i/30,2.1)*.94+.04+noise*(i/30); 536 pts.push(Math.min(.99,Math.max(.02,v))); 537 } 538 } 539 function draw(){ 540 if(!w) size(); 541 ctx.clearRect(0,0,w,h); 542 var n=Math.max(2,Math.round(pts.length*grow)); 543 var col='rgba('+tone[0]+','+tone[1]+','+tone[2]+','; 544 ctx.beginPath(); 545 for(var i=0;i<n;i++){ 546 var x=i/(pts.length-1)*w, y=h-3-pts[i]*(h-14); 547 i? ctx.lineTo(x,y):ctx.moveTo(x,y); 548 } 549 ctx.strokeStyle=col+'.95)'; ctx.lineWidth=1.8; ctx.lineJoin='round'; ctx.lineCap='round'; ctx.stroke(); 550 ctx.lineTo((n-1)/(pts.length-1)*w,h); ctx.lineTo(0,h); ctx.closePath(); 551 var g=ctx.createLinearGradient(0,h*.1,0,h); 552 g.addColorStop(0,col+'.22)'); g.addColorStop(1,col+'0)'); 553 ctx.fillStyle=g; ctx.fill(); 554 if(n>1){ /* ÑÑÐºÐ°Ñ ÑоÑка на веÑÑине ÑоÑÑа */ 555 var lx=(n-1)/(pts.length-1)*w, ly=h-3-pts[n-1]*(h-14); 556 ctx.beginPath(); ctx.arc(lx,ly,2.6,0,6.283); ctx.fillStyle=col+'1)'; ctx.fill(); 557 } 558 } 559 function run(target){ 560 cancelAnimationFrame(raf); 561 (function step(){ 562 grow+=(target-grow)*(calm2?1:.045); 563 draw(); 564 if(Math.abs(target-grow)>.004) raf=requestAnimationFrame(step); 565 })(); 566 } 567 fg.addEventListener('pointermove',function(e){ 568 var r=fg.getBoundingClientRect(); 569 fg.style.setProperty('--mx',((e.clientX-r.left)/r.width*100)+'%'); 570 fg.style.setProperty('--my',((e.clientY-r.top)/r.height*100)+'%'); 571 },{passive:true}); 572 fg.addEventListener('pointerenter',function(){ grow=0; run(1); },{passive:true}); 573 fg.addEventListener('pointerleave',function(){ 574 fg.style.removeProperty('--mx'); fg.style.removeProperty('--my'); run(1); 575 },{passive:true}); 576 addEventListener('resize',function(){ size(); draw(); },{passive:true}); 577 size(); grow=1; draw(); 578 }); 579 })(); 580 581 /* ---------- оÑÑÑÑÑ: живой гÑаÑик ---------- 582 ÐаннÑе наÑÑоÑÑие: Ñнимок /api/donation-month-reports/app â ÑÐ¾Ñ Ð¶Ðµ иÑÑоÑник, ÑÑо Ñ amCharts 583 на нÑнеÑней ÑÑÑаниÑе. ÐÑделение пеÑиода мÑÑÑÑ Ð¿Ð¾Ð²ÑоÑÑÐµÑ range selector amCharts. */ 584 (function(){ 585 var svg=document.getElementById('d-plot'), tip=document.getElementById('d-tip'), 586 wrapEl=document.getElementById('d-plotwrap'), keysEl=document.getElementById('d-keys'), 587 selBox=document.getElementById('d-sel'); 588 if(!svg||!SNAP.chart) return; 589 var NS='http://www.w3.org/2000/svg'; 590 var COLORS=['#6c7bff','#35d6a4','#ffc25c','#a98bff']; 591 var series=SNAP.chart.sources.map(function(name,i){ 592 return {name:name,color:COLORS[i%COLORS.length],off:false, 593 data:SNAP.chart.rows.map(function(r){ return r[i+1]; })}; 594 });
595 /* С гÑаÑика ÑÑ Ð¾Ð´Ð¸Ñ ÑолÑко Ñо, по ÑÐµÐ¼Ñ Ð·Ð° поÑледний год не пÑиÑло вообÑе ниÑего 596 (ÑейÑÐ°Ñ ÑÑо мобилÑнÑе плаÑежи). Ðопейки по SMS показÑваем: ÑоÑноÑÑÑ Ð²Ð°Ð¶Ð½ÐµÐµ ÑиÑÑоÑÑ 597 каÑÑинки. ÐÑовеÑка Ð¶Ð¸Ð²Ð°Ñ â пойдÑÑ Ð´ÐµÐ½Ñги, и кÑÐ¸Ð²Ð°Ñ Ð²ÐµÑнÑÑÑÑ Ñама. */ 598 (function(){ 599 var tail=Math.min(12,SNAP.chart.rows.length), start=SNAP.chart.rows.length-tail; 600 series=series.filter(function(z){ 601 for(var i=start;i<z.data.length;i++) if(z.data[i]>0) return true; 602 return false; 603 }); 604 })(); 605 var months=SNAP.chart.rows.map(function(r){ 606 var p2=r[0].split('-'); return new Date(+p2[0],+p2[1]-1,1); 607 }); 608 var MON=['ÑнваÑÑ','ÑевÑалÑ','маÑÑа','апÑелÑ','маÑ','иÑнÑ','иÑлÑ','авгÑÑÑа','ÑенÑÑбÑÑ','окÑÑбÑÑ','ноÑбÑÑ','декабÑÑ']; 609 function money(v){ return String(Math.round(v)).replace(/\B(?=(\d{3})+(?!\d))/g,' ')+' â½'; } 610 function el(n,at){ var e=document.createElementNS(NS,n); for(var k in at) e.setAttribute(k,at[k]); return e; } 611 612 var W=900,H=320,L=62,R=12,T=14,B=30; 613 var from=0, to=months.length-1, hoverI=-1; 614 var xOf=function(i){ return L+(i-from)/Math.max(to-from,1)*(W-L-R); }; 615 616 function draw(){ 617 while(svg.firstChild) svg.removeChild(svg.firstChild); 618 var live=series.filter(function(z){return !z.off;}); 619 var max=1, i; 620 for(i=from;i<=to;i++) live.forEach(function(z){ if(z.data[i]>max) max=z.data[i]; }); 621 max*=1.12; 622 var y=function(v){ return T+(1-v/max)*(H-T-B); }; 623 624 for(var g=0;g<=4;g++){ 625 var vy=T+(H-T-B)*g/4, val=max*(1-g/4); 626 svg.appendChild(el('line',{x1:L,x2:W-R,y1:vy,y2:vy,'class':'plot-grid'})); 627 var lb=el('text',{x:L-10,y:vy+4,'class':'plot-lbl','text-anchor':'end'}); 628 lb.textContent = val>=1e6 ? (val/1e6).toFixed(1)+' млн' : Math.round(val/1000)+' ÑÑÑ'; 629 svg.appendChild(lb); 630 } 631 var span=to-from, seen={}; 632 for(i=from;i<=to;i++){ 633 var d=months[i], yr=d.getFullYear(), put=false; 634 if(span<=14) put=true; 635 else if(span<=40) put=(d.getMonth()%3===0); 636 else put=(d.getMonth()===0 && !seen[yr]); 637 if(!put) continue; 638 seen[yr]=1; 639 var tx=el('text',{x:xOf(i),y:H-8,'class':'plot-lbl','text-anchor':'middle'}); 640 tx.textContent = span<=40 ? MON[d.getMonth()].slice(0,3)+' '+String(yr).slice(2) : yr; 641 svg.appendChild(tx); 642 } 643 live.forEach(function(z){ 644 var dd='', ar='M'+xOf(from)+','+y(0); 645 for(var k=from;k<=to;k++){ 646 dd+=(k===from?'M':'L')+xOf(k)+','+y(z.data[k]); 647 ar+='L'+xOf(k)+','+y(z.data[k]); 648 } 649 ar+='L'+xOf(to)+','+y(0)+'Z'; 650 svg.appendChild(el('path',{d:ar,fill:z.color,opacity:.09})); 651 svg.appendChild(el('path',{d:dd,'class':'plot-line',stroke:z.color})); 652 }); 653 if(hoverI>=from&&hoverI<=to){ 654 svg.appendChild(el('line',{x1:xOf(hoverI),x2:xOf(hoverI),y1:T,y2:H-B,'class':'plot-cursor'})); 655 live.forEach(function(z){ 656 svg.appendChild(el('circle',{cx:xOf(hoverI),cy:y(z.data[hoverI]),r:4, 657 fill:z.color,stroke:'var(--surf)','stroke-width':2})); 658 }); 659 } 660 var zo=document.getElementById('d-zoomout'); 661 if(zo) zo.hidden=(from===0&&to===months.length-1); 662 } 663 function keys(){ 664 keysEl.innerHTML=''; 665 series.forEach(function(z){ 666 var b2=document.createElement('button'); 667 b2.className='key'; b2.type='button'; b2.style.color=z.color; 668 b2.dataset.off=z.off?'1':'0'; 669 b2.innerHTML='<i></i><span style="color:var(--dim)">'+z.name+'</span>'; 670 b2.addEventListener('click',function(){ 671 z.off=!z.off; 672 if(series.every(function(q){return q.off;})) z.off=false; 673 keys(); draw(); 674 }); 675 keysEl.appendChild(b2); 676 }); 677 } 678 /* Ð¸Ð½Ð´ÐµÐºÑ Ð¼ÐµÑÑÑа под кÑÑÑоÑом */
679 function idxAt(clientX){ 680 var r=svg.getBoundingClientRect(); 681 var rel=(clientX-r.left)/r.width*W; 682 var i=Math.round(from+(rel-L)/(W-L-R)*(to-from)); 683 return Math.min(to,Math.max(from,i)); 684 } 685 function showTip(e,i){ 686 var d=months[i], live=series.filter(function(z){return !z.off;}), total=0; 687 var html='<h6>'+MON[d.getMonth()]+' '+d.getFullYear()+'</h6>'; 688 live.forEach(function(z){ 689 total+=z.data[i]; 690 html+='<div><span><i style="background:'+z.color+'"></i>'+z.name+'</span><b>'+money(z.data[i])+'</b></div>'; 691 }); 692 html+='<div><span>ÐÑего</span><b>'+money(total)+'</b></div>'; 693 tip.innerHTML=html; tip.hidden=false; 694 var box=wrapEl.getBoundingClientRect(), tw=tip.offsetWidth; 695 var px=e.clientX-box.left+14; 696 if(px+tw>box.width) px=e.clientX-box.left-tw-14; 697 tip.style.left=Math.max(4,px)+'px'; 698 tip.style.top=Math.min(box.height-tip.offsetHeight-4,Math.max(4,e.clientY-box.top-20))+'px'; 699 } 700 701 /* --- вÑделение пеÑиода мÑÑÑÑ --- */ 702 var dragFrom=null, dragX=0; 703 wrapEl.addEventListener('pointerdown',function(e){ 704 if(e.button) return; 705 dragFrom=idxAt(e.clientX); dragX=e.clientX-wrapEl.getBoundingClientRect().left; 706 selBox.style.display='block'; 707 selBox.style.left=dragX+'px'; selBox.style.width='0px'; 708 wrapEl.setPointerCapture&&wrapEl.setPointerCapture(e.pointerId); 709 }); 710 wrapEl.addEventListener('pointermove',function(e){ 711 var i=idxAt(e.clientX); 712 if(dragFrom!==null){ 713 var x=e.clientX-wrapEl.getBoundingClientRect().left; 714 selBox.style.left=Math.min(dragX,x)+'px'; 715 selBox.style.width=Math.abs(x-dragX)+'px'; 716 tip.hidden=true; 717 return; 718 } 719 if(i===hoverI) return; 720 hoverI=i; draw(); showTip(e,i); 721 },{passive:true}); 722 function endDrag(e){ 723 if(dragFrom===null) return; 724 var i=idxAt(e.clientX), a2=Math.min(dragFrom,i), b2=Math.max(dragFrom,i); 725 dragFrom=null; selBox.style.display='none'; 726 if(b2-a2>=2){ /* ÑлÑÑайнÑй клик не должен ÑÑ Ð»Ð¾Ð¿ÑваÑÑ Ð³ÑаÑик */ 727 from=a2; to=b2; hoverI=-1; 728 root.querySelectorAll('.chip').forEach(function(c){ c.dataset.on='0'; }); 729 draw(); 730 } 731 } 732 wrapEl.addEventListener('pointerup',endDrag); 733 wrapEl.addEventListener('pointercancel',endDrag); 734 wrapEl.addEventListener('pointerleave',function(){ hoverI=-1; tip.hidden=true; draw(); },{passive:true}); 735 736 root.querySelectorAll('.chip').forEach(function(c){ 737 c.addEventListener('click',function(){ 738 var m=+c.dataset.months||0; 739 to=months.length-1; 740 from=m? Math.max(0,months.length-m):0; 741 hoverI=-1; tip.hidden=true; draw(); 742 }); 743 }); 744 var zo=document.getElementById('d-zoomout'); 745 if(zo) zo.addEventListener('click',function(){ 746 from=0; to=months.length-1; hoverI=-1; tip.hidden=true; 747 root.querySelectorAll('.chip').forEach(function(c){ c.dataset.on=(+c.dataset.months===0)?'1':'0'; }); 748 draw(); 749 }); 750 keys(); draw(); 751 })(); 752 753 /* ---------- пÑогÑÐ°Ð¼Ð¼Ñ Ð¸ благодаÑноÑÑи ---------- 754 Ðбложки наÑиÑÐ¾Ð²Ð°Ð½Ñ Ð² ÑÑиле ÑÑвеÑждÑннÑÑ 3D-Ñканов; в Ð±Ð¾Ñ ÑÑда вÑÑаÑÑ Ð½Ð°ÑÑоÑÑие изобÑажениÑ. */ 755 (function(){ 756 function cvIn(host,w,h){ 757 var c=document.createElement('canvas'); c.width=w; c.height=h; host.appendChild(c); return c; 758 } 759 function scan(c,kind,tone){ 760 var x=c.getContext('2d'), w=c.width, h=c.height; 761 var g=x.createLinearGradient(0,0,w,h); 762 g.addColorStop(0,'#0d1220'); g.addColorStop(1,'#141b2c'); 763 x.fillStyle=g; x.fillRect(0,0,w,h); 764 var glow=x.createRadialGradient(w*.52,h*.5,10,w*.52,h*.5,w*.55); 765 glow.addColorStop(0,'rgba('+tone+',.42)'); glow.addColorStop(1,'rgba('+tone+',0)'); 766 x.fillStyle=glow; x.fillRect(0,0,w,h); 767 x.save(); x.translate(w*.5,h*.54); x.strokeStyle='rgba('+tone+',.85)'; x.lineWidth=1.4; 768 x.shadowColor='rgba('+tone+',.9)'; x.shadowBlur=14; 769 var R=Math.min(w,h)*.32, i, a; 770 if(kind==='face'){
771 for(i=0;i<26;i++){ 772 x.globalAlpha=.16+.5*(1-i/26); 773 x.beginPath(); 774 x.moveTo(-R*.75, -R*.9+i*R*.07); 775 x.bezierCurveTo(R*.2,-R*1.05+i*R*.06, R*.95,-R*.1+i*R*.05, R*.28, R*.95-i*R*.02); 776 x.stroke(); 777 } 778 } else if(kind==='neuro'){ 779 for(i=0;i<14;i++){ 780 x.globalAlpha=.2+.45*(1-i/14); 781 x.beginPath(); 782 for(a=-Math.PI;a<=Math.PI;a+=.08){ 783 var rr=R*(1+.12*Math.sin(a*6+i*.7)+.05*Math.sin(a*11-i)); 784 var px=Math.cos(a)*rr*(1+i*.012), py=Math.sin(a)*rr*.8*(1+i*.012); 785 a===-Math.PI? x.moveTo(px,py):x.lineTo(px,py); 786 } 787 x.stroke(); 788 } 789 } else { 790 for(i=0;i<20;i++){ 791 x.globalAlpha=.18+.45*(1-i/20); 792 x.beginPath(); 793 for(a=0;a<7.6;a+=.09){ 794 var r2=R*(.16+a*.12)*(1+i*.01); 795 var qx=Math.cos(a+i*.05)*r2, qy=Math.sin(a+i*.05)*r2*.92; 796 a===0? x.moveTo(qx,qy):x.lineTo(qx,qy); 797 } 798 x.stroke(); 799 } 800 } 801 x.restore(); 802 x.globalAlpha=.1; x.strokeStyle='#9fb4ff'; x.lineWidth=1; x.shadowBlur=0; 803 for(i=0;i<h;i+=7){ x.beginPath(); x.moveTo(0,i); x.lineTo(w,i); x.stroke(); } 804 x.globalAlpha=1; 805 } 806 /* обложки видеоблагодаÑноÑÑей в набÑоÑке ÑелеÑона */ 807 var tones=[[108,123,255],[53,214,164],[255,194,92],[169,139,255]]; 808 [].slice.call(root.querySelectorAll('.shelf .thx')).forEach(function(card,i){ 809 var q=tones[i%tones.length]; 810 var c=document.createElement('canvas'); c.width=184; c.height=286; 811 c.style.cssText='position:absolute;inset:0;width:100%;height:100%;display:block'; 812 var x=c.getContext('2d'); 813 var g=x.createLinearGradient(0,0,184,286); 814 g.addColorStop(0,'rgb('+Math.round(q[0]*.5)+','+Math.round(q[1]*.5)+','+Math.round(q[2]*.55)+')'); 815 g.addColorStop(1,'#141a26'); 816 x.fillStyle=g; x.fillRect(0,0,184,286); 817 for(var k=0;k<6;k++){ 818 var rg=x.createRadialGradient(20+Math.random()*140,30+Math.random()*200,3, 819 20+Math.random()*140,30+Math.random()*200,64); 820 rg.addColorStop(0,'rgba(255,255,255,.10)'); rg.addColorStop(1,'rgba(255,255,255,0)'); 821 x.fillStyle=rg; x.fillRect(0,0,184,286); 822 } 823 card.insertBefore(c,card.firstChild); 824 }); 825 })(); 826
827 /* ---------- звÑзднÑй ландÑаÑÑ Ð½Ð° ÐºÐ½Ð¾Ð¿ÐºÐ°Ñ ---------- 828 ÐаÑÐ¸ÐºÐ»ÐµÐ½Ð½Ð°Ñ ÑÑена ÑиÑÑеÑÑÑ Ð¿ÑоÑедÑÑно: беÑконеÑÐ½Ð°Ñ Ð¿ÑокÑÑÑка без видеоÑайла. */ 829 (function(){ 830 var quiet=matchMedia('(prefers-reduced-motion: reduce)').matches; 831 var tones=[[108,123,255],[53,214,164],[255,194,92],[169,139,255]]; 832 [].slice.call(root.querySelectorAll('.steps .sp')).forEach(function(btn,idx){ 833 var tone=tones[idx%tones.length]; 834 var c=document.createElement('canvas'); c.className='sky'; c.setAttribute('aria-hidden','true'); 835 btn.insertBefore(c,btn.firstChild); 836 c.setAttribute('aria-hidden','true'); 837 var ctx=c.getContext('2d'), w=0,h=0,stars=[],t=0,raf=0,last=0; 838 839 function size(){ 840 var d=Math.min(devicePixelRatio||1,2); 841 w=btn.clientWidth; h=btn.clientHeight; 842 if(!w||!h) return; 843 c.width=Math.round(w*d); c.height=Math.round(h*d); 844 ctx.setTransform(d,0,0,d,0,0); 845 stars=[]; 846 for(var i=0;i<48;i++) stars.push({ 847 x:Math.random()*w, y:Math.random()*h*.74, 848 z:.35+Math.random()*1, r:Math.random()<.22?1.3:.75 849 }); 850 } 851 function hill(off,amp,base,speed,fill){ 852 ctx.beginPath(); ctx.moveTo(0,h); 853 for(var x=0;x<=w;x+=4){ 854 var y=base+Math.sin((x+t*speed)*.017+off)*amp+Math.sin((x+t*speed)*.006+off*2)*amp*.6; 855 ctx.lineTo(x,y); 856 } 857 ctx.lineTo(w,h); ctx.closePath(); ctx.fillStyle=fill; ctx.fill(); 858 } 859 function mix(c,к){ return Math.round(c+(255-c)*к); } 860 function frame(now){ 861 if(!w||!h){ size(); if(!w||!h){ raf=requestAnimationFrame(frame); return; } } 862 var dt=Math.min((now-last)/16.7,3)||1; last=now; 863 if(!quiet) t+=dt; 864 var day=currentTheme()==='light'; 865 var g=ctx.createLinearGradient(0,0,0,h); 866 if(day){ 867 /* днÑм небо ÑвеÑлое: Ñа же ÑÑена, но без Ñезкого ÑÑÑного пÑÑна на белой ÑÑÑаниÑе */ 868 g.addColorStop(0,'rgb('+mix(tone[0],.86)+','+mix(tone[1],.88)+','+mix(tone[2],.9)+')'); 869 g.addColorStop(1,'rgb('+mix(tone[0],.55)+','+mix(tone[1],.6)+','+mix(tone[2],.68)+')'); 870 } else { 871 g.addColorStop(0,'rgb('+Math.round(tone[0]*.16)+','+Math.round(tone[1]*.17)+','+Math.round(tone[2]*.28)+')'); 872 g.addColorStop(1,'rgb('+Math.round(tone[0]*.34)+','+Math.round(tone[1]*.36)+','+Math.round(tone[2]*.5)+')'); 873 } 874 ctx.fillStyle=g; ctx.fillRect(0,0,w,h); 875 for(var i=0;i<stars.length;i++){ 876 var st=stars[i]; 877 if(!quiet){ st.x-=st.z*.32*dt; if(st.x<-2) st.x=w+2; } 878 ctx.globalAlpha=day? (.10+st.z*.16) : (.35+st.z*.55); 879 ctx.fillStyle=day? 'rgb('+mix(tone[0],.35)+','+mix(tone[1],.4)+','+mix(tone[2],.5)+')' : '#fff'; 880 ctx.fillRect(st.x,st.y,st.r,st.r); 881 } 882 ctx.globalAlpha=1; 883 if(day){ 884 hill(0, h*.10, h*.72, .55, 'rgba('+tone[0]+','+tone[1]+','+tone[2]+',.20)'); 885 hill(2.1,h*.13, h*.86, 1.1, 'rgba('+Math.round(tone[0]*.7)+','+Math.round(tone[1]*.72)+','+Math.round(tone[2]*.8)+',.45)'); 886 } else { 887 hill(0, h*.10, h*.72, .55, 'rgba('+tone[0]+','+tone[1]+','+tone[2]+',.30)'); 888 hill(2.1,h*.13, h*.86, 1.1, 'rgba(14,17,26,.85)'); 889 } 890 raf=requestAnimationFrame(frame); 891 } 892 function start(){ if(raf) return; size(); last=performance.now(); raf=requestAnimationFrame(frame); } 893 function stop(){ if(!raf) return; cancelAnimationFrame(raf); raf=0; } 894 btn.addEventListener('pointerenter',start); 895 btn.addEventListener('focus',start); 896 btn.addEventListener('pointerleave',function(){ setTimeout(stop,420); }); 897 btn.addEventListener('blur',function(){ setTimeout(stop,420); }); 898 addEventListener('resize',function(){ if(raf) size(); },{passive:true}); 899 }); 900 })(); 901 902 /* ---------- 3D-Ñлой в геÑое ---------- */ 903 var canvas=document.getElementById('d-scene'); 904 var calm=matchMedia('(prefers-reduced-motion: reduce)').matches; 905 if(window.THREE&&canvas){ 906 var host=canvas.parentNode, 907 renderer=new THREE.WebGLRenderer({canvas:canvas,alpha:true,antialias:false,powerPreference:'low-power'}), 908 scene=new THREE.Scene(), 909 camera=new THREE.PerspectiveCamera(55,1,.1,100); 910 camera.position.z=4.2; 911 /* палиÑÑа каÑÑоÑек по Ñеме: на ÑвеÑлом Ñоне леÑаÑÑ ÑвеÑлÑе каÑÑоÑки */ 912 var SK={dark:{card:'#1b2130',edge:'rgba(255,255,255,.12)',name:'#ffffff',dim:'#8b909c', 913 soft:'#c4c8d0',screen:'#151a25',row:'#181a21',bar:'#1b1d24', 914 line1:'#2f323c',line2:'#24272f',fog:0x181d28,dust:0.72,ring:0x7aa6ff}, 915 light:{card:'#ffffff',edge:'rgba(20,25,38,.14)',name:'#141926',dim:'#67708a', 916 soft:'#3d4457',screen:'#f7f9fd',row:'#e9edf6',bar:'#eef1f8', 917 line1:'#ccd3e2',line2:'#dde3ee',fog:0xeef1f7,dust:0.5,ring:0x4a59e8}};
918 var SKIN=SK[currentTheme()]||SK.dark; 919 /* ÐаÑколÑко подÑвеÑиваÑÑ Ð¿Ð¾Ð¹Ð¼Ð°Ð½Ð½ÑÑ ÐºÐ°ÑÑоÑкÑ. Ðа ÑÑмном Ñоне дÑмка ÑÑÐµÐ´Ð°ÐµÑ ÐºÐ¾Ð½ÑÑаÑÑ 920 и подÑвеÑка нÑжна; на ÑвеÑлом Ñа же подÑвеÑка вÑÐ±ÐµÐ»Ð¸Ð²Ð°ÐµÑ ÑоÑо и ÑекÑÑ. */ 921 var HL=currentTheme()==='light'?0:.55; 922 scene.fog=new THREE.FogExp2(SKIN.fog,.105); 923 924 /* ТекÑÑÑÑÑ ÑиÑÑем на canvas â в Ð±Ð¾Ñ Ð½Ð° Ð¸Ñ Ð¼ÐµÑÑо вÑÑаÑÑ Ð½Ð°ÑÑоÑÑие ÑоÑо деÑей 925 из Ð±Ð°Ð·Ñ Ð¸ ÑеалÑнÑе ÑкÑинÑоÑÑ Ð¿ÑиложениÑ. */ 926 var CO='#fb5039', pal=['#6c7bff','#35d6a4','#ffc25c','#a98bff']; 927 928 function cv(w,h){var c=document.createElement('canvas');c.width=w;c.height=h;return c;} 929 function rr(x,g,y,w,h,r){x.beginPath();x.moveTo(g+r,y);x.arcTo(g+w,y,g+w,y+h,r); 930 x.arcTo(g+w,y+h,g,y+h,r);x.arcTo(g,y+h,g,y,r);x.arcTo(g,y,g+w,y,r);x.closePath();} 931 function wrap(x,text,left,top,maxw,lh,lines){ 932 var words=text.split(' '),line='',n=0; 933 for(var i=0;i<words.length&&n<lines;i++){ 934 var t=line?line+' '+words[i]:words[i]; 935 if(x.measureText(t).width>maxw&&line){x.fillText(line,left,top+n*lh);n++;line=words[i];} 936 else line=t; 937 } 938 if(n<lines&&line)x.fillText(line,left,top+n*lh); 939 } 940 var MAXA=renderer.capabilities.getMaxAnisotropy?renderer.capabilities.getMaxAnisotropy():1; 941 function tex(c){ 942 var t=new THREE.CanvasTexture(c); 943 t.anisotropy=MAXA; t.minFilter=THREE.LinearMipmapLinearFilter; t.generateMipmaps=true; 944 return t; 945 } 946 /* Ñ Ð¾Ð»ÑÑÑ â ÑÑÑого ÑÑÐµÐ¿ÐµÐ½Ñ Ð´Ð²Ð¾Ð¹ÐºÐ¸, инаÑе WebGL оÑклÑÑÐ°ÐµÑ Ð¼Ð¸Ð¿Ð¼Ð°Ð¿Ñ Ð¸ мелкое мÑлиÑÑÑ */ 947 function letterTex(name,diag,sum,tint,photo){ 948 var c=cv(512,256),x=c.getContext('2d'); 949 x.fillStyle=SKIN.card;rr(x,0,0,512,256,30);x.fill(); 950 x.strokeStyle=SKIN.edge;x.lineWidth=3;x.stroke(); 951 var g=x.createLinearGradient(24,24,170,200);g.addColorStop(0,tint);g.addColorStop(1,'#20232c'); 952 x.fillStyle=g;rr(x,24,28,132,132,24);x.fill(); 953 if(photo&&photo.complete&&photo.naturalWidth){ 954 x.save(); rr(x,24,28,132,132,24); x.clip(); 955 x.drawImage(photo,24,28,132,132); x.restore(); 956 } else { 957 x.fillStyle='rgba(255,255,255,.6)';x.font='600 54px system-ui,sans-serif';x.textAlign='center'; 958 x.fillText(name.charAt(0),90,112);x.textAlign='left'; 959 } 960 x.fillStyle=SKIN.name;x.font='700 32px system-ui,sans-serif';x.fillText(name,176,58); 961 x.fillStyle=SKIN.dim;x.font='400 22px system-ui,sans-serif';wrap(x,diag,176,92,312,27,3); 962 x.fillStyle=SKIN.soft;x.font='400 22px system-ui,sans-serif';x.fillText('Ðе Ñ Ð²Ð°ÑаеÑ',24,206); 963 x.fillStyle=CO;x.font='700 34px system-ui,sans-serif';x.fillText(sum,24,240); 964 return tex(c); 965 } 966 function thanksTex(tint,name,photo){ 967 var c=cv(128,256),x=c.getContext('2d'); 968 if(photo&&photo.complete&&photo.naturalWidth){ 969 /* ÐºÐ°Ð´Ñ Ð¸Ð· видео впиÑÑваем по коÑоÑкой ÑÑоÑоне, лиÑнее ÑÑезаем по ÑенÑÑÑ */ 970 var s2=Math.max(128/photo.naturalWidth,256/photo.naturalHeight); 971 var dw=photo.naturalWidth*s2, dh=photo.naturalHeight*s2; 972 x.save(); rr(x,0,0,128,256,18); x.clip(); 973 x.drawImage(photo,(128-dw)/2,(256-dh)/2,dw,dh); 974 x.restore(); 975 } else { 976 var g=x.createLinearGradient(0,0,128,256);g.addColorStop(0,tint);g.addColorStop(1,SKIN.card); 977 x.fillStyle=g;rr(x,0,0,128,256,18);x.fill(); 978 } 979 x.strokeStyle='rgba(255,255,255,.9)';x.lineWidth=3; 980 x.beginPath();x.arc(64,104,22,0,6.3);x.stroke(); 981 x.fillStyle='#fff';x.beginPath();x.moveTo(58,92);x.lineTo(78,104);x.lineTo(58,116);x.closePath();x.fill(); 982 var grad=x.createLinearGradient(0,150,0,256); 983 grad.addColorStop(0,'rgba(10,13,20,0)'); grad.addColorStop(1,'rgba(10,13,20,.88)'); 984 x.fillStyle=grad; x.fillRect(0,150,128,106); 985 x.textAlign='center'; x.fillStyle='#ffffff'; x.font='700 15px system-ui,sans-serif'; 986 var parts=name.split(' '); 987 x.fillText(parts[0],64,214); 988 if(parts[1]) x.fillText(parts[1],64,232); 989 x.fillStyle='rgba(255,255,255,.72)'; x.font='400 11px system-ui,sans-serif'; 990 x.fillText('леÑение позади',64,194); 991 x.textAlign='left'; 992 return tex(c); 993 } 994 995 /* ÐаÑÑинка Ñ Ð´ÑÑгого домена, наÑиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ Ð½Ð° Ñ Ð¾Ð»ÑÑе, Ð´ÐµÐ»Ð°ÐµÑ ÐµÐ³Ð¾ tainted, и WebGL 996 оÑказÑваеÑÑÑ Ð±ÑаÑÑ Ð¸Ð· него ÑекÑÑÑÑÑ. РпÑоÑоÑипе ÑоÑо бÑли вÑиÑÑ Ð² ÑÑÑаниÑÑ Ð¸ 997 вопÑоÑа не возникало, в Ð±Ð¾Ñ Ð¾Ð½Ð¸ пÑÐ¸Ñ Ð¾Ð´ÑÑ Ñ im.rusfond.ru â поÑÑÐ¾Ð¼Ñ Ð¿ÑоÑим CORS 998 Ñвно (оба иÑÑоÑника оÑдаÑÑ Access-Control-Allow-Origin: *). */ 999 function photo(url){ 1000 if(!url) return null; 1001 var im=new Image(); 1002 im.crossOrigin='anonymous'; 1003 im.src=url; 1004 return im; 1005 } 1006 /* ÐиÑем в Ñнимке ÑÑолÑко, ÑколÑко Ð¸Ñ Ð¾ÑкÑÑÑо на ÑайÑе, а в кадÑе ÑÑÐµÐ½Ñ Ð¿Ð¾Ð¼ÐµÑаеÑÑÑ 1007 полÑоÑа деÑÑÑка: беÑÑм Ñовно ÑÑолÑко, ÑколÑко лÑÐ¶ÐµÑ Ð½Ð° каÑÑоÑки, инаÑе гÑÑзили Ð±Ñ 1008 ÑоÑогÑаÑии, коÑоÑÑе никÑо не ÑвидиÑ. ÐалÑÑе по ÐºÐ¾Ð´Ñ src[4] â гоÑÐ¾Ð²Ð°Ñ ÐºÐ°ÑÑинка: 1009 пеÑеÑиÑовка по загÑÑзке и пеÑеклÑÑение ÑÐµÐ¼Ñ Ð¶Ð´ÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ еÑ. */ 1010 var inScene=innerWidth<700?12:22; 1011 var src=kids.slice(0,inScene).map(function(k){ 1012 return [k.n,k.d,k.s,k.u,photo(k.p)]; 1013 });
1014 /* благодаÑноÑÑи Ð´Ð»Ñ ÑÑÐµÐ½Ñ â ÑÐ¾Ñ Ð¶Ðµ Ñнимок API, ÑÑо и в ÑелеÑоне, Ñ ÐºÐ°Ð´Ñами из видео */ 1015 var thanksSrc=(SNAP.thanks||[]).map(function(t){ 1016 return [t.n, t.u, photo(t.cover)]; 1017 }); 1018 if(!thanksSrc.length) thanksSrc=[['ÐлагодаÑноÑÑÑ','https://rusfond.ru/thanks',null]]; 1019 1020 var flock=new THREE.Group(); flock.position.z=-4.8; scene.add(flock); 1021 var items=[], total=inScene; 1022 for(var i=0;i<total;i++){ 1023 var tint=pal[i%pal.length], kind=(i%4===3)?4:0, tx2, w, h; 1024 var url,label; 1025 if(kind===4){ var th=thanksSrc[i%thanksSrc.length]; tx2=thanksTex(tint,th[0],th[2]); w=.38; h=.76; url=th[1]; label='ÐлагодаÑноÑÑÑ: '+th[0]; } 1026 else { var d=src[i%src.length]; tx2=letterTex(d[0],d[1],d[2],tint,d[4]); w=1.08; h=.54; url=d[3]; label='ÐиÑÑмо: '+d[0]; } 1027 var m=new THREE.Mesh(new THREE.PlaneGeometry(w,h), 1028 new THREE.MeshBasicMaterial({map:tx2,transparent:true,opacity:.82,depthWrite:false,fog:true})); 1029 var it={m:m,ang:(i/ (total||1))*6.283+Math.random()*.35,rad:2.25+Math.random()*1.75, 1030 y:(Math.random()-.5)*3.1,sp:.055+Math.random()*.075,bob:Math.random()*6.283, 1031 url:url,label:label,hover:0,k:0,kind:kind,tint:tint, 1032 src:(kind===4)?thanksSrc[i%thanksSrc.length]:src[i%src.length]}; 1033 m.renderOrder=1; m.userData.it=it; 1034 items.push(it); flock.add(m); 1035 } 1036 1037 /* ÑвеÑнÑе квадÑаÑики â Ñа ÑÐ°Ð¼Ð°Ñ Ð¶Ð¸Ð²Ð°Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÐºÐ° на Ñоне, ÑолÑко мелÑÑе */ 1038 var dn=innerWidth<700?900:2000, dp=new Float32Array(dn*3), dc=new Float32Array(dn*3); 1039 var rgbs=[[.42,.48,1],[.21,.84,.64],[1,.76,.36],[.66,.55,1]]; 1040 for(var j=0;j<dn;j++){ 1041 var th=Math.random()*6.283, r2=1.5+Math.random()*2.9; 1042 dp[j*3]=Math.cos(th)*r2; dp[j*3+1]=(Math.random()-.5)*3.8; dp[j*3+2]=Math.sin(th)*r2-5.6; 1043 var q=rgbs[(Math.random()*rgbs.length)|0]; 1044 dc[j*3]=q[0];dc[j*3+1]=q[1];dc[j*3+2]=q[2]; 1045 } 1046 var dg=new THREE.BufferGeometry(); 1047 dg.setAttribute('position',new THREE.BufferAttribute(dp,3)); 1048 dg.setAttribute('color',new THREE.BufferAttribute(dc,3)); 1049 var dust=new THREE.Points(dg,new THREE.PointsMaterial({size:.017,vertexColors:true, 1050 transparent:true,opacity:SKIN.dust,depthWrite:false,depthTest:false, 1051 blending:(currentTheme()==='light'?THREE.NormalBlending:THREE.AdditiveBlending)})); 1052 dust.renderOrder=-2; scene.add(dust); 1053 1054 var ring=new THREE.Mesh( 1055 new THREE.TorusGeometry(5.5,.009,3,220), 1056 new THREE.MeshBasicMaterial({color:SKIN.ring,transparent:true,opacity:.5,depthTest:false}) 1057 ); 1058 ring.renderOrder=-1; 1059 ring.rotation.x=1.15; ring.position.z=-4.8; scene.add(ring); 1060 1061 function size(){ 1062 var w=host.clientWidth,h=host.clientHeight; 1063 renderer.setPixelRatio(Math.min(devicePixelRatio||1,1.6)); 1064 renderer.setSize(w,h,false); 1065 camera.aspect=w/h; camera.updateProjectionMatrix(); 1066 } 1067 size(); addEventListener('resize',size,{passive:true}); 1068 /* вÑÑоÑа hero менÑеÑÑÑ Ð¸ без resize окна â ÑаÑкÑÑли «Ðак ÑÑÑановиÑÑ APK», подÑÑавилаÑÑ 1069 веÑÑÐ¸Ñ Ð¸Ð· маниÑеÑÑа; без пеÑеÑÑÑÑа Ñ Ð¾Ð»ÑÑ ÑаÑÑÑгиваеÑÑÑ Ð¸ каÑÑоÑки ÑплÑÑиваÑÑÑÑ */ 1070 if(window.ResizeObserver) new ResizeObserver(size).observe(host); 1071 1072 var mx=0,my=0,tx=0,ty=0,live=true; 1073 var ray=new THREE.Raycaster(), ptr=new THREE.Vector2(), caught=null; 1074 var CATCH_DIST=13.5; /* ловÑÑÑÑ Ð¸ далÑние: Ð¾Ñ Ð´ÑÐ¾Ð¶Ð°Ð½Ð¸Ñ ÑпаÑÐ°ÐµÑ ÑдеÑжание Ð·Ð°Ñ Ð²Ð°Ñа ниже */ 1075 1076 function pick(e){ 1077 var r=canvas.getBoundingClientRect(); 1078 var nx=(e.clientX-r.left)/r.width, ny=(e.clientY-r.top)/r.height; 1079 /* Ñлева ÑÑена ÑкÑÑÑа маÑкой â Ñам ловиÑÑ Ð½ÐµÑего */ 1080 if(innerWidth>960 && nx<.38) return null; 1081 ptr.set(nx*2-1, -(ny*2-1)); 1082 ray.setFromCamera(ptr,camera); 1083 var hits=ray.intersectObjects(flock.children,false); 1084 for(var i=0;i<hits.length;i++){ 1085 var cand=hits[i].object.userData.it; 1086 /* вÑлеÑевÑÑÑ ÐºÐ°ÑÑоÑÐºÑ Ð½Ðµ ловим повÑоÑно: она закÑÑÐ²Ð°ÐµÑ Ñобой вÑÑ Ð¾ÑÑалÑное */ 1087 if(cand===caught) continue; 1088 /* ловим ÑолÑко ÑÐµÑ , кÑо Ñже вÑÑел на ближний план: далÑние мелкие, 1089 и ÑÑвок Ð¾Ñ Ð½Ð¸Ñ Ðº ÑенÑÑÑ Ð±Ñл Ð±Ñ ÑлиÑком болÑÑим */ 1090 if(hits[i].distance>CATCH_DIST) continue; /* ÑовÑем за ÑÑманом не ловим */ 1091 return cand; 1092 } 1093 return null; 1094 } 1095 function hold(it){ 1096 if(caught===it) return; 1097 /* ÐÑмка ÑÑÐµÐ½Ñ Ð¸ маÑка геÑÐ¾Ñ Ð²Ð¼ÐµÑÑе ÑÑедаÑÑ ÐºÐ¾Ð½ÑÑаÑÑ: пойманное пиÑÑмо вÑглÑÐ´Ð¸Ñ 1098 заÑÑнÑÑÑм пеленой, Ñ Ð¾ÑÑ Ð¾Ð½Ð¾ Ñже полноÑÑÑÑ Ð½ÐµÐ¿ÑозÑаÑно. Ð
1098Ñводим его из ÑÑмана â 1099 оÑÑалÑнÑе каÑÑоÑки оÑÑаÑÑÑÑ Ð² глÑбине, и поймаÑÑ Ð²Ð·Ð³Ð»Ñдом ÑÑановиÑÑÑ Ð»ÐµÐ³Ñе. 1100 ÐеÑеÑбоÑка маÑеÑиала здеÑÑ Ð½Ðµ в ÑÑгоÑÑÑ: Ð»Ð¾Ð²Ð»Ñ Ð¿ÑоиÑÑ Ð¾Ð´Ð¸Ñ Ñаз в неÑколÑко ÑекÑнд. */ 1101 if(caught){ caught.m.material.fog=true; caught.m.material.needsUpdate=true; } 1102 if(it) { it.m.material.fog=false; it.m.material.needsUpdate=true; } 1103 caught=it; 1104 canvas.title=it?it.label:''; 1105 } 1106 host.addEventListener('pointermove',function(e){ 1107 var r=host.getBoundingClientRect(); 1108 tx=((e.clientX-r.left)/r.width-.5)*.6; 1109 ty=((e.clientY-r.top)/r.height-.5)*.4; 1110 },{passive:true}); 1111 /* .wrap Ð»ÐµÐ¶Ð¸Ñ Ð¿Ð¾Ð²ÐµÑÑ ÐºÐ°Ð½Ð²Ð°Ñа и пеÑÐµÑ Ð²Ð°ÑÑвал Ð±Ñ ÑказаÑелÑ, поÑÑÐ¾Ð¼Ñ ÑлÑÑаем Ñам геÑой 1112 и пÑопÑÑкаем вÑÑ, ÑÑо попало в инÑеÑакÑивнÑй или ÑекÑÑовÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑÑÑаниÑÑ */ 1113 function overUI(e){ 1114 var t=e.target; 1115 return !!(t&&t.closest&&t.closest('a,button,input,summary,.device,.figs,.badge,h1,.lede,.scenehint,.helpline')); 1116 } 1117 /* ÐаÑÑоÑка ÑлеÑÐ°ÐµÑ Ð¸Ð·-под кÑÑÑоÑа, и лÑÑ Ð¿ÐµÑеÑÑаÑÑ Ð² Ð½ÐµÑ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÑÑ â еÑли на ÑÑо 1118 ÑеагиÑоваÑÑ, полÑÑаеÑÑÑ Ð´Ñожание: поймал, оÑпÑÑÑил, Ñнова поймал. ÐоÑÑÐ¾Ð¼Ñ 1119 Ð·Ð°Ñ Ð²Ð°Ñ Ð´ÐµÑжим, пока ÑказаÑÐµÐ»Ñ Ð½Ðµ оÑойдÑÑ Ð¾Ñ Ð¼ÐµÑÑа Ð·Ð°Ñ Ð²Ð°Ñа или не попадÑÑ 1120 на дÑÑгÑÑ ÐºÐ°ÑÑоÑкÑ. */ 1121 var grabX=0, grabY=0, HOLD=110; 1122 host.addEventListener('pointermove',function(e){ 1123 if(overUI(e)){ hold(null); host.style.cursor=''; return; } 1124 if(caught){ 1125 var far=Math.abs(e.clientX-grabX)+Math.abs(e.clientY-grabY)>HOLD; 1126 var other=far?pick(e):null; 1127 if(other){ hold(other); grabX=e.clientX; grabY=e.clientY; } 1128 else if(far) hold(null); 1129 host.style.cursor=caught?'pointer':''; 1130 return; 1131 } 1132 var it=pick(e); 1133 if(it){ grabX=e.clientX; grabY=e.clientY; } 1134 hold(it); 1135 host.style.cursor=caught?'pointer':''; 1136 },{passive:true}); 1137 host.addEventListener('pointerleave',function(){ hold(null); host.style.cursor=''; },{passive:true}); 1138 /* window.open в пеÑоÑниÑе iframe ÑаÑÑо блокиÑÑеÑÑÑ â Ñогда оÑкÑÑваем обÑÑной ÑÑÑлкой */ 1139 function openUrl(u){ 1140 var win=null; 1141 try{ win=window.open(u,'_blank','noopener'); }catch(err){} 1142 if(win) return; 1143 var a=document.createElement('a'); 1144 a.href=u; a.target='_blank'; a.rel='noopener'; 1145 document.body.appendChild(a); a.click(); a.remove(); 1146 } 1147 host.addEventListener('click',function(e){ 1148 if(overUI(e)) return; 1149 var it=pick(e)||caught; /* на ÑаÑ-ÑкÑане Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½ÐµÑ, беÑÑм пойманнÑÑ ÐºÐ°ÑÑоÑÐºÑ */ 1150 if(it&&it.url) openUrl(it.url); 1151 }); 1152 if('IntersectionObserver' in window){ 1153 new IntersectionObserver(function(es){live=es[0].isIntersecting;},{threshold:0}).observe(host); 1154 } 1155 function rebuild(){ 1156 items.forEach(function(it){ 1157 var old=it.m.material.map, t2; 1158 if(it.kind===4) t2=thanksTex(it.tint,it.src[0],it.src[2]); 1159 else t2=letterTex(it.src[0],it.src[1],it.src[2],it.tint,it.src[4]); 1160 it.m.material.map=t2; it.m.material.needsUpdate=true; 1161 if(old&&old.dispose) old.dispose(); 1162 }); 1163 } 1164 addEventListener('load',rebuild); 1165 setTimeout(rebuild,600); 1166 1167 /* РанÑÑе ÑоÑо бÑли вÑиÑÑ Ð² ÑÑÑаниÑÑ Ð¸ к пеÑвой оÑÑиÑовке бÑли гоÑовÑ. ТепеÑÑ Ð¾Ð½Ð¸ 1168 гÑÑзÑÑÑÑ Ð¿Ð¾ ÑеÑи: ждÑм каждÑÑ Ð¸ пеÑеÑиÑовÑваем паÑкой, ÑÑÐ¾Ð±Ñ Ð½Ðµ гонÑÑÑ 20 пеÑеÑбоÑок. */ 1169 (function(){ 1170 var timer=null; 1171 function later(){ clearTimeout(timer); timer=setTimeout(rebuild,120); } 1172 src.map(function(s){ return s[4]; }) 1173 .concat(thanksSrc.map(function(t){ return t[2]; })) 1174 .forEach(function(im){
1175 if(im && !im.complete) im.addEventListener('load',later); 1176 }); 1177 })(); 1178 1179 themeHooks.push(function(mode){ 1180 SKIN=SK[mode]||SK.dark; 1181 HL=(mode==='light')?0:.55; 1182 scene.fog=new THREE.FogExp2(SKIN.fog,.105); 1183 ring.material.color.setHex(SKIN.ring); 1184 dust.material.opacity=SKIN.dust; 1185 dust.material.blending=(mode==='light'?THREE.NormalBlending:THREE.AdditiveBlending); 1186 dust.material.needsUpdate=true; 1187 items.forEach(function(it){ 1188 var old=it.m.material.map, t2; 1189 if(it.kind===4) t2=thanksTex(it.tint,it.src[0],it.src[2]); 1190 else t2=letterTex(it.src[0],it.src[1],it.src[2],it.tint,it.src[4]); 1191 it.m.material.map=t2; it.m.material.needsUpdate=true; 1192 if(old&&old.dispose) old.dispose(); 1193 }); 1194 }); 1195 1196 var prev=0, stagePt=new THREE.Vector3(); 1197 (function loop(t){ 1198 requestAnimationFrame(loop); 1199 if(!live){prev=t;return;} 1200 var dt=Math.min((t-prev)/1000,.05); prev=t; 1201 mx+=(tx-mx)*.05; my+=(ty-my)*.05; 1202 /* ÐÐ¾Ð¹Ð¼Ð°Ð½Ð½Ð°Ñ ÐºÐ°ÑÑоÑка вÑлеÑÐ°ÐµÑ Ð² Ñвободное окно Ð¼ÐµÐ¶Ð´Ñ ÑекÑÑом и ÑелеÑоном. 1203 ТоÑÐºÑ Ð·Ð°Ð´Ð°Ñм в кооÑдинаÑÐ°Ñ ÑкÑана и пеÑеводим в ÑÑенÑ, поÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð° оÑÑаÑÑÑÑ 1204 на меÑÑе пÑи лÑбом ÑазмеÑе окна. */ 1205 var wide=innerWidth>960; 1206 /* ÐаÑÑоÑка должна Ñеликом ÑмеÑÑиÑÑÑÑ Ð² окно Ð¼ÐµÐ¶Ð´Ñ ÑекÑÑом и ÑелеÑоном, инаÑе 1207 ÑÐµÐ·Ð¶Ð°ÐµÑ Ð¿Ð¾Ð´ Ð½Ð¸Ñ . СÑиÑаем, ÑколÑко миÑовÑÑ ÐµÐ´Ð¸Ð½Ð¸Ñ Ð·Ð°Ð½Ð¸Ð¼Ð°ÐµÑ ÑÑо окно на нÑжной 1208 глÑбине, и подбиÑаем глÑÐ±Ð¸Ð½Ñ Ñак, ÑÑÐ¾Ð±Ñ Ð¿Ð¸ÑÑмо в него впиÑалоÑÑ. */ 1209 var winShare=wide?.19:.62; /* Ð´Ð¾Ð»Ñ ÑиÑÐ¸Ð½Ñ ÑкÑана под каÑÑоÑÐºÑ */ 1210 var halfFov=camera.fov*Math.PI/360; 1211 var need=1.08*1.25; /* ÑиÑина пиÑÑма Ñ ÑÑÑÑом ÑкÑÑÐ¿Ð½ÐµÐ½Ð¸Ñ */ 1212 var depth=need/(2*Math.tan(halfFov)*camera.aspect*winShare); 1213 if(depth<3.4) depth=3.4; 1214 stagePt.set(wide?.12:0, wide?.06:.02, .5).unproject(camera); 1215 stagePt.sub(camera.position).normalize().multiplyScalar(depth).add(camera.position); 1216 flock.worldToLocal(stagePt); 1217 for(var k=0;k<items.length;k++){ 1218 var it=items[k], on=(it===caught)?1:0; 1219 it.hover+=(on-it.hover)*.085; 1220 if(!calm) it.ang+=it.sp*dt*(1-it.hover); /* Ð¿Ð¾Ð¹Ð¼Ð°Ð½Ð½Ð°Ñ ÐºÐ°ÑÑоÑка замиÑÐ°ÐµÑ */ 1221 var yy=it.y+(calm?0:Math.sin(t*.0009+it.bob)*.12*(1-it.hover)); 1222 var px=Math.cos(it.ang)*it.rad+1.05, py=yy, pz=Math.sin(it.ang)*it.rad; 1223 if(it.hover>.002){ 1224 px+=(stagePt.x-px)*it.hover; 1225 py+=(stagePt.y-py)*it.hover; 1226 pz+=(stagePt.z-pz)*it.hover; 1227 } 1228 it.m.position.set(px,py,pz); 1229 it.m.quaternion.copy(camera.quaternion); 1230 var sc=1+it.hover*.25; /* оÑÑалÑное ÑкÑÑпнение даÑÑ Ñама пеÑÑпекÑива */ 1231 it.m.scale.set(sc,sc,1); 1232 var far=caught? .45 : .82; /* ÑоÑедние пÑиÑÑÑ Ð°ÑÑ, Ð¿Ð¾Ð¹Ð¼Ð°Ð½Ð½Ð°Ñ Ð¿Ð»Ð¾ÑÐ½Ð°Ñ */ 1233 it.m.material.opacity=far+it.hover*(1-far); 1234 /* MeshBasicMaterial ÑÐ¼Ð½Ð¾Ð¶Ð°ÐµÑ ÑекÑÑÑÑÑ Ð½Ð° color: болÑÑе единиÑÑ â подÑвеÑка. 1235 ÐÑжна как Ñаз Ñлева, где маÑка геÑÐ¾Ñ Ð³Ð°ÑÐ¸Ñ ÑÑÐµÐ½Ñ ÑилÑнее вÑего. */ 1236 it.m.material.color.setScalar(1+it.hover*HL); 1237 it.m.renderOrder=1+Math.round(it.hover*3); 1238 } 1239 if(!calm){ dust.rotation.y=t*.00013; ring.rotation.z=t*.00014; } 1240 flock.rotation.x=my*.16; flock.position.x=mx*.5; 1241 dust.position.x=mx*.7; 1242 ring.position.x=mx*.4; 1243 renderer.render(scene,camera); 1244 })(0); 1245 } 1246})();
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.