Files
felhom.eu/documentation/audits/i18n-slice5-2026-09-20/C3/final/stacks.hu.html
T
admin 8e9401c6bf
gates / gates (push) Successful in 27s
Localisation slice 5 CLOSED: the catalog speaks English and the floor is at 0.257.0
Part C shipped the same day the pilot was read: fifty apps in three pushes, 1 031 of
1 032 strings. The English Apps list shows ZERO Hungarian app descriptions across all
53 apps — the only Hungarian left on it is the "Naprakész" badge (R-589) and the
language picker naming itself, which is correct.

The Hungarian Apps list is identical to the pre-slice capture once the per-session
CSRF token AND Docker's own "Up N hours" container string are normalised. Both
normalisations are stated in the evidence rather than applied quietly — the second
one moved because two hours of wall clock passed between captures, not because any
copy changed.

Fleet floor raised to 0.257.0 with the declared MinAgent 0.131.0, above the vouched
golden so the declaration carries it. demo-felhom went 0.255.0 -> 0.257.0 by itself
in under 12 seconds and THEN rendered the English tagline: the floor delivered the
feature, not a version string.

Rows: R-593 (papra describes a session-signing key as "the app's subdomain" — the one
string left untranslated) and R-594 (the catalog gate can convict a retrieval promise
but has no way to REGISTER a true one, which the shared vocabulary's design calls
for). R-560 closed. 281 -> 287 rows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 16:40:59 +02:00

3292 lines
144 KiB
HTML

<!DOCTYPE html>
<html lang="hu" class="no-js">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Alkalmazások — Felhom.eu</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=0.257.0">
<link rel="stylesheet" href="/static/style.css?v=0.257.0">
<meta name="csrf-token" content="8869722e21aa4e65abe2803da4fbb736f7a901b80840b9976cb56fe18295b071">
<script>
document.documentElement.className=document.documentElement.className.replace('no-js','js');
function csrfHeaders(){var el=document.querySelector('meta[name="csrf-token"]');return el?{'X-CSRF-Token':el.content}:{};}
function felhomConfirm(el,question,onYes){
if(!el||el.dataset.fcOpen)return;
el.dataset.fcOpen='1';
var wrap=document.createElement('span');wrap.className='inline-confirm';
var q=document.createElement('span');q.className='inline-confirm-q';q.textContent=question;
var yes=document.createElement('button');yes.type='button';yes.className='btn btn-xs btn-danger';yes.textContent='Igen';
var no=document.createElement('button');no.type='button';no.className='btn btn-xs btn-outline';no.textContent='Mégse';
wrap.appendChild(q);wrap.appendChild(yes);wrap.appendChild(no);
el.style.display='none';el.parentNode.insertBefore(wrap,el.nextSibling);
function close(){wrap.remove();el.style.display='';delete el.dataset.fcOpen;}
no.addEventListener('click',close);
yes.addEventListener('click',function(){close();onYes();});
}
document.addEventListener('click',function(e){
var btn=e.target.closest?e.target.closest('[data-confirm]'):null;
if(!btn)return;
e.preventDefault();
felhomConfirm(btn,btn.getAttribute('data-confirm'),function(){
var form=btn.closest('form');
if(form){if(form.requestSubmit)form.requestSubmit(btn);else form.submit();}
});
});
document.addEventListener('click',function(e){
var btn=e.target.closest?e.target.closest('.nav-group-toggle'):null;
if(!btn)return;
var group=btn.closest('.nav-group');
if(!group)return;
var willOpen=!group.classList.contains('is-open');
document.querySelectorAll('.nav-group.is-open').forEach(function(g){
g.classList.remove('is-open');
var t=g.querySelector('.nav-group-toggle');
if(t)t.setAttribute('aria-expanded','false');
});
if(willOpen){group.classList.add('is-open');btn.setAttribute('aria-expanded','true');}
});
function showAlert(msg){var o=document.createElement('div');o.className='modal-overlay';o.id='alert-modal';o.addEventListener('click',function(e){if(e.target===o)o.remove();});var c=document.createElement('div');c.className='modal-card';c.innerHTML='<h3>Üzenet</h3><pre style="white-space:pre-wrap;word-break:break-word;background:var(--bg-2);padding:.75rem;border-radius:.375rem;font-size:.85rem;max-height:60vh;overflow-y:auto;user-select:text;cursor:text">'+msg.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')+'</pre><div class="modal-actions"><button class="btn btn-primary" onclick="document.getElementById(\'alert-modal\').remove()">OK</button></div>';o.appendChild(c);document.body.appendChild(o);}
</script>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
<symbol id="i-hard-drive" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 16h.01" /> <path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" /> <path d="M21.946 12.013H2.054" /> <path d="M6 16h.01" /></symbol>
<symbol id="i-cpu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20v2" /> <path d="M12 2v2" /> <path d="M17 20v2" /> <path d="M17 2v2" /> <path d="M2 12h2" /> <path d="M2 17h2" /> <path d="M2 7h2" /> <path d="M20 12h2" /> <path d="M20 17h2" /> <path d="M20 7h2" /> <path d="M7 20v2" /> <path d="M7 2v2" /> <rect x="4" y="4" width="16" height="16" rx="2" /> <rect x="8" y="8" width="8" height="8" rx="1" /></symbol>
<symbol id="i-memory-stick" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 12v-2" /> <path d="M12 18v-2" /> <path d="M16 12v-2" /> <path d="M16 18v-2" /> <path d="M2 11h1.5" /> <path d="M20 18v-2" /> <path d="M20.5 11H22" /> <path d="M4 18v-2" /> <path d="M8 12v-2" /> <path d="M8 18v-2" /> <rect x="2" y="6" width="20" height="10" rx="2" /></symbol>
<symbol id="i-thermometer" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z" /></symbol>
<symbol id="i-triangle-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /> <path d="M12 9v4" /> <path d="M12 17h.01" /></symbol>
<symbol id="i-lock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2" /> <path d="M7 11V7a5 5 0 0 1 10 0v4" /></symbol>
<symbol id="i-cloud" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z" /></symbol>
<symbol id="i-square" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2" /></symbol>
<symbol id="i-rotate-cw" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" /> <path d="M21 3v5h-5" /></symbol>
<symbol id="i-file-text" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /> <path d="M14 2v5a1 1 0 0 0 1 1h5" /> <path d="M10 9H8" /> <path d="M16 13H8" /> <path d="M16 17H8" /></symbol>
<symbol id="i-external-link" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6" /> <path d="M10 14 21 3" /> <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" /></symbol>
<symbol id="i-shield" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" /></symbol>
<symbol id="i-server" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2" /> <rect width="20" height="8" x="2" y="14" rx="2" ry="2" /> <line x1="6" x2="6.01" y1="6" y2="6" /> <line x1="6" x2="6.01" y1="18" y2="18" /></symbol>
<symbol id="i-share" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3" /> <circle cx="6" cy="12" r="3" /> <circle cx="18" cy="19" r="3" /> <line x1="8.59" x2="15.42" y1="13.51" y2="17.49" /> <line x1="15.41" x2="8.59" y1="6.51" y2="10.49" /></symbol>
<symbol id="i-layout-grid" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="7" height="7" x="3" y="3" rx="1" /> <rect width="7" height="7" x="14" y="3" rx="1" /> <rect width="7" height="7" x="14" y="14" rx="1" /> <rect width="7" height="7" x="3" y="14" rx="1" /></symbol>
<symbol id="i-rocket" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91 0z" /> <path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z" /> <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0" /> <path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5" /></symbol>
<symbol id="i-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /> <circle cx="12" cy="12" r="3" /></symbol>
<symbol id="i-bell" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.268 21a2 2 0 0 0 3.464 0" /> <path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" /></symbol>
<symbol id="i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /> <path d="m6 6 12 12" /></symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5" /></symbol>
<symbol id="i-pencil" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" /> <path d="m15 5 4 4" /></symbol>
<symbol id="i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 16v-4" /> <path d="M12 8h.01" /></symbol>
<symbol id="i-download" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 15V3" /> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /> <path d="m7 10 5 5 5-5" /></symbol>
<symbol id="i-upload" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12" /> <path d="m17 8-5-5-5 5" /> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /></symbol>
<symbol id="i-trash-2" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 11v6" /> <path d="M14 11v6" /> <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" /> <path d="M3 6h18" /> <path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" /></symbol>
<symbol id="i-wrench" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z" /></symbol>
<symbol id="i-link" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /> <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" /></symbol>
<symbol id="i-search" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21 21-4.34-4.34" /> <circle cx="11" cy="11" r="8" /></symbol>
<symbol id="i-plus" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14" /> <path d="M12 5v14" /></symbol>
<symbol id="i-chevron-down" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6" /></symbol>
<symbol id="i-play" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z" /></symbol>
<symbol id="i-pause" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="14" y="3" width="5" height="18" rx="1" /> <rect x="5" y="3" width="5" height="18" rx="1" /></symbol>
<symbol id="i-menu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12h16" /> <path d="M4 6h16" /> <path d="M4 18h16" /></symbol>
</svg>
<header class="mobile-topbar">
<a href="/" class="mobile-topbar-logo"><img src="/static/felhom-logo.svg?v=0.257.0" alt="Felhom.eu"></a>
<button type="button" class="nav-burger" aria-expanded="false" aria-controls="sidebar" aria-label="Menü">
<svg class="ico"><use href="#i-menu"/></svg>
</button>
</header>
<div class="nav-backdrop" hidden></div>
<nav class="sidebar" id="sidebar">
<div class="sidebar-header">
<img src="/static/felhom-logo.svg?v=0.257.0" alt="Felhom.eu" class="sidebar-logo">
</div>
<ul class="nav-links">
<li><a href="/launcher" class=""><svg class="ico"><use href="#i-rocket"/></svg>Indítópult</a></li>
<li><a href="/dashboard" class=""><svg class="ico"><use href="#i-layout-grid"/></svg>Vezérlőpult</a></li>
<li><a href="/stacks" class="active"><svg class="ico"><use href="#i-cloud"/></svg>Alkalmazások</a></li>
<li class="nav-group">
<button type="button" class="nav-group-toggle" aria-expanded="false" aria-controls="nav-group-storage"><svg class="ico"><use href="#i-hard-drive"/></svg>Tárhely<svg class="ico nav-chevron"><use href="#i-chevron-down"/></svg></button>
<ul id="nav-group-storage" class="nav-links nav-links-sub nav-links-nested">
<li><a href="/storage" class="">Meghajtók</a></li>
<li><a href="/storage/network" class="">Hálózati tárhely</a></li>
</ul>
</li>
<li class="nav-group">
<button type="button" class="nav-group-toggle" aria-expanded="false" aria-controls="nav-group-backups"><svg class="ico"><use href="#i-shield"/></svg>Biztonsági mentés<svg class="ico nav-chevron"><use href="#i-chevron-down"/></svg></button>
<ul id="nav-group-backups" class="nav-links nav-links-sub nav-links-nested">
<li><a href="/backups" class="">Áttekintés</a></li>
<li><a href="/backups/remote" class="">Távoli mentés</a></li>
<li><a href="/backups/apps" class="">Alkalmazások</a></li>
<li><a href="/backups/restore" class="">Visszaállítás</a></li>
</ul>
</li>
<li class="nav-group">
<button type="button" class="nav-group-toggle" aria-expanded="false" aria-controls="nav-group-sharing"><svg class="ico"><use href="#i-share"/></svg>Megosztás<svg class="ico nav-chevron"><use href="#i-chevron-down"/></svg></button>
<ul id="nav-group-sharing" class="nav-links nav-links-sub nav-links-nested">
<li><a href="/sharing" class="">Hálózati megosztás</a></li>
</ul>
</li>
<li><a href="/monitoring" class=""><svg class="ico"><use href="#i-cpu"/></svg>Rendszermonitor</a></li>
<li><a href="/debug" class=""><svg class="ico"><use href="#i-wrench"/></svg>Debug</a></li>
</ul>
<div class="sidebar-bottom">
<div class="nav-group-label">Beállítások</div>
<ul class="nav-links nav-links-sub">
<li><a href="/settings" class=""><svg class="ico"><use href="#i-settings"/></svg>Rendszer</a></li>
<li><a href="/settings/notifications" class=""><svg class="ico"><use href="#i-bell"/></svg>Értesítések</a></li>
<li><a href="/settings/security" class=""><svg class="ico"><use href="#i-lock"/></svg>Biztonság és hozzáférés</a></li>
</ul>
<div class="sidebar-footer">
<span class="version">0.257.0</span><details class="lang-globe">
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
<ul class="lang-globe-menu">
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="8869722e21aa4e65abe2803da4fbb736f7a901b80840b9976cb56fe18295b071"><input type="hidden" name="back" value="/stacks"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="8869722e21aa4e65abe2803da4fbb736f7a901b80840b9976cb56fe18295b071"><input type="hidden" name="back" value="/stacks"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
</ul>
</details>
<a href="/logout" class="logout-link">Kijelentkezés ↗</a>
</div>
</div>
</nav>
<main class="content">
<div class="page-header">
<h2>Alkalmazások</h2>
<span class="domain-badge">enkisfelhom.hu</span>
<a href="/import" class="btn btn-sm btn-outline" title="Alkalmazás visszaállítása exportált csomagból">Importálás</a>
<button class="btn btn-sm btn-outline" id="sync-btn" onclick="syncTemplates()" title="Sablonok frissítése a központi katalógusból">↻ Sablonok frissítése</button>
</div>
<div id="sync-toast" class="sync-toast" style="display:none"></div>
<div class="filter-bar" id="filter-bar">
<button class="filter-btn active" data-filter="all">Mind <span class="filter-count" id="count-all"></span></button>
<button class="filter-btn" data-filter="running">Futó <span class="filter-count" id="count-running"></span></button>
<button class="filter-btn" data-filter="stopped">Leállítva <span class="filter-count" id="count-stopped"></span></button>
<button class="filter-btn" data-filter="available">Telepíthető <span class="filter-count" id="count-available"></span></button>
</div>
<div class="stack-grid">
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/actualbudget">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/actualbudget-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/actualbudget-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>ActualBudget</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Személyes pénzügyek és költségvetés kezelése</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~50M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/actualbudget/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'actualbudget')">Telepítés</a>
<a href="/apps/actualbudget" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/adventurelog">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/adventurelog-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/adventurelog-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>AdventureLog</h3>
<a class="subdomain-link" href="https://travel.enkisfelhom.hu" target="_blank">
travel.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Utazási napló és kalandtervező</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">adventurelog</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">adventurelog-postgres</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">adventurelog-frontend</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'adventurelog', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'adventurelog', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'adventurelog', 'stop')">Leállítás</button>
<a href="/stacks/adventurelog/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/adventurelog" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/audiobookshelf">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/audiobookshelf-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/audiobookshelf-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Audiobookshelf</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Hangoskönyv és podcast kezelő szerver</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/audiobookshelf/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'audiobookshelf')">Telepítés</a>
<a href="/apps/audiobookshelf" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/bentopdf">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/bentopdf-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/bentopdf-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>BentoPDF</h3>
<a class="subdomain-link" href="https://pdf.enkisfelhom.hu" target="_blank">
pdf.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Adatvédelmi fókuszú PDF eszköztár</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">bentopdf</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'bentopdf', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'bentopdf', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'bentopdf', 'stop')">Leállítás</button>
<a href="/stacks/bentopdf/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/bentopdf" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/bookstack">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/bookstack-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/bookstack-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>BookStack</h3>
<a class="subdomain-link" href="https://wiki.enkisfelhom.hu" target="_blank">
wiki.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Egyszerű, könyv-szerű wiki és dokumentáció platform</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~150M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">bookstack</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">bookstack-db</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'bookstack', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'bookstack', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'bookstack', 'stop')">Leállítás</button>
<a href="/stacks/bookstack/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/bookstack" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/calcom">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/calcom-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/calcom-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Cal.com</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Nyílt forráskódú időpontfoglaló (Calendly alternatíva)</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~200M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/calcom/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'calcom')">Telepítés</a>
<a href="/apps/calcom" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/calibre-web">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/calibre-web-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/calibre-web-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Calibre-Web Automated</h3>
<a class="subdomain-link" href="https://books.enkisfelhom.hu" target="_blank">
books.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Automatizált e-könyv könyvtár - konvertálás, metaadat kezelés és webes olvasó</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~200M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
<span class="metarow" title="Adattároló: NVME 1TB"><svg class="ico"><use href="#i-hard-drive"/></svg>NVME 1TB</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">calibre-web</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'calibre-web', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'calibre-web', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'calibre-web', 'stop')">Leállítás</button>
<a href="/stacks/calibre-web/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/calibre-web" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/claper">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/claper-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/claper-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Claper</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Interaktív prezentáció és közönség bevonás</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/claper/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'claper')">Telepítés</a>
<a href="/apps/claper" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/cloudflared">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/cloudflared-logo.svg" alt="" data-fallback="/static/infra-logo.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/cloudflared-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Cloudflare Tunnel</h3>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
</div>
<p class="stack-detail-desc">Biztonságos internetkapcsolat — a szerver portnyitás nélkül érhető el kívülről.</p>
<div class="metarows">
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">cloudflared</span>
<span class="container-status state-text-run">Up 2 weeks</span>
</div>
</div>
<div class="stack-detail-actions">
<span class="tag"><svg class="ico ico-sm"><use href="#i-lock"/></svg>Védett rendszerkomponens</span>
<button class="btn btn-warning" onclick="stackAction(event, 'cloudflared', 'restart')">Újraindítás</button>
<a href="/apps/cloudflared" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/code-server">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/code-server-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/code-server-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Code-Server</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">VS Code a böngészőben - kódolás bárhonnan</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~200M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/code-server/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'code-server')">Telepítés</a>
<a href="/apps/code-server" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/crafty-controller">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/crafty-controller-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/crafty-controller-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Crafty Controller</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Minecraft szerver kezelő webes felülettel</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~256M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/crafty-controller/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'crafty-controller')">Telepítés</a>
<a href="/apps/crafty-controller" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/docmost">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/docmost-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/docmost-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Docmost</h3>
<a class="subdomain-link" href="https://docs.enkisfelhom.hu" target="_blank">
docs.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Modern wiki és dokumentáció platform (Notion-szerű)</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~200M</span></span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">docmost</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">docmost-postgres</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">docmost-redis</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'docmost', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'docmost', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'docmost', 'stop')">Leállítás</button>
<a href="/stacks/docmost/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/docmost" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/emby">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/emby-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/emby-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Emby</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Személyes média szerver élő TV és DVR támogatással</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~512M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/emby/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'emby')">Telepítés</a>
<a href="/apps/emby" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/filebrowser">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/filebrowser-logo.svg" alt="" data-fallback="/static/infra-logo.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/filebrowser-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>FileBrowser</h3>
<a class="subdomain-link" href="https://files.enkisfelhom.hu" target="_blank">
files.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
</div>
<p class="stack-detail-desc">Fájlkezelő — a tárhely fájljainak böngészése a böngészőből.</p>
<div class="metarows">
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">filebrowser</span>
<span class="container-status state-text-run">Up 2 weeks (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<span class="tag"><svg class="ico ico-sm"><use href="#i-lock"/></svg>Védett rendszerkomponens</span>
<button class="btn btn-warning" onclick="stackAction(event, 'filebrowser', 'restart')">Újraindítás</button>
<a href="/apps/filebrowser" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/ghost">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/ghost-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/ghost-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Ghost</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Professzionális blog és hírlevél platform</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~150M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/ghost/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'ghost')">Telepítés</a>
<a href="/apps/ghost" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/gitea">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/gitea-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/gitea-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Gitea</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Könnyű, saját Git szerver webes felülettel</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/gitea/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'gitea')">Telepítés</a>
<a href="/apps/gitea" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/glance">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/glance-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/glance-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Glance</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Minimalista információs dashboard</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~20M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/glance/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'glance')">Telepítés</a>
<a href="/apps/glance" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/gokapi">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/gokapi-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/gokapi-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Gokapi</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Ideiglenes fájlmegosztás lejáró linkekkel</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~30M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/gokapi/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'gokapi')">Telepítés</a>
<a href="/apps/gokapi" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/grafana">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/grafana-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/grafana-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Grafana</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Professzionális monitoring és vizualizációs platform</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/grafana/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'grafana')">Telepítés</a>
<a href="/apps/grafana" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/gramps-web">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/gramps-web-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/gramps-web-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Gramps Web</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Családfa készítő és genealógiai szoftver</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~384M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/gramps-web/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'gramps-web')">Telepítés</a>
<a href="/apps/gramps-web" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/home-assistant">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/home-assistant-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/home-assistant-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Home Assistant</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Nyílt forráskódú okos otthon központ</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~256M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/home-assistant/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'home-assistant')">Telepítés</a>
<a href="/apps/home-assistant" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/homebox">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/homebox-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/homebox-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Homebox</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Otthoni leltár és eszköznyilvántartás</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~50M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/homebox/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'homebox')">Telepítés</a>
<a href="/apps/homebox" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/homepage">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/homepage-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/homepage-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Homepage</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Személyre szabható kezdőlap szolgáltatás widgetekkel</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~50M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/homepage/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'homepage')">Telepítés</a>
<a href="/apps/homepage" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/immich">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/immich-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/immich-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Immich</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Fotók és videók kezelése (Google Photos alternatíva)</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~2048M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/immich/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'immich')">Telepítés</a>
<a href="/apps/immich" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/jellyfin">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/jellyfin-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/jellyfin-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Jellyfin</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Ingyenes és nyílt forráskódú média szerver</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~512M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/jellyfin/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'jellyfin')">Telepítés</a>
<a href="/apps/jellyfin" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/seerr">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/seerr-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/seerr-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Jellyseerr</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Média igénylés kezelő Jellyfin/Plex integrációval</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/seerr/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'seerr')">Telepítés</a>
<a href="/apps/seerr" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/kimai">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/kimai-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/kimai-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Kimai</h3>
<a class="subdomain-link" href="https://time.enkisfelhom.hu" target="_blank">
time.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Időkövetés és projektmenedzsment</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">kimai</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">kimai-db</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'kimai', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'kimai', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'kimai', 'stop')">Leállítás</button>
<a href="/stacks/kimai/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/kimai" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/komga">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/komga-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/komga-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Komga</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Képregény és manga szerver OPDS támogatással</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~200M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/komga/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'komga')">Telepítés</a>
<a href="/apps/komga" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/mealie">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/mealie-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/mealie-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Mealie</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Receptkezelő és étkezéstervező</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~200M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/mealie/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'mealie')">Telepítés</a>
<a href="/apps/mealie" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/navidrome">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/navidrome-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/navidrome-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Navidrome</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Könnyű zene szerver Subsonic API támogatással</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~50M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/navidrome/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'navidrome')">Telepítés</a>
<a href="/apps/navidrome" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/nextcloud">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/nextcloud-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/nextcloud-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Nextcloud</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Saját felhő tárhely - Google Drive/Dropbox alternatíva</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~256M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/nextcloud/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'nextcloud')">Telepítés</a>
<a href="/apps/nextcloud" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/onlyoffice">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/onlyoffice-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/onlyoffice-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>OnlyOffice</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Teljes értékű irodai csomag a böngészőben</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~512M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/onlyoffice/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'onlyoffice')">Telepítés</a>
<a href="/apps/onlyoffice" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/opengist">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/opengist-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/opengist-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>OpenGist</h3>
<a class="subdomain-link" href="https://gist.enkisfelhom.hu" target="_blank">
gist.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Kód snippetek megosztása (GitHub Gist alternatíva)</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~30M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">opengist</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'opengist', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'opengist', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'opengist', 'stop')">Leállítás</button>
<a href="/stacks/opengist/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/opengist" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/outline">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/outline-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/outline-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Outline</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Modern csapat tudásbázis Markdown támogatással</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~200M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/outline/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'outline')">Telepítés</a>
<a href="/apps/outline" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/paperless-ngx">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/paperless-ngx-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/paperless-ngx-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Paperless-ngx</h3>
<a class="subdomain-link" href="https://papir.enkisfelhom.hu" target="_blank">
papir.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Dokumentumok digitalizálása és rendszerezése</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~500M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
<span class="metarow" title="Adattároló: NVME 1TB"><svg class="ico"><use href="#i-hard-drive"/></svg>NVME 1TB</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">paperless-webserver</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">paperless-postgres</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">paperless-redis</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'paperless-ngx', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'paperless-ngx', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'paperless-ngx', 'stop')">Leállítás</button>
<a href="/stacks/paperless-ngx/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/paperless-ngx" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/papra">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/papra-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/papra-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Papra</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Minimalista dokumentumtár és rendszerező</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~50M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/papra/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'papra')">Telepítés</a>
<a href="/apps/papra" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/plex">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/plex-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/plex-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Plex</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Népszerű média szerver csiszolt felülettel</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~512M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/plex/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'plex')">Telepítés</a>
<a href="/apps/plex" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/privatebin">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/privatebin-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/privatebin-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>PrivateBin</h3>
<a class="subdomain-link" href="https://paste.enkisfelhom.hu" target="_blank">
paste.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Titkosított jegyzet és szöveg megosztás</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~30M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">privatebin</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'privatebin', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'privatebin', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'privatebin', 'stop')">Leállítás</button>
<a href="/stacks/privatebin/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/privatebin" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/radarr">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/radarr-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/radarr-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Radarr</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Automatikus film letöltő és rendszerező</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~150M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/radarr/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'radarr')">Telepítés</a>
<a href="/apps/radarr" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/rallly">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/rallly-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/rallly-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Rallly</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Időpont szavazás (Doodle alternatíva)</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~384M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/rallly/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'rallly')">Telepítés</a>
<a href="/apps/rallly" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/recipe-importer">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/recipe-importer-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/recipe-importer-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Recipe Importer</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Magyar receptoldalak importálása Mealie-be és Tandoor-ba</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~30M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/recipe-importer/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'recipe-importer')">Telepítés</a>
<a href="/apps/recipe-importer" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/romm">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/romm-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/romm-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>RomM</h3>
<a class="subdomain-link" href="https://jatek.enkisfelhom.hu" target="_blank">
jatek.enkisfelhom.hu ↗
</a>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
<span class="tag tag-ok" title="Ez az alkalmazás a legfrissebb elérhető változatot futtatja.">Naprakész</span>
</div>
<p class="stack-detail-desc">Retró játékgyűjtemény kezelő</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~300M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
<span class="metarow" title="Adattároló: NVME 1TB"><svg class="ico"><use href="#i-hard-drive"/></svg>NVME 1TB</span>
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">romm</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">romm-redis</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
<div class="container-row">
<span class="container-name">romm-db</span>
<span class="container-status state-text-run">Up 10 hours (healthy)</span>
</div>
</div>
<div class="stack-detail-actions">
<button class="btn btn-success" onclick="stackAction(event, 'romm', 'update')">Frissítés</button>
<button class="btn btn-warning" onclick="stackAction(event, 'romm', 'restart')">Újraindítás</button>
<button class="btn btn-danger" onclick="stackAction(event, 'romm', 'stop')">Leállítás</button>
<a href="/stacks/romm/logs" class="btn btn-outline">Naplók</a>
<a href="/apps/romm" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/sonarr">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/sonarr-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/sonarr-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Sonarr</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Automatikus sorozat letöltő és rendszerező</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~150M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/sonarr/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'sonarr')">Telepítés</a>
<a href="/apps/sonarr" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/sparkyfitness">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/sparkyfitness-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/sparkyfitness-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>SparkyFitness</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Táplálkozás- és edzéskövető</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~400M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/sparkyfitness/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'sparkyfitness')">Telepítés</a>
<a href="/apps/sparkyfitness" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/tandoor">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/tandoor-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/tandoor-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Tandoor Recipes</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Receptkezelő és étkezés tervező</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~512M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/tandoor/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'tandoor')">Telepítés</a>
<a href="/apps/tandoor" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/termix">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/termix-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/termix-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Termix</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Webes SSH és szerver menedzser</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~30M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/termix/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'termix')">Telepítés</a>
<a href="/apps/termix" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-run" data-filter-state="running" data-href="/apps/traefik">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/traefik-logo.svg" alt="" data-fallback="/static/infra-logo.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/traefik-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Traefik</h3>
</div>
</div>
<span class="tag tag-run"><span class="dot"></span>Fut</span>
</div>
<p class="stack-detail-desc">Forgalomirányító (reverse proxy) — a kéréseket a megfelelő alkalmazáshoz irányítja.</p>
<div class="metarows">
</div>
<div class="container-list">
<div class="container-row">
<span class="container-name">traefik</span>
<span class="container-status state-text-run">Up 2 weeks</span>
</div>
</div>
<div class="stack-detail-actions">
<span class="tag"><svg class="ico ico-sm"><use href="#i-lock"/></svg>Védett rendszerkomponens</span>
<button class="btn btn-warning" onclick="stackAction(event, 'traefik', 'restart')">Újraindítás</button>
<a href="/apps/traefik" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/uptime-kuma">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/uptime-kuma-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/uptime-kuma-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Uptime Kuma</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Szolgáltatás és weboldal monitoring</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~50M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/uptime-kuma/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'uptime-kuma')">Telepítés</a>
<a href="/apps/uptime-kuma" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/vaultwarden">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/vaultwarden-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/vaultwarden-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Vaultwarden</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Jelszókezelő (Bitwarden-kompatibilis)</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~50M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/vaultwarden/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'vaultwarden')">Telepítés</a>
<a href="/apps/vaultwarden" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/vikunja">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/vikunja-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/vikunja-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Vikunja</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Feladatkezelő listák és táblák (Todoist/Trello alternatíva)</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~50M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/vikunja/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'vikunja')">Telepítés</a>
<a href="/apps/vikunja" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/wanderer">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/wanderer-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/wanderer-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Wanderer</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Túra tervező és nyomkövetéssel</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~350M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/wanderer/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'wanderer')">Telepítés</a>
<a href="/apps/wanderer" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/wishlist">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/wishlist-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/wishlist-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Wishlist</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Családi kívánságlista megosztás</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~30M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/wishlist/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'wishlist')">Telepítés</a>
<a href="/apps/wishlist" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/zipline">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/zipline-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/zipline-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>Zipline</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">ShareX/Flameshot szerver - screenshot és fájlmegosztás</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/zipline/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'zipline')">Telepítés</a>
<a href="/apps/zipline" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/n8n">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/n8n-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/n8n-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>n8n</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Workflow automatizálás vizuális szerkesztővel</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~512M</span></span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/n8n/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'n8n')">Telepítés</a>
<a href="/apps/n8n" class="btn btn-outline">Részletek</a>
</div>
</div>
<div class="stack-detail-card stack-state-off" data-filter-state="available" data-href="/apps/wger">
<div class="stack-detail-header">
<div class="stack-title-row">
<img class="stack-logo-lg" src="/static/assets/wger-logo.svg" alt="" data-fallback="/static/app-placeholder.svg"
onerror="if(!this.dataset.step){this.dataset.step='1';this.src='\/static\/assets\/wger-logo.png';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
<div>
<h3>wger</h3>
</div>
</div>
<span class="tag tag-off"><span class="dot"></span>Nincs telepítve</span>
</div>
<p class="stack-detail-desc">Edzésnapló és fitnesz tervező</p>
<div class="metarows">
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~100M</span></span>
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
</div>
<div class="stack-detail-actions">
<a href="/stacks/wger/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, 'wger')">Telepítés</a>
<a href="/apps/wger" class="btn btn-outline">Részletek</a>
</div>
</div>
</div>
<script>
(function() {
var cards = document.querySelectorAll('.stack-detail-card[data-filter-state]');
var counts = {all: cards.length, running: 0, stopped: 0, available: 0};
cards.forEach(function(card) {
var cat = card.getAttribute('data-filter-state');
if (counts[cat] !== undefined) counts[cat]++;
});
['all', 'running', 'stopped', 'available'].forEach(function(f) {
var el = document.getElementById('count-' + f);
if (el) el.textContent = '(' + counts[f] + ')';
});
function applyFilter(filter) {
cards.forEach(function(card) {
if (filter === 'all' || card.getAttribute('data-filter-state') === filter) {
card.style.display = '';
} else {
card.style.display = 'none';
}
});
document.querySelectorAll('.filter-btn').forEach(function(btn) {
btn.classList.toggle('active', btn.getAttribute('data-filter') === filter);
});
var url = new URL(window.location);
if (filter === 'all') {
url.searchParams.delete('filter');
} else {
url.searchParams.set('filter', filter);
}
history.replaceState(null, '', url);
}
document.querySelectorAll('.filter-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
applyFilter(this.getAttribute('data-filter'));
});
});
var urlFilter = new URLSearchParams(window.location.search).get('filter');
if (urlFilter && ['running', 'stopped', 'available'].indexOf(urlFilter) !== -1) {
applyFilter(urlFilter);
}
})();
</script>
</main>
<script>
(function(){
var burger=document.querySelector('.nav-burger');
var sidebar=document.getElementById('sidebar');
var backdrop=document.querySelector('.nav-backdrop');
if(!burger||!sidebar||!backdrop)return;
function setOpen(open){
sidebar.classList.toggle('is-open',open);
document.body.classList.toggle('nav-open',open);
backdrop.hidden=!open;
burger.setAttribute('aria-expanded',open?'true':'false');
}
burger.addEventListener('click',function(){setOpen(!sidebar.classList.contains('is-open'));});
backdrop.addEventListener('click',function(){setOpen(false);});
document.addEventListener('keydown',function(e){
if(e.key==='Escape'&&sidebar.classList.contains('is-open'))setOpen(false);
});
})();
document.addEventListener('click', function(e) {
if (e.target.closest('a, button, .btn, input, select, textarea, .app-row-actions, .stack-detail-actions')) return;
var card = e.target.closest('[data-href]');
if (card) window.location.href = card.dataset.href;
});
async function checkBeforeDeploy(e, name) {
try {
var resp = await fetch('/api/stacks/' + name);
var data = await resp.json();
if (data.ok && data.data && data.data.deployed) {
e.preventDefault();
showAlert('Ez az alkalmazás már telepítve van.');
window.location.reload();
return false;
}
} catch(err) {}
return true;
}
async function syncTemplates() {
const btn = document.getElementById('sync-btn');
const toast = document.getElementById('sync-toast');
if (!btn) return;
const origText = btn.innerHTML;
btn.disabled = true;
btn.innerHTML = '↻ Frissítés...';
btn.classList.add('loading');
try {
const resp = await fetch('/api/sync', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/json'}, csrfHeaders())
});
const data = await resp.json();
if (toast) {
toast.textContent = data.ok ? (data.message || 'Sablonok frissítve') : ('Hiba: ' + (data.error || 'Ismeretlen hiba'));
toast.className = 'sync-toast ' + (data.ok ? 'sync-toast-ok' : 'sync-toast-err');
toast.style.display = 'block';
setTimeout(function() { toast.style.display = 'none'; }, 5000);
}
if (data.ok && data.data && (data.data.new_apps && data.data.new_apps.length > 0 || data.data.updated && data.data.updated.length > 0)) {
setTimeout(function() { window.location.reload(); }, 1500);
}
} catch (err) {
if (toast) {
toast.textContent = 'Hálózati hiba: ' + err.message;
toast.className = 'sync-toast sync-toast-err';
toast.style.display = 'block';
setTimeout(function() { toast.style.display = 'none'; }, 5000);
}
}
btn.innerHTML = origText;
btn.disabled = false;
btn.classList.remove('loading');
}
async function stackAction(event, name, action) {
const btn = event.currentTarget;
const origText = btn.textContent;
btn.disabled = true;
btn.textContent = 'Folyamatban...';
btn.classList.add('loading');
try {
const resp = await fetch('/api/stacks/' + name + '/' + action, {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/json'}, csrfHeaders())
});
const data = await resp.json();
if (!data.ok) {
showAlert('Hiba: ' + (data.error || 'Ismeretlen hiba'));
btn.textContent = origText;
btn.disabled = false;
btn.classList.remove('loading');
return;
}
if (action === 'update') {
followUpdate(name, btn);
return;
}
window.location.reload();
} catch (err) {
showAlert('Hálózati hiba: ' + err.message);
btn.textContent = origText;
btn.disabled = false;
btn.classList.remove('loading');
}
}
function followUpdate(name, btn) {
var started = Date.now();
var timer = setInterval(async function() {
if (Date.now() - started > 30 * 60 * 1000) { clearInterval(timer); window.location.reload(); return; }
try {
var r = await fetch('/api/stacks/' + name);
var d = await r.json();
if (!d.ok || !d.data) return;
if (d.data.update_phase_label) btn.textContent = d.data.update_phase_label;
if (!d.data.updating) { clearInterval(timer); window.location.reload(); }
} catch (e) {}
}, 3000);
}
async function deleteOrphanStack(name) {
var modal = document.createElement('div');
modal.className = 'modal-overlay';
modal.id = 'delete-modal';
modal.innerHTML = '<div class="modal-card"><h3>Betöltés...</h3></div>';
modal.addEventListener('click', function(e) { if (e.target === modal) closeDeleteModal(); });
document.body.appendChild(modal);
try {
var resp = await fetch('/api/stacks/' + name + '/hdd-data');
var data = await resp.json();
var hddInfo = '';
var checkboxHTML = '';
if (data.ok && data.data && data.data.has_hdd_data) {
hddInfo = '<div class="modal-hdd-info"><strong>Felhasználói adatok a merevlemezen:</strong>';
data.data.hdd_paths.forEach(function(p) {
hddInfo += '<div class="modal-hdd-path">' + p.path + ' (' + (p.exists ? p.size_human : 'nem létezik') + ')</div>';
});
hddInfo += '</div>';
checkboxHTML = '<label class="modal-checkbox"><input type="checkbox" id="delete-hdd-check"> Felhasználói adatok törlése a merevlemezről</label>';
}
modal.querySelector('.modal-card').innerHTML =
'<h3>Alkalmazás törlése: ' + name + '</h3>' +
'<p style="color:var(--text-2);font-size:.9rem;margin-bottom:.75rem">Ez a művelet eltávolítja a konténereket, a köteteket és a konfigurációs fájlokat.</p>' +
'<div class="alert alert-warning" style="margin-bottom:.75rem">Ez a művelet nem visszavonható!</div>' +
hddInfo + checkboxHTML +
'<div class="modal-actions">' +
'<button class="btn btn-outline" onclick="closeDeleteModal()">Mégsem</button>' +
'<button class="btn btn-danger" id="confirm-delete-btn" onclick="confirmDelete(\'' + name + '\')">Törlés</button>' +
'</div>';
} catch (err) {
modal.querySelector('.modal-card').innerHTML =
'<h3>Hiba</h3><p style="color:var(--text-2)">Nem sikerült lekérni az adatokat: ' + err.message + '</p>' +
'<div class="modal-actions"><button class="btn btn-outline" onclick="closeDeleteModal()">Bezárás</button></div>';
}
}
function closeDeleteModal() {
var modal = document.getElementById('delete-modal');
if (modal) modal.remove();
}
async function confirmDelete(name) {
var btn = document.getElementById('confirm-delete-btn');
var checkbox = document.getElementById('delete-hdd-check');
var removeHDD = checkbox ? checkbox.checked : false;
btn.disabled = true;
btn.textContent = 'Törlés folyamatban...';
try {
var resp = await fetch('/api/stacks/' + name, {
method: 'DELETE',
headers: Object.assign({'Content-Type': 'application/json'}, csrfHeaders()),
body: JSON.stringify({remove_hdd_data: removeHDD})
});
var data = await resp.json();
if (data.ok) {
var modal = document.getElementById('delete-modal');
var removedInfo = '';
if (data.data && data.data.hdd_paths_removed && data.data.hdd_paths_removed.length > 0) {
removedInfo = '<p style="color:var(--text-2);font-size:.85rem;margin-top:.5rem">Törölt adatok: ' + data.data.hdd_paths_removed.join(', ') + '</p>';
}
var preservedInfo = '';
if (data.data && data.data.hdd_paths_preserved && data.data.hdd_paths_preserved.length > 0) {
preservedInfo = '<p style="color:var(--text-2);font-size:.85rem;margin-top:.5rem">Megőrzött adatok: ' + data.data.hdd_paths_preserved.join(', ') + '</p>';
}
if (data.data && data.data.hdd_note) {
preservedInfo += '<p style="color:var(--text-2);font-size:.85rem;margin-top:.5rem">' + data.data.hdd_note + '</p>';
}
modal.querySelector('.modal-card').innerHTML =
'<h3>Sikeresen törölve!</h3>' +
'<p style="color:var(--text-2)">Az alkalmazás (' + name + ') törölve lett.</p>' +
removedInfo + preservedInfo +
'<div class="modal-actions"><button class="btn btn-primary" onclick="window.location.href=\'/stacks\'">Bezárás</button></div>';
} else {
showAlert('Hiba: ' + (data.error || 'Ismeretlen hiba'));
btn.disabled = false;
btn.textContent = 'Törlés';
}
} catch (err) {
showAlert('Hálózati hiba: ' + err.message);
btn.disabled = false;
btn.textContent = 'Törlés';
}
}
async function removeStack(name) {
var modal = document.createElement('div');
modal.className = 'modal-overlay';
modal.id = 'remove-modal';
modal.innerHTML = '<div class="modal-card"><h3>Betöltés...</h3></div>';
modal.addEventListener('click', function(e) { if (e.target === modal) closeRemoveModal(); });
document.body.appendChild(modal);
try {
var [hddResp, backupResp] = await Promise.all([
fetch('/api/stacks/' + name + '/hdd-data').then(function(r) { return r.json(); }),
fetch('/api/stacks/' + name + '/backup-data').then(function(r) { return r.json(); })
]);
var sections = '';
sections += '<div class="modal-section">' +
'<strong>Mindig törlődik:</strong>' +
'<ul style="margin:.25rem 0;padding-left:1.2rem;color:var(--text-2);font-size:.85rem">' +
'<li>Docker kötetek (adatbázis, alkalmazás konfiguráció)</li>' +
'<li>Telepítési konfiguráció (app.yaml)</li>' +
'<li>Másodlagos mentés ütemezése</li>' +
'</ul></div>';
var hddCheckbox = '';
if (hddResp.ok && hddResp.data && hddResp.data.has_hdd_data) {
var hddPaths = '';
hddResp.data.hdd_paths.forEach(function(p) {
hddPaths += '<div class="modal-hdd-path">' + p.path + ' (' + (p.exists ? p.size_human : 'nem létezik') + ')</div>';
});
sections += '<div class="modal-section">' +
'<strong>Felhasználói adatok a merevlemezen:</strong>' + hddPaths +
'<label class="modal-checkbox"><input type="checkbox" id="remove-hdd-check"> Felhasználói adatok törlése</label>' +
'<div class="alert alert-info" style="margin-top:.5rem;font-size:.8rem" id="remove-hdd-keep-warning">' +
'Ha újratelepíti az alkalmazást, az adatokat újra importálnia kell, mivel az adatbázis törlődik. A megtartott adatok a továbbiakban NEM lesznek automatikusan mentve.' +
'</div></div>';
hddCheckbox = '\x3Cscript>document.getElementById("remove-hdd-check").addEventListener("change",function(){document.getElementById("remove-hdd-keep-warning").style.display=this.checked?"none":"";});<\/script>';
}
var backupCheckbox = '';
if (backupResp.ok && backupResp.data && backupResp.data.has_backups) {
var bkPaths = '';
backupResp.data.backup_paths.forEach(function(p) {
if (p.exists) bkPaths += '<div class="modal-hdd-path">' + p.path + ' (' + p.size_human + ')</div>';
});
if (bkPaths) {
sections += '<div class="modal-section">' +
'<strong>Mentési adatok:</strong>' + bkPaths +
'<label class="modal-checkbox"><input type="checkbox" id="remove-backup-check"> Mentési adatok törlése</label>' +
'<div class="alert alert-info" style="margin-top:.5rem;font-size:.8rem">' +
'Az éjszakai restic pillanatképek nem törölhetők egyenként — a megőrzési szabályok szerint automatikusan elavulnak.' +
'</div></div>';
}
}
modal.querySelector('.modal-card').innerHTML =
'<h3>Alkalmazás eltávolítása: ' + name + '</h3>' +
'<p style="color:var(--text-2);font-size:.9rem;margin-bottom:.75rem">Az alkalmazás visszaáll "Nincs telepítve" állapotba. A sablon megmarad, újratelepíthető.</p>' +
'<div class="alert alert-warning" style="margin-bottom:.75rem">Ez a művelet nem visszavonható!</div>' +
sections +
'<div class="modal-actions">' +
'<button class="btn btn-outline" onclick="closeRemoveModal()">Mégsem</button>' +
'<button class="btn btn-danger" id="confirm-remove-btn" onclick="confirmRemoveStack(\'' + name + '\')">Eltávolítás</button>' +
'</div>' + hddCheckbox;
} catch (err) {
modal.querySelector('.modal-card').innerHTML =
'<h3>Hiba</h3><p style="color:var(--text-2)">Nem sikerült lekérni az adatokat: ' + err.message + '</p>' +
'<div class="modal-actions"><button class="btn btn-outline" onclick="closeRemoveModal()">Bezárás</button></div>';
}
}
function closeRemoveModal() {
var modal = document.getElementById('remove-modal');
if (modal) modal.remove();
}
async function confirmRemoveStack(name) {
var btn = document.getElementById('confirm-remove-btn');
var hddCheck = document.getElementById('remove-hdd-check');
var backupCheck = document.getElementById('remove-backup-check');
var removeHDD = hddCheck ? hddCheck.checked : false;
var removeBackups = backupCheck ? backupCheck.checked : false;
btn.disabled = true;
btn.textContent = 'Eltávolítás folyamatban...';
try {
var resp = await fetch('/api/stacks/' + name + '/remove', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/json'}, csrfHeaders()),
body: JSON.stringify({remove_hdd_data: removeHDD, remove_backups: removeBackups})
});
var data = await resp.json();
if (data.ok) {
var modal = document.getElementById('remove-modal');
var removedInfo = '';
if (data.data && data.data.hdd_paths_removed && data.data.hdd_paths_removed.length > 0) {
removedInfo += '<p style="color:var(--text-2);font-size:.85rem;margin-top:.5rem">Törölt adatok: ' + data.data.hdd_paths_removed.join(', ') + '</p>';
}
if (data.data && data.data.backup_paths_removed && data.data.backup_paths_removed.length > 0) {
removedInfo += '<p style="color:var(--text-2);font-size:.85rem;margin-top:.5rem">Törölt mentések: ' + data.data.backup_paths_removed.join(', ') + '</p>';
}
var preservedInfo = '';
if (data.data && data.data.hdd_paths_preserved && data.data.hdd_paths_preserved.length > 0) {
preservedInfo = '<p style="color:var(--text-2);font-size:.85rem;margin-top:.5rem">Megőrzött adatok: ' + data.data.hdd_paths_preserved.join(', ') + '</p>';
}
if (data.data && data.data.hdd_note) {
preservedInfo += '<p style="color:var(--text-2);font-size:.85rem;margin-top:.5rem">' + data.data.hdd_note + '</p>';
}
if (data.data && data.data.backup_paths_refused && data.data.backup_paths_refused.length > 0) {
preservedInfo += '<p style="color:var(--text-2);font-size:.85rem;margin-top:.5rem">Nem törölt mentések: ' + data.data.backup_paths_refused.join('; ') + '</p>';
}
modal.querySelector('.modal-card').innerHTML =
'<h3>Sikeresen eltávolítva!</h3>' +
'<p style="color:var(--text-2)">Az alkalmazás (' + name + ') eltávolítva. Újratelepíthető a Telepítés gombbal.</p>' +
removedInfo + preservedInfo +
'<div class="modal-actions"><button class="btn btn-primary" onclick="window.location.href=\'/stacks\'">Bezárás</button></div>';
} else {
showAlert('Hiba: ' + (data.error || 'Ismeretlen hiba'));
btn.disabled = false;
btn.textContent = 'Eltávolítás';
}
} catch (err) {
showAlert('Hálózati hiba: ' + err.message);
btn.disabled = false;
btn.textContent = 'Eltávolítás';
}
}
</script>
</body>
</html>