alfredlinux.com/download.php
Commander 60f940cdd0 feat: complete alfredlinux.com website — 9 pages + 404 + robots + sitemap
- index.php: Landing page with feature showcase, editions, roadmap
- download.php: WebTorrent P2P download (no torrent client needed)
- apps.php: Ecosystem app downloads (Browser, IDE, Veil, Pulse)
- releases.php: Full changelog RC1 through RC8
- docs.php: Technical documentation and build specs
- security.php: Kernel hardening transparency report
- developers.php: Developer foundation and contribution guide
- compare.php: Head-to-head vs Ubuntu/Mint/Fedora/Arch
- about.php: Company provenance, founder, verification commands
- 404.html: Branded error page
- JSON-LD structured data on 4 pages
- Twitter Card + OpenGraph meta tags on all pages
- Security headers (HSTS, X-Frame-Options, CSP)
2026-04-07 15:47:54 -04:00

1110 lines
42 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Alfred Linux — P2P Download Page
* Browser-based WebTorrent client — no client install needed.
* When download completes, users are encouraged to keep seeding.
*/
header('Cache-Control: no-cache, no-store, must-revalidate');
$pageTitle = "Download Alfred Linux — Powered by the People";
$isoName = "alfred-linux-4.0-rc8-amd64.iso"; // Updated when new builds ship
$isoSize = "2.4 GB";
$version = "4.0 RC8";
$torrentURL = "/downloads/{$isoName}.torrent";
$magnetURI = "magnet:?xt=urn:btih:5eedd261364a0975763fc1a24cab433ab598692a&dn=alfred-linux-4.0-rc8-amd64-20260407.iso&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=udp%3A%2F%2Fopen.stealth.si%3A80%2Fannounce&tr=udp%3A%2F%2Ftracker.torrent.eu.org%3A451%2Fannounce&tr=http%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($pageTitle) ?></title>
<meta name="description" content="Download Alfred Linux via peer-to-peer — directly in your browser. No torrent client needed. Seed to help the community.">
<meta property="og:title" content="Download Alfred Linux — Powered by the People">
<meta property="og:description" content="Download Alfred Linux via P2P — directly in your browser. No torrent client needed. Seed to help the community.">
<meta property="og:url" content="https://alfredlinux.com/download">
<meta property="og:image" content="https://alfredlinux.com/og-image.png">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Download Alfred Linux — Powered by the People">
<meta name="twitter:description" content="Download Alfred Linux via P2P — directly in your browser. No torrent client needed. Seed to help the community.">
<meta name="twitter:image" content="https://alfredlinux.com/og-image.png">
<link rel="canonical" href="https://alfredlinux.com/download">
<link rel="icon" href="/favicon.ico">
<style>
:root {
--bg: #0a0a0f;
--surface: #12121a;
--border: #1e1e2e;
--accent: #6c5ce7;
--accent2: #00cec9;
--gold: #fdcb6e;
--text: #e0e0e0;
--dim: #888;
--success: #00b894;
--danger: #e17055;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
overflow-x: hidden;
}
/* ── Nav ──────────────────────────────────── */
nav {
display: flex; align-items: center; justify-content: space-between;
padding: 1rem 2rem;
border-bottom: 1px solid var(--border);
background: rgba(10,10,15,0.95);
position: sticky; top: 0; z-index: 100;
backdrop-filter: blur(12px);
}
nav .logo { font-size: 1.3rem; font-weight: 700; }
nav .logo span { color: var(--accent); }
nav .links { display: flex; gap: 1.5rem; }
nav .links a { color: var(--dim); text-decoration: none; font-size: 0.9rem; transition: color 0.2s; }
nav .links a:hover { color: var(--text); }
/* ── Hero ─────────────────────────────────── */
.hero {
text-align: center;
padding: 4rem 2rem 2rem;
}
.hero h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
font-weight: 800;
line-height: 1.1;
margin-bottom: 1rem;
}
.hero h1 .glow {
background: linear-gradient(135deg, var(--accent), var(--accent2));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.hero p {
color: var(--dim);
font-size: 1.15rem;
max-width: 640px;
margin: 0 auto 2rem;
line-height: 1.6;
}
.badge {
display: inline-block;
background: rgba(108,92,231,0.15);
color: var(--accent);
padding: 0.3rem 0.8rem;
border-radius: 999px;
font-size: 0.8rem;
font-weight: 600;
border: 1px solid rgba(108,92,231,0.3);
margin-bottom: 1.5rem;
}
/* ── Download Card ────────────────────────── */
.dl-card {
max-width: 720px;
margin: 0 auto 3rem;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 16px;
padding: 2.5rem;
position: relative;
overflow: hidden;
}
.dl-card::before {
content: '';
position: absolute; top: 0; left: 0; right: 0; height: 3px;
background: linear-gradient(90deg, var(--accent), var(--accent2), var(--gold));
}
/* Start state */
#start-section { text-align: center; }
#start-section h2 { font-size: 1.5rem; margin-bottom: 0.5rem; }
#start-section .meta { color: var(--dim); font-size: 0.9rem; margin-bottom: 1.5rem; }
.btn-torrent {
display: inline-flex; align-items: center; gap: 0.5rem;
background: linear-gradient(135deg, var(--accent), #5a4bd1);
color: #fff;
border: none; border-radius: 12px;
padding: 1rem 2.5rem;
font-size: 1.1rem; font-weight: 700;
cursor: pointer;
transition: transform 0.15s, box-shadow 0.15s;
}
.btn-torrent:hover {
transform: translateY(-2px);
box-shadow: 0 8px 30px rgba(108,92,231,0.4);
}
.btn-torrent svg { width: 22px; height: 22px; }
.alt-links {
margin-top: 1rem;
font-size: 0.85rem; color: var(--dim);
}
.alt-links a { color: var(--accent); text-decoration: none; }
.alt-links a:hover { text-decoration: underline; }
.btn-direct {
display: inline-flex; align-items: center; gap: 0.5rem;
background: rgba(255,255,255,0.08);
color: #ccc;
border: 1px solid rgba(255,255,255,0.15); border-radius: 12px;
padding: 0.75rem 2rem;
font-size: 1rem; font-weight: 600;
cursor: pointer; text-decoration: none;
transition: transform 0.15s, background 0.15s;
margin-top: 0.75rem;
}
.btn-direct:hover {
transform: translateY(-1px);
background: rgba(255,255,255,0.12);
color: #fff;
}
.btn-direct svg { width: 18px; height: 18px; }
/* Progress state */
#progress-section { display: none; }
.progress-bar-outer {
width: 100%;
height: 28px;
background: rgba(255,255,255,0.05);
border-radius: 14px;
overflow: hidden;
margin-bottom: 1.5rem;
position: relative;
}
.progress-bar-inner {
height: 100%;
width: 0%;
background: linear-gradient(90deg, var(--accent), var(--accent2));
border-radius: 14px;
transition: width 0.5s ease;
position: relative;
}
.progress-bar-inner::after {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent);
animation: shimmer 2s infinite;
}
@keyframes shimmer { 0%{transform:translateX(-100%)} 100%{transform:translateX(100%)} }
.progress-pct {
position: absolute;
top: 50%; left: 50%; transform: translate(-50%,-50%);
font-weight: 700; font-size: 0.85rem; z-index: 2;
text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 1rem;
margin-bottom: 1.5rem;
}
.stat-box {
background: rgba(255,255,255,0.03);
border: 1px solid var(--border);
border-radius: 10px;
padding: 0.8rem 1rem;
text-align: center;
}
.stat-box .label { font-size: 0.75rem; color: var(--dim); text-transform: uppercase; letter-spacing: 0.05em; }
.stat-box .value { font-size: 1.3rem; font-weight: 700; margin-top: 0.3rem; }
/* Complete / Seeding state */
#seed-section { display: none; text-align: center; }
.seed-banner {
background: linear-gradient(135deg, rgba(0,184,148,0.1), rgba(108,92,231,0.1));
border: 1px solid rgba(0,184,148,0.3);
border-radius: 16px;
padding: 2.5rem;
margin-bottom: 2rem;
}
.seed-banner h2 {
font-size: 1.8rem;
margin-bottom: 0.5rem;
background: linear-gradient(135deg, var(--success), var(--accent2));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.seed-banner p {
color: var(--text);
font-size: 1.1rem;
line-height: 1.6;
max-width: 520px;
margin: 0 auto;
}
.seed-banner .big-msg {
font-size: 1.5rem;
font-weight: 800;
color: var(--gold);
margin-top: 1.5rem;
-webkit-text-fill-color: unset;
}
.seed-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
}
.seed-timer {
font-size: 2.5rem;
font-weight: 800;
font-variant-numeric: tabular-nums;
background: linear-gradient(135deg, var(--gold), var(--accent));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
margin-bottom: 0.5rem;
}
.seed-timer-label { color: var(--dim); font-size: 0.85rem; }
.btn-save {
display: inline-flex; align-items: center; gap: 0.5rem;
background: var(--success);
color: #fff;
border: none; border-radius: 12px;
padding: 0.8rem 2rem;
font-size: 1rem; font-weight: 700;
cursor: pointer;
margin-top: 1rem;
}
.btn-save:hover { opacity: 0.9; }
.share-btn {
display: inline-flex; align-items: center; gap: 0.5rem;
background: rgba(108,92,231,0.15);
color: var(--accent);
border: 1px solid rgba(108,92,231,0.3);
border-radius: 10px;
padding: 0.6rem 1.5rem;
font-size: 0.9rem; font-weight: 600;
cursor: pointer;
margin: 0.5rem;
transition: all 0.2s;
}
.share-btn:hover { background: rgba(108,92,231,0.25); }
/* ── Community Section ────────────────────── */
.community {
max-width: 720px;
margin: 0 auto 4rem;
text-align: center;
}
.community h2 { font-size: 1.8rem; margin-bottom: 1rem; }
.community p { color: var(--dim); max-width: 540px; margin: 0 auto 2rem; line-height: 1.6; }
.swarm-vis {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 16px;
padding: 2rem;
min-height: 200px;
position: relative;
overflow: hidden;
}
.swarm-vis canvas { width: 100%; height: 200px; }
.swarm-counter {
font-size: 3rem;
font-weight: 800;
background: linear-gradient(135deg, var(--accent), var(--accent2));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.swarm-label { color: var(--dim); font-size: 0.9rem; }
/* ── How It Works ─────────────────────────── */
.how-it-works {
max-width: 720px;
margin: 0 auto 4rem;
padding: 0 2rem;
}
.how-it-works h2 { text-align: center; font-size: 1.5rem; margin-bottom: 2rem; }
.steps {
display: grid; gap: 1.5rem;
}
.step {
display: flex; gap: 1.2rem; align-items: flex-start;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 1.5rem;
}
.step-num {
width: 36px; height: 36px;
background: linear-gradient(135deg, var(--accent), var(--accent2));
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-weight: 800; font-size: 0.9rem;
flex-shrink: 0;
}
.step h3 { font-size: 1rem; margin-bottom: 0.3rem; }
.step p { color: var(--dim); font-size: 0.9rem; line-height: 1.5; }
/* ── Footer ───────────────────────────────── */
footer {
text-align: center;
padding: 2rem;
border-top: 1px solid var(--border);
color: var(--dim);
font-size: 0.85rem;
}
footer a { color: var(--accent); text-decoration: none; }
/* ── Error state ──────────────────────────── */
.error-box {
display: none;
background: rgba(225,112,85,0.1);
border: 1px solid rgba(225,112,85,0.3);
border-radius: 10px;
padding: 1rem 1.5rem;
margin-top: 1rem;
color: var(--danger);
font-size: 0.9rem;
}
/* ── Flash to USB Guide ────────────────── */
.flash-guide {
max-width: 720px;
margin: 0 auto 3rem;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 16px;
padding: 2.5rem;
display: none;
}
.flash-guide.visible { display: block; }
.flash-guide h2 {
font-size: 1.5rem;
margin-bottom: 0.5rem;
text-align: center;
}
.flash-guide .subtitle {
color: var(--dim);
text-align: center;
font-size: 0.95rem;
margin-bottom: 2rem;
}
.flash-tabs {
display: flex;
gap: 0.5rem;
margin-bottom: 1.5rem;
border-bottom: 1px solid var(--border);
padding-bottom: 0.5rem;
}
.flash-tab {
background: none;
border: none;
color: var(--dim);
font-size: 0.9rem;
font-weight: 600;
padding: 0.5rem 1rem;
cursor: pointer;
border-radius: 8px 8px 0 0;
transition: all 0.2s;
}
.flash-tab:hover { color: var(--text); }
.flash-tab.active {
color: var(--accent);
background: rgba(108,92,231,0.1);
border-bottom: 2px solid var(--accent);
}
.flash-panel { display: none; }
.flash-panel.active { display: block; }
.flash-panel h3 {
font-size: 1.1rem;
margin-bottom: 0.8rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.flash-panel ol {
list-style: decimal;
padding-left: 1.5rem;
color: var(--text);
line-height: 2;
font-size: 0.95rem;
}
.flash-panel ol li { margin-bottom: 0.3rem; }
.flash-panel a {
color: var(--accent);
text-decoration: none;
font-weight: 600;
}
.flash-panel a:hover { text-decoration: underline; }
.flash-cmd {
display: flex;
align-items: center;
gap: 0.5rem;
background: rgba(0,0,0,0.4);
border: 1px solid var(--border);
border-radius: 8px;
padding: 0.6rem 1rem;
margin: 0.5rem 0;
font-family: 'SF Mono', 'Fira Code', monospace;
font-size: 0.85rem;
color: var(--accent2);
overflow-x: auto;
}
.flash-cmd code { flex: 1; white-space: nowrap; }
.flash-cmd button {
background: none;
border: 1px solid var(--border);
color: var(--dim);
border-radius: 6px;
padding: 0.3rem 0.6rem;
cursor: pointer;
font-size: 0.75rem;
flex-shrink: 0;
}
.flash-cmd button:hover { color: var(--text); border-color: var(--accent); }
.flash-warn {
background: rgba(253,203,110,0.1);
border: 1px solid rgba(253,203,110,0.25);
border-radius: 8px;
padding: 0.7rem 1rem;
color: var(--gold);
font-size: 0.85rem;
margin-top: 0.8rem;
}
@media (max-width: 600px) {
.dl-card { margin: 0 1rem 3rem; padding: 1.5rem; }
.flash-guide { margin: 0 1rem 3rem; padding: 1.5rem; }
.stats-grid { grid-template-columns: 1fr 1fr; }
nav { padding: 0.8rem 1rem; }
.hero { padding: 2rem 1rem 1rem; }
.flash-tabs { flex-wrap: wrap; }
}
</style>
</head>
<body>
<!-- ── Nav ──────────────────────────────────────── -->
<nav>
<div class="logo">Alfred <span>Linux</span></div>
<div class="links">
<a href="/">Home</a>
<a href="/download" style="color:var(--accent);font-weight:600;">Download</a>
<a href="/apps">Apps</a>
<a href="/docs">Docs</a>
<a href="/releases">Releases</a>
<a href="/security">Security</a>
<a href="/developers">Developers</a>
<a href="/compare">Compare</a>
<a href="/about">About</a>
</div>
</nav>
<!-- ── Hero ─────────────────────────────────────── -->
<section class="hero">
<div class="badge">⚡ Peer-to-Peer · Zero Install · Browser-Native</div>
<h1>Download at the <span class="glow">Speed of the Swarm</span></h1>
<p>No torrent client needed. Your browser IS the client. Every downloader becomes a seeder.<br>
The more people who join, the faster everyone downloads.</p>
</section>
<!-- ── Download Card ───────────────────────────── -->
<div class="dl-card">
<!-- Start -->
<div id="start-section">
<h2>Alfred Linux <?= htmlspecialchars($version) ?></h2>
<div class="meta"><?= htmlspecialchars($isoName) ?> · <?= htmlspecialchars($isoSize) ?> · Debian Trixie 13 · Kernel 7.0.0-rc7 · 16 Hooks · 32 Security Modules · Hardened</div>
<button class="btn-torrent" onclick="startDownload()">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 5v14M5 12l7 7 7-7"/></svg>
Start P2P Download
</button>
<div class="alt-links">
<a href="<?= htmlspecialchars($torrentURL) ?>">Download .torrent file</a> (for desktop torrent clients like qBittorrent)
</div>
</div>
<!-- Progress -->
<div id="progress-section">
<div class="progress-bar-outer">
<div class="progress-bar-inner" id="progress-bar"></div>
<div class="progress-pct" id="progress-pct">0%</div>
</div>
<div class="stats-grid">
<div class="stat-box">
<div class="label">Downloaded</div>
<div class="value" id="stat-downloaded">0 MB</div>
</div>
<div class="stat-box">
<div class="label">Speed</div>
<div class="value" id="stat-speed">0 KB/s</div>
</div>
<div class="stat-box">
<div class="label">Peers</div>
<div class="value" id="stat-peers">0</div>
</div>
<div class="stat-box">
<div class="label">ETA</div>
<div class="value" id="stat-eta">—</div>
</div>
<div class="stat-box">
<div class="label">Uploaded</div>
<div class="value" id="stat-uploaded">0 MB</div>
</div>
</div>
<p style="color:var(--dim);font-size:0.85rem;text-align:center;">
You're already sharing pieces with other downloaders! ✨
</p>
</div>
<!-- Seed / Complete -->
<div id="seed-section">
<div class="seed-banner">
<h2>🎉 Download Complete!</h2>
<p>Your copy of Alfred Linux is ready. But here's the thing —</p>
<p class="big-msg">
The longer you keep this page open,<br>
the faster the new free world is built<br>
with YOUR help!
</p>
</div>
<div class="seed-timer" id="seed-timer">00:00:00</div>
<div class="seed-timer-label">Time you've been seeding for the community</div>
<div class="seed-stats">
<div class="stat-box">
<div class="label">You've Shared</div>
<div class="value" id="seed-uploaded">0 MB</div>
</div>
<div class="stat-box">
<div class="label">Upload Speed</div>
<div class="value" id="seed-speed">0 KB/s</div>
</div>
<div class="stat-box">
<div class="label">Souls Saved</div>
<div class="value" id="seed-peers" style="color:var(--gold);">0</div>
</div>
<div class="stat-box">
<div class="label">Your Ratio</div>
<div class="value" id="seed-ratio">0.00</div>
</div>
</div>
<button class="btn-save" id="save-btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><path d="M12 5v14M5 12l7 7 7-7"/></svg>
Save ISO to Disk
</button>
<div style="margin-top: 2rem;">
<p style="color:var(--dim);font-size:0.9rem;margin-bottom:0.8rem;">Spread the word:</p>
<button class="share-btn" onclick="shareTwitter()">𝕏 Share on X</button>
<button class="share-btn" onclick="shareLink()">🔗 Copy Link</button>
</div>
</div>
<div class="error-box" id="error-box"></div>
</div>
<!-- ── Flash to USB Guide ──────────────────────── -->
<div class="flash-guide" id="flash-guide">
<h2>Flash to USB Drive</h2>
<p class="subtitle">Turn your ISO into a bootable USB stick in minutes</p>
<div class="flash-tabs">
<button class="flash-tab active" onclick="showFlashTab('windows')">Windows</button>
<button class="flash-tab" onclick="showFlashTab('mac')">macOS</button>
<button class="flash-tab" onclick="showFlashTab('linux')">Linux</button>
<button class="flash-tab" onclick="showFlashTab('etcher')">balenaEtcher</button>
</div>
<div class="flash-panel active" id="flash-windows">
<h3>&#x1f4bb; Rufus (Windows)</h3>
<ol>
<li>Download <a href="https://rufus.ie" target="_blank" rel="noopener">Rufus</a> (free, portable, no install needed)</li>
<li>Insert a USB drive (8 GB minimum)</li>
<li>Open Rufus &rarr; select your USB under <strong>Device</strong></li>
<li>Click <strong>SELECT</strong> &rarr; choose the Alfred Linux ISO you just saved</li>
<li>Partition scheme: <strong>GPT</strong> &middot; Target: <strong>UEFI</strong></li>
<li>Click <strong>START</strong> &rarr; wait until &ldquo;READY&rdquo; appears</li>
<li>Reboot your PC and boot from USB (usually F12 / F2 / DEL at startup)</li>
</ol>
</div>
<div class="flash-panel" id="flash-mac">
<h3>&#x1f34e; Terminal (macOS)</h3>
<ol>
<li>Insert a USB drive (8 GB minimum)</li>
<li>Open Terminal and find your USB disk:</li>
</ol>
<div class="flash-cmd"><code>diskutil list</code><button onclick="copyCmd(this)">Copy</button></div>
<ol start="3">
<li>Unmount the USB (replace <strong>diskN</strong> with your disk):</li>
</ol>
<div class="flash-cmd"><code>diskutil unmountDisk /dev/diskN</code><button onclick="copyCmd(this)">Copy</button></div>
<ol start="4">
<li>Flash the ISO (use <strong>rdiskN</strong> for speed):</li>
</ol>
<div class="flash-cmd"><code>sudo dd if=~/Downloads/<?= htmlspecialchars($isoName) ?> of=/dev/rdiskN bs=4m status=progress</code><button onclick="copyCmd(this)">Copy</button></div>
<ol start="5">
<li>Wait until complete, then eject and reboot from USB</li>
</ol>
<div class="flash-warn">&#x26a0;&#xfe0f; Double-check the disk number! <code>dd</code> overwrites the target without confirmation.</div>
</div>
<div class="flash-panel" id="flash-linux">
<h3>&#x1f427; Terminal (Linux)</h3>
<ol>
<li>Insert a USB drive (8 GB minimum)</li>
<li>Find your USB device:</li>
</ol>
<div class="flash-cmd"><code>lsblk</code><button onclick="copyCmd(this)">Copy</button></div>
<ol start="3">
<li>Flash the ISO (replace <strong>/dev/sdX</strong> with your USB &mdash; e.g. /dev/sdb):</li>
</ol>
<div class="flash-cmd"><code>sudo dd if=~/Downloads/<?= htmlspecialchars($isoName) ?> of=/dev/sdX bs=4M status=progress oflag=sync</code><button onclick="copyCmd(this)">Copy</button></div>
<ol start="4">
<li>Wait until complete, then reboot and boot from USB</li>
</ol>
<div class="flash-warn">&#x26a0;&#xfe0f; Make sure <code>/dev/sdX</code> is your USB, not your main drive! Check <code>lsblk</code> output carefully.</div>
</div>
<div class="flash-panel" id="flash-etcher">
<h3>&#x26a1; balenaEtcher (Any OS)</h3>
<ol>
<li>Download <a href="https://etcher.balena.io" target="_blank" rel="noopener">balenaEtcher</a> (free, works on Windows/Mac/Linux)</li>
<li>Open Etcher &rarr; click <strong>Flash from file</strong> &rarr; select the Alfred Linux ISO</li>
<li>Click <strong>Select target</strong> &rarr; choose your USB drive</li>
<li>Click <strong>Flash!</strong> and wait for completion + verification</li>
<li>Reboot and boot from USB</li>
</ol>
<p style="color:var(--dim);font-size:0.85rem;margin-top:1rem;">Etcher is the easiest option if you're not comfortable with command-line tools. It validates the write automatically.</p>
</div>
</div>
<!-- ── Community Swarm ─────────────────────────── -->
<section class="community">
<h2>The Alfred Swarm</h2>
<p>Every dot is a person — downloading, seeding, building the future of computing together.</p>
<div class="swarm-vis">
<div class="swarm-counter" id="swarm-count">0</div>
<div class="swarm-label">active peers in the swarm right now</div>
<canvas id="swarm-canvas"></canvas>
</div>
</section>
<!-- ── Integrity Verification ───────────────────── -->
<section class="how-it-works" style="border-top:1px solid var(--border);">
<h2>Verify Your Download</h2>
<p style="color:var(--dim);text-align:center;max-width:700px;margin:0 auto 2rem;line-height:1.6;">
Two independent hash algorithms — different math, different authors, different attack surfaces.<br>
If an attacker somehow breaks one, the other catches it. No other distro does this.
</p>
<div style="background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:1.5rem;max-width:800px;margin:0 auto 1.5rem;">
<h3 style="color:var(--accent2);margin-bottom:1rem;font-size:1rem;">SHA-256 <span style="color:var(--dim);font-weight:400;font-size:0.85rem;">(NIST Standard)</span></h3>
<div style="background:#0a0a0f;border-radius:8px;padding:0.8rem 1rem;font-family:monospace;font-size:0.8rem;word-break:break-all;color:var(--gold);margin-bottom:0.5rem;">
7d49ef3cfb957cb9854bd3f451ef99ec8255afd68069a89ed0cf5a847d5d79bf
</div>
<div style="font-size:0.8rem;color:var(--dim);">
<code style="color:var(--text);background:#1e1e2e;padding:2px 6px;border-radius:4px;">sha256sum alfred-linux-4.0-rc8-amd64-20260407.iso</code>
</div>
</div>
<div style="background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:1.5rem;max-width:800px;margin:0 auto 1.5rem;">
<h3 style="color:var(--accent);margin-bottom:1rem;font-size:1rem;">BLAKE3 <span style="color:var(--dim);font-weight:400;font-size:0.85rem;">(Fastest &amp; most secure hash on the planet)</span></h3>
<div style="background:#0a0a0f;border-radius:8px;padding:0.8rem 1rem;font-family:monospace;font-size:0.8rem;word-break:break-all;color:var(--accent2);margin-bottom:0.5rem;">
e021d2024599aa918972d9e6b9fd9c1d97d226ac69da035913fd7a462dbef47d
</div>
<div style="font-size:0.8rem;color:var(--dim);">
<code style="color:var(--text);background:#1e1e2e;padding:2px 6px;border-radius:4px;">b3sum alfred-linux-4.0-rc8-amd64-20260407.iso</code>
&nbsp;·&nbsp; Install: <code style="color:var(--text);background:#1e1e2e;padding:2px 6px;border-radius:4px;">pip install blake3</code> or <code style="color:var(--text);background:#1e1e2e;padding:2px 6px;border-radius:4px;">cargo install b3sum</code>
</div>
</div>
<p style="color:var(--dim);text-align:center;font-size:0.85rem;margin-top:1rem;">
Both hashes must match. If either one doesn't — <strong style="color:var(--danger);">do not install</strong>. Re-download via P2P.
</p>
</section>
<!-- ── How It Works ────────────────────────────── -->
<section class="how-it-works">
<h2>How Peer-to-Peer Download Works</h2>
<div class="steps">
<div class="step">
<div class="step-num">1</div>
<div>
<h3>Click "Start P2P Download"</h3>
<p>Your browser connects to the Alfred Linux swarm using WebTorrent — a BitTorrent client that runs natively in your browser. No plugins, no installs.</p>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div>
<h3>Download from everyone at once</h3>
<p>Instead of one server, you download pieces from every peer in the swarm simultaneously. More people = faster download for everyone.</p>
</div>
</div>
<div class="step">
<div class="step-num">3</div>
<div>
<h3>You become a seeder</h3>
<p>While downloading, you're already sharing completed pieces with others. When done, you keep sharing as long as the page stays open.</p>
</div>
</div>
<div class="step">
<div class="step-num">4</div>
<div>
<h3>The swarm grows stronger</h3>
<p>Every seeder makes the next download faster. You're not just getting an OS — you're powering a movement. The longer you seed, the more people you help.</p>
</div>
</div>
</div>
</section>
<!-- ── Footer ──────────────────────────────────── -->
<footer>
<p>Alfred Linux &copy; <?= date('Y') ?> · <a href="/">alfredlinux.com</a> · <a href="/forge/">GoForge</a> · Powered by WebTorrent + the Community</p>
</footer>
<!-- ── WebTorrent Browser Client ───────────────── -->
<script src="/assets/js/webtorrent.min.js"></script>
<script>
(function() {
'use strict';
// ── Config ────────────────────────────────────
const ISO_NAME = <?= json_encode($isoName) ?>;
const DIRECT_URL = ''; // Torrent-only distribution
const TORRENT_URL = <?= json_encode($torrentURL) ?>;
const MAGNET_URI = <?= json_encode($magnetURI) ?>;
let client = null;
let torrent = null;
let seedStart = null;
let blobURL = null;
let seedTimer = null;
// ── UI Elements ───────────────────────────────
const $start = document.getElementById('start-section');
const $progress = document.getElementById('progress-section');
const $seed = document.getElementById('seed-section');
const $error = document.getElementById('error-box');
// ── Format helpers ────────────────────────────
function fmtBytes(b) {
if (b < 1024) return b + ' B';
if (b < 1048576) return (b / 1024).toFixed(1) + ' KB';
if (b < 1073741824) return (b / 1048576).toFixed(1) + ' MB';
return (b / 1073741824).toFixed(2) + ' GB';
}
function fmtSpeed(bps) {
if (bps < 1024) return bps + ' B/s';
if (bps < 1048576) return (bps / 1024).toFixed(0) + ' KB/s';
return (bps / 1048576).toFixed(1) + ' MB/s';
}
function fmtTime(secs) {
if (!secs || secs === Infinity) return '—';
const h = Math.floor(secs / 3600);
const m = Math.floor((secs % 3600) / 60);
const s = Math.floor(secs % 60);
return (h > 0 ? h + 'h ' : '') + m + 'm ' + s + 's';
}
function fmtTimer(secs) {
const h = String(Math.floor(secs / 3600)).padStart(2, '0');
const m = String(Math.floor((secs % 3600) / 60)).padStart(2, '0');
const s = String(Math.floor(secs % 60)).padStart(2, '0');
return h + ':' + m + ':' + s;
}
// ── Start Download ────────────────────────────
window.startDownload = function() {
if (!window.WebTorrent) {
showError('WebTorrent library failed to load. Please <a href="' + TORRENT_URL + '">download the .torrent file</a> and use a desktop torrent client instead.');
return;
}
try {
client = new WebTorrent();
} catch (e) {
showError('Could not initialize WebTorrent: ' + e.message + '. <a href="' + TORRENT_URL + '">Download .torrent file</a> instead.');
return;
}
client.on('error', function(err) {
console.error('WebTorrent error:', err);
showError('Torrent error: ' + err.message + '. <a href="' + TORRENT_URL + '">Download .torrent file</a> and use a desktop torrent client instead.');
});
$start.style.display = 'none';
$progress.style.display = 'block';
// Use magnet URI directly — most reliable method for browser WebTorrent
console.log('[Alfred] Adding torrent via magnet URI');
addTorrentFromMagnet(MAGNET_URI);
};
function addTorrentFromMagnet(magnetURI) {
client.add(magnetURI, {
announce: [
'wss://tracker.openwebtorrent.com',
]
}, function(t) {
torrent = t;
console.log('Torrent added:', t.infoHash, '— Files:', t.files.length);
// Update progress periodically
var progressInterval = setInterval(function() {
var pct = Math.round(torrent.progress * 100);
document.getElementById('progress-bar').style.width = pct + '%';
document.getElementById('progress-pct').textContent = pct + '%';
document.getElementById('stat-downloaded').textContent = fmtBytes(torrent.downloaded);
document.getElementById('stat-speed').textContent = fmtSpeed(torrent.downloadSpeed);
document.getElementById('stat-peers').textContent = torrent.numPeers;
document.getElementById('stat-eta').textContent = fmtTime(torrent.timeRemaining / 1000);
document.getElementById('stat-uploaded').textContent = fmtBytes(torrent.uploaded);
// Update swarm counter
document.getElementById('swarm-count').textContent = torrent.numPeers;
}, 500);
torrent.on('done', function() {
clearInterval(progressInterval);
showSeedMode();
});
});
};
// ── Seed Mode ─────────────────────────────────
function showSeedMode() {
$progress.style.display = 'none';
$seed.style.display = 'block';
seedStart = Date.now();
// Save button — use File System Access API for large files, fall back to direct HTTP
var saveBtn = document.getElementById('save-btn');
saveBtn.onclick = async function() {
// Try modern File System Access API first (Chrome/Edge 86+)
if (window.showSaveFilePicker) {
try {
var handle = await window.showSaveFilePicker({
suggestedName: ISO_NAME,
types: [{ description: 'ISO Image', accept: { 'application/octet-stream': ['.iso'] } }]
});
var writable = await handle.createWritable();
var file = torrent.files[0];
var stream = file.createReadStream();
saveBtn.textContent = 'Saving...';
saveBtn.disabled = true;
stream.on('data', function(chunk) { writable.write(chunk); });
stream.on('end', function() {
writable.close();
saveBtn.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><path d="M20 6L9 17l-5-5"/></svg> Saved!';
});
stream.on('error', function(e) {
console.error('Stream error:', e);
writable.close();
// Fall back to direct download
triggerDirectDownload();
});
return;
} catch (e) {
if (e.name === 'AbortError') return; // user cancelled
console.warn('File System Access failed:', e);
}
}
// Fallback: direct HTTP download (file already came via P2P, this just saves it)
triggerDirectDownload();
};
function triggerDirectDownload() {
// Save from WebTorrent blob — ISO is not served via HTTP
if (!torrent || !torrent.files || !torrent.files[0]) {
showError('No downloaded file available. Please re-download via P2P.');
return;
}
torrent.files[0].getBlob(function(err, blob) {
if (err) {
showError('Could not create file: ' + err.message);
return;
}
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = ISO_NAME;
a.click();
setTimeout(function() { URL.revokeObjectURL(url); }, 60000);
});
}
// Show the Flash to USB guide
var flashGuide = document.getElementById('flash-guide');
if (flashGuide) flashGuide.classList.add('visible');
// Seed stats updater
seedTimer = setInterval(function() {
var elapsed = Math.floor((Date.now() - seedStart) / 1000);
document.getElementById('seed-timer').textContent = fmtTimer(elapsed);
document.getElementById('seed-uploaded').textContent = fmtBytes(torrent.uploaded);
document.getElementById('seed-speed').textContent = fmtSpeed(torrent.uploadSpeed);
document.getElementById('seed-peers').textContent = torrent.numPeers;
document.getElementById('seed-ratio').textContent = torrent.ratio.toFixed(2);
document.getElementById('swarm-count').textContent = torrent.numPeers;
}, 1000);
}
// ── Share ─────────────────────────────────────
window.shareTwitter = function() {
var text = encodeURIComponent(
"I just downloaded Alfred Linux via peer-to-peer — directly in my browser! 🐧⚡\n\n" +
"No torrent client needed. The more people who download, the faster it gets for everyone.\n\n" +
"Join the swarm: https://alfredlinux.com/download\n\n#AlfredLinux #OpenSource #P2P"
);
window.open('https://x.com/intent/tweet?text=' + text, '_blank', 'noopener,noreferrer');
};
window.shareLink = function() {
navigator.clipboard.writeText('https://alfredlinux.com/download').then(function() {
var btn = document.querySelector('.share-btn:last-child');
btn.textContent = '✅ Copied!';
setTimeout(function() { btn.textContent = '🔗 Copy Link'; }, 2000);
});
};
// ── Error handling ────────────────────────────
function showError(msg) {
$error.style.display = 'block';
$error.innerHTML = msg;
}
// ── Swarm Visualization ───────────────────────
(function initSwarmVis() {
var canvas = document.getElementById('swarm-canvas');
if (!canvas) return;
var ctx = canvas.getContext('2d');
var particles = [];
function resize() {
canvas.width = canvas.parentElement.clientWidth;
canvas.height = 200;
}
resize();
window.addEventListener('resize', resize);
// Create initial particles
for (var i = 0; i < 30; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.8,
vy: (Math.random() - 0.5) * 0.8,
r: 2 + Math.random() * 3,
color: Math.random() > 0.5 ? '#6c5ce7' : '#00cec9',
});
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw connections
for (var i = 0; i < particles.length; i++) {
for (var j = i + 1; j < particles.length; j++) {
var dx = particles[i].x - particles[j].x;
var dy = particles[i].y - particles[j].y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 120) {
ctx.beginPath();
ctx.strokeStyle = 'rgba(108,92,231,' + (1 - dist / 120) * 0.2 + ')';
ctx.lineWidth = 0.5;
ctx.moveTo(particles[i].x, particles[i].y);
ctx.lineTo(particles[j].x, particles[j].y);
ctx.stroke();
}
}
}
// Draw particles
for (var k = 0; k < particles.length; k++) {
var p = particles[k];
p.x += p.vx;
p.y += p.vy;
if (p.x < 0 || p.x > canvas.width) p.vx *= -1;
if (p.y < 0 || p.y > canvas.height) p.vy *= -1;
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
ctx.fillStyle = p.color;
ctx.fill();
ctx.beginPath();
ctx.arc(p.x, p.y, p.r + 4, 0, Math.PI * 2);
ctx.fillStyle = p.color.replace(')', ',0.15)').replace('rgb', 'rgba');
ctx.fill();
}
requestAnimationFrame(draw);
}
draw();
// Add particles when peers connect
setInterval(function() {
var count = torrent ? torrent.numPeers : 0;
while (particles.length < Math.min(count + 10, 80)) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.8,
vy: (Math.random() - 0.5) * 0.8,
r: 2 + Math.random() * 3,
color: Math.random() > 0.5 ? '#6c5ce7' : '#00cec9',
});
}
}, 3000);
})();
// ── Flash to USB tab switching ────────────────
window.showFlashTab = function(tab) {
document.querySelectorAll('.flash-tab').forEach(function(t) { t.classList.remove('active'); });
document.querySelectorAll('.flash-panel').forEach(function(p) { p.classList.remove('active'); });
event.target.classList.add('active');
var panel = document.getElementById('flash-' + tab);
if (panel) panel.classList.add('active');
};
window.copyCmd = function(btn) {
var code = btn.parentElement.querySelector('code').textContent;
navigator.clipboard.writeText(code).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
// Auto-select the right tab based on OS
(function detectOS() {
var ua = navigator.userAgent;
var tab = 'etcher'; // default
if (/Win/.test(ua)) tab = 'windows';
else if (/Mac/.test(ua)) tab = 'mac';
else if (/Linux/.test(ua)) tab = 'linux';
document.querySelectorAll('.flash-tab').forEach(function(t) { t.classList.remove('active'); });
document.querySelectorAll('.flash-panel').forEach(function(p) { p.classList.remove('active'); });
var tabs = document.querySelectorAll('.flash-tab');
tabs.forEach(function(t) { if (t.textContent.toLowerCase().indexOf(tab === 'windows' ? 'windows' : tab === 'mac' ? 'mac' : tab === 'linux' ? 'linux' : 'etcher') !== -1) t.classList.add('active'); });
var panel = document.getElementById('flash-' + tab);
if (panel) panel.classList.add('active');
})();
// ── Warn before leaving while seeding ─────────
window.addEventListener('beforeunload', function(e) {
if (torrent && torrent.done) {
e.preventDefault();
e.returnValue = 'You\'re currently seeding Alfred Linux for the community. Are you sure you want to leave?';
}
});
})();
</script>
<footer style="text-align:center;padding:1.5rem;color:#94a3b8;font-size:.85rem;border-top:1px solid rgba(255,255,255,0.06);">
&copy; <?= date('Y') ?> <a href="https://gositeme.com" style="color:#6366f1;text-decoration:none;">GoSiteMe Inc.</a> &mdash; Alfred Linux &middot; Open Source (AGPL-3.0)
</footer>
</body>
</html>