diff --git a/src/lib/components/ServerCard.svelte b/src/lib/components/ServerCard.svelte index 76cb242..f8b34e1 100644 --- a/src/lib/components/ServerCard.svelte +++ b/src/lib/components/ServerCard.svelte @@ -12,11 +12,8 @@ let { server, icons, monitor } = $props<{ server: Server; icons: Array<string>; - monitor?: Heartbeat; }>(); - let status = $state(4); - let hover = $state({ title: false, link: false, @@ -65,19 +62,7 @@ </script> <div - class="flex h-48 w-[28rem] flex-col gap-y-3 rounded-xl border-t-4 - {status == 99 - ? 'border-primary' - : status == 0 - ? 'border-offline' - : status == 1 - ? 'border-online' - : status == 2 - ? 'border-pending' - : status == 3 - ? 'border-maintenance' - : 'border-maintenance'} - z-0 bg-black/55 p-4 backdrop-blur-sm" + class="flex h-48 w-[28rem] flex-col gap-y-3 rounded-xl border-t-4 border-secondary z-0 bg-black/55 p-4 backdrop-blur-sm" > <div class="flex flex-row justify-between"> <div @@ -114,41 +99,6 @@ <h2 class="font-bold">{server.name}</h2> {/if} </div> - - {#if typeof server.id !== 'undefined'} - <h1 - class="w-16 rounded-md border-b-2 - {status == 0 - ? 'border-offline' - : status == 1 - ? 'border-online' - : status == 2 - ? 'border-pending' - : status == 3 - ? 'border-maintenance' - : 'border-maintenance'} - text-center text-sm - {status == 0 - ? 'text-offline' - : status == 1 - ? 'text-online' - : status == 2 - ? 'text-pending' - : status == 3 - ? 'text-maintenance' - : 'text-maintenance'}" - > - {status == 0 - ? 'Offline' - : status == 1 - ? 'Online' - : status == 2 - ? 'Pending' - : status == 3 - ? 'Maint.' - : 'Loading'} - </h1> - {/if} </div> <p class="text-wrap text-center text-sm">{server.desc}</p> {#if typeof server.connection !== 'undefined'} diff --git a/src/lib/components/ServiceCard.svelte b/src/lib/components/ServiceCard.svelte index 86bceb8..8edb54c 100644 --- a/src/lib/components/ServiceCard.svelte +++ b/src/lib/components/ServiceCard.svelte @@ -57,17 +57,7 @@ </script> <div - class="flex h-48 w-[28rem] flex-col gap-y-3 rounded-xl border-t-4 - {status == 0 - ? 'border-offline' - : status == 1 - ? 'border-online' - : status == 2 - ? 'border-pending' - : status == 3 - ? 'border-maintenance' - : 'border-maintenance'} - z-0 bg-black/55 p-4 backdrop-blur-sm" + class="flex h-48 w-[28rem] flex-col gap-y-3 rounded-xl border-t-4 border-secondary z-0 bg-black/55 p-4 backdrop-blur-sm" > <div class="flex flex-row justify-between"> <div @@ -100,39 +90,6 @@ </div> {/if} </div> - - <h1 - class="w-16 rounded-md border-b-2 - {status == 0 - ? 'border-offline' - : status == 1 - ? 'border-online' - : status == 2 - ? 'border-pending' - : status == 3 - ? 'border-maintenance' - : 'border-maintenance'} - text-center text-sm - {status == 0 - ? 'text-offline' - : status == 1 - ? 'text-online' - : status == 2 - ? 'text-pending' - : status == 3 - ? 'text-maintenance' - : 'text-maintenance'}" - > - {status == 0 - ? 'Offline' - : status == 1 - ? 'Online' - : status == 2 - ? 'Pending' - : status == 3 - ? 'Maint.' - : 'Loading'} - </h1> </div> <p class="text-wrap text-center text-sm">{service.desc}</p> <p class="text-center text-sm font-bold text-destructive">{service.warn}</p> diff --git a/src/routes/servers/+page.server.ts b/src/routes/servers/+page.server.ts deleted file mode 100644 index f9ba6b5..0000000 --- a/src/routes/servers/+page.server.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { io, Socket } from 'socket.io-client'; -import * as fs from 'fs'; - -export async function load() { - const promise = getJwt(); - - return { - promise - }; -} - -async function getJwt(): Promise<string> { - const socket = io('https://status.neshweb.net/'); - const credFile = './credentials.json'; - let token = ''; - let valid = false; - - if (fs.existsSync(credFile)) { - const content = fs.readFileSync(credFile); - token = content.toString(); - } - - socket.on('connect', async () => { - if (token == '') { - token = await login(socket); - valid = true; - } else { - socket.emit('loginByToken', token, async (res) => { - if (!res.ok) { - token = await login(socket); - } - valid = true; - }); - } - }); - - while (!valid) { - await new Promise((resolve) => setTimeout(resolve, 10)); - } - - fs.writeFileSync(credFile, token); - - return token; -} - -async function login(socket: Socket): Promise<string> { - let token = ''; - socket.emit( - 'login', - { username: process.env.KUMA_USERNAME, password: process.env.KUMA_PASSWORD, token: '' }, - (res: { token: string }) => { - token = res.token; - socket.close(); - } - ); - - while (token == '') { - await new Promise((resolve) => setTimeout(resolve, 10)); - } - - return token; -} diff --git a/src/routes/servers/+page.svelte b/src/routes/servers/+page.svelte index b1a6ab6..5479ef8 100644 --- a/src/routes/servers/+page.svelte +++ b/src/routes/servers/+page.svelte @@ -8,56 +8,10 @@ import { socketStore } from '$lib/stores/socketStore'; import { uptimeStore } from '$lib/stores/uptimeStore'; - let { data }: { data: { promise: Promise<string> } } = $props(); - - let token = $state(); - - data.promise.then((jwt) => { - token = jwt; - }); - let servers: readonly Server[] = $state.frozen([]); let icons: readonly string[] = $state.frozen([]); - let monitorList = $state($uptimeStore); - - let socket = $socketStore; - - $effect(() => { - if (token) { - if (!socket.connected) { - socket.connect(); - } - - socket.on('connect', () => { - socket.emit('loginByToken', token, () => {}); - }); - - socket.on('heartbeatList', (_, data) => { - let recent = data[data.length - 1]; - let monitor: Heartbeat = { - monitorID: recent.monitor_id, - status: recent.status, - time: recent.time, - msg: recent.msg, - ping: recent.ping, - important: recent.important, - duration: recent.duration - }; - monitorList.set(monitor.monitorID, monitor); - monitorList = new Map(monitorList.entries()); - $uptimeStore = monitorList; - }); - - socket.on('heartbeat', (data) => { - monitorList.set(data.monitorID, data); - monitorList = new Map(monitorList.entries()); - $uptimeStore = monitorList; - }); - } - }); - async function get(url: string): Promise<any> { let res = await fetch(url); if (res.ok) { @@ -91,7 +45,7 @@ {#if typeof server.id === 'undefined'} <ServerCard {server} {icons} /> {:else} - <ServerCard {server} {icons} monitor={monitorList.get(server.id)} /> + <ServerCard {server} {icons} /> {/if} {/each} </div> diff --git a/src/routes/services/+page.server.ts b/src/routes/services/+page.server.ts deleted file mode 100644 index f9ba6b5..0000000 --- a/src/routes/services/+page.server.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { io, Socket } from 'socket.io-client'; -import * as fs from 'fs'; - -export async function load() { - const promise = getJwt(); - - return { - promise - }; -} - -async function getJwt(): Promise<string> { - const socket = io('https://status.neshweb.net/'); - const credFile = './credentials.json'; - let token = ''; - let valid = false; - - if (fs.existsSync(credFile)) { - const content = fs.readFileSync(credFile); - token = content.toString(); - } - - socket.on('connect', async () => { - if (token == '') { - token = await login(socket); - valid = true; - } else { - socket.emit('loginByToken', token, async (res) => { - if (!res.ok) { - token = await login(socket); - } - valid = true; - }); - } - }); - - while (!valid) { - await new Promise((resolve) => setTimeout(resolve, 10)); - } - - fs.writeFileSync(credFile, token); - - return token; -} - -async function login(socket: Socket): Promise<string> { - let token = ''; - socket.emit( - 'login', - { username: process.env.KUMA_USERNAME, password: process.env.KUMA_PASSWORD, token: '' }, - (res: { token: string }) => { - token = res.token; - socket.close(); - } - ); - - while (token == '') { - await new Promise((resolve) => setTimeout(resolve, 10)); - } - - return token; -} diff --git a/src/routes/services/+page.svelte b/src/routes/services/+page.svelte index 36afcdf..2f36d21 100644 --- a/src/routes/services/+page.svelte +++ b/src/routes/services/+page.svelte @@ -9,56 +9,10 @@ import { onDestroy } from 'svelte'; import { uptimeStore } from '$lib/stores/uptimeStore'; - let { data }: { data: { promise: Promise<string> } } = $props(); - - let token = $state(); - - data.promise.then((jwt) => { - token = jwt; - }); - let services: readonly Service[] = $state.frozen([]); let icons: readonly string[] = $state.frozen([]); - let monitorList = $state($uptimeStore); - - let socket = $socketStore; - - $effect(() => { - if (token) { - if (!socket.connected) { - socket.connect(); - } - - socket.on('connect', () => { - socket.emit('loginByToken', token, () => {}); - }); - - socket.on('heartbeatList', (_, data) => { - let recent = data[data.length - 1]; - let monitor: Heartbeat = { - monitorID: recent.monitor_id, - status: recent.status, - time: recent.time, - msg: recent.msg, - ping: recent.ping, - important: recent.important, - duration: recent.duration - }; - monitorList.set(monitor.monitorID, monitor); - monitorList = new Map(monitorList.entries()); - $uptimeStore = monitorList; - }); - - socket.on('heartbeat', (data) => { - monitorList.set(data.monitorID, data); - monitorList = new Map(monitorList.entries()); - $uptimeStore = monitorList; - }); - } - }); - async function get(url: string): Promise<any> { let res = await fetch(url); if (res.ok) { @@ -89,6 +43,6 @@ <div class="flex max-h-full flex-row flex-wrap justify-center gap-10 overflow-auto p-8"> {#each services as service} - <ServiceCard {service} {icons} monitor={monitorList.get(service.id)} /> + <ServiceCard {service} {icons} /> {/each} </div> diff --git a/static/assets/icons/calibre-logo-36.avif b/static/assets/icons/calibre-logo-36.avif deleted file mode 100644 index 701b81a..0000000 Binary files a/static/assets/icons/calibre-logo-36.avif and /dev/null differ diff --git a/static/assets/icons/calibre-logo.avif b/static/assets/icons/calibre-logo.avif deleted file mode 100644 index 060df19..0000000 Binary files a/static/assets/icons/calibre-logo.avif and /dev/null differ diff --git a/static/assets/icons/calibre-logo.ico b/static/assets/icons/calibre-logo.ico deleted file mode 100644 index 0774d0f..0000000 Binary files a/static/assets/icons/calibre-logo.ico and /dev/null differ diff --git a/static/assets/icons/chevereto-logo.png b/static/assets/icons/chevereto-logo.png new file mode 100644 index 0000000..92dc1e0 Binary files /dev/null and b/static/assets/icons/chevereto-logo.png differ diff --git a/static/assets/icons/element-logo.svg b/static/assets/icons/element-logo.svg deleted file mode 100644 index 54a91b7..0000000 --- a/static/assets/icons/element-logo.svg +++ /dev/null @@ -1,7 +0,0 @@ -<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M100 200C155.228 200 200 155.228 200 100C200 44.7715 155.228 0 100 0C44.7715 0 0 44.7715 0 100C0 155.228 44.7715 200 100 200Z" fill="#0DBD8B"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M81.7169 46.5946C81.7169 42.5581 84.9959 39.2859 89.0408 39.2859C116.456 39.2859 138.681 61.4642 138.681 88.8225C138.681 92.859 135.401 96.1312 131.357 96.1312C127.312 96.1312 124.033 92.859 124.033 88.8225C124.033 69.5372 108.366 53.9033 89.0408 53.9033C84.9959 53.9033 81.7169 50.6311 81.7169 46.5946Z" fill="white"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M153.39 81.5137C157.435 81.5137 160.714 84.7859 160.714 88.8224C160.714 116.181 138.49 138.359 111.075 138.359C107.03 138.359 103.751 135.087 103.751 131.05C103.751 127.014 107.03 123.742 111.075 123.742C130.4 123.742 146.066 108.108 146.066 88.8224C146.066 84.7859 149.345 81.5137 153.39 81.5137Z" fill="white"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M118.398 153.405C118.398 157.442 115.119 160.714 111.074 160.714C83.6592 160.714 61.4347 138.536 61.4347 111.177C61.4347 107.141 64.7138 103.869 68.7587 103.869C72.8035 103.869 76.0826 107.141 76.0826 111.177C76.0826 130.463 91.7489 146.097 111.074 146.097C115.119 146.097 118.398 149.369 118.398 153.405Z" fill="white"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M46.6097 118.486C42.5648 118.486 39.2858 115.214 39.2858 111.178C39.2858 83.8193 61.5102 61.6409 88.9255 61.6409C92.9704 61.6409 96.2494 64.9132 96.2494 68.9497C96.2494 72.9862 92.9704 76.2584 88.9255 76.2584C69.6 76.2584 53.9337 91.8922 53.9337 111.178C53.9337 115.214 50.6546 118.486 46.6097 118.486Z" fill="white"/> -</svg> diff --git a/static/assets/icons/forgejo-logo.svg b/static/assets/icons/forgejo-logo.svg new file mode 100644 index 0000000..9c390e9 --- /dev/null +++ b/static/assets/icons/forgejo-logo.svg @@ -0,0 +1,40 @@ +<svg viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg"> + <metadata + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/" + > + <rdf:RDF> + <cc:Work rdf:about="https://codeberg.org/forgejo/governance/src/branch/main/branding#logo"> + <dc:title>Forgejo logo</dc:title> + <cc:creator rdf:resource="https://caesarschinas.com/"><cc:attributionName>Caesar Schinas</cc:attributionName></cc:creator> + <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> + </cc:Work> + </rdf:RDF> + </metadata> + <style type="text/css"> + circle { + fill: none; + stroke: #000; + stroke-width: 15; + } + path { + fill: none; + stroke: #000; + stroke-width: 25; + } + .orange { + stroke:#ff6600; + } + .red { + stroke:#d40000; + } + </style> + <g transform="translate(28,28)"> + <path d="M58 168 v-98 a50 50 0 0 1 50-50 h20" class="orange" /> + <path d="M58 168 v-30 a50 50 0 0 1 50-50 h20" class="red" /> + <circle cx="142" cy="20" r="18" class="orange" /> + <circle cx="142" cy="88" r="18" class="red" /> + <circle cx="58" cy="180" r="18" class="red" /> + </g> +</svg> diff --git a/static/assets/icons/gitlab-logo.svg b/static/assets/icons/gitlab-logo.svg deleted file mode 100644 index 5fabd74..0000000 --- a/static/assets/icons/gitlab-logo.svg +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - viewBox="-4 -8 200 200.00003" - version="1.1" - id="svg15" - sodipodi:docname="gitlab-logo.svg" - width="200" - height="200" - inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns="http://www.w3.org/2000/svg" - xmlns:svg="http://www.w3.org/2000/svg"> - <sodipodi:namedview - id="namedview17" - pagecolor="#505050" - bordercolor="#eeeeee" - borderopacity="1" - inkscape:showpageshadow="0" - inkscape:pageopacity="0" - inkscape:pagecheckerboard="0" - inkscape:deskcolor="#505050" - showgrid="false" - inkscape:zoom="2.7026316" - inkscape:cx="95.832522" - inkscape:cy="92.132425" - inkscape:window-width="2560" - inkscape:window-height="1391" - inkscape:window-x="0" - inkscape:window-y="0" - inkscape:window-maximized="1" - inkscape:current-layer="svg15" /> - <defs - id="defs4"> - <style - id="style2">.cls-1{fill:#e24329;}.cls-2{fill:#fc6d26;}.cls-3{fill:#fca326;}</style> - </defs> - <g - id="LOGO" - transform="translate(-93.973245,-97.517263)"> - <path - class="cls-1" - d="m 282.83,170.73 -0.27,-0.69 -26.14,-68.22 a 6.81,6.81 0 0 0 -2.69,-3.24 7,7 0 0 0 -8,0.43 7,7 0 0 0 -2.32,3.52 l -17.65,54 h -71.47 l -17.65,-54 a 6.86,6.86 0 0 0 -2.32,-3.53 7,7 0 0 0 -8,-0.43 6.87,6.87 0 0 0 -2.69,3.24 L 97.44,170 l -0.26,0.69 a 48.54,48.54 0 0 0 16.1,56.1 l 0.09,0.07 0.24,0.17 39.82,29.82 19.7,14.91 12,9.06 a 8.07,8.07 0 0 0 9.76,0 l 12,-9.06 19.7,-14.91 40.06,-30 0.1,-0.08 a 48.56,48.56 0 0 0 16.08,-56.04 z" - id="path6" /> - <path - class="cls-2" - d="m 282.83,170.73 -0.27,-0.69 a 88.3,88.3 0 0 0 -35.15,15.8 L 190,229.25 c 19.55,14.79 36.57,27.64 36.57,27.64 l 40.06,-30 0.1,-0.08 a 48.56,48.56 0 0 0 16.1,-56.08 z" - id="path8" /> - <path - class="cls-3" - d="m 153.43,256.89 19.7,14.91 12,9.06 a 8.07,8.07 0 0 0 9.76,0 l 12,-9.06 19.7,-14.91 c 0,0 -17.04,-12.89 -36.59,-27.64 -19.55,14.75 -36.57,27.64 -36.57,27.64 z" - id="path10" /> - <path - class="cls-2" - d="M 132.58,185.84 A 88.19,88.19 0 0 0 97.44,170 l -0.26,0.69 a 48.54,48.54 0 0 0 16.1,56.1 l 0.09,0.07 0.24,0.17 39.82,29.82 c 0,0 17,-12.85 36.57,-27.64 z" - id="path12" /> - </g> -</svg> diff --git a/static/assets/icons/grafana-logo.svg b/static/assets/icons/grafana-logo.svg deleted file mode 100644 index e91f3ab..0000000 --- a/static/assets/icons/grafana-logo.svg +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" - width="351px" height="365px" viewBox="0 0 351 365" style="enable-background:new 0 0 351 365;" xml:space="preserve"> -<style type="text/css"> - .st0{fill:url(#SVGID_1_);} -</style> -<g id="Layer_1_1_"> -</g> -<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="175.5" y1="30%" x2="175.5" y2="99%"> - <stop offset="0" style="stop-color:#F05A28"/> - <stop offset="1" style="stop-color:#FBCA0A"/> -</linearGradient> -<path class="st0" d="M342,161.2c-0.6-6.1-1.6-13.1-3.6-20.9c-2-7.7-5-16.2-9.4-25c-4.4-8.8-10.1-17.9-17.5-26.8 - c-2.9-3.5-6.1-6.9-9.5-10.2c5.1-20.3-6.2-37.9-6.2-37.9c-19.5-1.2-31.9,6.1-36.5,9.4c-0.8-0.3-1.5-0.7-2.3-1 - c-3.3-1.3-6.7-2.6-10.3-3.7c-3.5-1.1-7.1-2.1-10.8-3c-3.7-0.9-7.4-1.6-11.2-2.2c-0.7-0.1-1.3-0.2-2-0.3 - c-8.5-27.2-32.9-38.6-32.9-38.6c-27.3,17.3-32.4,41.5-32.4,41.5s-0.1,0.5-0.3,1.4c-1.5,0.4-3,0.9-4.5,1.3c-2.1,0.6-4.2,1.4-6.2,2.2 - c-2.1,0.8-4.1,1.6-6.2,2.5c-4.1,1.8-8.2,3.8-12.2,6c-3.9,2.2-7.7,4.6-11.4,7.1c-0.5-0.2-1-0.4-1-0.4c-37.8-14.4-71.3,2.9-71.3,2.9 - c-3.1,40.2,15.1,65.5,18.7,70.1c-0.9,2.5-1.7,5-2.5,7.5c-2.8,9.1-4.9,18.4-6.2,28.1c-0.2,1.4-0.4,2.8-0.5,4.2 - C18.8,192.7,8.5,228,8.5,228c29.1,33.5,63.1,35.6,63.1,35.6c0,0,0.1-0.1,0.1-0.1c4.3,7.7,9.3,15,14.9,21.9c2.4,2.9,4.8,5.6,7.4,8.3 - c-10.6,30.4,1.5,55.6,1.5,55.6c32.4,1.2,53.7-14.2,58.2-17.7c3.2,1.1,6.5,2.1,9.8,2.9c10,2.6,20.2,4.1,30.4,4.5 - c2.5,0.1,5.1,0.2,7.6,0.1l1.2,0l0.8,0l1.6,0l1.6-0.1l0,0.1c15.3,21.8,42.1,24.9,42.1,24.9c19.1-20.1,20.2-40.1,20.2-44.4l0,0 - c0,0,0-0.1,0-0.3c0-0.4,0-0.6,0-0.6l0,0c0-0.3,0-0.6,0-0.9c4-2.8,7.8-5.8,11.4-9.1c7.6-6.9,14.3-14.8,19.9-23.3 - c0.5-0.8,1-1.6,1.5-2.4c21.6,1.2,36.9-13.4,36.9-13.4c-3.6-22.5-16.4-33.5-19.1-35.6l0,0c0,0-0.1-0.1-0.3-0.2 - c-0.2-0.1-0.2-0.2-0.2-0.2c0,0,0,0,0,0c-0.1-0.1-0.3-0.2-0.5-0.3c0.1-1.4,0.2-2.7,0.3-4.1c0.2-2.4,0.2-4.9,0.2-7.3l0-1.8l0-0.9 - l0-0.5c0-0.6,0-0.4,0-0.6l-0.1-1.5l-0.1-2c0-0.7-0.1-1.3-0.2-1.9c-0.1-0.6-0.1-1.3-0.2-1.9l-0.2-1.9l-0.3-1.9 - c-0.4-2.5-0.8-4.9-1.4-7.4c-2.3-9.7-6.1-18.9-11-27.2c-5-8.3-11.2-15.6-18.3-21.8c-7-6.2-14.9-11.2-23.1-14.9 - c-8.3-3.7-16.9-6.1-25.5-7.2c-4.3-0.6-8.6-0.8-12.9-0.7l-1.6,0l-0.4,0c-0.1,0-0.6,0-0.5,0l-0.7,0l-1.6,0.1c-0.6,0-1.2,0.1-1.7,0.1 - c-2.2,0.2-4.4,0.5-6.5,0.9c-8.6,1.6-16.7,4.7-23.8,9c-7.1,4.3-13.3,9.6-18.3,15.6c-5,6-8.9,12.7-11.6,19.6c-2.7,6.9-4.2,14.1-4.6,21 - c-0.1,1.7-0.1,3.5-0.1,5.2c0,0.4,0,0.9,0,1.3l0.1,1.4c0.1,0.8,0.1,1.7,0.2,2.5c0.3,3.5,1,6.9,1.9,10.1c1.9,6.5,4.9,12.4,8.6,17.4 - c3.7,5,8.2,9.1,12.9,12.4c4.7,3.2,9.8,5.5,14.8,7c5,1.5,10,2.1,14.7,2.1c0.6,0,1.2,0,1.7,0c0.3,0,0.6,0,0.9,0c0.3,0,0.6,0,0.9-0.1 - c0.5,0,1-0.1,1.5-0.1c0.1,0,0.3,0,0.4-0.1l0.5-0.1c0.3,0,0.6-0.1,0.9-0.1c0.6-0.1,1.1-0.2,1.7-0.3c0.6-0.1,1.1-0.2,1.6-0.4 - c1.1-0.2,2.1-0.6,3.1-0.9c2-0.7,4-1.5,5.7-2.4c1.8-0.9,3.4-2,5-3c0.4-0.3,0.9-0.6,1.3-1c1.6-1.3,1.9-3.7,0.6-5.3 - c-1.1-1.4-3.1-1.8-4.7-0.9c-0.4,0.2-0.8,0.4-1.2,0.6c-1.4,0.7-2.8,1.3-4.3,1.8c-1.5,0.5-3.1,0.9-4.7,1.2c-0.8,0.1-1.6,0.2-2.5,0.3 - c-0.4,0-0.8,0.1-1.3,0.1c-0.4,0-0.9,0-1.2,0c-0.4,0-0.8,0-1.2,0c-0.5,0-1,0-1.5-0.1c0,0-0.3,0-0.1,0l-0.2,0l-0.3,0 - c-0.2,0-0.5,0-0.7-0.1c-0.5-0.1-0.9-0.1-1.4-0.2c-3.7-0.5-7.4-1.6-10.9-3.2c-3.6-1.6-7-3.8-10.1-6.6c-3.1-2.8-5.8-6.1-7.9-9.9 - c-2.1-3.8-3.6-8-4.3-12.4c-0.3-2.2-0.5-4.5-0.4-6.7c0-0.6,0.1-1.2,0.1-1.8c0,0.2,0-0.1,0-0.1l0-0.2l0-0.5c0-0.3,0.1-0.6,0.1-0.9 - c0.1-1.2,0.3-2.4,0.5-3.6c1.7-9.6,6.5-19,13.9-26.1c1.9-1.8,3.9-3.4,6-4.9c2.1-1.5,4.4-2.8,6.8-3.9c2.4-1.1,4.8-2,7.4-2.7 - c2.5-0.7,5.1-1.1,7.8-1.4c1.3-0.1,2.6-0.2,4-0.2c0.4,0,0.6,0,0.9,0l1.1,0l0.7,0c0.3,0,0,0,0.1,0l0.3,0l1.1,0.1 - c2.9,0.2,5.7,0.6,8.5,1.3c5.6,1.2,11.1,3.3,16.2,6.1c10.2,5.7,18.9,14.5,24.2,25.1c2.7,5.3,4.6,11,5.5,16.9c0.2,1.5,0.4,3,0.5,4.5 - l0.1,1.1l0.1,1.1c0,0.4,0,0.8,0,1.1c0,0.4,0,0.8,0,1.1l0,1l0,1.1c0,0.7-0.1,1.9-0.1,2.6c-0.1,1.6-0.3,3.3-0.5,4.9 - c-0.2,1.6-0.5,3.2-0.8,4.8c-0.3,1.6-0.7,3.2-1.1,4.7c-0.8,3.1-1.8,6.2-3,9.3c-2.4,6-5.6,11.8-9.4,17.1 - c-7.7,10.6-18.2,19.2-30.2,24.7c-6,2.7-12.3,4.7-18.8,5.7c-3.2,0.6-6.5,0.9-9.8,1l-0.6,0l-0.5,0l-1.1,0l-1.6,0l-0.8,0 - c0.4,0-0.1,0-0.1,0l-0.3,0c-1.8,0-3.5-0.1-5.3-0.3c-7-0.5-13.9-1.8-20.7-3.7c-6.7-1.9-13.2-4.6-19.4-7.8 - c-12.3-6.6-23.4-15.6-32-26.5c-4.3-5.4-8.1-11.3-11.2-17.4c-3.1-6.1-5.6-12.6-7.4-19.1c-1.8-6.6-2.9-13.3-3.4-20.1l-0.1-1.3l0-0.3 - l0-0.3l0-0.6l0-1.1l0-0.3l0-0.4l0-0.8l0-1.6l0-0.3c0,0,0,0.1,0-0.1l0-0.6c0-0.8,0-1.7,0-2.5c0.1-3.3,0.4-6.8,0.8-10.2 - c0.4-3.4,1-6.9,1.7-10.3c0.7-3.4,1.5-6.8,2.5-10.2c1.9-6.7,4.3-13.2,7.1-19.3c5.7-12.2,13.1-23.1,22-31.8c2.2-2.2,4.5-4.2,6.9-6.2 - c2.4-1.9,4.9-3.7,7.5-5.4c2.5-1.7,5.2-3.2,7.9-4.6c1.3-0.7,2.7-1.4,4.1-2c0.7-0.3,1.4-0.6,2.1-0.9c0.7-0.3,1.4-0.6,2.1-0.9 - c2.8-1.2,5.7-2.2,8.7-3.1c0.7-0.2,1.5-0.4,2.2-0.7c0.7-0.2,1.5-0.4,2.2-0.6c1.5-0.4,3-0.8,4.5-1.1c0.7-0.2,1.5-0.3,2.3-0.5 - c0.8-0.2,1.5-0.3,2.3-0.5c0.8-0.1,1.5-0.3,2.3-0.4l1.1-0.2l1.2-0.2c0.8-0.1,1.5-0.2,2.3-0.3c0.9-0.1,1.7-0.2,2.6-0.3 - c0.7-0.1,1.9-0.2,2.6-0.3c0.5-0.1,1.1-0.1,1.6-0.2l1.1-0.1l0.5-0.1l0.6,0c0.9-0.1,1.7-0.1,2.6-0.2l1.3-0.1c0,0,0.5,0,0.1,0l0.3,0 - l0.6,0c0.7,0,1.5-0.1,2.2-0.1c2.9-0.1,5.9-0.1,8.8,0c5.8,0.2,11.5,0.9,17,1.9c11.1,2.1,21.5,5.6,31,10.3 - c9.5,4.6,17.9,10.3,25.3,16.5c0.5,0.4,0.9,0.8,1.4,1.2c0.4,0.4,0.9,0.8,1.3,1.2c0.9,0.8,1.7,1.6,2.6,2.4c0.9,0.8,1.7,1.6,2.5,2.4 - c0.8,0.8,1.6,1.6,2.4,2.5c3.1,3.3,6,6.6,8.6,10c5.2,6.7,9.4,13.5,12.7,19.9c0.2,0.4,0.4,0.8,0.6,1.2c0.2,0.4,0.4,0.8,0.6,1.2 - c0.4,0.8,0.8,1.6,1.1,2.4c0.4,0.8,0.7,1.5,1.1,2.3c0.3,0.8,0.7,1.5,1,2.3c1.2,3,2.4,5.9,3.3,8.6c1.5,4.4,2.6,8.3,3.5,11.7 - c0.3,1.4,1.6,2.3,3,2.1c1.5-0.1,2.6-1.3,2.6-2.8C342.6,170.4,342.5,166.1,342,161.2z"/> -</svg> diff --git a/static/assets/icons/kavita-logo.svg b/static/assets/icons/kavita-logo.svg new file mode 100644 index 0000000..f56f8a7 --- /dev/null +++ b/static/assets/icons/kavita-logo.svg @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve"> +<g> + <g> + <g> + <path fill="#4AC694" d="M32,0c17.7,0,32,14.3,32,32S49.7,64,32,64S0,49.7,0,32S14.3,0,32,0z"/> + </g> + </g> + <g> + <g> + <path fill="#424C72" d="M52,17H12c-0.6,0-1,0.4-1,1v30c0,0.6,0.4,1,1,1h14.3c1,0,1.9,0.4,2.4,1.2c0.7,1.1,1.9,1.8,3.3,1.8 + s2.6-0.7,3.3-1.8c0.5-0.8,1.5-1.2,2.4-1.2H52c0.6,0,1-0.4,1-1V18C53,17.4,52.6,17,52,17z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M14,28v18h16c1.1,0,2,0.9,2,2c0-1.1,0.9-2,2-2h16V28H14z"/> + </g> + </g> + <g> + <g> + <path fill="#FFFFFF" d="M35,13c-1.7,0-3,1.3-3,3c0-1.7-1.3-3-3-3H14v31h16c1.1,0,2,0.9,2,2c0-1.1,0.9-2,2-2h16V13H35z"/> + </g> + </g> + <g> + <g> + <rect x="18" y="16" fill="#57D1F7" width="4" height="7"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,26.5H18c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S29.3,26.5,29,26.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,23.5h-4.4c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5H29c0.3,0,0.5,0.2,0.5,0.5S29.3,23.5,29,23.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,20.5h-4.4c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5H29c0.3,0,0.5,0.2,0.5,0.5S29.3,20.5,29,20.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,17.5h-4.4c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5H29c0.3,0,0.5,0.2,0.5,0.5S29.3,17.5,29,17.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,29.5H18c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S29.3,29.5,29,29.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,32.5H18c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S29.3,32.5,29,32.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,35.5H18c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S29.3,35.5,29,35.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,38.5H18c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S29.3,38.5,29,38.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M29,41.5H18c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S29.3,41.5,29,41.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,26.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,26.5,46,26.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,29.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,29.5,46,29.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,20.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,20.5,46,20.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,17.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,17.5,46,17.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,23.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,23.5,46,23.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,32.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,32.5,46,32.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,35.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,35.5,46,35.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,38.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,38.5,46,38.5z"/> + </g> + </g> + <g> + <g> + <path fill="#E4E7EF" d="M46,41.5H35c-0.3,0-0.5-0.2-0.5-0.5s0.2-0.5,0.5-0.5h11c0.3,0,0.5,0.2,0.5,0.5S46.3,41.5,46,41.5z"/> + </g> + </g> +</g> +</svg> diff --git a/static/assets/icons/npm-logo-36.avif b/static/assets/icons/npm-logo-36.avif deleted file mode 100644 index ea9642e..0000000 Binary files a/static/assets/icons/npm-logo-36.avif and /dev/null differ diff --git a/static/assets/icons/npm-logo.avif b/static/assets/icons/npm-logo.avif deleted file mode 100644 index 69fe17e..0000000 Binary files a/static/assets/icons/npm-logo.avif and /dev/null differ diff --git a/static/assets/icons/npm-logo.png b/static/assets/icons/npm-logo.png deleted file mode 100644 index 2bfb661..0000000 Binary files a/static/assets/icons/npm-logo.png and /dev/null differ diff --git a/static/assets/icons/portainer-logo-36.avif b/static/assets/icons/portainer-logo-36.avif deleted file mode 100644 index ac045d4..0000000 Binary files a/static/assets/icons/portainer-logo-36.avif and /dev/null differ diff --git a/static/assets/icons/portainer-logo.avif b/static/assets/icons/portainer-logo.avif deleted file mode 100644 index 256bf2c..0000000 Binary files a/static/assets/icons/portainer-logo.avif and /dev/null differ diff --git a/static/assets/icons/portainer-logo.png b/static/assets/icons/portainer-logo.png deleted file mode 100644 index b4bfd29..0000000 Binary files a/static/assets/icons/portainer-logo.png and /dev/null differ diff --git a/static/assets/icons/roundcube-logo.svg b/static/assets/icons/roundcube-logo.svg new file mode 100644 index 0000000..04238a0 --- /dev/null +++ b/static/assets/icons/roundcube-logo.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="9.14 141.8 573.65 573.65"> +<style type="text/css"> +.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#404F54;} +.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#E5E5E5;} +.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#CCCCCC;} +.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#37BEFF;} +</style> +<polygon class="st3" points="582.79,549.77 295.96,384.1 295.96,207.27 582.79,372.95 "/> +<polygon class="st0" points="9.14,549.77 295.96,384.1 295.96,207.27 9.14,372.95 "/> +<path class="st2" d="M295.96,141.8c109.56,0,198.41,88.85,198.41,198.41c0,109.56-88.85,198.41-198.41,198.41 c-109.56,0-198.41-88.85-198.41-198.41C97.55,230.65,186.4,141.8,295.96,141.8"/> +<path class="st1" d="M295.96,141.8c109.6,0,198.48,88.85,198.48,198.41c0,109.56-88.88,198.41-198.48,198.41 c-62.91-42.34-88.94-127.64-88.94-198.3S233.05,184.22,295.96,141.8"/> +<polygon class="st3" points="582.79,372.95 295.96,538.62 295.96,715.45 582.79,549.77 "/> +<polygon class="st0" points="9.14,372.95 295.96,538.62 295.96,715.45 9.14,549.77 "/> +</svg> \ No newline at end of file diff --git a/static/assets/icons/vaultwarden-logo.svg b/static/assets/icons/vaultwarden-logo.svg new file mode 100644 index 0000000..91abbd6 --- /dev/null +++ b/static/assets/icons/vaultwarden-logo.svg @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg version="1.1" viewBox="0 0 256 256" id="svg383" sodipodi:docname="vaultwarden-icon.svg" inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)" width="256" height="256" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <defs id="defs387" /> + <sodipodi:namedview id="namedview385" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" showgrid="false" inkscape:zoom="3.3359375" inkscape:cx="128" inkscape:cy="128" inkscape:window-width="1874" inkscape:window-height="1056" inkscape:window-x="46" inkscape:window-y="24" inkscape:window-maximized="1" inkscape:current-layer="svg383" /> + <title id="title287">Vaultwarden Icon</title> + <g id="logo" transform="matrix(2.4381018,0,0,2.4381018,128,128)"> + <g id="gear" mask="url(#holes)"> + <path d="m-31.1718-33.813208 26.496029 74.188883h9.3515399l26.49603-74.188883h-9.767164l-16.728866 47.588948q-1.662496 4.571864-2.805462 8.624198-1.142966 3.948427-1.870308 7.585137-.72734199-3.63671-1.8703079-7.689043-1.142966-4.052334-2.805462-8.728104l-16.624959-47.381136z" stroke="#000" stroke-width="4.51171" id="path289" /> + <circle transform="scale(-1,1)" r="43" fill="none" stroke="#000" stroke-width="9" id="circle291" /> + <g id="cogs" transform="scale(-1,1)"> + <polygon id="cog" points="51 0 46 -3 46 3" stroke="#000" stroke-linejoin="round" stroke-width="3" /> + <use transform="rotate(11.25)" xlink:href="#cog" id="use294" /> + <use transform="rotate(22.5)" xlink:href="#cog" id="use296" /> + <use transform="rotate(33.75)" xlink:href="#cog" id="use298" /> + <use transform="rotate(45)" xlink:href="#cog" id="use300" /> + <use transform="rotate(56.25)" xlink:href="#cog" id="use302" /> + <use transform="rotate(67.5)" xlink:href="#cog" id="use304" /> + <use transform="rotate(78.75)" xlink:href="#cog" id="use306" /> + <use transform="rotate(90)" xlink:href="#cog" id="use308" /> + <use transform="rotate(101.25)" xlink:href="#cog" id="use310" /> + <use transform="rotate(112.5)" xlink:href="#cog" id="use312" /> + <use transform="rotate(123.75)" xlink:href="#cog" id="use314" /> + <use transform="rotate(135)" xlink:href="#cog" id="use316" /> + <use transform="rotate(146.25)" xlink:href="#cog" id="use318" /> + <use transform="rotate(157.5)" xlink:href="#cog" id="use320" /> + <use transform="rotate(168.75)" xlink:href="#cog" id="use322" /> + <use transform="scale(-1)" xlink:href="#cog" id="use324" /> + <use transform="rotate(191.25)" xlink:href="#cog" id="use326" /> + <use transform="rotate(202.5)" xlink:href="#cog" id="use328" /> + <use transform="rotate(213.75)" xlink:href="#cog" id="use330" /> + <use transform="rotate(225)" xlink:href="#cog" id="use332" /> + <use transform="rotate(236.25)" xlink:href="#cog" id="use334" /> + <use transform="rotate(247.5)" xlink:href="#cog" id="use336" /> + <use transform="rotate(258.75)" xlink:href="#cog" id="use338" /> + <use transform="rotate(-90)" xlink:href="#cog" id="use340" /> + <use transform="rotate(-78.75)" xlink:href="#cog" id="use342" /> + <use transform="rotate(-67.5)" xlink:href="#cog" id="use344" /> + <use transform="rotate(-56.25)" xlink:href="#cog" id="use346" /> + <use transform="rotate(-45)" xlink:href="#cog" id="use348" /> + <use transform="rotate(-33.75)" xlink:href="#cog" id="use350" /> + <use transform="rotate(-22.5)" xlink:href="#cog" id="use352" /> + <use transform="rotate(-11.25)" xlink:href="#cog" id="use354" /> + </g> + <g id="mounts" transform="scale(-1,1)"> + <polygon id="mount" points="0 -35 7 -42 -7 -42" stroke="#000" stroke-linejoin="round" stroke-width="6" /> + <use transform="rotate(72)" xlink:href="#mount" id="use358" /> + <use transform="rotate(144)" xlink:href="#mount" id="use360" /> + <use transform="rotate(216)" xlink:href="#mount" id="use362" /> + <use transform="rotate(-72)" xlink:href="#mount" id="use364" /> + </g> + </g> + <mask id="holes"> + <rect x="-60" y="-60" width="120" height="120" fill="#fff" id="rect368" /> + <circle id="hole" cy="-40" r="3" /> + <use transform="rotate(72)" xlink:href="#hole" id="use371" /> + <use transform="rotate(144)" xlink:href="#hole" id="use373" /> + <use transform="rotate(216)" xlink:href="#hole" id="use375" /> + <use transform="rotate(-72)" xlink:href="#hole" id="use377" /> + </mask> + </g> + <metadata id="metadata381"> + <rdf:RDF> + <cc:Work rdf:about=""> + <dc:title>Vaultwarden Icon</dc:title> + <dc:creator> + <cc:Agent> + <dc:title>Mathijs van Veluw</dc:title> + </cc:Agent> + </dc:creator> + <dc:relation>Rust Logo</dc:relation> + </cc:Work> + </rdf:RDF> + </metadata> +</svg> diff --git a/static/data/services.json b/static/data/services.json index 5cd849e..a9aeea1 100644 --- a/static/data/services.json +++ b/static/data/services.json @@ -3,7 +3,7 @@ "name": "Nextcloud", "icon": "/assets/icons/nextcloud-logo", "iconType": "svg", - "href": "https://nextcloud.neshweb.net/", + "href": "https://cloud.neshweb.net/", "desc": "Self-hosted Cloud Storage Service", "warn": "Note: Registration requires approval", "extLink": "https://nextcloud.com/", @@ -19,24 +19,24 @@ "id": 5 }, { - "name": "Images", - "icon": "/assets/icons/images-logo", + "name": "Roundcube Mail", + "icon": "/assets/icons/roundcube-logo", "iconType": "svg", - "href": "https://imgs.neshweb.net/", + "href": "https://mail.neshweb.net/rc", + "desc": "Self-hosted Mail Server", + "warn": "Registration via Admin invite", + "id": 5 + }, + { + "name": "Dun Scaith", + "icon": "/assets/icons/chevereto-logo", + "iconType": "png", + "href": "https://dun-scaith.com/", "desc": "Self-hosted Chevereto Image Service", "warn": "", "extLink": "https://chevereto.com/", "id": 4 }, - { - "name": "Calibre Web", - "icon": "/assets/icons/calibre-logo", - "iconType": "avif", - "href": "https://calibre.neshweb.net/", - "desc": "Self-hosted Ebook Library Service", - "warn": "Note: Registration only via Admin", - "id": 6 - }, { "name": "PeerTube", "icon": "/assets/icons/peertube-logo", @@ -77,7 +77,7 @@ "name": "Navidrome", "icon": "/assets/icons/navidrome-logo", "iconType": "avif", - "href": "https://navidrome.neshweb.net/", + "href": "https://music.neshweb.net/", "desc": "Open-Source, Self-Hosted Music Streaming Platform", "warn": "Note: Registration only via Admin", "id": 10 @@ -91,42 +91,6 @@ "warn": "Note: Registration only via Admin", "id": 36 }, - { - "name": "Portainer", - "icon": "/assets/icons/portainer-logo", - "iconType": "avif", - "href": "https://portainer.neshweb.net/", - "desc": "Docker Container Manager", - "warn": "Note: Admin Only", - "id": 34 - }, - { - "name": "Nginx", - "icon": "/assets/icons/npm-logo", - "iconType": "avif", - "href": "https://nginx.neshweb.net/", - "desc": "Web-based Nginx Proxy Manager", - "warn": "Note: Admin Only", - "id": 31 - }, - { - "name": "Proxmox", - "icon": "/assets/icons/proxmox-logo", - "iconType": "avif", - "href": "https://proxmox.neshweb.net/", - "desc": "Hypervisor Webinterface", - "warn": "Note: Admin Only", - "id": 33 - }, - { - "name": "Dockge", - "icon": "/assets/icons/dockge-logo", - "iconType": "avif", - "href": "https://dockge.neshweb.net/", - "desc": "Docker Compose WebUI", - "warn": "Note: Admin Only", - "id": 35 - }, { "name": "bookwormstory.social", "icon": "/assets/icons/bookworm-logo",