async function configureRepository() { // Generated by Pages workflow; no account names or release URLs are hardcoded. const response = await fetch('repository.json', { cache: 'no-cache' }); if (!response.ok) return; const { repository } = await response.json(); if (typeof repository !== 'string' || !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repository)) return; const root = `https://github.com/${repository}`; const links = { repo: root, source: root, releases: `${root}/releases`, privacy: `${root}/blob/main/PRIVACY.md`, license: `${root}/blob/main/LICENSE` }; for (const [name, url] of Object.entries(links)) { document.querySelectorAll(`[data-${name}]`).forEach(link => { link.href = url; link.target = '_blank'; link.rel = 'noopener noreferrer'; link.hidden = false; }); } const button = document.getElementById('download'); button.target = '_blank'; button.rel = 'noopener noreferrer'; button.href = `${root}/releases`; let releaseDetails = null; const renderDownload = () => { button.textContent = window.siteI18n.t(releaseDetails ? 'Download for Windows ↓' : 'View downloads ↓'); document.getElementById('release-note').textContent = releaseDetails ? `${releaseDetails.tag} · ${releaseDetails.size} ${window.siteI18n.language === 'ru' ? 'МБ' : 'MB'} · Windows x64 · ${window.siteI18n.language === 'ru' ? 'бесплатно' : 'free'}` : window.siteI18n.t('Free · open source · no .NET installation needed'); }; document.addEventListener('languagechange', renderDownload); renderDownload(); try { const latest = await fetch(`https://api.github.com/repos/${repository}/releases/latest`, { headers: { Accept: 'application/vnd.github+json' } }); if (!latest.ok) return; const release = await latest.json(); const asset = release.assets?.find(item => /^BashkortKeyboard-.+-win-x64\.zip$/i.test(item.name)); if (!asset) return; const url = new URL(asset.browser_download_url); if (url.origin !== 'https://github.com' || !url.pathname.startsWith(`/${repository}/releases/download/`)) return; button.href = url.href; releaseDetails = { tag: release.tag_name, size: Math.round(asset.size / 1024 / 1024) }; renderDownload(); } catch { // Releases link remains usable when API is offline or rate limited. } } configureRepository().catch(() => {});