VVG1.RAR [11/11]

ZXNet echo conference «zx.spectrum»

From Andrey Teplyakov To All 27 February 1998


section 11 of 11 of file vvg1.rar AutoUUEž3.0,žbyžAleksžA.žAleksandrov

M3ODS,K)C+?+*D[Z/;S90\C%;[D_->>3FY.1F=7_)I'*ROERLZ-L>X]76\?G"
M#8_29[GNR)&OH9PZ'!Q+X_#S^7\0_APUF\&XNAF98WZTP%._FSKPD<$6W0Z^
M1\_RC,@EG5ZN3VAQ&'2;SV^QVAH,B/5%KE.WEYT+J7WSLX!B@[--ST;&8G"(
M8SO^"+]M$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1
M$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1
M$1$1$1$1$1$1$1$1$1$1$1$1$1$`L@)V`$!N`!0T%#HD-N5Q,RW_$$("?@Z2
M!8R$&>:?/V= 0) { e.preventDefault(); applyItem(items[sel]); } else if (e.keyCode === 27) { hideDrop(true); sel = -1; } }); drop.addEventListener('mousedown', function (e) { // Only left click opens a suggestion; ignore right/middle. if (e.button !== 0) { e.preventDefault(); return; } var row = e.target.closest('.smn-suggest-row'); if (!row || !drop.contains(row)) return; e.preventDefault(); applyItem(row); }); input.addEventListener('blur', function () { setTimeout(function () { hideDrop(false); }, 200); }); input.addEventListener('focus', function () { if (dropItems().length) showDrop(); }); window.addEventListener('resize', function () { if (drop.style.display === 'block') sizeDrop(); }); } function initCoverZoom() { if ( document.body.classList.contains('smn-page-letters') || document.body.classList.contains('smn-page-authors') ) { return; } var covers = document.querySelectorAll('.smn-list-cover'); for (var i = 0; i < covers.length; i++) { (function (cover) { var img = cover.querySelector('img'); var item = cover.closest('.smn-list-item'); if (!img || !item) return; function resetZoom() { img.style.transform = ''; cover.classList.remove('is-zoomed'); item.classList.remove('is-zoomed'); } function applyZoom() { var rect = img.getBoundingClientRect(); var margin = 16; var cx = window.innerWidth / 2; var cy = window.innerHeight / 2; var imgCx = rect.left + rect.width / 2; var imgCy = rect.top + rect.height / 2; var maxW = window.innerWidth - margin * 2; var maxH = window.innerHeight - margin * 2; var scale = Math.min(maxW / rect.width, maxH / rect.height); var dx = cx - imgCx; var dy = cy - imgCy; img.style.transform = 'translate(' + dx + 'px, ' + dy + 'px) scale(' + scale + ')'; cover.classList.add('is-zoomed'); item.classList.add('is-zoomed'); } cover.addEventListener('mouseenter', applyZoom); item.addEventListener('mouseleave', resetZoom); })(covers[i]); } } function initThemeToggle() { var lang = document.querySelector('.smn-lang'); if (!lang || lang.querySelector('.smn-theme-toggle')) return; var isEng = (document.documentElement.lang || '').toLowerCase().indexOf('en') === 0; function currentTheme() { return document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'; } function applyTheme(theme) { if (theme === 'dark') { document.documentElement.setAttribute('data-theme', 'dark'); } else { document.documentElement.removeAttribute('data-theme'); } try { localStorage.setItem('smn-theme', theme); } catch (e) {} syncButtons(); } function syncButtons() { var dark = currentTheme() === 'dark'; var buttons = document.querySelectorAll('.smn-theme-toggle'); for (var i = 0; i < buttons.length; i++) { buttons[i].setAttribute( 'aria-label', dark ? (isEng ? 'Switch to light theme' : 'Включить светлую тему') : (isEng ? 'Switch to dark theme' : 'Включить тёмную тему') ); buttons[i].setAttribute('aria-pressed', dark ? 'true' : 'false'); } } function toggleTheme() { applyTheme(currentTheme() === 'dark' ? 'light' : 'dark'); } function makeButton() { var btn = document.createElement('button'); btn.type = 'button'; btn.className = 'smn-theme-toggle'; btn.innerHTML = '' + ''; btn.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); toggleTheme(); }); return btn; } // Keep .smn-lang as the header grid cell; put the toggle inside it. // Wrap rus/eng so flex gap doesn't stretch the slash between languages. if (!lang.querySelector('.smn-lang-switch')) { var switchWrap = document.createElement('span'); switchWrap.className = 'smn-lang-switch'; while (lang.firstChild) { switchWrap.appendChild(lang.firstChild); } lang.appendChild(switchWrap); } lang.insertBefore(makeButton(), lang.firstChild); lang.classList.add('smn-lang--with-theme'); window.__smnMakeThemeButton = makeButton; window.__smnToggleTheme = toggleTheme; window.__smnSyncThemeButtons = syncButtons; syncButtons(); } function initMobileMenu() { var header = document.querySelector('.smn-header'); var bar = header && header.querySelector('.smn-header-bar'); var brand = bar && bar.querySelector('.smn-brand'); var nav = bar && bar.querySelector('.smn-nav'); var lang = bar && bar.querySelector('.smn-lang'); if (!header || !bar || !brand || !nav) return; var mq = window.matchMedia('(max-width: 820px)'); var isEng = (document.documentElement.lang || '').toLowerCase().indexOf('en') === 0; var btn = document.createElement('button'); btn.type = 'button'; btn.className = 'smn-menu-toggle'; btn.setAttribute('aria-expanded', 'false'); btn.setAttribute('aria-controls', 'smn-menu-drawer'); btn.setAttribute('aria-label', isEng ? 'Menu' : 'Меню'); btn.innerHTML = ''; bar.insertBefore(btn, brand); var drawer = document.createElement('div'); drawer.id = 'smn-menu-drawer'; drawer.className = 'smn-menu-drawer'; drawer.hidden = true; var drawerNav = document.createElement('nav'); drawerNav.className = 'smn-menu-drawer-nav'; drawerNav.setAttribute('aria-label', isEng ? 'Sections' : 'Разделы'); drawer.appendChild(drawerNav); header.insertBefore(drawer, header.querySelector('.smn-breadcrumbs') || null); function menuFullLabel(el) { var href = (el.getAttribute('href') || '').toLowerCase(); var text = (el.textContent || '').replace(/\s+/g, ' ').trim(); if ( href.indexOf('/ezines') !== -1 || text === 'Эл.пресса' || text === 'Электронная пресса' || text === 'Diskmags' ) { return isEng ? 'Electronic magazines and newspapers' : 'Электронные журналы и газеты'; } if ( href.indexOf('/books') !== -1 || text === 'Книги' || text === 'Books' ) { return isEng ? 'Books and magazines' : 'Книги и журналы'; } if ( href.indexOf('/snailmail') !== -1 || href.indexOf('/letters') !== -1 || text === 'Письма' || text === 'Letters' ) { return isEng ? 'Paper letters from Spectrumists' : 'Бумажные письма спектрумистов'; } if (href.indexOf('/zxnet') !== -1 || text === 'ZXNet') { return isEng ? 'Fido, ZXNet and SPBZXNet echoes' : 'Эхоконференции Fido, ZXNet и SPBZXNet'; } return null; } function fillDrawer() { drawerNav.innerHTML = ''; var primary = nav.querySelectorAll('.smn-nav-primary .smn-nav-item'); var galleryHref = null; for (var i = 0; i < primary.length; i++) { var clone = primary[i].cloneNode(true); var full = menuFullLabel(primary[i]); if (full) clone.textContent = full; drawerNav.appendChild(clone); } var secondaryLinks = nav.querySelectorAll('.smn-nav-secondary > a'); for (var g = 0; g < secondaryLinks.length; g++) { var sh = (secondaryLinks[g].getAttribute('href') || '').toLowerCase(); if (sh.indexOf('/gallery') !== -1) { galleryHref = secondaryLinks[g].getAttribute('href'); break; } } if (!galleryHref) { galleryHref = isEng ? '/en/gallery' : '/ru/gallery'; } var galleryLink = document.createElement('a'); galleryLink.href = galleryHref; galleryLink.textContent = isEng ? 'Gallery of electronic magazines and newspapers' : 'Галерея электронных журналов и газет'; if (window.location.pathname.toLowerCase().indexOf('/gallery') !== -1) { galleryLink.className = 'is-active'; } drawerNav.appendChild(galleryLink); var more = document.createElement('div'); more.className = 'smn-menu-drawer-more'; var secondary = nav.querySelectorAll('.smn-nav-secondary > a, .smn-nav-secondary > form'); for (var j = 0; j < secondary.length; j++) { var href = ((secondary[j].getAttribute && secondary[j].getAttribute('href')) || '').toLowerCase(); if (href.indexOf('/gallery') !== -1) continue; more.appendChild(secondary[j].cloneNode(true)); } if (lang) { var langBox = document.createElement('div'); langBox.className = 'smn-menu-drawer-lang'; if (typeof window.__smnMakeThemeButton === 'function') { langBox.appendChild(window.__smnMakeThemeButton()); } var langText = document.createElement('span'); langText.className = 'smn-menu-drawer-lang-text'; var switchSrc = lang.querySelector('.smn-lang-switch'); langText.innerHTML = switchSrc ? switchSrc.innerHTML : lang.innerHTML; langBox.appendChild(langText); more.appendChild(langBox); if (typeof window.__smnSyncThemeButtons === 'function') { window.__smnSyncThemeButtons(); } } if (more.childNodes.length) { drawerNav.appendChild(more); } } function syncDrawerPad() { var search = header.querySelector('.smn-search'); var bottom = Math.max( btn.getBoundingClientRect().bottom, brand.getBoundingClientRect().bottom, search ? search.getBoundingClientRect().bottom : 0 ); header.style.setProperty('--smn-menu-pad-top', Math.ceil(bottom + 14) + 'px'); } function closeMenu() { header.classList.remove('is-menu-open'); document.body.classList.remove('smn-menu-open'); btn.setAttribute('aria-expanded', 'false'); drawer.hidden = true; } function openMenu() { fillDrawer(); syncDrawerPad(); header.classList.add('is-menu-open'); document.body.classList.add('smn-menu-open'); btn.setAttribute('aria-expanded', 'true'); drawer.hidden = false; drawer.scrollTop = 0; } function toggleMenu(e) { e.stopPropagation(); if (header.classList.contains('is-menu-open')) { closeMenu(); } else { openMenu(); } } btn.addEventListener('click', toggleMenu); document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeMenu(); }); window.addEventListener('resize', function () { if (header.classList.contains('is-menu-open')) syncDrawerPad(); }); function onViewportChange() { if (!mq.matches) closeMenu(); } if (mq.addEventListener) { mq.addEventListener('change', onViewportChange); } else if (mq.addListener) { mq.addListener(onViewportChange); } fillDrawer(); } function initNavMore() { var nav = document.querySelector('.smn-nav'); if (!nav) return; var primary = nav.querySelector('.smn-nav-primary'); var wrap = nav.querySelector('.smn-nav-more-wrap'); var btn = nav.querySelector('.smn-nav-more-toggle'); var panel = nav.querySelector('.smn-nav-more'); var overflow = nav.querySelector('.smn-nav-overflow'); if (!primary || !wrap || !btn || !panel || !overflow) return; var items = Array.prototype.slice.call(primary.querySelectorAll('.smn-nav-item')); var gap = 14; var frame = null; var mqMobile = window.matchMedia('(max-width: 820px)'); var widthCache = null; var lastHideFrom = -1; var ignoreRo = false; function closeMenu() { wrap.classList.remove('is-open'); btn.setAttribute('aria-expanded', 'false'); panel.hidden = true; } function openMenu() { wrap.classList.add('is-open'); btn.setAttribute('aria-expanded', 'true'); panel.hidden = false; } function measureGap() { var styles = window.getComputedStyle(primary); var g = parseFloat(styles.columnGap || styles.gap || '14'); return isNaN(g) ? 14 : g; } function resetOverflowDom() { for (var i = 0; i < items.length; i++) { items[i].classList.remove('is-overflow'); } overflow.innerHTML = ''; overflow.hidden = true; } function updateOverflow(remeasure) { // Mobile uses the hamburger drawer — skip overflow collapsing. if (mqMobile.matches) { if (lastHideFrom !== items.length) { resetOverflowDom(); lastHideFrom = items.length; widthCache = null; } closeMenu(); return; } if (remeasure || !widthCache || widthCache.length !== items.length) { resetOverflowDom(); gap = measureGap(); // One layout pass: read all widths together while items are visible. var widths = []; for (var m = 0; m < items.length; m++) { widths.push(items[m].offsetWidth); } widthCache = widths; } var available = nav.clientWidth - wrap.offsetWidth - gap; if (available < 0) available = 0; var used = 0; var hideFrom = items.length; for (var i = 0; i < widthCache.length; i++) { var next = used + (i > 0 ? gap : 0) + widthCache[i]; if (next > available) { hideFrom = i; break; } used = next; } // Keep at least one primary item visible when possible. if (hideFrom === 0 && items.length > 0 && available > 40) { hideFrom = 1; } if (hideFrom === lastHideFrom && overflow.childNodes.length === items.length - hideFrom) { return; } lastHideFrom = hideFrom; ignoreRo = true; resetOverflowDom(); for (var j = hideFrom; j < items.length; j++) { var src = items[j]; src.classList.add('is-overflow'); var clone = src.cloneNode(true); clone.classList.remove('is-overflow'); overflow.appendChild(clone); } overflow.hidden = overflow.childNodes.length === 0; requestAnimationFrame(function () { ignoreRo = false; }); } function scheduleUpdate(remeasure) { if (frame) cancelAnimationFrame(frame); frame = requestAnimationFrame(function () { frame = null; updateOverflow(!!remeasure); }); } btn.addEventListener('click', function (e) { e.stopPropagation(); if (wrap.classList.contains('is-open')) { closeMenu(); } else { openMenu(); } }); document.addEventListener('click', function (e) { if (!wrap.contains(e.target)) closeMenu(); }); document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeMenu(); }); window.addEventListener('resize', function () { scheduleUpdate(true); }); if (window.ResizeObserver) { var bar = nav.closest('.smn-header-bar'); var ro = new ResizeObserver(function () { if (ignoreRo) return; scheduleUpdate(true); }); // Observe the bar, not the nav — hiding items changes nav size and caused a loop. if (bar) ro.observe(bar); else ro.observe(nav); } scheduleUpdate(true); } function initTextCollapse(id, options) { var el = document.getElementById(id); if (!el) return; var always = !!(options && options.always); var mq = window.matchMedia('(max-width: 820px)'); function clearCollapse() { el.classList.remove('is-expanded', 'is-collapsible'); el.removeAttribute('role'); el.removeAttribute('tabindex'); el.removeAttribute('aria-expanded'); } function applyCollapse(keepOpen) { el.classList.add('is-collapsible'); el.setAttribute('role', 'button'); el.setAttribute('tabindex', '0'); if (keepOpen) { el.classList.add('is-expanded'); el.setAttribute('aria-expanded', 'true'); } else { el.classList.remove('is-expanded'); el.setAttribute('aria-expanded', 'false'); } } function syncCollapsed() { if (!always && !mq.matches) { clearCollapse(); return; } var keepOpen = el.classList.contains('is-expanded'); // Homepage lead is always long — skip expensive scrollHeight of the whole block. if (always && el.id === 'smn-lead') { applyCollapse(keepOpen); return; } // One layout read of natural height; compare to CSS clamp in em (no second measure). el.classList.remove('is-collapsible', 'is-expanded'); var fullH = el.scrollHeight; var fontSize = parseFloat(window.getComputedStyle(el).fontSize) || 16; var clampEm = mq.matches ? 7.2 : 5.6; if (fullH <= fontSize * clampEm + 4) { clearCollapse(); return; } applyCollapse(keepOpen); } function toggle(e) { if (e && e.target && e.target.closest && e.target.closest('a')) return; if (!el.classList.contains('is-collapsible')) return; if (!always && !mq.matches) return; var open = !el.classList.contains('is-expanded'); el.classList.toggle('is-expanded', open); el.setAttribute('aria-expanded', open ? 'true' : 'false'); } el.addEventListener('click', toggle); el.addEventListener('keydown', function (e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(); } }); if (mq.addEventListener) { mq.addEventListener('change', syncCollapsed); } else if (mq.addListener) { mq.addListener(syncCollapsed); } syncCollapsed(); } /* TEMP: pin category aside to sticky breadcrumbs level */ function initCatAsidePin() { var aside = document.querySelector('.smn-article-cat-aside'); var crumbs = document.getElementById('smn-sticky-breadcrumbs'); if (!aside || !crumbs) return; var header = crumbs.closest('.smn-header'); function measurePinTop() { if (!header) return 0; // Breadcrumbs level + a little lower, to clear the header fade. var pin = Math.round(crumbs.getBoundingClientRect().top - header.getBoundingClientRect().top) + 60; return pin < 0 ? 0 : pin; } function sync() { if (window.getComputedStyle(aside).position !== 'sticky') { aside.style.top = ''; aside.style.maxHeight = ''; return; } var pinTop = measurePinTop(); aside.style.top = pinTop + 'px'; aside.style.maxHeight = 'calc(100vh - ' + pinTop + 'px - 16px)'; } sync(); window.addEventListener('resize', sync); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function () { initSuggest('input_query_smn', 'suggest-smn'); initCoverZoom(); initThemeToggle(); initMobileMenu(); initNavMore(); initTextCollapse('smn-lead', { always: true }); initTextCollapse('smn-letter-summary'); initTextCollapse('smn-press-issue-desc'); initCatAsidePin(); }); } else { initSuggest('input_query_smn', 'suggest-smn'); initCoverZoom(); initThemeToggle(); initMobileMenu(); initNavMore(); initTextCollapse('smn-lead', { always: true }); initTextCollapse('smn-letter-summary'); initTextCollapse('smn-press-issue-desc'); initCatAsidePin(); } })();