homepage: app-card art, zealot-first order, common uncensored warning, admin identity gate
- Every app card carries hex-clipped art: 19 amber-tinted brand marks from the Simple Icons CDN plus 19 improvised monogram SVGs, wired via a per-service "art" field; homepage_config.bats pins art presence for all 32 apps. - Model cards render zealot -> dragoon -> archon (registry order pinned in the seam). - Dragoon and zealot share one common uncensored legal warning (adult content, harmful/hateful/illegal descriptions, sensitive offensive cybersecurity topics, severe legal risk, "don't ruin this server for everybody"), hover label on card and docs. - Archon gets a bordered red permission callout: ask Frank before use. - SearXNG obfuscation-not-anonymity note moved to a card-level hover warning (.svc-warn) and a docs hover note. - Gitea: self-service signup flow; no need to ask Frank. - Footer docs/admin/account-settings become glowing bordered buttons; the admin button is shown only to homepage-admins members via a new Caddy /whoami endpoint echoing the outpost-injected X-Authentik-* headers (spoof-proof; the /admin* 403 stays the real gate). e2e pins both sides. - Docs naming swept: Protoss names primary, bracketed api ids, explicit note that a future switchover renames the ids themselves.
@@ -337,6 +337,15 @@ http://:8017 {
|
||||
try_files /docs.html
|
||||
file_server
|
||||
}
|
||||
# /whoami echoes the outpost-injected identity headers so the page
|
||||
# can gate the admin button client-side (the /admin* 403 above stays
|
||||
# the real gate; this only decides what is shown). The outpost strips
|
||||
# client-supplied X-Authentik-* before injecting, so this is spoof-proof.
|
||||
handle /whoami {
|
||||
templates
|
||||
header Content-Type application/json
|
||||
respond "{\"user\":\"{header.X-Authentik-Username}\",\"groups\":\"{header.X-Authentik-Groups}\"}"
|
||||
}
|
||||
@data path /services.json /status.json /app.js /style.css /deployed.js /img/* /sfx/*
|
||||
handle @data {
|
||||
file_server
|
||||
|
||||
@@ -87,6 +87,34 @@ from the dankcloud SSO; SearXNG is obfuscated, not anonymous (upstream
|
||||
API keys tie to Frank). The user docs `/docs#models` section carries the
|
||||
same renames, api-id mapping, supervision and compaction notes.
|
||||
|
||||
**Icons, card polish, admin identity gate (2026-10-08, later wave):** every
|
||||
app card now carries hex-clipped art beside its name (`services.json` `art`
|
||||
field, files under `img/apps/`): 19 brand marks tinted amber from the
|
||||
Simple Icons CDN plus 19 hand-improvised monogram SVGs (amber hex + VT323
|
||||
initials) for apps with no mark — Copyparty, Marreta, Hermes (+dashboard),
|
||||
node-exporter, Gluetun, OpenWebUI, Calibre-Web, RomM, Seerr, Loki, Alloy,
|
||||
Alertmanager, Valkey, Prowlarr, Readarr, Lidarr, Tautulli, ComfyUI. Model
|
||||
cards render in the order zealot → dragoon → archon (registry order is the
|
||||
contract; `homepage_config.bats` pins it). Dragoon and zealot share one
|
||||
common uncensored legal warning (adult content, harmful/hateful/illegal
|
||||
descriptions, "sensitive offensive cybersecurity topics", severe legal
|
||||
risk, "don't ruin this server for everybody"), rendered as the hover
|
||||
label; archon's ask-Frank rule is a bordered red `.mi-perm` callout.
|
||||
SearXNG's obfuscation-not-anonymity note moved out of its description into
|
||||
a card-level `warn` (`.svc-warn` hover label) and the same hover treatment
|
||||
in the docs. Gitea's note now documents self-service signup — no need to
|
||||
ask Frank. Footer: docs / admin / account settings are bordered glowing
|
||||
`.foot-btn` buttons; **the admin button is identity-gated** — Caddy's
|
||||
`/whoami` echoes the outpost-injected `X-Authentik-Username`/`X-Authentik-Groups`
|
||||
headers (the outpost strips client-supplied copies, so the echo is
|
||||
spoof-proof), and `app.js` shows the button only to `homepage-admins`
|
||||
members. The `/admin*` 403 stays the real gate; the e2e specs pin both
|
||||
sides (standard user: hidden + 403; admin: visible). Docs were swept for
|
||||
naming consistency: Protoss names primary everywhere, bracketed api ids
|
||||
at the model headings, and a note that a future switchover renames the
|
||||
ids themselves (OpenWebUI picker + raw API + models.yml all move together
|
||||
— not done yet).
|
||||
|
||||
## Design decision — 2026-08-22
|
||||
|
||||
The live up/down check runs server-side. A checker on Dankclaw probes each backend and writes a same-origin `status.json`. The page fetches only that file and renders the badges. The browser never calls a backend directly. The checker runs as a systemd timer every 3 minutes.
|
||||
@@ -182,7 +210,9 @@ shared/homepage/
|
||||
├── style.css # full theme; a toggle strips to bare HTML
|
||||
├── app.js # loads status.json once, renders the panels
|
||||
├── services.json # service config (user + admin)
|
||||
├── img/ # screenshots served at /img (docs page; deployed with the page)
|
||||
├── img/ # served at /img: docs screenshots, unit portraits
|
||||
│ ├── apps/ # (unit-*.jpg) and app card icons (apps/*.svg)
|
||||
├── sfx/ # StarCraft unit voice .ogg files served at /sfx
|
||||
└── fonts/ # optional self-hosted fonts (deployed with the page; VT323 comes from the Google Fonts CDN, this dir is absent)
|
||||
```
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<main id="grid" class="sections"></main>
|
||||
<footer class="foot">
|
||||
<span>last master deployment: <span id="deployed-at"></span></span>
|
||||
<a href="/">home</a>
|
||||
<a class="foot-btn" href="/">home</a>
|
||||
</footer>
|
||||
<script src="deployed.js"></script>
|
||||
<script src="app.js"></script>
|
||||
|
||||
@@ -92,6 +92,7 @@ function miCard(svc, state) {
|
||||
if (m.use) parts.push('<div class="mi-use">Use: ' + esc(m.use) + '</div>');
|
||||
if (m.voice) parts.push(voiceBtn(m.voice.text, m.voice.sfx));
|
||||
if (m.supervision) parts.push('<div class="mi-super">' + esc(m.supervision) + '</div>');
|
||||
if (m.permission) parts.push('<div class="mi-perm" title="' + esc(m.permission) + '">⚠ ' + esc(m.permission) + '</div>');
|
||||
if (m.warn) parts.push('<div class="mi-warn" title="' + esc(m.warn) + '">' +
|
||||
'⚠ ' + esc(m.warn.split(':')[0]) + ' \u2014 hover to read</div>');
|
||||
const card = document.createElement('article');
|
||||
@@ -125,12 +126,16 @@ function renderPanel(svc, state) {
|
||||
const links = [];
|
||||
if (svc.showLink && svc.url) links.push('<a class="open" href="' + esc(svc.url) + '">open</a>');
|
||||
if (svc.docs) links.push('<a class="docs" href="' + esc(svc.docs) + '">docs</a>');
|
||||
const art = svc.art ? '<img class="app-art" src="' + esc(svc.art) + '" alt="">' : '';
|
||||
const warn = svc.warn
|
||||
? '<div class="svc-warn" title="' + esc(svc.warn) + '">⚠ privacy note \u2014 hover to read</div>'
|
||||
: '';
|
||||
panel.innerHTML =
|
||||
'<div class="panel-head">' +
|
||||
'<div class="panel-head">' + art +
|
||||
' <span class="badge ' + state + '">' + BADGE_LABEL[state] + '</span>' +
|
||||
' <span class="name">' + esc(svc.name) + '</span>' +
|
||||
'</div>' +
|
||||
'<div class="desc">' + descHTML(svc) + '</div>' +
|
||||
'<div class="desc">' + descHTML(svc) + '</div>' + warn +
|
||||
'<div class="links">' + links.join('') + '</div>';
|
||||
return panel;
|
||||
}
|
||||
@@ -197,9 +202,24 @@ function fillDeployed() {
|
||||
if (el && window.DEPLOYED_AT) el.textContent = window.DEPLOYED_AT;
|
||||
}
|
||||
|
||||
// Show the admin button only to members of the authentik homepage-admins
|
||||
// group (the same group the /admin* server gate enforces). The data comes
|
||||
// from Caddy's /whoami, which echoes the outpost-injected identity headers.
|
||||
function gateAdminLink() {
|
||||
const link = document.getElementById('admin-link');
|
||||
if (!link) return;
|
||||
fetch('/whoami', { headers: { accept: 'application/json' } })
|
||||
.then(function (r) { return r.ok ? r.json() : null; })
|
||||
.then(function (me) {
|
||||
if (me && /homepage-admins/i.test(me.groups || '')) link.hidden = false;
|
||||
})
|
||||
.catch(function () {});
|
||||
}
|
||||
|
||||
function main() {
|
||||
applyBare();
|
||||
fillDeployed();
|
||||
gateAdminLink();
|
||||
Promise.all([load('services.json'), load('status.json')])
|
||||
.then(function (pair) { renderPanels(pair[0], pair[1]); })
|
||||
.catch(function (e) {
|
||||
|
||||
@@ -55,26 +55,9 @@
|
||||
The homepage "Model Information" panel shows whether each one is up right now —
|
||||
and plays the unit's voice if you click its quoted line.</p>
|
||||
|
||||
<h2>frank-dragoon — deep reasoning <em>(api id: frank-large)</em></h2>
|
||||
<ul>
|
||||
<li><strong>Model:</strong> Qwen3.8-Flash-Next v2 Swift1.5 abliterated (halogen flash-server, ~62 GiB) on the Strix Halo iGPU — an abliterated (censorship-removed) edition that thinks before answering.</li>
|
||||
<li><strong>Equivalent:</strong> Claude Sonnet 5 / OpenAI-Luna (Summer 2026 frontier intelligence).</li>
|
||||
<li><strong>Capacity:</strong> 200k-token context, two submissions at a time; sees images.</li>
|
||||
<li><strong>Inputs:</strong> text, image.</li>
|
||||
<li><strong>Best for:</strong> complex agentic tasks, programming, system administration, and "claw"-style personal agents.</li>
|
||||
<li><strong>Supervision:</strong> safe for autonomous, low-supervision use.</li>
|
||||
<li><strong>Warning:</strong> <span class="key-warn" title="Abliterated output can include adult themes. You are responsible for the legal consequences of how you use it.">⚠ legal note — hover to read</span></li>
|
||||
</ul>
|
||||
|
||||
<h2>frank-archon — the big one <em>(api id: frank-primary)</em></h2>
|
||||
<ul>
|
||||
<li><strong>Model:</strong> Qwen3.8-Flash-Next at native FP8 precision (radiance, 173 GiB) on twin AMD R9700s with more than 200 GB of system RAM — the biggest brain on the network and the fastest runtime.</li>
|
||||
<li><strong>Equivalent:</strong> Claude Opus 4.8 / OpenAI-Terra (Summer 2026 frontier intelligence).</li>
|
||||
<li><strong>Capacity:</strong> 200k-token context, two submissions at a time; sees images.</li>
|
||||
<li><strong>Inputs:</strong> text, image.</li>
|
||||
<li><strong>Best for:</strong> software engineering, system administration, and instruction tasks. <em>Please ask Frank before use — he uses this one primarily.</em></li>
|
||||
<li><strong>Supervision:</strong> safe for autonomous, low-supervision use.</li>
|
||||
</ul>
|
||||
<p class="foot-note">Naming: the Open WebUI picker and the raw API show the
|
||||
endpoint <em>api ids</em> in brackets below. The Protoss names are the family
|
||||
names; a future switchover will rename the ids to match.</p>
|
||||
|
||||
<h2>frank-zealot — the fast utility model <em>(api id: frank-secondary)</em></h2>
|
||||
<ul>
|
||||
@@ -85,15 +68,34 @@
|
||||
<li><strong>Best for:</strong> code editor autocomplete, agentic search, RAG, research subagents, translation, roleplay, and summarization — any small task that doesn't need much intelligence, and anything with a picture. This is the model Open WebUI offers to family accounts.</li>
|
||||
<li><strong>Compaction:</strong> if your agent harness supports setting a compaction model, set this one. A compaction job severely slows the bigger models for far longer than it slows this one.</li>
|
||||
<li><strong>Supervision:</strong> requires tight human supervision.</li>
|
||||
<li><strong>Warning:</strong> <span class="key-warn" title="Uncensored model — output can include adult content. You are responsible for the legal consequences of how you use it.">⚠ legal note — hover to read</span></li>
|
||||
<li><strong>Warning:</strong> <span class="key-warn" title="Uncensored model: output can include adult content, content that describes harmful, hateful, or illegal acts, content concerning “sensitive offensive cybersecurity topics”, and other output that may carry severe legal risk. Take this warning seriously — don’t ruin this server for everybody.">⚠ Uncensored model — hover to read</span></li>
|
||||
</ul>
|
||||
|
||||
<h2>frank-dragoon — deep reasoning <em>(api id: frank-large)</em></h2>
|
||||
<ul>
|
||||
<li><strong>Model:</strong> Qwen3.8-Flash-Next v2 Swift1.5 abliterated (halogen flash-server, ~62 GiB) on the Strix Halo iGPU — an abliterated (censorship-removed) edition that thinks before answering.</li>
|
||||
<li><strong>Equivalent:</strong> Claude Sonnet 5 / OpenAI-Luna (Summer 2026 frontier intelligence).</li>
|
||||
<li><strong>Capacity:</strong> 200k-token context, two submissions at a time; sees images.</li>
|
||||
<li><strong>Inputs:</strong> text, image.</li>
|
||||
<li><strong>Best for:</strong> complex agentic tasks, programming, system administration, and "claw"-style personal agents.</li>
|
||||
<li><strong>Supervision:</strong> safe for autonomous, low-supervision use.</li>
|
||||
<li><strong>Warning:</strong> <span class="key-warn" title="Uncensored model: output can include adult content, content that describes harmful, hateful, or illegal acts, content concerning “sensitive offensive cybersecurity topics”, and other output that may carry severe legal risk. Take this warning seriously — don’t ruin this server for everybody.">⚠ Uncensored model — hover to read</span></li>
|
||||
|
||||
<h2>frank-archon — the big one <em>(api id: frank-primary)</em></h2>
|
||||
<ul>
|
||||
<li><strong>Model:</strong> Qwen3.8-Flash-Next at native FP8 precision (radiance, 173 GiB) on twin AMD R9700s with more than 200 GB of system RAM — the biggest brain on the network and the fastest runtime.</li>
|
||||
<li><strong>Equivalent:</strong> Claude Opus 4.8 / OpenAI-Terra (Summer 2026 frontier intelligence).</li>
|
||||
<li><strong>Capacity:</strong> 200k-token context, two submissions at a time; sees images.</li>
|
||||
<li><strong>Inputs:</strong> text, image.</li>
|
||||
<li><strong>Best for:</strong> software engineering, system administration, and instruction tasks. <strong>⚠ Ask Frank for permission before use</strong> — this is his primary model; he uses it more than anything else on the fleet.</li>
|
||||
</ul>
|
||||
|
||||
<p class="foot-note">Which one to pick? Small utility work, autocomplete, RAG,
|
||||
search, and screenshots: <code>frank-zealot</code>. Complex agentic work,
|
||||
programming, and personal agents: <code>frank-dragoon</code>. Software
|
||||
engineering, sysadmin, and instruction tasks: <code>frank-archon</code> (ask
|
||||
Frank first). The names in brackets are the ids the API and Open WebUI
|
||||
use; the family names are the Protoss ones.</p>
|
||||
Frank first). The ids in brackets are what the Open WebUI picker and the
|
||||
raw API show today; the Protoss names are the family names, and the switchover
|
||||
will rename the ids to match.</p>
|
||||
</section>
|
||||
|
||||
<section id="api-access">
|
||||
@@ -182,7 +184,7 @@
|
||||
<li><strong>Books:</strong> <a href="https://books.franksdank.cloud">Calibre-Web</a> — the e-book library, with its own login.</li>
|
||||
<li><strong>Games:</strong> <a href="https://romm.franksdank.cloud">RomM</a> — ROM library and emulator collection.</li>
|
||||
<li><strong>Raw files:</strong> <a href="https://files.franksdank.cloud">Copyparty</a> — direct downloads and shares.</li>
|
||||
<li><strong>Search:</strong> <a href="https://search.franksdank.cloud">SearXNG</a> — metasearch, VPN-routed, no AI snoop.</li>
|
||||
<li><strong>Search:</strong> <a href="https://search.franksdank.cloud">SearXNG</a> — metasearch, VPN-routed, no AI snoop. <span class="key-warn" title="Searches are obfuscated, not anonymous: SearXNG hides you from the upstream engines and the VPN tunnel hides the traffic from the LAN — but the upstream search API keys are tied to Frank’s identity. Don’t treat it as Tor.">⚠ privacy note — hover to read</span></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Caddy</title><path d="M11.094.47c-.842 0-1.696.092-2.552.288a11.37 11.37 0 0 0-4.87 2.423 10.632 10.632 0 0 0-2.36 2.826A10.132 10.132 0 0 0 .305 8.582c-.398 1.62-.4 3.336-.043 5.048.085.405.183.809.31 1.212a11.85 11.85 0 0 0 1.662 3.729 3.273 3.273 0 0 0-.086.427 3.323 3.323 0 0 0 2.848 3.71 3.279 3.279 0 0 0 1.947-.346c1.045.51 2.17.864 3.339 1.04a11.66 11.66 0 0 0 4.285-.155 11.566 11.566 0 0 0 4.936-2.485 10.643 10.643 0 0 0 2.352-2.894 11.164 11.164 0 0 0 1.356-4.424 11.214 11.214 0 0 0-.498-4.335c.175-.077.338-.175.486-.293a.444.444 89.992 0 0 .001 0c.402-.322.693-.794.777-1.342a2.146 2.146 0 0 0-1.79-2.434 2.115 2.115 0 0 0-1.205.171c-.038-.043-.078-.086-.113-.13a11.693 11.693 0 0 0-3.476-2.93 13.348 13.348 0 0 0-1.76-.81 13.55 13.55 0 0 0-2.06-.613A12.121 12.121 0 0 0 11.093.47Zm.714.328c.345-.004.688.01 1.028.042a9.892 9.892 0 0 1 2.743.639c.984.39 1.89.958 2.707 1.632.803.662 1.502 1.45 2.091 2.328.026.039.048.08.07.12a2.12 2.12 0 0 0-.435 2.646c-.158.114-.97.692-1.634 1.183-.414.308-.733.557-.733.557l.581.68s.296-.276.665-.638c.572-.562 1.229-1.233 1.395-1.403a2.122 2.122 0 0 0 1.907.677 11.229 11.229 0 0 1-.013 4.046 11.41 11.41 0 0 1-1.475 3.897 12.343 12.343 0 0 1-2.079 2.587c-1.19 1.125-2.633 2.022-4.306 2.531a10.826 10.826 0 0 1-3.973.484 11.04 11.04 0 0 1-3.057-.652 3.304 3.304 0 0 0 1.417-2.294 3.275 3.275 0 0 0-.294-1.842c.18-.162.403-.363.656-.6 1.015-.955 2.353-2.303 2.353-2.303l-.47-.599s-1.63.972-2.801 1.728c-.307.198-.573.378-.777.517a3.273 3.273 0 0 0-1.516-.611c-1.507-.198-2.927.672-3.487 2.017a10.323 10.323 0 0 1-.695-1.078A10.92 10.92 0 0 1 .728 14.8a10.35 10.35 0 0 1-.2-1.212c-.164-1.653.103-3.258.629-4.754a12.95 12.95 0 0 1 1.087-2.288c.57-.968 1.248-1.872 2.069-2.656A11.013 11.013 0 0 1 11.808.797Zm-.147 3.257a3.838 3.838 0 0 0-3.82 3.82v2.36h-.94c-.751 0-1.377.625-1.377 1.377v3.8h1.46v-3.718h9.354v6.264H10.02v1.46h6.4c.751 0 1.377-.625 1.377-1.377v-6.43c0-.751-.626-1.377-1.377-1.377h-.94v-2.36a3.838 3.838 0 0 0-3.82-3.819zm0 1.46a2.371 2.371 0 0 1 2.36 2.36v2.36H9.3v-2.36a2.372 2.372 0 0 1 2.36-2.36zm10.141.392a1.253 1.253 0 0 1 1.296 1.434c-.049.319-.217.59-.453.78-.266.213-.61.318-.968.264a1.253 1.253 0 0 1-1.045-1.42 1.255 1.255 0 0 1 1.17-1.058zM5.384 17.425a2.02 2.02 0 0 1 1.917 1.298c.116.3.159.628.114.967a2.015 2.015 0 0 1-2.249 1.728 2.016 2.016 0 0 1-1.727-2.25 2.017 2.017 0 0 1 1.945-1.743z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Gitea</title><path d="M4.209 4.603c-.247 0-.525.02-.84.088-.333.07-1.28.283-2.054 1.027C-.403 7.25.035 9.685.089 10.052c.065.446.263 1.687 1.21 2.768 1.749 2.141 5.513 2.092 5.513 2.092s.462 1.103 1.168 2.119c.955 1.263 1.936 2.248 2.89 2.367 2.406 0 7.212-.004 7.212-.004s.458.004 1.08-.394c.535-.324 1.013-.893 1.013-.893s.492-.527 1.18-1.73c.21-.37.385-.729.538-1.068 0 0 2.107-4.471 2.107-8.823-.042-1.318-.367-1.55-.443-1.627-.156-.156-.366-.153-.366-.153s-4.475.252-6.792.306c-.508.011-1.012.023-1.512.027v4.474l-.634-.301c0-1.39-.004-4.17-.004-4.17-1.107.016-3.405-.084-3.405-.084s-5.399-.27-5.987-.324c-.187-.011-.401-.032-.648-.032zm.354 1.832h.111s.271 2.269.6 3.597C5.549 11.147 6.22 13 6.22 13s-.996-.119-1.641-.348c-.99-.324-1.409-.714-1.409-.714s-.73-.511-1.096-1.52C1.444 8.73 2.021 7.7 2.021 7.7s.32-.859 1.47-1.145c.395-.106.863-.12 1.072-.12zm8.33 2.554c.26.003.509.127.509.127l.868.422-.529 1.075a.686.686 0 0 0-.614.359.685.685 0 0 0 .072.756l-.939 1.924a.69.69 0 0 0-.66.527.687.687 0 0 0 .347.763.686.686 0 0 0 .867-.206.688.688 0 0 0-.069-.882l.916-1.874a.667.667 0 0 0 .237-.02.657.657 0 0 0 .271-.137 8.826 8.826 0 0 1 1.016.512.761.761 0 0 1 .286.282c.073.21-.073.569-.073.569-.087.29-.702 1.55-.702 1.55a.692.692 0 0 0-.676.477.681.681 0 1 0 1.157-.252c.073-.141.141-.282.214-.431.19-.397.515-1.16.515-1.16.035-.066.218-.394.103-.814-.095-.435-.48-.638-.48-.638-.467-.301-1.116-.58-1.116-.58s0-.156-.042-.27a.688.688 0 0 0-.148-.241l.516-1.062 2.89 1.401s.48.218.583.619c.073.282-.019.534-.069.657-.24.587-2.1 4.317-2.1 4.317s-.232.554-.748.588a1.065 1.065 0 0 1-.393-.045l-.202-.08-4.31-2.1s-.417-.218-.49-.596c-.083-.31.104-.691.104-.691l2.073-4.272s.183-.37.466-.497a.855.855 0 0 1 .35-.077z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Grafana</title><path d="M23.02 10.59a8.578 8.578 0 0 0-.862-3.034 8.911 8.911 0 0 0-1.789-2.445c.337-1.342-.413-2.505-.413-2.505-1.292-.08-2.113.4-2.416.62-.052-.02-.102-.044-.154-.064-.22-.089-.446-.172-.677-.247-.231-.073-.47-.14-.711-.197a9.867 9.867 0 0 0-.875-.161C14.557.753 12.94 0 12.94 0c-1.804 1.145-2.147 2.744-2.147 2.744l-.018.093c-.098.029-.2.057-.298.088-.138.042-.275.094-.413.143-.138.055-.275.107-.41.166a8.869 8.869 0 0 0-1.557.87l-.063-.029c-2.497-.955-4.716.195-4.716.195-.203 2.658.996 4.33 1.235 4.636a11.608 11.608 0 0 0-.607 2.635C1.636 12.677.953 15.014.953 15.014c1.926 2.214 4.171 2.351 4.171 2.351.003-.002.006-.002.006-.005.285.509.615.994.986 1.446.156.19.32.371.488.548-.704 2.009.099 3.68.099 3.68 2.144.08 3.553-.937 3.849-1.173a9.784 9.784 0 0 0 3.164.501h.08l.055-.003.107-.002.103-.005.003.002c1.01 1.44 2.788 1.646 2.788 1.646 1.264-1.332 1.337-2.653 1.337-2.94v-.058c0-.02-.003-.039-.003-.06.265-.187.52-.387.758-.6a7.875 7.875 0 0 0 1.415-1.7c1.43.083 2.437-.885 2.437-.885-.236-1.49-1.085-2.216-1.264-2.354l-.018-.013-.016-.013a.217.217 0 0 1-.031-.02c.008-.092.016-.18.02-.27.011-.162.016-.323.016-.48v-.253l-.005-.098-.008-.135a1.891 1.891 0 0 0-.01-.13c-.003-.042-.008-.083-.013-.125l-.016-.124-.018-.122a6.215 6.215 0 0 0-2.032-3.73 6.015 6.015 0 0 0-3.222-1.46 6.292 6.292 0 0 0-.85-.048l-.107.002h-.063l-.044.003-.104.008a4.777 4.777 0 0 0-3.335 1.695c-.332.4-.592.84-.768 1.297a4.594 4.594 0 0 0-.312 1.817l.003.091c.005.055.007.11.013.164a3.615 3.615 0 0 0 .698 1.82 3.53 3.53 0 0 0 1.827 1.282c.33.098.66.14.971.137.039 0 .078 0 .114-.002l.063-.003c.02 0 .041-.003.062-.003.034-.002.065-.007.099-.01.007 0 .018-.003.028-.003l.031-.005.06-.008a1.18 1.18 0 0 0 .112-.02c.036-.008.072-.013.109-.024a2.634 2.634 0 0 0 .914-.415c.028-.02.056-.041.085-.065a.248.248 0 0 0 .039-.35.244.244 0 0 0-.309-.06l-.078.042c-.09.044-.184.083-.283.116a2.476 2.476 0 0 1-.475.096c-.028.003-.054.006-.083.006l-.083.002c-.026 0-.054 0-.08-.002l-.102-.006h-.012l-.024.006c-.016-.003-.031-.003-.044-.006-.031-.002-.06-.007-.091-.01a2.59 2.59 0 0 1-.724-.213 2.557 2.557 0 0 1-.667-.438 2.52 2.52 0 0 1-.805-1.475 2.306 2.306 0 0 1-.029-.444l.006-.122v-.023l.002-.031c.003-.021.003-.04.005-.06a3.163 3.163 0 0 1 1.352-2.29 3.12 3.12 0 0 1 .937-.43 2.946 2.946 0 0 1 .776-.101h.06l.07.002.045.003h.026l.07.005a4.041 4.041 0 0 1 1.635.49 3.94 3.94 0 0 1 1.602 1.662 3.77 3.77 0 0 1 .397 1.414l.005.076.003.075c.002.026.002.05.002.075 0 .024.003.052 0 .07v.065l-.002.073-.008.174a6.195 6.195 0 0 1-.08.639 5.1 5.1 0 0 1-.267.927 5.31 5.31 0 0 1-.624 1.13 5.052 5.052 0 0 1-3.237 2.014 4.82 4.82 0 0 1-.649.066l-.039.003h-.287a6.607 6.607 0 0 1-1.716-.265 6.776 6.776 0 0 1-3.4-2.274 6.75 6.75 0 0 1-.746-1.15 6.616 6.616 0 0 1-.714-2.596l-.005-.083-.002-.02v-.056l-.003-.073v-.096l-.003-.104v-.07l.003-.163c.008-.22.026-.45.054-.678a8.707 8.707 0 0 1 .28-1.355c.128-.444.286-.872.473-1.277a7.04 7.04 0 0 1 1.456-2.1 5.925 5.925 0 0 1 .953-.763c.169-.111.343-.213.524-.306.089-.05.182-.091.273-.135.047-.02.093-.042.138-.062a7.177 7.177 0 0 1 .714-.267l.145-.045c.049-.015.098-.026.148-.041.098-.029.197-.052.296-.076.049-.013.1-.02.15-.033l.15-.032.151-.028.076-.013.075-.01.153-.024c.057-.01.114-.013.171-.023l.169-.021c.036-.003.073-.008.106-.01l.073-.008.036-.003.042-.002c.057-.003.114-.008.171-.01l.086-.006h.023l.037-.003.145-.007a7.999 7.999 0 0 1 1.708.125 7.917 7.917 0 0 1 2.048.68 8.253 8.253 0 0 1 1.672 1.09l.09.077.089.078c.06.052.114.107.171.159.057.052.112.106.166.16.052.055.107.107.159.164a8.671 8.671 0 0 1 1.41 1.978c.012.026.028.052.04.078l.04.078.075.156c.023.051.05.1.07.153l.065.15a8.848 8.848 0 0 1 .45 1.34.19.19 0 0 0 .201.142.186.186 0 0 0 .172-.184c.01-.246.002-.532-.024-.856z"/></svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Jellyfin</title><path d="M12 .002C8.826.002-1.398 18.537.16 21.666c1.56 3.129 22.14 3.094 23.682 0C25.384 18.573 15.177 0 12 0zm7.76 18.949c-1.008 2.028-14.493 2.05-15.514 0C3.224 16.9 9.92 4.755 12.003 4.755c2.081 0 8.77 12.166 7.759 14.196zM12 9.198c-1.054 0-4.446 6.15-3.93 7.189.518 1.04 7.348 1.027 7.86 0 .511-1.027-2.874-7.19-3.93-7.19z"/></svg>
|
||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>MariaDB</title><path d="M23.157 4.412c-.676.284-.79.31-1.673.372-.65.045-.757.057-1.212.209-.75.246-1.395.75-2.02 1.59-.296.398-1.249 1.913-1.249 1.988 0 .057-.65.998-.915 1.32-.574.713-1.08 1.079-2.14 1.59-.77.36-1.224.524-4.102 1.477-1.073.353-2.133.738-2.367.864-.852.449-1.515 1.036-2.203 1.938-1.003 1.32-.972 1.313-3.042.947a12.264 12.264 0 00-.675-.063c-.644-.05-1.023.044-1.332.334L0 17.193l.177.088c.094.05.353.234.561.398.215.17.461.347.55.391.088.044.17.088.183.101.012.013-.089.17-.228.353-.435.581-.593.871-.574 1.048.019.164.032.17.43.17.517-.006.826-.056 1.261-.208.65-.233 2.058-.94 2.784-1.4.776-.5 1.717-.998 1.956-1.042.082-.02.354-.07.594-.114.58-.107 1.464-.095 2.587.05.108.013.373.045.6.064.227.025.43.057.454.076.026.012.474.037.998.056.934.026 1.104.007 1.3-.189.126-.133.385-.631.498-.985.209-.643.417-.921.366-.492-.113.966-.322 1.692-.713 2.411-.259.499-.663 1.092-.934 1.395-.322.347-.315.36.088.315.619-.063 1.471-.397 2.096-.82.827-.562 1.647-1.691 2.19-3.03.107-.27.22-.22.183.083-.013.094-.038.315-.057.498l-.031.328.353-.202c.833-.48 1.414-1.262 2.127-2.884.227-.518.877-2.922 1.073-3.976a9.64 9.64 0 01.271-1.042c.127-.429.196-.555.48-.858.183-.19.625-.555.978-.808.72-.505.953-.75 1.187-1.205.208-.417.284-1.13.132-1.357-.132-.202-.284-.196-.763.006Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">AM</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">AY</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">CP</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">CU</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">CW</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">GT</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">HD</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">HM</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">LD</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">LK</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">MR</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">NE</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">OW</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">PW</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">RA</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">RM</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">SR</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">TT</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><polygon points="48,6 86,27 86,69 48,90 10,69 10,27" fill="#1c1300" stroke="#ffb000" stroke-width="3"/><text x="48" y="60" font-family="monospace" font-size="30" font-weight="bold" fill="#ffb000" text-anchor="middle">VK</text></svg>
|
||||
|
After Width: | Height: | Size: 292 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Pi-hole</title><path d="M4.344 0c.238 4.792 3.256 7.056 6.252 7.376.165-1.692-4.319-5.6-4.319-5.6-.008-.011.009-.025.019-.014 0 0 4.648 4.01 5.423 5.645 2.762-.15 5.196-1.947 5-4.912 0 0-4.12-.613-5 4.618C11.48 2.753 8.993 0 4.344 0zM12 7.682v.002a3.68 3.68 0 0 0-2.591 1.077L4.94 13.227a3.683 3.683 0 0 0-.86 1.356 3.31 3.31 0 0 0-.237 1.255A3.681 3.681 0 0 0 4.92 18.45l4.464 4.466a3.69 3.69 0 0 0 2.251 1.06l.002.001c.093.01.187.015.28.017l-.1-.008c.06.003.117.009.177.009l-.077-.001L12 24l-.004-.005a3.68 3.68 0 0 0 2.61-1.077l4.469-4.465a3.683 3.683 0 0 0 1.006-1.888l.012-.063a3.682 3.682 0 0 0 .057-.541l.003-.061c0-.017.003-.05.004-.06h-.002a3.683 3.683 0 0 0-1.077-2.607l-4.466-4.468a3.694 3.694 0 0 0-1.564-.927l-.07-.02a3.43 3.43 0 0 0-.946-.133L12 7.682zm3.165 3.357c.023 1.748-1.33 3.078-1.33 4.806.164 2.227 1.733 3.207 3.266 3.146-.035.003-.068.007-.104.009-1.847.135-3.209-1.326-5.002-1.326-2.23.164-3.21 1.736-3.147 3.27l-.008-.104c-.133-1.847 1.328-3.21 1.328-5.002-.173-2.32-1.867-3.284-3.46-3.132.1-.011.203-.021.31-.027 1.847-.133 3.209 1.328 5.002 1.328 2.082-.155 3.074-1.536 3.145-2.968zM4.344 0c.238 4.792 3.256 7.056 6.252 7.376.165-1.692-4.319-5.6-4.319-5.6-.008-.011.009-.025.019-.014 0 0 4.648 4.01 5.423 5.645 2.762-.15 5.196-1.947 5-4.912 0 0-4.12-.613-5 4.618C11.48 2.753 8.993 0 4.344 0zM12 7.682v.002a3.68 3.68 0 0 0-2.591 1.077L4.94 13.227a3.683 3.683 0 0 0-.86 1.356 3.31 3.31 0 0 0-.237 1.255A3.681 3.681 0 0 0 4.92 18.45l4.464 4.466a3.69 3.69 0 0 0 2.251 1.06l.002.001c.093.01.187.015.28.017l-.1-.008c.06.003.117.009.177.009l-.077-.001L12 24l-.004-.005a3.68 3.68 0 0 0 2.61-1.077l4.469-4.465a3.683 3.683 0 0 0 1.006-1.888l.012-.063a3.682 3.682 0 0 0 .057-.541l.003-.061c0-.017.003-.05.004-.06h-.002a3.683 3.683 0 0 0-1.077-2.607l-4.466-4.468a3.694 3.694 0 0 0-1.564-.927l-.07-.02a3.43 3.43 0 0 0-.946-.133L12 7.682zm3.165 3.357c.023 1.748-1.33 3.078-1.33 4.806.164 2.227 1.733 3.207 3.266 3.146-.035.003-.068.007-.104.009-1.847.135-3.209-1.326-5.002-1.326-2.23.164-3.21 1.736-3.147 3.27l-.008-.104c-.133-1.847 1.328-3.21 1.328-5.002-.173-2.32-1.867-3.284-3.46-3.132.1-.011.203-.021.31-.027 1.847-.133 3.209 1.328 5.002 1.328 2.082-.155 3.074-1.536 3.145-2.968z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Plex</title><path d="M3.987 8.409c-.96 0-1.587.28-2.12.933v-.72H0v8.88s.038.018.127.037c.138.03.821.187 1.331-.249.441-.377.542-.814.542-1.318v-1.283c.533.573 1.147.813 2 .813 1.84 0 3.253-1.493 3.253-3.48 0-2.12-1.36-3.613-3.266-3.613Zm16.748 5.595.406.591c.391.614.894.906 1.492.908.621-.012 1.064-.562 1.226-.755 0 0-.307-.27-.686-.72-.517-.614-1.214-1.755-1.24-1.803l-1.198 1.779Zm-3.205-1.955c0-2.08-1.52-3.64-3.52-3.64s-3.467 1.587-3.467 3.573a3.48 3.48 0 0 0 3.507 3.52c1.413 0 2.626-.84 3.253-2.293h-2.04l-.093.093c-.427.4-.72.533-1.227.533-.787 0-1.373-.506-1.453-1.266h4.986c.04-.214.054-.307.054-.52Zm-7.671-.219c0 .769.11 1.701.868 2.722l.056.069c-.306.526-.742.88-1.248.88-.399 0-.814-.211-1.138-.579a2.177 2.177 0 0 1-.538-1.441V6.409H9.86l-.001 5.421Zm9.283 3.46h-2.39l2.247-3.332-2.247-3.335h2.39l2.248 3.335-2.248 3.332Zm1.593-1.286Zm-17.162-.342c-.933 0-1.68-.773-1.68-1.72s.76-1.666 1.68-1.666c.92 0 1.68.733 1.68 1.68 0 .946-.733 1.706-1.68 1.706Zm18.361-1.974L24 8.622h-2.391l-.87 1.293 1.195 1.773Zm-9.404-.466c.16-.706.72-1.133 1.493-1.133.773 0 1.373.467 1.507 1.133h-3Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Prometheus</title><path d="M12 0C5.373 0 0 5.372 0 12c0 6.627 5.373 12 12 12s12-5.373 12-12c0-6.628-5.373-12-12-12zm0 22.46c-1.885 0-3.414-1.26-3.414-2.814h6.828c0 1.553-1.528 2.813-3.414 2.813zm5.64-3.745H6.36v-2.046h11.28v2.046zm-.04-3.098H6.391c-.037-.043-.075-.086-.111-.13-1.155-1.401-1.427-2.133-1.69-2.879-.005-.025 1.4.287 2.395.511 0 0 .513.119 1.262.255-.72-.843-1.147-1.915-1.147-3.01 0-2.406 1.845-4.508 1.18-6.207.648.053 1.34 1.367 1.387 3.422.689-.951.977-2.69.977-3.755 0-1.103.727-2.385 1.454-2.429-.648 1.069.168 1.984.894 4.256.272.854.237 2.29.447 3.201.07-1.892.395-4.652 1.595-5.605-.529 1.2.079 2.702.494 3.424.671 1.164 1.078 2.047 1.078 3.716a4.642 4.642 0 01-1.11 2.996c.792-.149 1.34-.283 1.34-.283l2.573-.502s-.374 1.538-1.81 3.019z"/></svg>
|
||||
|
After Width: | Height: | Size: 862 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>qbittorrent</title><path d="M11.911 23.994c-1.31 0-2.605-.232-3.831-.705-3.4-1.024-6.2-3.865-7.433-7.58-1.23-3.708-.685-7.654 1.459-10.554C4.062 2.038 7.677.094 11.742.008c4.064-.079 7.758 1.703 9.882 4.785a12.066 12.066 0 0 1 2.369 7.145c.138 3.733-1.75 7.368-5.052 9.728-2.147 1.535-4.61 2.328-7.03 2.328zm.11-22.314c-.081 0-.162 0-.244.002-3.5.074-6.599 1.725-8.29 4.415-1.856 2.516-2.31 5.893-1.25 9.086 1.06 3.197 3.448 5.636 6.386 6.523 3.025 1.165 6.496.633 9.345-1.402 2.847-2.035 4.473-5.144 4.351-8.318v-.032c0-2.214-.73-4.41-2.055-6.185-1.78-2.58-4.84-4.09-8.243-4.09zM9.406 20.246v-4.578a2.663 2.663 0 0 1-.952.863 2.573 2.573 0 0 1-1.29.344c-1.016 0-1.893-.444-2.63-1.33-.731-.887-1.097-2.102-1.097-3.646 0-.939.148-1.781.444-2.527.301-.746.734-1.309 1.299-1.69A3.26 3.26 0 0 1 7.052 7.1c1.058 0 1.891.487 2.5 1.46v-1.25h1.306v12.935H9.406zm-4.477-8.285c0 1.203.232 2.108.694 2.711.463.6 1.016.9 1.662.9.619 0 1.15-.286 1.597-.855.446-.576.67-1.447.67-2.615 0-1.245-.237-2.18-.71-2.81-.468-.627-1.02-.941-1.654-.941-.63 0-1.164.293-1.605.88-.435.581-.654 1.491-.654 2.73m9.55 4.702h-1.346V3.755h1.452v4.604c.613-.84 1.395-1.258 2.347-1.258.526 0 1.024.117 1.492.351.464.222.864.558 1.161.978.307.416.546.922.718 1.514.172.593.258 1.227.258 1.902 0 1.603-.363 2.841-1.088 3.716-.727.874-1.598 1.312-2.614 1.312-1.011 0-1.804-.46-2.379-1.382v1.17m-.016-4.746c0 1.122.14 1.932.42 2.432.456.815 1.074 1.223 1.854 1.223.635 0 1.183-.3 1.646-.898.462-.604.693-1.503.693-2.695 0-1.22-.224-2.122-.67-2.703-.44-.58-.975-.872-1.605-.872-.634 0-1.182.303-1.645.907-.463.6-.694 1.468-.694 2.607"/></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>radarr</title><path d="M5.274 0C3.189.039 1.19 1.547 1.19 4.705l.184 14.518c0 1.47 1.103 2.205 2.573 2.021L3.764 3.786c0-1.654.919-1.838 2.022-1.103l14.7 8.27c1.103.734 1.655 1.47 1.838 2.756.92-1.654.552-4.043-1.286-5.33L7.991.846A4.559 4.559 0 0 0 5.274.001zm1.982 6.91-.184 10.107 9.004-5.146Zm13.598 6.064-15.068 8.82c-.92.552-2.022.736-3.124.368.918 1.47 3.307 2.389 5.145 1.47l12.68-7.35c1.102-.736 1.286-2.022.367-3.308z"/></svg>
|
||||
|
After Width: | Height: | Size: 529 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>SearXNG</title><path d="m13.716 17.261 6.873 6.582L24 20.282l-6.824-6.536a9.11 9.11 0 0 0 1.143-4.43c0-5.055-4.105-9.159-9.16-9.159S0 4.261 0 9.316c0 5.055 4.104 9.159 9.159 9.159a9.11 9.11 0 0 0 4.557-1.214ZM9.159 2.773a6.546 6.546 0 0 1 6.543 6.543 6.545 6.545 0 0 1-6.543 6.542 6.545 6.545 0 0 1-6.542-6.542 6.545 6.545 0 0 1 6.542-6.543ZM7.26 5.713a4.065 4.065 0 0 1 4.744.747 4.064 4.064 0 0 1 .707 4.749l1.157.611a5.376 5.376 0 0 0-.935-6.282 5.377 5.377 0 0 0-6.274-.987l.601 1.162Z"/></svg>
|
||||
|
After Width: | Height: | Size: 591 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#ffb000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>sonarr</title><path d="M21.212 4.282c1.851 2.204 2.777 4.776 2.777 7.718 0 2.848-.867 5.344-2.602 7.489a934.355 934.355 0 0 1-2.101-2.095c-1.477-1.477-1.792-3.293-1.792-5.278 0-2.224.127-3.486 1.577-4.935l2.478-2.478a13.209 13.209 0 0 0-.337-.421Zm-17.7 16.193C1.708 18.678.6 16.59.188 14.213A11.84 11.84 0 0 1 .011 12c0-.28.006-.548.017-.802 0-.026.007-.052.022-.078.153-2.601 1.076-4.889 2.767-6.865-.108.127-.214.256-.316.387 0 0 1.351 1.346 2.329 2.323 1.408 1.409 1.726 3.215 1.726 5.151 0 1.985-.249 3.762-1.781 5.295-1.035 1.035-2.119 2.124-2.119 2.124.112.136.229.271.349.404.029-.027 1.297-1.348 2.123-2.175 1.638-1.637 1.928-3.528 1.928-5.648 0-2.072-.365-3.997-1.873-5.504a620.045 620.045 0 0 0-2.366-2.357c.168-.196.342-.388.523-.576l3.117 3.106-.194.195 1.903 1.898.547-.549L6.81 6.432l-.196.196L3.495 3.52c.01-.009.436-.416.643-.597.009.011 2.28 2.283 2.28 2.283 1.538 1.537 3.5 1.955 5.621 1.955 2.18 0 4.134-.442 5.731-2.038.907-.908 2.153-2.149 2.162-2.16.17.151.491.461.56.528l.013.013-3.111 3.028-.001.002-.197-.194-1.876 1.903.552.543 1.875-1.903-.197-.194 3.109-3.026c.193.203.377.41.553.619-.03.025-2.495 2.546-2.495 2.546-1.556 1.556-1.723 2.9-1.723 5.288 0 2.121.361 4.054 1.939 5.632a576.91 576.91 0 0 0 2.133 2.124c-.183.208-.599.645-.613.66l-3.066-3.174.195-.196-1.995-1.986-.546.549 1.995 1.986.195-.196 3.065 3.172c-.021.019-.385.362-.552.506-.01-.013-1.974-1.978-1.974-1.978-1.842-1.842-3.299-2.039-5.731-2.039-2.338 0-3.92.239-5.632 1.95-.944.944-2.078 2.085-2.089 2.099-.275-.23-.649-.594-.649-.594l3.019-3.024.199.192 1.854-1.925-.558-.538-1.854 1.926.199.191-3.016 3.022ZM12 8.672A3.33 3.33 0 0 0 8.672 12 3.33 3.33 0 0 0 12 15.328 3.33 3.33 0 0 0 15.328 12 3.33 3.33 0 0 0 12 8.672ZM4.52 2.6C6.665.867 9.162 0 12.011 0c2.88 0 5.394.88 7.541 2.639 0 0-1.215 1.209-2.136 2.13-1.496 1.496-3.334 1.892-5.377 1.892-1.985 0-3.829-.37-5.267-1.809L4.52 2.6Zm14.837 18.909a9.507 9.507 0 0 1-.342.256C16.994 23.255 14.659 24 12.011 24c-2.652 0-4.983-.745-6.993-2.235-.104-.074-.208-.15-.31-.227 0 0 1.096-1.101 2.053-2.058 1.602-1.602 3.09-1.804 5.278-1.804 2.28 0 3.651.166 5.377 1.892l1.941 1.941Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -19,9 +19,11 @@
|
||||
<main id="grid" class="sections"></main>
|
||||
<footer class="foot">
|
||||
<span>last master deployment: <span id="deployed-at"></span></span>
|
||||
<a href="/docs">docs</a>
|
||||
<a href="/admin/">admin</a>
|
||||
<a href="https://auth.franksdank.cloud/if/flow/default-user-settings-flow/" target="_blank" rel="noopener">account</a>
|
||||
<span class="foot-links">
|
||||
<a class="foot-btn" href="/docs">docs</a>
|
||||
<a class="foot-btn" id="admin-link" href="/admin/" hidden>admin</a>
|
||||
<a class="foot-btn" href="https://auth.franksdank.cloud/if/flow/default-user-settings-flow/" target="_blank" rel="noopener">account settings</a>
|
||||
</span>
|
||||
</footer>
|
||||
<script src="deployed.js"></script>
|
||||
<script src="app.js"></script>
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
"name": "SearXNG",
|
||||
"category": "user",
|
||||
"section": "Web Apps",
|
||||
"description": "AI-free, VPN-routed search engine, fully hosted on Frank's server. Your searches are obfuscated, not anonymous: upstream API keys are tied to Frank's identity.",
|
||||
"description": "AI-free, VPN-routed search engine, fully hosted on Frank's server.",
|
||||
"url": "http://search.franksdank.cloud",
|
||||
"docs": "",
|
||||
"probe": "127.0.0.1:8081",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"warn": "Searches are obfuscated, not anonymous: SearXNG hides you from the upstream engines and the VPN tunnel hides the traffic from the LAN — but the upstream search API keys are tied to Frank’s identity. Don’t treat it as Tor.",
|
||||
"art": "/img/apps/searxng.svg"
|
||||
},
|
||||
{
|
||||
"name": "OpenWebUI",
|
||||
@@ -21,19 +23,21 @@
|
||||
"probe": "127.0.0.1:3005",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-ow.svg"
|
||||
},
|
||||
{
|
||||
"name": "Gitea",
|
||||
"category": "user",
|
||||
"section": "Web Apps",
|
||||
"description": "Git code hosting and review platform. Needs its own login, separate from the dankcloud single sign-on (ask Frank).",
|
||||
"description": "Git code hosting and review platform. Needs its own login, separate from the dankcloud single sign-on — use the sign-up flow in the app to get an account; no need to ask Frank.",
|
||||
"url": "http://gitea.franksdank.cloud",
|
||||
"docs": "",
|
||||
"probe": "127.0.0.1:3000",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/gitea.svg"
|
||||
},
|
||||
{
|
||||
"name": "Calibre-Web",
|
||||
@@ -45,7 +49,8 @@
|
||||
"probe": "192.168.0.235:8083",
|
||||
"method": "http",
|
||||
"wip": "down",
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mono-cw.svg"
|
||||
},
|
||||
{
|
||||
"name": "RomM",
|
||||
@@ -57,7 +62,8 @@
|
||||
"probe": "192.168.0.235:8085",
|
||||
"method": "http",
|
||||
"wip": "down",
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mono-rm.svg"
|
||||
},
|
||||
{
|
||||
"name": "Copyparty",
|
||||
@@ -69,7 +75,8 @@
|
||||
"probe": "192.168.0.235:3923",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-cp.svg"
|
||||
},
|
||||
{
|
||||
"name": "Plex",
|
||||
@@ -81,7 +88,8 @@
|
||||
"probe": "192.168.0.235:32400",
|
||||
"method": "tcp",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/plex.svg"
|
||||
},
|
||||
{
|
||||
"name": "Jellyfin",
|
||||
@@ -93,7 +101,8 @@
|
||||
"probe": "192.168.0.235:8096",
|
||||
"method": "http",
|
||||
"wip": "down",
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/jellyfin.svg"
|
||||
},
|
||||
{
|
||||
"name": "Seerr",
|
||||
@@ -105,7 +114,8 @@
|
||||
"probe": "127.0.0.1:5055",
|
||||
"method": "http",
|
||||
"wip": "down",
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mono-sr.svg"
|
||||
},
|
||||
{
|
||||
"name": "Marreta",
|
||||
@@ -117,7 +127,8 @@
|
||||
"probe": "127.0.0.1:8082",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-mr.svg"
|
||||
},
|
||||
{
|
||||
"name": "Sonarr",
|
||||
@@ -129,7 +140,8 @@
|
||||
"probe": "192.168.0.112:8989",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/sonarr.svg"
|
||||
},
|
||||
{
|
||||
"name": "Hermes",
|
||||
@@ -141,7 +153,8 @@
|
||||
"probe": "127.0.0.1:8787",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-hm.svg"
|
||||
},
|
||||
{
|
||||
"name": "Hermes dashboard",
|
||||
@@ -153,7 +166,8 @@
|
||||
"probe": "192.168.0.143:9119",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-hd.svg"
|
||||
},
|
||||
{
|
||||
"name": "Grafana",
|
||||
@@ -165,7 +179,8 @@
|
||||
"probe": "127.0.0.1:3002",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/grafana.svg"
|
||||
},
|
||||
{
|
||||
"name": "Prometheus",
|
||||
@@ -177,7 +192,8 @@
|
||||
"probe": "127.0.0.1:9090",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/prometheus.svg"
|
||||
},
|
||||
{
|
||||
"name": "Loki",
|
||||
@@ -189,7 +205,8 @@
|
||||
"probe": "127.0.0.1:3100",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-lk.svg"
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
@@ -201,7 +218,8 @@
|
||||
"probe": "127.0.0.1:9100",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mono-ne.svg"
|
||||
},
|
||||
{
|
||||
"name": "alloy",
|
||||
@@ -213,7 +231,8 @@
|
||||
"probe": "127.0.0.1:12345",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mono-ay.svg"
|
||||
},
|
||||
{
|
||||
"name": "alertmanager",
|
||||
@@ -225,7 +244,8 @@
|
||||
"probe": "127.0.0.1:9093",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mono-am.svg"
|
||||
},
|
||||
{
|
||||
"name": "Caddy",
|
||||
@@ -237,7 +257,8 @@
|
||||
"probe": "127.0.0.1:80",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/caddy.svg"
|
||||
},
|
||||
{
|
||||
"name": "Pi-hole",
|
||||
@@ -249,7 +270,8 @@
|
||||
"probe": "192.168.0.143:8083",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/pihole.svg"
|
||||
},
|
||||
{
|
||||
"name": "Gluetun",
|
||||
@@ -261,6 +283,41 @@
|
||||
"probe": "127.0.0.1:51820",
|
||||
"method": "tcp",
|
||||
"wip": "closed",
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mono-gt.svg"
|
||||
},
|
||||
{
|
||||
"name": "frank-zealot",
|
||||
"category": "user",
|
||||
"section": "AI",
|
||||
"model": {
|
||||
"unit": "zealot",
|
||||
"role": "Frank's utility model",
|
||||
"tagline": "HONOR GUIDE ME!",
|
||||
"sfx": [
|
||||
"zealot-honor.ogg"
|
||||
],
|
||||
"equiv": "Equivalent to last year's frontier level (2025).",
|
||||
"spec": "Qwen3.5-9B-Uncensored (Q6_K) on an NVIDIA RTX 3090 — ~95 tokens/s; 200k-token context, two submissions at a time; sees images.",
|
||||
"inputs": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"use": "Code editor autocomplete, agentic search, RAG, research subagents, translation, roleplay, and summarization. If your agent harness lets you set a compaction model, set this one: a compaction job on the bigger models blocks them for far longer.",
|
||||
"voice": {
|
||||
"text": "I LONG FOR COMBAT!",
|
||||
"sfx": [
|
||||
"zealot-combat.ogg"
|
||||
]
|
||||
},
|
||||
"supervision": "Requires tight human supervision.",
|
||||
"warn": "Uncensored model: output can include adult content, content that describes harmful, hateful, or illegal acts, content concerning “sensitive offensive cybersecurity topics”, and other output that may carry severe legal risk. Take this warning seriously — don’t ruin this server for everybody."
|
||||
},
|
||||
"url": "",
|
||||
"docs": "/docs#models",
|
||||
"probe": "127.0.0.1:7771",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": false
|
||||
},
|
||||
{
|
||||
@@ -271,14 +328,25 @@
|
||||
"unit": "dragoon",
|
||||
"role": "Frank's deep reasoning model",
|
||||
"tagline": "I have returned — make use of me.",
|
||||
"sfx": ["dragoon-returned.ogg", "dragoon-makeuse.ogg"],
|
||||
"sfx": [
|
||||
"dragoon-returned.ogg",
|
||||
"dragoon-makeuse.ogg"
|
||||
],
|
||||
"equiv": "Equivalent to Claude Sonnet 5 / OpenAI-Luna (Summer 2026 frontier intelligence).",
|
||||
"spec": "Qwen3.8-Flash-Next v2 Swift1.5 abliterated (halogen flash-server, ~62 GiB) on the Strix Halo iGPU — 200k-token context, two submissions at a time; sees images.",
|
||||
"inputs": ["text", "image"],
|
||||
"inputs": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"use": "Complex agentic tasks, programming, system administration, and \"claw\"-style personal agents.",
|
||||
"voice": { "text": "Awaiting instructions.", "sfx": ["dragoon-awaiting.ogg"] },
|
||||
"voice": {
|
||||
"text": "Awaiting instructions.",
|
||||
"sfx": [
|
||||
"dragoon-awaiting.ogg"
|
||||
]
|
||||
},
|
||||
"supervision": "Safe for autonomous, low-supervision use.",
|
||||
"warn": "Abliterated (censorship-removed) model: output can include adult themes. You are responsible for the legal consequences of how you use it."
|
||||
"warn": "Uncensored model: output can include adult content, content that describes harmful, hateful, or illegal acts, content concerning “sensitive offensive cybersecurity topics”, and other output that may carry severe legal risk. Take this warning seriously — don’t ruin this server for everybody."
|
||||
},
|
||||
"url": "",
|
||||
"docs": "/docs#models",
|
||||
@@ -295,13 +363,24 @@
|
||||
"unit": "archon",
|
||||
"role": "Frank's strongest and fastest model runtime",
|
||||
"tagline": "...Power Overwhelming...",
|
||||
"sfx": ["archon-power.ogg"],
|
||||
"sfx": [
|
||||
"archon-power.ogg"
|
||||
],
|
||||
"equiv": "Equivalent to Claude Opus 4.8 / OpenAI-Terra (Summer 2026 frontier intelligence).",
|
||||
"spec": "Qwen3.8-Flash-Next at native FP8 precision (radiance, 173 GiB) on twin AMD R9700s with more than 200 GB of system RAM — 200k-token context, two submissions at a time; sees images.",
|
||||
"inputs": ["text", "image"],
|
||||
"use": "Software engineering, system administration, and instruction tasks. Please ask Frank before use, as he uses this one primarily.",
|
||||
"voice": { "text": "...we BURN.", "sfx": ["archon-burn.ogg"] },
|
||||
"supervision": "Safe for autonomous, low-supervision use."
|
||||
"inputs": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"use": "Software engineering, system administration, and instruction tasks.",
|
||||
"voice": {
|
||||
"text": "...we BURN.",
|
||||
"sfx": [
|
||||
"archon-burn.ogg"
|
||||
]
|
||||
},
|
||||
"supervision": "Safe for autonomous, low-supervision use.",
|
||||
"permission": "Ask Frank for permission before use — this is his primary model; he uses it more than anything else on the fleet."
|
||||
},
|
||||
"url": "",
|
||||
"docs": "/docs#models",
|
||||
@@ -310,30 +389,6 @@
|
||||
"wip": false,
|
||||
"showLink": false
|
||||
},
|
||||
{
|
||||
"name": "frank-zealot",
|
||||
"category": "user",
|
||||
"section": "AI",
|
||||
"model": {
|
||||
"unit": "zealot",
|
||||
"role": "Frank's utility model",
|
||||
"tagline": "HONOR GUIDE ME!",
|
||||
"sfx": ["zealot-honor.ogg"],
|
||||
"equiv": "Equivalent to last year's frontier level (2025).",
|
||||
"spec": "Qwen3.5-9B-Uncensored (Q6_K) on an NVIDIA RTX 3090 — ~95 tokens/s; 200k-token context, two submissions at a time; sees images.",
|
||||
"inputs": ["text", "image"],
|
||||
"use": "Code editor autocomplete, agentic search, RAG, research subagents, translation, roleplay, and summarization. If your agent harness lets you set a compaction model, set this one: a compaction job on the bigger models blocks them for far longer.",
|
||||
"voice": { "text": "I LONG FOR COMBAT!", "sfx": ["zealot-combat.ogg"] },
|
||||
"supervision": "Requires tight human supervision.",
|
||||
"warn": "Uncensored model: output can include adult content. You are responsible for the legal consequences of how you use it."
|
||||
},
|
||||
"url": "",
|
||||
"docs": "/docs#models",
|
||||
"probe": "127.0.0.1:7771",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": false
|
||||
},
|
||||
{
|
||||
"name": "mariadb",
|
||||
"category": "admin",
|
||||
@@ -344,7 +399,8 @@
|
||||
"probe": "192.168.0.235:3306",
|
||||
"method": "tcp",
|
||||
"wip": "closed",
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mariadb.svg"
|
||||
},
|
||||
{
|
||||
"name": "valkey",
|
||||
@@ -356,7 +412,8 @@
|
||||
"probe": "127.0.0.1:6379",
|
||||
"method": "tcp",
|
||||
"wip": "closed",
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/mono-vk.svg"
|
||||
},
|
||||
{
|
||||
"name": "Prowlarr",
|
||||
@@ -368,7 +425,8 @@
|
||||
"probe": "192.168.0.112:9696",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-pw.svg"
|
||||
},
|
||||
{
|
||||
"name": "Radarr",
|
||||
@@ -380,7 +438,8 @@
|
||||
"probe": "192.168.0.112:7878",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/radarr.svg"
|
||||
},
|
||||
{
|
||||
"name": "Readarr",
|
||||
@@ -392,7 +451,8 @@
|
||||
"probe": "192.168.0.112:8787",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-ra.svg"
|
||||
},
|
||||
{
|
||||
"name": "Lidarr",
|
||||
@@ -404,7 +464,8 @@
|
||||
"probe": "192.168.0.112:8686",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-ld.svg"
|
||||
},
|
||||
{
|
||||
"name": "qBittorrent",
|
||||
@@ -416,7 +477,8 @@
|
||||
"probe": "192.168.0.112:8080",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/qbittorrent.svg"
|
||||
},
|
||||
{
|
||||
"name": "Tautulli",
|
||||
@@ -428,7 +490,8 @@
|
||||
"probe": "192.168.0.235:8181",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-tt.svg"
|
||||
},
|
||||
{
|
||||
"name": "Postgres",
|
||||
@@ -440,7 +503,8 @@
|
||||
"probe": "127.0.0.1:5432",
|
||||
"method": "tcp",
|
||||
"wip": "closed",
|
||||
"showLink": false
|
||||
"showLink": false,
|
||||
"art": "/img/apps/postgresql.svg"
|
||||
},
|
||||
{
|
||||
"name": "ComfyUI",
|
||||
@@ -452,6 +516,7 @@
|
||||
"probe": "127.0.0.1:8188",
|
||||
"method": "http",
|
||||
"wip": false,
|
||||
"showLink": true
|
||||
"showLink": true,
|
||||
"art": "/img/apps/mono-cu.svg"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -71,7 +71,19 @@ body::before {
|
||||
}
|
||||
|
||||
.panel { border: 1px solid var(--border); background: var(--panel); padding: 12px 14px; border-radius: 2px; }
|
||||
.panel-head { display: flex; justify-content: space-between; align-items: center; }
|
||||
.panel-head { display: flex; align-items: center; gap: 8px; }
|
||||
.panel-head .name { flex: 1; }
|
||||
.app-art {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
flex: 0 0 auto;
|
||||
object-fit: contain;
|
||||
padding: 4px;
|
||||
clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0% 50%);
|
||||
border: 1px solid var(--dim);
|
||||
background: color-mix(in srgb, var(--fg) 8%, transparent);
|
||||
filter: saturate(0.85) brightness(0.95);
|
||||
}
|
||||
.name { color: var(--head); }
|
||||
.badge { border: 1px solid currentColor; padding: 0 6px; border-radius: 2px; font-size: 12px; }
|
||||
.badge.up { color: var(--fg); }
|
||||
@@ -96,6 +108,19 @@ body::before {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.foot a { color: var(--link); text-decoration: none; }
|
||||
.foot-links { display: flex; gap: 10px; flex-wrap: wrap; }
|
||||
.foot-btn {
|
||||
border: 1px solid var(--link);
|
||||
padding: 2px 14px;
|
||||
border-radius: 2px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
text-shadow: 0 0 6px color-mix(in srgb, var(--link) 55%, transparent);
|
||||
}
|
||||
.foot-btn:hover {
|
||||
background: color-mix(in srgb, var(--link) 16%, transparent);
|
||||
box-shadow: 0 0 10px color-mix(in srgb, var(--link) 45%, transparent);
|
||||
}
|
||||
|
||||
/* The user docs page (static prose). */
|
||||
.docs { max-width: 780px; }
|
||||
@@ -107,6 +132,8 @@ body::before {
|
||||
.docs pre code { color: var(--fg); }
|
||||
.docs img { display: block; max-width: 100%; border: 1px solid var(--border); border-radius: 2px; margin: 10px 0; }
|
||||
.docs .key-warn { color: var(--down); }
|
||||
.docs [title].key-warn { cursor: help;
|
||||
text-decoration: underline dotted color-mix(in srgb, var(--down) 60%, transparent); }
|
||||
.docs .foot-note { color: var(--dim); }
|
||||
html[data-bare="1"] .docs h1, html[data-bare="1"] .docs h2 { color: #000; border-color: #000; }
|
||||
html[data-bare="1"] .docs a, html[data-bare="1"] .docs code { color: #000; }
|
||||
@@ -123,6 +150,7 @@ html[data-bare="1"] .badge, html[data-bare="1"] .name, html[data-bare="1"] .desc
|
||||
html[data-bare="1"] .desc-role, html[data-bare="1"] .desc-spec, html[data-bare="1"] .desc-inputs, html[data-bare="1"] .desc-use, html[data-bare="1"] .desc-equiv { color: #000; font-weight: normal; }
|
||||
html[data-bare="1"] .section-title { border-color: #000; }
|
||||
html[data-bare="1"] .links a, html[data-bare="1"] .toggle, html[data-bare="1"] .foot a { color: #000; }
|
||||
html[data-bare="1"] .foot-btn { border-color: #000; text-shadow: none; }
|
||||
|
||||
/* Model Information: one fused panel for the fleet models. Informational
|
||||
panels, so the type is smaller than the app panels; each model wears its
|
||||
@@ -191,6 +219,16 @@ html[data-bare="1"] .links a, html[data-bare="1"] .toggle, html[data-bare="1"] .
|
||||
.mi-super { color: var(--link); margin-top: 6px; }
|
||||
.mi-warn { color: var(--down); margin-top: 4px; cursor: help;
|
||||
text-decoration: underline dotted color-mix(in srgb, var(--down) 60%, transparent); }
|
||||
.mi-perm {
|
||||
margin-top: 8px;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid var(--down);
|
||||
color: var(--down);
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 6px color-mix(in srgb, var(--down) 45%, transparent);
|
||||
}
|
||||
.svc-warn { color: var(--down); margin-top: 6px; cursor: help;
|
||||
text-decoration: underline dotted color-mix(in srgb, var(--down) 60%, transparent); }
|
||||
|
||||
/* Bare mode strips the model component to plain prose too. */
|
||||
html[data-bare="1"] .mi-card { border-color: #000; box-shadow: none; background: none; }
|
||||
@@ -200,3 +238,6 @@ html[data-bare="1"] .mi-voice { color: #000; text-decoration: underline; }
|
||||
html[data-bare="1"] .mi-role, html[data-bare="1"] .mi-spec, html[data-bare="1"] .mi-use,
|
||||
html[data-bare="1"] .mi-inputs, html[data-bare="1"] .mi-equiv, html[data-bare="1"] .mi-super,
|
||||
html[data-bare="1"] .mi-warn { color: #000; }
|
||||
html[data-bare="1"] .app-art { display: none; }
|
||||
html[data-bare="1"] .svc-warn, html[data-bare="1"] .mi-perm { color: #000; border: none; text-shadow: none; padding: 0; }
|
||||
html[data-bare="1"] .mi-perm { border: 1px solid #000; }
|
||||
|
||||
@@ -47,8 +47,11 @@ test("standard user is denied the admin panel (RBAC)", async ({ page }) => {
|
||||
expect(resp.status()).toBe(403);
|
||||
expect(await resp.text()).toContain("Forbidden: homepage admins only");
|
||||
|
||||
// The footer link a standard user can click also dead-ends at the gate.
|
||||
// The admin button is identity-gated: /whoami reports the authentik
|
||||
// groups, and the page hides the button from non-admins (the server-side
|
||||
// 403 above stays the real gate). Direct navigation dead-ends all the same.
|
||||
await page.goto("/");
|
||||
await page.locator('footer a[href="/admin/"]').click();
|
||||
await expect(page.locator("#admin-link")).toBeHidden();
|
||||
await page.goto("/admin/");
|
||||
await expect(page.locator("body")).toContainText("Forbidden: homepage admins only");
|
||||
});
|
||||
|
||||
@@ -4,6 +4,10 @@ import { expect, test } from "@playwright/test";
|
||||
// allow-leg: the same path returns 403 for the standard user (10-homepage).
|
||||
|
||||
test("admin panel renders admin-category services", async ({ page }) => {
|
||||
// Identity gate (admin side): a homepage-admins member sees the admin
|
||||
// button on the user homepage (the standard user does not: 10-homepage).
|
||||
await page.goto("/");
|
||||
await expect(page.locator("#admin-link")).toBeVisible({ timeout: 60_000 });
|
||||
await page.goto("/admin/");
|
||||
await expect(page).toHaveTitle(/frank — admin/, { timeout: 60_000 });
|
||||
|
||||
|
||||
@@ -101,7 +101,35 @@ for s in fleet:
|
||||
uncensored = "ncensored" in m["spec"] or "bliterated" in m["spec"]
|
||||
if uncensored:
|
||||
assert "legal" in m.get("warn", "").lower(), f"{s['name']} is uncensored but has no legal warning"
|
||||
assert [s["name"] for s in fleet] == ["frank-zealot", "frank-dragoon", "frank-archon"], \
|
||||
"card render order must be zealot, dragoon, archon: " + str([s["name"] for s in fleet])
|
||||
w = {s["name"]: s["model"].get("warn", "") for s in fleet}
|
||||
assert w["frank-zealot"] == w["frank-dragoon"] != "", "the legal warnings must be the common uncensored text"
|
||||
assert "legal risk" in w["frank-zealot"].lower() and "everybody" in w["frank-zealot"].lower()
|
||||
archon = next(s for s in fleet if s["name"] == "frank-archon")
|
||||
assert "permission" in archon["model"], "archon card needs the ask-Frank permission callout"
|
||||
PY
|
||||
grep -q "renderModelInfo" "$REPO_ROOT/shared/homepage/app.js"
|
||||
grep -q ".mi-card" "$REPO_ROOT/shared/homepage/style.css"
|
||||
}
|
||||
|
||||
@test "every app card carries icon art and SearXNG carries the privacy note" {
|
||||
# The family sees unit-portrait art on every card, not just the models:
|
||||
# brand marks where Simple Icons has them, improvised monograms otherwise.
|
||||
# SearXNG's card must warn (hover) that obfuscation is not anonymity.
|
||||
python3 - "$REPO_ROOT/shared/homepage/services.json" "$REPO_ROOT/shared/homepage" <<'PY'
|
||||
import json, os, sys
|
||||
services = json.load(open(sys.argv[1]))
|
||||
root = sys.argv[2]
|
||||
apps = [s for s in services if "model" not in s]
|
||||
for s in apps:
|
||||
art = s.get("art", "")
|
||||
assert art.startswith("/img/apps/"), f"{s['name']} has no app art"
|
||||
assert os.path.isfile(os.path.join(root, art.lstrip("/"))), f"{s['name']} art file missing: {art}"
|
||||
sx = next(s for s in services if s["name"] == "SearXNG")
|
||||
assert "anonymous" in sx.get("warn", "").lower(), "SearXNG must warn that searches are obfuscated, not anonymous"
|
||||
PY
|
||||
grep -q "app-art" "$REPO_ROOT/shared/homepage/app.js"
|
||||
grep -q ".app-art" "$REPO_ROOT/shared/homepage/style.css"
|
||||
grep -q "/whoami" "$REPO_ROOT/dankclaw/Caddyfile"
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ setup() {
|
||||
|
||||
@test "the user docs page exists and is reachable from the service pages" {
|
||||
[ -f "$BASE/docs.html" ]
|
||||
grep -q '<a href="/docs">docs</a>' "$BASE/index.html"
|
||||
grep -q 'class="foot-btn" href="/docs"' "$BASE/index.html"
|
||||
grep -q 'id="models"' "$BASE/docs.html"
|
||||
grep -q '<base href="/">' "$BASE/docs.html"
|
||||
grep -q 'style.css' "$BASE/docs.html"
|
||||
|
||||