<?php
/**
 * Streamora Updates Browser
 * Secure file browser locked to the updates directory only.
 */

// ── Security: Lock base directory ──────────────────────────────
define('BASE_DIR', __DIR__);

// ── Resolve requested path safely ──────────────────────────────
$requestedPath = isset($_GET['path']) ? $_GET['path'] : '';

// Strip null bytes and normalize
$requestedPath = str_replace("\0", '', $requestedPath);
$requestedPath = str_replace('\\', '/', $requestedPath);

// Remove any leading slashes or dots
$requestedPath = ltrim($requestedPath, '/.');

// Build full path and resolve symlinks / traversal
$fullPath = realpath(BASE_DIR . '/' . $requestedPath);

// Security check: realpath returns false for non-existent paths
if ($fullPath === false) {
    $fullPath = BASE_DIR;
    $requestedPath = '';
}

// Security check: ensure resolved path is within BASE_DIR
if (strpos($fullPath, BASE_DIR) !== 0) {
    http_response_code(403);
    exit('Access denied.');
}

// ── Handle raw text fetch (AJAX) ──────────────────────────────
if (is_file($fullPath) && isset($_GET['raw']) && $_GET['raw'] === '1') {
    $ext = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION));
    if ($ext !== 'txt') {
        http_response_code(403);
        exit('Only text files can be viewed.');
    }
    header('Content-Type: text/plain; charset=UTF-8');
    header('Cache-Control: no-store');
    header('X-Content-Type-Options: nosniff');
    readfile($fullPath);
    exit;
}

// ── Handle file download ───────────────────────────────────────
if (is_file($fullPath)) {
    // Block serving PHP files
    if (strtolower(pathinfo($fullPath, PATHINFO_EXTENSION)) === 'php') {
        http_response_code(403);
        exit('Access denied.');
    }

    $filename = basename($fullPath);
    $mimeType = 'application/octet-stream';

    header('Content-Type: ' . $mimeType);
    header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"');
    header('Content-Length: ' . filesize($fullPath));
    header('Cache-Control: no-store');
    header('X-Content-Type-Options: nosniff');
    readfile($fullPath);
    exit;
}

// ── List directory contents ────────────────────────────────────
if (!is_dir($fullPath)) {
    http_response_code(404);
    exit('Not found.');
}

$items = @scandir($fullPath);
if ($items === false) {
    http_response_code(403);
    exit('Access denied.');
}

// Separate folders and files, skip hidden and special entries
$folders = [];
$files = [];

foreach ($items as $item) {
    // Skip . , .. , hidden files, underscore dirs, and system files in root
    if ($item === '.' || $item === '..') continue;
    if ($item[0] === '.' || $item[0] === '_') continue;
    if ($requestedPath === '' && preg_match('/\.(php|sh)$/i', $item)) continue;

    $itemFullPath = $fullPath . '/' . $item;
    $relativePath = $requestedPath === '' ? $item : $requestedPath . '/' . $item;

    if (is_dir($itemFullPath)) {
        $folders[] = ['name' => $item, 'path' => $relativePath, 'mtime' => filemtime($itemFullPath)];
    } else {
        $files[] = [
            'name' => $item,
            'path' => $relativePath,
            'size' => filesize($itemFullPath),
            'mtime' => filemtime($itemFullPath),
        ];
    }
}

// Sort: newest first
usort($folders, function ($a, $b) { return $b['mtime'] - $a['mtime']; });
usort($files, function ($a, $b) { return $b['mtime'] - $a['mtime']; });

// ── Helper functions ───────────────────────────────────────────
function esc($str) {
    return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}

function formatSize($bytes) {
    if ($bytes >= 1073741824) return round($bytes / 1073741824, 2) . ' GB';
    if ($bytes >= 1048576) return round($bytes / 1048576, 2) . ' MB';
    if ($bytes >= 1024) return round($bytes / 1024, 2) . ' KB';
    return $bytes . ' B';
}

function buildUrl($path) {
    if ($path === '') return '?';
    return '?path=' . rawurlencode($path);
}

// ── Build breadcrumb ───────────────────────────────────────────
$breadcrumbs = [];
if ($requestedPath !== '') {
    $parts = explode('/', $requestedPath);
    $accumulated = '';
    foreach ($parts as $part) {
        $accumulated = $accumulated === '' ? $part : $accumulated . '/' . $part;
        $breadcrumbs[] = ['name' => $part, 'path' => $accumulated];
    }
}

// Page title & SEO
$canonical = 'https://streamora.dev/updates/';
if ($requestedPath === '') {
    $pageTitle = 'DRM Panel Download, Free Widevine DRM Panel | DASH to HLS Converter';
    $metaDesc = 'Download DRM panel free. Widevine DRM panel with auto key dump, MPD to HLS converter, DASH to HLS restreaming. DRM panel free download for Linux server. OTT panel with Widevine decryption.';
    $robotsMeta = 'index, follow';
} else {
    $pageTitle = esc(basename($requestedPath)) . ', DRM Panel Free Download | Streamora';
    $metaDesc = 'Download Streamora ' . esc(basename($requestedPath)) . '. DRM panel with Widevine decryption, DASH to HLS converter, OTT restreaming panel. Free download.';
    $robotsMeta = 'noindex, follow';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="robots" content="<?= $robotsMeta ?>">
    <title><?= $pageTitle ?></title>
    <meta name="description" content="<?= esc($metaDesc) ?>">
    <meta name="keywords" content="drm panel, drm panel download, drm panel free download, download drm panel, widevine panel, widevine drm panel, widevine panel download, ott panel, ott panel download, dash to hls, dash to hls converter, mpd to hls, mpd to hls converter, drm restream, drm restream panel, widevine restream, drm decryption panel, widevine decryption panel, drm streaming panel, drm server, drm panel software, iptv drm panel, drm panel 2026, free drm panel, widevine to hls, mpd to m3u8, drm panel linux, ott streaming panel, live drm panel, drm panel setup">
    <link rel="canonical" href="<?= $canonical ?>">

    <!-- Favicon -->
    <link rel="icon" href="/favicon.ico" sizes="48x48">
    <link rel="icon" href="/favicon.svg" type="image/svg+xml">
    <link rel="apple-touch-icon" href="/apple-touch-icon.png">
    <link rel="manifest" href="/site.webmanifest">
    <meta name="theme-color" content="#6366f1">

    <!-- Open Graph -->
    <meta property="og:type" content="website">
    <meta property="og:url" content="<?= $canonical ?>">
    <meta property="og:title" content="DRM Panel Download - Free Widevine DRM Panel | DASH to HLS">
    <meta property="og:description" content="<?= esc($metaDesc) ?>">
    <meta property="og:site_name" content="Streamora">
    <meta property="og:image" content="https://streamora.dev/assets/streamora.png">
    <meta property="og:image:secure_url" content="https://streamora.dev/assets/streamora.png">
    <meta property="og:image:type" content="image/png">
    <meta property="og:image:width" content="2560">
    <meta property="og:image:height" content="1283">
    <meta property="og:image:alt" content="Streamora DRM Streaming Panel, Download">
    <meta property="og:locale" content="en_US">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="DRM Panel Free Download - Widevine Panel | DASH to HLS Converter">
    <meta name="twitter:description" content="Download DRM panel free. Widevine DRM panel, MPD to HLS converter, DASH to HLS restreaming, OTT panel with auto key dump.">
    <meta name="twitter:image" content="https://streamora.dev/assets/streamora.png">
    <meta name="twitter:image:alt" content="Streamora DRM Panel Download">

    <!-- Structured Data: SoftwareApplication -->
    <script type="application/ld+json">
    {
        "@context": "https://schema.org",
        "@type": "SoftwareApplication",
        "name": "Streamora",
        "applicationCategory": "MultimediaApplication",
        "operatingSystem": "Linux",
        "description": "DRM streaming panel with Widevine, PlayReady and FairPlay decryption. Converts DASH DRM and HLS DRM to clean HLS output. Internal remux engine, auto key acquisition, multi-provider scripts.",
        "url": "https://streamora.dev",
        "downloadUrl": "<?= $canonical ?>",
        "softwareVersion": "1.3",
        "offers": {
            "@type": "Offer",
            "price": "0",
            "priceCurrency": "USD",
            "description": "Free trial available"
        },
        "featureList": [
            "Widevine DRM decryption panel",
            "PlayReady DRM decryption",
            "FairPlay DRM support",
            "MPD to HLS converter",
            "DASH to HLS live conversion",
            "Internal fMP4 remux engine",
            "Auto DRM key acquisition",
            "Multi-provider script system",
            "OTT restreaming server",
            "Self-hosted Linux server"
        ]
    }
    </script>

    <?php include __DIR__ . '/../assets/theme-3d.php'; ?>
    <style>
        /* ── Updates Page Styles ─────────────────── */

        .header {
            margin-bottom: 32px;
        }

        .header h1 {
            font-size: clamp(20px, 4vw, 28px);
            font-weight: 800;
            color: #fff;
            margin-bottom: 12px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            flex-wrap: wrap;
            gap: 12px;
        }

        .seo-subtitle {
            font-size: 14px;
            color: #94a3b8;
            margin-bottom: 8px;
            line-height: 1.7;
        }

        /* Breadcrumb */
        .breadcrumb {
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            gap: 4px;
            font-size: 13px;
            color: #64748b;
        }

        .breadcrumb a {
            color: #818cf8;
            text-decoration: none;
            font-weight: 500;
            transition: color 0.2s;
        }

        .breadcrumb a:hover {
            color: #a5b4fc;
        }

        .breadcrumb .sep {
            color: #475569;
            margin: 0 2px;
            user-select: none;
        }

        .breadcrumb .current {
            color: #e2e8f0;
            font-weight: 600;
        }

        /* Card list */
        .card {
            background: #131620;
            border: 1px solid #1e2433;
            border-radius: 12px;
            overflow: hidden;
        }

        .item {
            display: flex;
            align-items: center;
            padding: 14px 20px;
            border-bottom: 1px solid #1e2433;
            transition: background 0.2s;
            text-decoration: none;
            color: inherit;
        }

        .item:last-child { border-bottom: none; }

        .item:hover {
            background: rgba(99, 102, 241, 0.04);
        }

        .item-icon {
            width: 40px;
            height: 40px;
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 14px;
            flex-shrink: 0;
            font-size: 18px;
        }

        .icon-folder {
            background: #1e1b4b;
            color: #818cf8;
        }

        .icon-file {
            background: #052e16;
            color: #4ade80;
        }

        .icon-text {
            background: #422006;
            color: #fbbf24;
        }

        .item-info { flex: 1; min-width: 0; }

        .item-name {
            font-size: 14px;
            font-weight: 600;
            color: #e2e8f0;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .item-meta {
            font-size: 12px;
            color: #64748b;
            margin-top: 3px;
        }

        .item-action {
            font-size: 13px;
            font-weight: 500;
            color: #818cf8;
            flex-shrink: 0;
            margin-left: 12px;
            transition: color 0.2s;
        }

        .item:hover .item-action {
            color: #a5b4fc;
        }

        .empty {
            text-align: center;
            padding: 60px 20px;
            color: #64748b;
            font-size: 14px;
        }

        .empty-icon {
            font-size: 40px;
            margin-bottom: 12px;
            opacity: 0.4;
        }

        .badge {
            display: inline-block;
            background: #1e1b4b;
            color: #a5b4fc;
            font-size: 11px;
            font-weight: 600;
            padding: 2px 8px;
            border-radius: 20px;
            margin-left: 8px;
        }

        /* Top action buttons */
        .top-actions {
            display: flex;
            flex-wrap: wrap;
            gap: 12px;
            margin-bottom: 24px;
        }

        .action-btn {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            background: #4f46e5;
            color: #fff;
            text-decoration: none;
            border: none;
            border-radius: 8px;
            padding: 10px 20px;
            font-size: 13px;
            font-weight: 600;
            cursor: pointer;
            transition: background 0.2s;
        }

        .action-btn:hover {
            background: #4338ca;
            color: #fff;
        }

        .action-btn.secondary {
            background: #1e1b4b;
            color: #a5b4fc;
        }

        .action-btn.secondary:hover {
            background: #312e81;
        }

        .action-btn.emerald {
            background: #059669;
        }

        .action-btn.emerald:hover {
            background: #047857;
        }

        .action-btn svg {
            width: 14px;
            height: 14px;
            flex-shrink: 0;
        }

        /* Install command box */
        .install-box {
            background: #131620;
            border: 1px solid #1e2433;
            border-radius: 12px;
            padding: 20px 24px;
            margin-bottom: 24px;
        }

        .install-box .install-label {
            font-size: 12px;
            font-weight: 700;
            color: #818cf8;
            margin-bottom: 12px;
            text-transform: uppercase;
            letter-spacing: 0.05em;
        }

        .install-cmd {
            display: flex;
            align-items: center;
            background: #0a0d14;
            border: 1px solid #1e2433;
            border-radius: 8px;
            padding: 14px 16px;
            font-family: 'Courier New', Courier, monospace;
            font-size: 13px;
            color: #a5b4fc;
            overflow-x: auto;
            gap: 12px;
        }

        .install-cmd .terminal-dots {
            display: flex;
            gap: 5px;
            flex-shrink: 0;
            margin-right: 4px;
        }

        .install-cmd .terminal-dots span {
            width: 8px;
            height: 8px;
            border-radius: 50%;
        }

        .install-cmd .terminal-dots span:nth-child(1) { background: #f43f5e; }
        .install-cmd .terminal-dots span:nth-child(2) { background: #f59e0b; }
        .install-cmd .terminal-dots span:nth-child(3) { background: #10b981; }

        .install-cmd .prefix {
            color: #6366f1;
            user-select: none;
            flex-shrink: 0;
            font-weight: 700;
        }

        .install-cmd code {
            flex: 1;
            white-space: nowrap;
            user-select: all;
            color: #a5b4fc;
        }

        .copy-btn {
            background: #4f46e5;
            color: #fff;
            border: none;
            border-radius: 6px;
            padding: 6px 14px;
            font-size: 12px;
            font-weight: 600;
            cursor: pointer;
            flex-shrink: 0;
            transition: background 0.2s;
        }

        .copy-btn:hover {
            background: #4338ca;
        }

        .copy-btn.copied {
            background: #059669;
        }

        .install-note {
            font-size: 12px;
            color: #64748b;
            margin-top: 10px;
        }

        .install-note a {
            color: #818cf8;
            text-decoration: none;
            font-weight: 500;
        }

        .install-note a:hover {
            color: #a5b4fc;
        }

        /* SEO Feature highlights */
        .seo-features {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
            gap: 12px;
            margin-bottom: 24px;
        }

        .seo-feat {
            display: flex;
            align-items: center;
            gap: 12px;
            background: #131620;
            border: 1px solid #1e2433;
            border-radius: 12px;
            padding: 14px 16px;
            transition: border-color 0.2s;
        }

        .seo-feat:hover {
            border-color: #2d3548;
        }

        .seo-feat-icon {
            font-size: 20px;
            flex-shrink: 0;
            width: 40px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 10px;
            background: #1e1b4b;
        }

        .seo-feat strong {
            display: block;
            font-size: 13px;
            font-weight: 700;
            color: #e2e8f0;
        }

        .seo-feat span {
            font-size: 12px;
            color: #64748b;
        }

        /* Section label */
        .section-label {
            font-size: 14px;
            font-weight: 700;
            color: #94a3b8;
            margin-bottom: 16px;
        }

        /* Back link */
        .back-link {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            color: #818cf8;
            text-decoration: none;
            font-size: 14px;
            font-weight: 500;
            margin-bottom: 16px;
            transition: color 0.2s;
        }

        .back-link:hover {
            color: #a5b4fc;
        }

        /* ── Text Modal ───────────────────────── */
        .modal-overlay {
            display: none;
            position: fixed;
            inset: 0;
            background: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(4px);
            z-index: 1000;
            justify-content: center;
            align-items: center;
            padding: 24px;
        }

        .modal-overlay.active { display: flex; }

        .modal {
            background: #131620;
            border: 1px solid #1e2433;
            border-radius: 16px;
            width: 100%;
            max-width: 720px;
            max-height: 85vh;
            display: flex;
            flex-direction: column;
            box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
        }

        .modal-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 18px 24px;
            border-bottom: 1px solid #1e2433;
            flex-shrink: 0;
        }

        .modal-title {
            font-size: 15px;
            font-weight: 700;
            color: #e2e8f0;
            display: flex;
            align-items: center;
            gap: 10px;
            min-width: 0;
        }

        .modal-title span {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .modal-title-icon {
            flex-shrink: 0;
            width: 32px;
            height: 32px;
            border-radius: 8px;
            background: #422006;
            color: #fbbf24;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 16px;
        }

        .modal-actions {
            display: flex;
            align-items: center;
            gap: 8px;
            flex-shrink: 0;
        }

        .modal-btn {
            background: #1e1b4b;
            color: #a5b4fc;
            border: 1px solid #1e2433;
            border-radius: 8px;
            padding: 8px 14px;
            font-size: 12px;
            font-weight: 600;
            cursor: pointer;
            transition: background 0.2s;
            display: inline-flex;
            align-items: center;
            gap: 6px;
            text-decoration: none;
        }

        .modal-btn:hover {
            background: #312e81;
            color: #c7d2fe;
        }

        .modal-btn.primary {
            background: #4f46e5;
            color: #fff;
            border-color: #4f46e5;
        }

        .modal-btn.primary:hover {
            background: #4338ca;
        }

        .modal-close {
            background: none;
            border: 1px solid #1e2433;
            color: #64748b;
            font-size: 20px;
            cursor: pointer;
            padding: 4px 10px;
            border-radius: 6px;
            line-height: 1;
            transition: all 0.2s;
        }

        .modal-close:hover {
            background: rgba(99, 102, 241, 0.1);
            color: #e2e8f0;
        }

        .modal-body {
            padding: 24px;
            overflow-y: auto;
            flex: 1;
            min-height: 0;
        }

        .modal-body pre {
            font-family: 'Courier New', Courier, monospace;
            font-size: 13px;
            line-height: 1.7;
            color: #94a3b8;
            white-space: pre-wrap;
            word-break: break-word;
            margin: 0;
        }

        .modal-loading {
            text-align: center;
            padding: 40px;
            color: #64748b;
            font-size: 13px;
        }

        .modal-loading .spinner {
            display: inline-block;
            width: 24px;
            height: 24px;
            border: 2px solid #1e2433;
            border-top-color: #6366f1;
            border-radius: 50%;
            animation: spin 0.6s linear infinite;
            margin-bottom: 12px;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        /* Responsive */
        @media (max-width: 640px) {
            .header h1 { font-size: 18px; }
            .install-cmd { font-size: 11px; padding: 12px 14px; }
            .item { padding: 12px 16px; }
        }
    </style>
</head>
<body>
    <canvas id="bg-canvas"></canvas>
    <div class="page-content">
    <div class="container">
        <div class="header">
            <?php if ($requestedPath === ''): ?>
            <h1>DRM Panel Download
                <div style="display:flex;gap:8px;flex-wrap:wrap">
                    <a href="/" class="action-btn secondary" style="font-size:10px;padding:8px 18px;border-radius:6px">
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
                        Home
                    </a>
                    <a href="/extend/" class="action-btn emerald" style="font-size:10px;padding:8px 18px;border-radius:6px">
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
                        Extend License
                    </a>
                </div>
            </h1>
            <p class="seo-subtitle">Widevine DRM panel with DASH to HLS converter, MPD to HLS restreaming, OTT panel scripts &amp; auto key dump. Download latest release below.</p>
            <?php else: ?>
            <h1><?= esc(basename($requestedPath)) ?></h1>
            <?php endif; ?>
            <div class="breadcrumb">
                <?php if ($requestedPath === ''): ?>
                    <span class="current">All Releases</span>
                <?php else: ?>
                    <a href="?">All Releases</a>
                    <?php foreach ($breadcrumbs as $i => $crumb): ?>
                        <span class="sep">/</span>
                        <?php if ($i === count($breadcrumbs) - 1): ?>
                            <span class="current"><?= esc($crumb['name']) ?></span>
                        <?php else: ?>
                            <a href="<?= buildUrl($crumb['path']) ?>"><?= esc($crumb['name']) ?></a>
                        <?php endif; ?>
                    <?php endforeach; ?>
                <?php endif; ?>
            </div>
        </div>

        <?php if ($requestedPath === ''): ?>
            <!-- SEO: Feature highlights -->
			<!--
            <div class="seo-features">
                <div class="seo-feat">
                    <span class="seo-feat-icon">&#128274;</span>
                    <div>
                        <strong>Widevine &amp; PlayReady DRM</strong>
                        <span>Auto key dump, CENC/CBCS decryption</span>
                    </div>
                </div>
                <div class="seo-feat">
                    <span class="seo-feat-icon">&#9889;</span>
                    <div>
                        <strong>MPD to HLS Converter</strong>
                        <span>DASH DRM to clean HLS in real-time</span>
                    </div>
                </div>
                <div class="seo-feat">
                    <span class="seo-feat-icon">&#127760;</span>
                    <div>
                        <strong>OTT Provider Scripts</strong>
                        <span>Auto-sync channels, token refresh</span>
                    </div>
                </div>
            </div>
			-->
			
            <div class="install-box">
                <div class="install-label">One Command Auto Installer</div>
                <div class="install-cmd">
                    <span class="terminal-dots"><span></span><span></span><span></span></span>
                    <span class="prefix">$</span>
                    <code id="installCmd">bash &lt;(curl -s https://streamora.dev/updates/install.sh)</code>
                    <button class="copy-btn" onclick="copyCmd(this)">Copy</button>
                </div>
                <div class="install-note">Run as root on Ubuntu, Debian, CentOS, RHEL, Rocky, AlmaLinux, or Fedora. &nbsp;|&nbsp; <a href="?path=manual_install.txt">Manual Install Guide</a></div>
            </div>

            <div class="top-actions">
                <a href="/docs" target="_blank" class="action-btn secondary">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
                    Script Development Guide
                </a>
            </div>

            <h2 class="section-label">DRM Panel Free Download &mdash; Latest Releases</h2>
        <?php endif; ?>

        <?php if ($requestedPath !== ''): ?>
            <?php
                $parentPath = dirname($requestedPath);
                $parentUrl = $parentPath === '.' ? '?' : buildUrl($parentPath);
            ?>
            <a href="<?= $parentUrl ?>" class="back-link">&#8592; Back</a>
        <?php endif; ?>

        <div class="card">
            <?php if (empty($folders) && empty($files)): ?>
                <div class="empty">
                    <div class="empty-icon">&#128194;</div>
                    <div>No releases found yet.</div>
                </div>
            <?php endif; ?>

            <?php foreach ($folders as $folder): ?>
                <a href="<?= buildUrl($folder['path']) ?>" class="item">
                    <div class="item-icon icon-folder">&#128193;</div>
                    <div class="item-info">
                        <div class="item-name"><?= esc($folder['name']) ?></div>
                        <div class="item-meta"><?= date('d M Y, H:i', $folder['mtime']) ?></div>
                    </div>
                    <div class="item-action">Open &rarr;</div>
                </a>
            <?php endforeach; ?>

            <?php foreach ($files as $file): ?>
                <?php
                    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
                    $isTxt = $ext === 'txt';
                ?>
                <?php if ($isTxt): ?>
                <a href="javascript:void(0)" class="item" onclick="openTxtModal('<?= esc($file['name']) ?>', '<?= buildUrl($file['path']) ?>')">
                <?php else: ?>
                <a href="<?= buildUrl($file['path']) ?>" class="item">
                <?php endif; ?>
                    <div class="item-icon <?= $isTxt ? 'icon-text' : 'icon-file' ?>">
                        <?= $isTxt ? '&#128196;' : '&#128230;' ?>
                    </div>
                    <div class="item-info">
                        <div class="item-name">
                            <?= esc($file['name']) ?>
                            <?php if (!$isTxt): ?>
                                <span class="badge"><?= formatSize($file['size']) ?></span>
                            <?php endif; ?>
                        </div>
                        <div class="item-meta">
                            <?= date('d M Y, H:i', $file['mtime']) ?>
                            <?php if ($isTxt): ?>
                                &middot; Changelog
                            <?php else: ?>
                                &middot; Binary
                            <?php endif; ?>
                        </div>
                    </div>
                    <div class="item-action"><?= $isTxt ? 'View' : 'Download' ?></div>
                </a>
            <?php endforeach; ?>
        </div>
    </div>
    <!-- Text File Modal -->
    <div class="modal-overlay" id="txtModal">
        <div class="modal">
            <div class="modal-header">
                <div class="modal-title">
                    <div class="modal-title-icon">&#128196;</div>
                    <span id="modalFileName">Changelog</span>
                </div>
                <div class="modal-actions">
                    <a href="#" id="modalDownloadBtn" class="modal-btn" download>
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
                        Download
                    </a>
                    <button class="modal-close" onclick="closeTxtModal()" title="Close">&times;</button>
                </div>
            </div>
            <div class="modal-body" id="modalBody">
                <div class="modal-loading">
                    <div class="spinner"></div>
                    <div>Loading...</div>
                </div>
            </div>
        </div>
    </div>

    <script>
    function copyCmd(btn) {
        var cmd = 'bash <(curl -s https://streamora.dev/updates/install.sh)';
        if (navigator.clipboard) {
            navigator.clipboard.writeText(cmd).then(function() {
                btn.textContent = 'Copied!';
                btn.classList.add('copied');
                setTimeout(function() { btn.textContent = 'Copy'; btn.classList.remove('copied'); }, 2000);
            });
        } else {
            var ta = document.createElement('textarea');
            ta.value = cmd;
            document.body.appendChild(ta);
            ta.select();
            document.execCommand('copy');
            document.body.removeChild(ta);
            btn.textContent = 'Copied!';
            btn.classList.add('copied');
            setTimeout(function() { btn.textContent = 'Copy'; btn.classList.remove('copied'); }, 2000);
        }
    }

    function openTxtModal(filename, url) {
        var modal = document.getElementById('txtModal');
        var body = document.getElementById('modalBody');
        var title = document.getElementById('modalFileName');
        var dlBtn = document.getElementById('modalDownloadBtn');

        title.textContent = filename;
        dlBtn.href = url;
        body.innerHTML = '<div class="modal-loading"><div class="spinner"></div><div>Loading...</div></div>';
        modal.classList.add('active');
        document.body.style.overflow = 'hidden';

        var rawUrl = url + (url.indexOf('?') === -1 ? '?' : '&') + 'raw=1';
        fetch(rawUrl)
            .then(function(r) {
                if (!r.ok) throw new Error('Failed to load');
                return r.text();
            })
            .then(function(text) {
                var pre = document.createElement('pre');
                pre.textContent = text || '(empty file)';
                body.innerHTML = '';
                body.appendChild(pre);
            })
            .catch(function() {
                body.innerHTML = '<div class="modal-loading" style="color:#f87171;">Failed to load file content.</div>';
            });
    }

    function closeTxtModal() {
        document.getElementById('txtModal').classList.remove('active');
        document.body.style.overflow = '';
    }

    // Close on overlay click
    document.getElementById('txtModal').addEventListener('click', function(e) {
        if (e.target === this) closeTxtModal();
    });

    // Close on Escape key
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape') closeTxtModal();
    });
    </script>
    </div><!-- /page-content -->
    <?php include __DIR__ . '/../assets/bg-3d.php'; ?>
</body>
</html>
