Merge branch 'main' into add-whatsupdocker-widget

This commit is contained in:
shamoon 2023-04-27 11:21:46 -07:00 committed by GitHub
commit 5934adf8c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 1949 additions and 366 deletions

View File

@ -151,7 +151,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "أفلام", "movies": "أفلام",
"tv": "مسلسلات" "tv": "مسلسلات",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "معدل", "rate": "معدل",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"scheduled": "Scheduled",
"passes": "Passes",
"shows": "Shows",
"recordings": "Recordings"
} }
} }

View File

@ -99,7 +99,8 @@
"plex": { "plex": {
"streams": "Активни Потоци", "streams": "Активни Потоци",
"movies": "Филми", "movies": "Филми",
"tv": "Сериали" "tv": "Сериали",
"albums": "Albums"
}, },
"transmission": { "transmission": {
"download": "Сваляне", "download": "Сваляне",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -183,7 +183,7 @@
"qbittorrent": { "qbittorrent": {
"download": "Descàrrega", "download": "Descàrrega",
"upload": "Pujada", "upload": "Pujada",
"leech": "Companys", "leech": "Clients",
"seed": "Llavors" "seed": "Llavors"
}, },
"mastodon": { "mastodon": {
@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Transmissions actives", "streams": "Transmissions actives",
"movies": "Pel·lícules", "movies": "Pel·lícules",
"tv": "Programes de TV" "tv": "Programes de TV",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "Processador", "cpu": "Processador",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -105,7 +105,8 @@
"plex": { "plex": {
"streams": "Aktivní streamy", "streams": "Aktivní streamy",
"movies": "Filmy", "movies": "Filmy",
"tv": "Seriály" "tv": "Seriály",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rychlost", "rate": "Rychlost",
@ -562,5 +563,20 @@
"books": "Knihy", "books": "Knihy",
"podcastsDuration": "Trvání", "podcastsDuration": "Trvání",
"booksDuration": "Trvání" "booksDuration": "Trvání"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -2,7 +2,8 @@
"plex": { "plex": {
"movies": "Film", "movies": "Film",
"tv": "TV-Shows", "tv": "TV-Shows",
"streams": "Aktive Streams" "streams": "Aktive Streams",
"albums": "Albums"
}, },
"radarr": { "radarr": {
"queued": "I Kø", "queued": "I Kø",
@ -562,5 +563,20 @@
"podcasts": "Podcasts", "podcasts": "Podcasts",
"books": "Books", "books": "Books",
"podcastsDuration": "Duration" "podcastsDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Aktive Streams", "streams": "Aktive Streams",
"movies": "Filme", "movies": "Filme",
"tv": "TV Sendungen" "tv": "TV Sendungen",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "Prozessor", "cpu": "Prozessor",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -1,25 +1,25 @@
{ {
"resources": { "resources": {
"used": "Used", "used": "χρησιμοποιημένο",
"load": "Load", "load": "Φόρτωση",
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "MEM",
"temp": "TEMP", "temp": "ΘΕΡΜΟΚΡΑΣΪΑ",
"total": "Total", "total": "Σύνολο",
"free": "Free", "free": "Δωρεάν",
"max": "Max", "max": "Μέγιστο",
"uptime": "UP", "uptime": "ΠΑΝΩ",
"months": "mo", "months": "mo",
"days": "d", "days": "d",
"hours": "h", "hours": "h",
"minutes": "m" "minutes": "m"
}, },
"omada": { "omada": {
"activeUser": "Active devices", "activeUser": "Ενεργές συσκευές",
"alerts": "Alerts", "alerts": "Ειδοποιήσεις",
"connectedAp": "Connected APs", "connectedAp": "Συνδεδεμένα APs",
"connectedGateway": "Connected gateways", "connectedGateway": "Συνδεδεμένα gateways",
"connectedSwitches": "Connected switches" "connectedSwitches": "Συνδεδεμένα switches"
}, },
"wmo": { "wmo": {
"0-night": "Clear", "0-night": "Clear",
@ -84,120 +84,121 @@
"bibitrate": "{{value, rate(bits: true; binary: true)}}" "bibitrate": "{{value, rate(bits: true; binary: true)}}"
}, },
"widget": { "widget": {
"missing_type": "Missing Widget Type: {{type}}", "missing_type": "Λείπει ο τύπος widget: {{type}}",
"api_error": "API Error", "api_error": "Σφάλμα API",
"information": "Information", "information": "Πληροφορία",
"status": "Status", "status": "Κατάσταση",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Ανεπεξέργαστο σφάλμα",
"response_data": "Response Data" "response_data": "Δεδομένα απόκρισης"
}, },
"weather": { "weather": {
"current": "Current Location", "current": "Τωρινή τοποθεσία",
"allow": "Click to allow", "allow": "Κάντε κλικ για να επιτρέψετε",
"updating": "Updating", "updating": "Ενημέρωση",
"wait": "Please wait" "wait": "Παρακαλώ περιμένετε"
}, },
"search": { "search": {
"placeholder": "Search…" "placeholder": "Αναζήτηση…"
}, },
"unifi": { "unifi": {
"users": "Users", "users": "Χρήστες",
"uptime": "System Uptime", "uptime": "Χρόνος λειτουργίας συστήματος",
"days": "Days", "days": "Ημέρες",
"wan": "WAN", "wan": "WAN",
"lan": "LAN", "lan": "LAN",
"wlan": "WLAN", "wlan": "WLAN",
"devices": "Devices", "devices": "Συσκευές",
"lan_devices": "LAN Devices", "lan_devices": "LAN Συσκευές",
"wlan_devices": "WLAN Devices", "wlan_devices": "WLAN Συσκευές",
"lan_users": "LAN Users", "lan_users": "LAN Χρήστες",
"wlan_users": "WLAN Users", "wlan_users": "WLAN Χρήστες",
"up": "UP", "up": "ΠΑΝΩ",
"down": "DOWN", "down": "ΚΑΤΩ",
"wait": "Please wait", "wait": "Παρακαλώ περιμένετε",
"empty_data": "Subsystem status unknown" "empty_data": "Άγνωστη κατάσταση υποσυστήματος"
}, },
"docker": { "docker": {
"rx": "RX", "rx": "RX",
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"running": "Running", "running": "Τρέχων",
"offline": "Offline", "offline": "Εκτός σύνδεσης",
"error": "Error", "error": "Σφάλμα",
"unknown": "Unknown", "unknown": "Άγνωστο",
"healthy": "Healthy", "healthy": "Υγειές",
"exited": "Exited", "exited": "Έκλεισε",
"starting": "Starting", "starting": "Ξεκινάει",
"partial": "Partial", "partial": "Μερικό",
"unhealthy": "Unhealthy", "unhealthy": "Άρρωστο",
"not_found": "Not Found" "not_found": "Δεν βρέθηκε"
}, },
"ping": { "ping": {
"error": "Error", "error": "Σφάλμα",
"ping": "Ping" "ping": "Ping"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Παίζει",
"transcoding": "Transcoding", "transcoding": "Διακωδικοποίηση",
"bitrate": "Bitrate", "bitrate": "Ρυθμός bit",
"no_active": "No Active Streams", "no_active": "Δεν υπάρχουν ενεργές ροές",
"movies": "Movies", "movies": "Ταινίες",
"series": "Series", "series": "Σειρές",
"episodes": "Episodes", "episodes": "Επεισόδια",
"songs": "Songs" "songs": "Τραγούδια"
}, },
"flood": { "flood": {
"download": "Download", "download": "Κατέβασμα",
"upload": "Upload", "upload": "Ανέβασμα",
"leech": "Leech", "leech": "Αφαίμαξη",
"seed": "Seed" "seed": "Σπείρε"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Συνολικά παρατηρηθείσα",
"diffsDetected": "Diffs Detected" "diffsDetected": "Εντοπίστηκαν διαφορές"
}, },
"tautulli": { "tautulli": {
"playing": "Playing", "playing": "Παίζει",
"transcoding": "Transcoding", "transcoding": "Διακωδικοποίηση",
"bitrate": "Bitrate", "bitrate": "Ρυθμός bit",
"no_active": "No Active Streams" "no_active": "Δεν υπάρχουν ενεργές ροές"
}, },
"nzbget": { "nzbget": {
"rate": "Rate", "rate": "βαθμός",
"remaining": "Remaining", "remaining": "Υπόλοιπο",
"downloaded": "Downloaded" "downloaded": "Κατεβασμένο"
}, },
"plex": { "plex": {
"streams": "Active Streams", "streams": "Ενεργά Streams",
"movies": "Movies", "movies": "Ταινίες",
"tv": "TV Shows" "tv": "Σειρές",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Βαθμός",
"queue": "Queue", "queue": "Ουρά",
"timeleft": "Time Left" "timeleft": "Χρόνος που απομένει"
}, },
"rutorrent": { "rutorrent": {
"active": "Active", "active": "Ενεργό",
"upload": "Upload", "upload": "Ανέβασμα",
"download": "Download" "download": "Κατέβασμα"
}, },
"transmission": { "transmission": {
"download": "Download", "download": "Κατέβασμα",
"upload": "Upload", "upload": "Ανέβασμα",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
"qbittorrent": { "qbittorrent": {
"download": "Download", "download": "Κατέβασμα",
"upload": "Upload", "upload": "Ανέβασμα",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
"deluge": { "deluge": {
"download": "Download", "download": "Κατέβασμα",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
@ -561,6 +562,21 @@
"podcasts": "Podcasts", "podcasts": "Podcasts",
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Διάρκεια"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -98,10 +98,20 @@
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
"diffsDetected": "Diffs Detected" "diffsDetected": "Diffs Detected"
}, },
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
},
"tautulli": { "tautulli": {
"playing": "Playing", "playing": "Playing",
"transcoding": "Transcoding", "transcoding": "Transcoding",
@ -122,6 +132,7 @@
}, },
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"albums": "Albums",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows"
}, },
@ -572,6 +583,11 @@
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
}, },
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Monitoring", "monitoring": "Monitoring",
"updates": "Updates" "updates": "Updates"

View File

@ -1,18 +1,18 @@
{ {
"widget": { "widget": {
"missing_type": "Missing Widget Type: {{type}}", "missing_type": "Manka Tipo de Fenestraĵo: {{type}}",
"api_error": "API Error", "api_error": "Eraro de API",
"information": "Informo", "information": "Informo",
"status": "Stato", "status": "Stato",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Kruda Eraro",
"response_data": "Response Data" "response_data": "Respondoj de Demandoj"
}, },
"weather": { "weather": {
"current": "Aktuala loko", "current": "Aktuala loko",
"allow": "Click to allow", "allow": "Klaku por permesi",
"updating": "Updating", "updating": "Ĝisdatiganta",
"wait": "Please wait" "wait": "Bonvolu atendi"
}, },
"search": { "search": {
"placeholder": "Serĉi…" "placeholder": "Serĉi…"
@ -26,58 +26,58 @@
"mem": "MEM", "mem": "MEM",
"temp": "TEMP", "temp": "TEMP",
"months": "mo", "months": "mo",
"max": "Max", "max": "Maks",
"uptime": "UP", "uptime": "UP",
"days": "d", "days": "t",
"hours": "h", "hours": "h",
"minutes": "m" "minutes": "m"
}, },
"unifi": { "unifi": {
"users": "Uzantoj", "users": "Uzantoj",
"uptime": "System Uptime", "uptime": "Uptempo de la Sistemo",
"days": "Tagoj", "days": "Tagoj",
"wan": "WAN", "wan": "WAN",
"lan": "LAN", "lan": "LAN",
"wlan": "WLAN", "wlan": "WLAN",
"devices": "Aparatoj", "devices": "Aparatoj",
"lan_devices": "LAN Devices", "lan_devices": "LAN-Aparatoj",
"wlan_devices": "WLAN Devices", "wlan_devices": "WLAN-Aparatoj",
"lan_users": "LAN Users", "lan_users": "LAN-Uzantoj",
"wlan_users": "WLAN Users", "wlan_users": "WLAN-Uzantoj",
"up": "UP", "up": "UP",
"down": "DOWN", "down": "DOWN",
"wait": "Please wait", "wait": "Bonvolu atendi",
"empty_data": "Subsystem status unknown" "empty_data": "Subsistemostatuso nekonata"
}, },
"docker": { "docker": {
"rx": "RX", "rx": "RX",
"tx": "TX", "tx": "TX",
"mem": "Memoro", "mem": "MEM",
"cpu": "Ĉefprocesoro", "cpu": "CPO",
"offline": "Offline", "offline": "Malkonekta",
"error": "Eraro", "error": "Eraro",
"unknown": "Nekonata", "unknown": "Nekonata",
"running": "Running", "running": "Rulata",
"starting": "Starting", "starting": "Lanĉante",
"unhealthy": "Unhealthy", "unhealthy": "Malsana",
"not_found": "Not Found", "not_found": "Ne trovita",
"exited": "Exited", "exited": "Eliris",
"partial": "Partial", "partial": "Parta",
"healthy": "Healthy" "healthy": "Sana"
}, },
"ping": { "ping": {
"error": "Eraro", "error": "Eraro",
"ping": "Ping" "ping": "Sondaĵo"
}, },
"emby": { "emby": {
"playing": "Ludante", "playing": "Ludante",
"transcoding": "Transcoding", "transcoding": "Transkodigo",
"bitrate": "Bitrate", "bitrate": "Bitrapido",
"no_active": "No Active Streams", "no_active": "No Active Streams",
"movies": "Movies", "movies": "Filmoj",
"series": "Series", "series": "Serioj",
"episodes": "Episodes", "episodes": "Epizodoj",
"songs": "Songs" "songs": "Kantoj"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@ -97,7 +97,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Filmoj", "movies": "Filmoj",
"tv": "Televidprogramoj" "tv": "Televidprogramoj",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Rate",
@ -382,8 +383,8 @@
"total": "Totalo" "total": "Totalo"
}, },
"flood": { "flood": {
"download": "Download", "download": "Elŝuti",
"upload": "Upload", "upload": "Alŝuti",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -18,7 +18,7 @@
"load": "Carga", "load": "Carga",
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "MEM",
"temp": "TEMPORAL", "temp": "TEMP",
"max": "Máx.", "max": "Máx.",
"uptime": "ARRIBA", "uptime": "ARRIBA",
"months": "Meses", "months": "Meses",
@ -158,7 +158,7 @@
"transmission": { "transmission": {
"download": "Bajada", "download": "Bajada",
"upload": "Subida", "upload": "Subida",
"leech": "Sanguijuela", "leech": "Compañeros",
"seed": "Semillas" "seed": "Semillas"
}, },
"jackett": { "jackett": {
@ -183,7 +183,7 @@
"qbittorrent": { "qbittorrent": {
"download": "Bajada", "download": "Bajada",
"upload": "Subida", "upload": "Subida",
"leech": "Compañeros", "leech": "Pares",
"seed": "Semillas" "seed": "Semillas"
}, },
"mastodon": { "mastodon": {
@ -213,11 +213,11 @@
"users": "Usuarios", "users": "Usuarios",
"uptime": "Tiempo de actividad", "uptime": "Tiempo de actividad",
"days": "Días", "days": "Días",
"wan": "Red WAN", "wan": "WAN",
"lan_users": "Usuarios LAN", "lan_users": "Usuarios LAN",
"wlan_users": "Usuarios WLAN", "wlan_users": "Usuarios WLAN",
"down": "CAÍDO", "down": "CAÍDO",
"wait": "Espere por favor", "wait": "Espera por favor",
"lan": "LAN", "lan": "LAN",
"wlan": "WLAN", "wlan": "WLAN",
"devices": "Dispositivos", "devices": "Dispositivos",
@ -228,12 +228,13 @@
"plex": { "plex": {
"streams": "Transmisiones activas", "streams": "Transmisiones activas",
"movies": "Películas", "movies": "Películas",
"tv": "Series" "tv": "Series",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "Procesador", "cpu": "Procesador",
"mem": "Memoria", "mem": "Memoria",
"wait": "Espere por favor", "wait": "Espera por favor",
"temp": "TEMPORAL", "temp": "TEMPORAL",
"uptime": "ARRIBA", "uptime": "ARRIBA",
"days": "Días", "days": "Días",
@ -277,20 +278,20 @@
"66-night": "Granizo", "66-night": "Granizo",
"67-night": "Granizo", "67-night": "Granizo",
"71-day": "Nevada Leve", "71-day": "Nevada Leve",
"71-night": "Nevada Leva", "71-night": "Nevada Leve",
"73-day": "Nevada", "73-day": "Nevada",
"73-night": "Nevada", "73-night": "Nevada",
"75-day": "Fuertes Nevadas", "75-day": "Fuertes Nevadas",
"75-night": "Fuertes Nevadas", "75-night": "Fuertes Nevadas",
"77-day": "Nevada Leve", "77-day": "Nevada Leve",
"77-night": "Nevada Leve", "77-night": "Nevada Leve",
"80-day": "llovizna", "80-day": "Llovizna",
"80-night": "Llovizna", "80-night": "Llovizna",
"81-day": "Lluvia", "81-day": "Lluvia",
"81-night": "Lluvia", "81-night": "Lluvia",
"82-day": "Chubascos", "82-day": "Chubascos",
"82-night": "Chubascos", "82-night": "Chubascos",
"85-day": "Chubascos", "85-day": "Lluvia de nieve",
"85-night": "Lluvia de nieve", "85-night": "Lluvia de nieve",
"86-day": "Lluvia de nieve", "86-day": "Lluvia de nieve",
"86-night": "Lluvia de nieve", "86-night": "Lluvia de nieve",
@ -378,12 +379,12 @@
"deluge": { "deluge": {
"download": "Descarga", "download": "Descarga",
"upload": "Subida", "upload": "Subida",
"leech": "Depender", "leech": "Compañeros",
"seed": "Semilla" "seed": "Semillas"
}, },
"flood": { "flood": {
"download": "Descargar", "download": "Descarga",
"upload": "Subir", "upload": "Subida",
"leech": "Depender", "leech": "Depender",
"seed": "Semillas" "seed": "Semillas"
}, },
@ -398,7 +399,7 @@
"unread": "Sin leer" "unread": "Sin leer"
}, },
"nextdns": { "nextdns": {
"wait": "Espere, por favor", "wait": "Espera, por favor",
"no_devices": "No se reciben datos del dispositivo" "no_devices": "No se reciben datos del dispositivo"
}, },
"common": { "common": {
@ -415,7 +416,7 @@
"downloadstation": { "downloadstation": {
"download": "Descargar", "download": "Descargar",
"upload": "Subir", "upload": "Subir",
"leech": "Sanguijuela", "leech": "Compañeros",
"seed": "Semilla" "seed": "Semilla"
}, },
"mikrotik": { "mikrotik": {
@ -425,8 +426,8 @@
"numberOfLeases": "Alquileres" "numberOfLeases": "Alquileres"
}, },
"xteve": { "xteve": {
"streams_all": "Todos los flujos", "streams_all": "Todas las transmisiones",
"streams_active": "Flujos activos", "streams_active": "Transmisiones activas",
"streams_xepg": "Canales XEPG" "streams_xepg": "Canales XEPG"
}, },
"opnsense": { "opnsense": {
@ -437,7 +438,7 @@
}, },
"moonraker": { "moonraker": {
"printer_state": "Estado de la impresora", "printer_state": "Estado de la impresora",
"print_status": "Estado de la impresora", "print_status": "Estado de la impresión",
"print_progress": "Progreso", "print_progress": "Progreso",
"layers": "Capas" "layers": "Capas"
}, },
@ -447,9 +448,9 @@
"series": "Serie" "series": "Serie"
}, },
"octoprint": { "octoprint": {
"temp_bed": "temperatura de la plataforma", "temp_bed": "Temperatura de la plataforma",
"printer_state": "Estado", "printer_state": "Estado",
"temp_tool": "Temperatura de herramienta", "temp_tool": "Temperatura de la herramienta",
"job_completion": "Finalización" "job_completion": "Finalización"
}, },
"cloudflared": { "cloudflared": {
@ -533,7 +534,7 @@
"grace": "En Periodo de Gracia", "grace": "En Periodo de Gracia",
"paused": "Pausado", "paused": "Pausado",
"status": "Estado", "status": "Estado",
"last_ping": "Último Ping", "last_ping": "Último ping",
"never": "Aún no hay pings" "never": "Aún no hay pings"
}, },
"pterodactyl": { "pterodactyl": {
@ -562,5 +563,20 @@
"books": "Libros", "books": "Libros",
"podcastsDuration": "Duración", "podcastsDuration": "Duración",
"booksDuration": "Duración" "booksDuration": "Duración"
},
"homeassistant": {
"people_home": "Inicio de personas",
"lights_on": "Luces encendidas",
"switches_on": "Encendido"
},
"freshrss": {
"subscriptions": "Suscripciones",
"unread": "Sin leer"
},
"channelsdvrserver": {
"shows": "Espectáculos",
"recordings": "Grabaciones",
"scheduled": "Programado",
"passes": "Pases"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"glances": { "glances": {
"wait": "Please wait", "wait": "Please wait",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,15 +228,16 @@
"plex": { "plex": {
"streams": "Flux actif", "streams": "Flux actif",
"movies": "Films", "movies": "Films",
"tv": "Séries TV" "tv": "Séries TV",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "Cpu", "cpu": "Cpu",
"mem": "Mém", "mem": "Mém",
"wait": "Merci de patienter", "wait": "Merci de patienter",
"temp": "TEMP", "temp": "Temp",
"uptime": "UP", "uptime": "Up",
"days": "d", "days": "j",
"hours": "h" "hours": "h"
}, },
"changedetectionio": { "changedetectionio": {
@ -562,5 +563,20 @@
"books": "Livres", "books": "Livres",
"podcastsDuration": "Durée", "podcastsDuration": "Durée",
"booksDuration": "Durée" "booksDuration": "Durée"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lumières allumées",
"switches_on": "Switches On"
},
"freshrss": {
"unread": "Non lu",
"subscriptions": "Abonnements"
},
"channelsdvrserver": {
"shows": "Affichages",
"recordings": "Enregistrements",
"scheduled": "Planifié",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -127,7 +127,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Rate",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -15,10 +15,10 @@
"load": "Opterećenje", "load": "Opterećenje",
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "MEM",
"minutes": "m", "minutes": "min",
"max": "Max", "max": "Maks",
"uptime": "UP", "uptime": "UP",
"months": "mo", "months": "mj",
"temp": "TEMP", "temp": "TEMP",
"days": "d", "days": "d",
"hours": "h" "hours": "h"
@ -37,7 +37,7 @@
"pihole": { "pihole": {
"queries": "Upiti", "queries": "Upiti",
"blocked": "Blokirano", "blocked": "Blokirano",
"gravity": "Čuvanje podataka" "gravity": "Gravity"
}, },
"adguard": { "adguard": {
"latency": "Kašnjenje", "latency": "Kašnjenje",
@ -78,26 +78,26 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Nepovezan", "offline": "Offline",
"error": "Greška", "error": "Greška",
"unknown": "Nepoznato", "unknown": "Nepoznato",
"running": "Running", "running": "Pokrenuto",
"starting": "Starting", "starting": "Pokretanje",
"unhealthy": "Unhealthy", "unhealthy": "Nefunkcionalno",
"not_found": "Not Found", "not_found": "Nepronađeno",
"exited": "Exited", "exited": "Zatoreno",
"partial": "Partial", "partial": "Djelomično",
"healthy": "Healthy" "healthy": "Funkcionalno"
}, },
"emby": { "emby": {
"playing": "Reprodukcija", "playing": "Reprodukcija",
"transcoding": "Prekodiranje", "transcoding": "Prekodiranje",
"bitrate": "Stopa bitova", "bitrate": "Stopa bitova",
"no_active": "Nema aktivnih prijenosa", "no_active": "Nema aktivnih prijenosa",
"movies": "Movies", "movies": "Filmovi",
"series": "Series", "series": "Serije",
"episodes": "Episodes", "episodes": "Epizode",
"songs": "Songs" "songs": "Pjesme"
}, },
"tautulli": { "tautulli": {
"playing": "Reprodukcija", "playing": "Reprodukcija",
@ -223,12 +223,13 @@
"devices": "Uređaji", "devices": "Uređaji",
"lan_devices": "LAN uređaji", "lan_devices": "LAN uređaji",
"wlan_devices": "WLAN uređaji", "wlan_devices": "WLAN uređaji",
"empty_data": "Subsystem status unknown" "empty_data": "Stanje podsustava nepoznato"
}, },
"plex": { "plex": {
"streams": "Aktivni prijenosi", "streams": "Aktivni prijenosi",
"movies": "Filmovi", "movies": "Filmovi",
"tv": "TV emisije" "tv": "TV emisije",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -304,9 +305,9 @@
"quicklaunch": { "quicklaunch": {
"bookmark": "Straničnik", "bookmark": "Straničnik",
"service": "Usluga", "service": "Usluga",
"search": "Search", "search": "Traži",
"custom": "Custom", "custom": "Prilagođeno",
"visit": "Visit", "visit": "Posjeti",
"url": "URL" "url": "URL"
}, },
"homebridge": { "homebridge": {
@ -317,7 +318,7 @@
"child_bridges": "Podređeni mosotvi", "child_bridges": "Podređeni mosotvi",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Predstoji",
"down": "Down" "down": "Down"
}, },
"autobrr": { "autobrr": {
@ -367,7 +368,7 @@
"ping": "Ping" "ping": "Ping"
}, },
"scrutiny": { "scrutiny": {
"passed": "Prošlo", "passed": "Uspjelo",
"failed": "Neuspjelo", "failed": "Neuspjelo",
"unknown": "Nepoznato" "unknown": "Nepoznato"
}, },
@ -399,7 +400,7 @@
}, },
"nextdns": { "nextdns": {
"wait": "Pričekaj", "wait": "Pričekaj",
"no_devices": "Podaci o uređaju nisu primljeni" "no_devices": "Podaci uređaja nisu primljeni"
}, },
"common": { "common": {
"bibyterate": "{{value, rate(bits: false; binary: true)}}", "bibyterate": "{{value, rate(bits: false; binary: true)}}",
@ -436,131 +437,146 @@
"wanDownload": "WAN preuzimanje" "wanDownload": "WAN preuzimanje"
}, },
"moonraker": { "moonraker": {
"printer_state": "Printer State", "printer_state": "Stanje pisača",
"print_status": "Print Status", "print_status": "Stanje ispisa",
"print_progress": "Progress", "print_progress": "Napredak",
"layers": "Layers" "layers": "Slojevi"
}, },
"medusa": { "medusa": {
"wanted": "Wanted", "wanted": "Zatraženo",
"queued": "Queued", "queued": "U redu čekanja",
"series": "Series" "series": "Serije"
}, },
"octoprint": { "octoprint": {
"printer_state": "Status", "printer_state": "Stanje",
"temp_tool": "Tool temp", "temp_tool": "Temperatura alata",
"temp_bed": "Bed temp", "temp_bed": "Temperatura platforme",
"job_completion": "Completion" "job_completion": "Dovršenost"
}, },
"cloudflared": { "cloudflared": {
"origin_ip": "Origin IP", "origin_ip": "IP izvora",
"status": "Status" "status": "Stanje"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "Spremište podataka",
"failed_tasks_24h": "Failed Tasks 24h", "failed_tasks_24h": "Neuspjeli zadaci 24 h",
"cpu_usage": "CPU", "cpu_usage": "CPU",
"memory_usage": "Memory" "memory_usage": "Memorija"
}, },
"immich": { "immich": {
"users": "Users", "users": "Korisnici",
"photos": "Photos", "photos": "Fotografije",
"videos": "Videos", "videos": "Videa",
"storage": "Storage" "storage": "Spremište"
}, },
"uptimekuma": { "uptimekuma": {
"up": "Sites Up", "up": "Aktivne stranice",
"down": "Sites Down", "down": "Neaktivne stranice",
"uptime": "Uptime", "uptime": "Radno vrijeme",
"incident": "Incident", "incident": "Incident",
"m": "m" "m": "min"
}, },
"komga": { "komga": {
"libraries": "Libraries", "libraries": "Biblioteke",
"series": "Series", "series": "Serije",
"books": "Books" "books": "Knjige"
}, },
"mylar": { "mylar": {
"series": "Series", "series": "Serije",
"issues": "Issues", "issues": "Problemi",
"wanted": "Wanted" "wanted": "Zatraženo"
}, },
"photoprism": { "photoprism": {
"videos": "Videos", "videos": "Videa",
"albums": "Albums", "albums": "Albumi",
"photos": "Photos", "photos": "Fotografije",
"people": "People" "people": "Osobe"
}, },
"diskstation": { "diskstation": {
"days": "Days", "days": "Dani",
"uptime": "Uptime", "uptime": "Radno vrijeme",
"volumeAvailable": "Available" "volumeAvailable": "Dostupno"
}, },
"fileflows": { "fileflows": {
"queue": "Queue", "queue": "Red čekanja",
"processing": "Processing", "processing": "Obrada",
"processed": "Processed", "processed": "Obrađeno",
"time": "Time" "time": "Vrijeme"
}, },
"grafana": { "grafana": {
"alertstriggered": "Alerts Triggered", "alertstriggered": "Aktivirana upozorenja",
"dashboards": "Dashboards", "dashboards": "Pregledne ploče",
"datasources": "Data Sources", "datasources": "Izvori podataka",
"totalalerts": "Total Alerts" "totalalerts": "Ukupno upozorenja"
}, },
"nextcloud": { "nextcloud": {
"cpuload": "Cpu Load", "cpuload": "Cpu opterećenje",
"memoryusage": "Memory Usage", "memoryusage": "Korištenje memorije",
"freespace": "Free Space", "freespace": "Slobodna memorija",
"activeusers": "Active Users" "activeusers": "Aktivni korisnici"
}, },
"kopia": { "kopia": {
"status": "Status", "status": "Stanje",
"size": "Size", "size": "Veličina",
"lastrun": "Last Run", "lastrun": "Zadnje pokretanje",
"nextrun": "Next Run", "nextrun": "Sljedeće pokretanje",
"failed": "Failed" "failed": "Neuspjelo"
}, },
"unmanic": { "unmanic": {
"active_workers": "Active Workers", "active_workers": "Aktivni radnici",
"total_workers": "Total Workers", "total_workers": "Ukupni radnici",
"records_total": "Queue Length" "records_total": "Količina zapisa u redu čekanja"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "Novo",
"up": "Online", "up": "Online",
"grace": "In Grace Period", "grace": "U razdoblju odgode",
"down": "Offline", "down": "Offline",
"paused": "Paused", "paused": "Zaustavljeno",
"status": "Status", "status": "Stanje",
"last_ping": "Last Ping", "last_ping": "Zadnji ping",
"never": "No pings yet" "never": "Još nema pingova"
}, },
"pterodactyl": { "pterodactyl": {
"servers": "Servers", "servers": "Serveri",
"nodes": "Nodes" "nodes": "Čvorovi"
}, },
"prometheus": { "prometheus": {
"targets_up": "Targets Up", "targets_up": "Aktivni ciljevi",
"targets_down": "Targets Down", "targets_down": "Neaktivni ciljevi",
"targets_total": "Total Targets" "targets_total": "Ukupno ciljeva"
}, },
"minecraft": { "minecraft": {
"players": "Players", "players": "Igrači",
"version": "Version", "version": "Verzija",
"status": "Status", "status": "Stanje",
"up": "Online", "up": "Online",
"down": "Offline" "down": "Offline"
}, },
"ghostfolio": { "ghostfolio": {
"gross_percent_today": "Today", "gross_percent_today": "Danas",
"gross_percent_1y": "One year", "gross_percent_1y": "Jedna godina",
"gross_percent_max": "All time" "gross_percent_max": "Svo vrijeme"
}, },
"audiobookshelf": { "audiobookshelf": {
"podcasts": "Podcasts", "podcasts": "Podcasti",
"books": "Books", "books": "Knjige",
"podcastsDuration": "Duration", "podcastsDuration": "Trajanje",
"booksDuration": "Duration" "booksDuration": "Trajanje"
},
"homeassistant": {
"people_home": "Ljudi doma",
"lights_on": "Upaljena svjetla",
"switches_on": "Prekidači uključeni"
},
"freshrss": {
"subscriptions": "Pretplate",
"unread": "Nepročitano"
},
"channelsdvrserver": {
"scheduled": "Planirano",
"passes": "Prolazi",
"shows": "Emisije",
"recordings": "Snimanja"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Trasmissioni attive", "streams": "Trasmissioni attive",
"movies": "Film", "movies": "Film",
"tv": "Programma televisivo" "tv": "Programma televisivo",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -149,7 +149,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Rate",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -128,7 +128,8 @@
"plex": { "plex": {
"streams": "활성 스트림", "streams": "활성 스트림",
"movies": "영화", "movies": "영화",
"tv": "TV 쇼" "tv": "TV 쇼",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "비율", "rate": "비율",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -114,7 +114,8 @@
"plex": { "plex": {
"streams": "Aktīvās straumes", "streams": "Aktīvās straumes",
"movies": "Filmas", "movies": "Filmas",
"tv": "TV pārraides" "tv": "TV pārraides",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Rate",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -201,7 +201,8 @@
"plex": { "plex": {
"streams": "Strim Aktif", "streams": "Strim Aktif",
"movies": "Filem", "movies": "Filem",
"tv": "Rancangan TV" "tv": "Rancangan TV",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Kadar", "rate": "Kadar",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Actieve Streams", "streams": "Actieve Streams",
"movies": "Films", "movies": "Films",
"tv": "TV Series" "tv": "TV Series",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Boeken", "books": "Boeken",
"podcastsDuration": "Duur", "podcastsDuration": "Duur",
"booksDuration": "Duur" "booksDuration": "Duur"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -15,10 +15,10 @@
"free": "Wolne", "free": "Wolne",
"cpu": "CPU", "cpu": "CPU",
"mem": "PAM", "mem": "PAM",
"temp": "TYMCZASOWE", "temp": "TEMP.",
"max": "Max", "max": "Max",
"uptime": "UP", "uptime": "UP",
"months": "misiąc", "months": "miesiąc",
"days": "dni", "days": "dni",
"hours": "h", "hours": "h",
"minutes": "minuty" "minutes": "minuty"
@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Aktywne strumienie", "streams": "Aktywne strumienie",
"movies": "Filmy", "movies": "Filmy",
"tv": "Seriale" "tv": "Seriale",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "Procesor", "cpu": "Procesor",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -52,10 +52,10 @@
"load": "Carregamento", "load": "Carregamento",
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "MEM",
"max": "Max", "max": "Máximo",
"temp": "TEMP", "temp": "TEMP",
"uptime": "UP", "uptime": "LIGADO",
"months": "mo", "months": "mês",
"days": "d", "days": "d",
"hours": "h", "hours": "h",
"minutes": "m" "minutes": "m"
@ -228,14 +228,15 @@
"plex": { "plex": {
"streams": "Transmissões ativas", "streams": "Transmissões ativas",
"movies": "Filmes", "movies": "Filmes",
"tv": "Séries de TV" "tv": "Séries de TV",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "MEM",
"wait": "Por favor aguarde", "wait": "Por favor aguarde",
"temp": "TEMP", "temp": "TEMP",
"uptime": "UP", "uptime": "LIGADO",
"days": "d", "days": "d",
"hours": "h" "hours": "h"
}, },
@ -316,9 +317,9 @@
"up_to_date": "Atualizado", "up_to_date": "Atualizado",
"child_bridges": "Pontes Filhas", "child_bridges": "Pontes Filhas",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Ligado",
"pending": "Pendente", "pending": "Pendente",
"down": "Down" "down": "Desligado"
}, },
"autobrr": { "autobrr": {
"approvedPushes": "Aprovado", "approvedPushes": "Aprovado",
@ -562,5 +563,20 @@
"books": "Livros", "books": "Livros",
"podcastsDuration": "Duração", "podcastsDuration": "Duração",
"booksDuration": "Duração" "booksDuration": "Duração"
},
"homeassistant": {
"people_home": "Pessoas em Casa",
"lights_on": "Luzes Ligadas",
"switches_on": "Interruptores Ligados"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -18,10 +18,10 @@
"load": "Carga", "load": "Carga",
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "MEM",
"max": "Max", "max": "Máximo",
"temp": "TEMP", "temp": "TEMP",
"uptime": "UP", "uptime": "CIMA",
"months": "mo", "months": "mês",
"days": "d", "days": "d",
"hours": "h", "hours": "h",
"minutes": "m" "minutes": "m"
@ -241,14 +241,15 @@
"plex": { "plex": {
"streams": "Streams Ativas", "streams": "Streams Ativas",
"movies": "Filmes", "movies": "Filmes",
"tv": "Series de TV" "tv": "Series de TV",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "MEM",
"wait": "Por favor, aguarde", "wait": "Por favor, aguarde",
"temp": "TEMP", "temp": "TEMP",
"uptime": "UP", "uptime": "Cima",
"days": "d", "days": "d",
"hours": "h" "hours": "h"
}, },
@ -331,7 +332,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pendente", "pending": "Pendente",
"down": "Down" "down": "Baixo"
}, },
"autobrr": { "autobrr": {
"approvedPushes": "Aprovado", "approvedPushes": "Aprovado",
@ -550,8 +551,8 @@
"nodes": "Nós" "nodes": "Nós"
}, },
"prometheus": { "prometheus": {
"targets_up": "Targets Up", "targets_up": "Alvo ativo",
"targets_down": "Targets Down", "targets_down": "Alvo inativo",
"targets_total": "Total de Alvos" "targets_total": "Total de Alvos"
}, },
"minecraft": { "minecraft": {
@ -571,5 +572,20 @@
"books": "Livros", "books": "Livros",
"podcastsDuration": "Duração", "podcastsDuration": "Duração",
"booksDuration": "Duração" "booksDuration": "Duração"
},
"homeassistant": {
"people_home": "Pessoas em Casa",
"lights_on": "Luzes Acesas",
"switches_on": "Interruptores Ligados"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Fluxuri active", "streams": "Fluxuri active",
"movies": "Filme", "movies": "Filme",
"tv": "Seriale" "tv": "Seriale",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "Procesor", "cpu": "Procesor",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -238,7 +238,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Rate",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -0,0 +1,582 @@
{
"common": {
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
},
"jellyseerr": {
"available": "Na voljo",
"pending": "V teku",
"approved": "Odobreno"
},
"overseerr": {
"pending": "V teku",
"processing": "Procesiram",
"approved": "Odobreno",
"available": "Na voljo"
},
"pihole": {
"queries": "Poizvedbe",
"blocked": "Blokirano",
"gravity": "Gravitacija"
},
"adguard": {
"filtered": "Filtrirano",
"latency": "Zakasnitev",
"queries": "Poizvedbe",
"blocked": "Blokirano"
},
"opnsense": {
"wanUpload": "WAN naloženo",
"wanDownload": "WAN prejeto",
"cpu": "CPU obremenitev",
"memory": "Aktiven spomin"
},
"octoprint": {
"temp_bed": "Temperatura postelje",
"job_completion": "Končano",
"printer_state": "Status",
"temp_tool": "Temperatura orodja"
},
"cloudflared": {
"origin_ip": "Izvorni IP",
"status": "Status"
},
"proxmoxbackupserver": {
"datastore_usage": "Shramba podatkov",
"failed_tasks_24h": "Opravila z napako 24h",
"cpu_usage": "CPU",
"memory_usage": "Spomin"
},
"mylar": {
"wanted": "Želeno",
"series": "Serije",
"issues": "Težave"
},
"photoprism": {
"albums": "Albumi",
"photos": "Slike",
"videos": "Videi",
"people": "Ljudje"
},
"grafana": {
"alertstriggered": "Sproženi alarmi",
"dashboards": "Nadzorne plošče",
"datasources": "Viri podatkov",
"totalalerts": "Skupaj alarmov"
},
"nextcloud": {
"cpuload": "CPU obremenitev",
"memoryusage": "Uporabljen spomin",
"freespace": "Prostor na voljo",
"activeusers": "Aktivni uporabniki"
},
"kopia": {
"status": "Stanje",
"size": "Velikost",
"lastrun": "Zadnji zagon",
"nextrun": "Naslednji zagon",
"failed": "Neuspešno"
},
"pterodactyl": {
"nodes": "Vozlišča",
"servers": "Strežniki"
},
"widget": {
"missing_type": "Manjka tip widgeta: {{type}}",
"api_error": "API napaka",
"information": "Informacija",
"raw_error": "Surova napaka",
"response_data": "Podatki iz odgovora",
"status": "Stanje",
"url": "URL"
},
"weather": {
"current": "Trenutna lokacija",
"allow": "Kliknite za dovolitev",
"updating": "Posodabljam",
"wait": "Prosimo počakajte"
},
"search": {
"placeholder": "Iskanje…"
},
"resources": {
"cpu": "CPU",
"mem": "MEM",
"total": "Skupaj",
"free": "Prosto",
"used": "V uporabi",
"load": "Bremenitev",
"temp": "TEMP",
"max": "Maks.",
"uptime": "Gor",
"months": "me",
"days": "d",
"hours": "u",
"minutes": "u"
},
"unifi": {
"devices": "Naprave",
"lan_devices": "LAN naprave",
"wlan_devices": "WLAN naprave",
"lan_users": "LAN uporabniki",
"wlan_users": "WLAN uporabniki",
"up": "Gor",
"down": "Dol",
"wait": "Prosimo počakajte",
"users": "Uporabniki",
"uptime": "Čas delovanja",
"days": "Dni",
"wan": "WAN",
"lan": "LAN",
"wlan": "WLAN",
"empty_data": "Neznani status podsistema"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"running": "Deluje",
"offline": "Ni povezan",
"error": "Napaka",
"unknown": "Neznano",
"healthy": "Zdrav",
"starting": "Se zaganja",
"unhealthy": "Ni zdrav",
"not_found": "Ni najden",
"exited": "V izhodu",
"partial": "Delni"
},
"ping": {
"error": "Napaka",
"ping": "Ping"
},
"emby": {
"playing": "Predvaja",
"transcoding": "Transkodira",
"bitrate": "Pasovna širina",
"no_active": "Ni aktivne vsebine",
"movies": "Filmi",
"series": "Serije",
"episodes": "Epizode",
"songs": "Pesmi"
},
"tautulli": {
"transcoding": "Transkodira",
"bitrate": "Pasovna širina",
"playing": "Predvaja",
"no_active": "Ni aktivne vsebine"
},
"flood": {
"download": "Prenos",
"upload": "Nalaganje",
"leech": "Pijavka",
"seed": "Sejanje"
},
"changedetectionio": {
"totalObserved": "Skupaj opazovano",
"diffsDetected": "Zaznanih sprememb"
},
"omada": {
"connectedAp": "Povezanih AP",
"activeUser": "Aktivne naprave",
"alerts": "Opozorila",
"connectedGateway": "Povezan prehod",
"connectedSwitches": "Povezana stikala"
},
"nzbget": {
"rate": "Razmerje",
"remaining": "Še preostane",
"downloaded": "Preneseno"
},
"plex": {
"streams": "Aktivna vsebina",
"movies": "Filmi",
"tv": "TV serije",
"albums": "Albums"
},
"sabnzbd": {
"rate": "Hitrost prenosa",
"queue": "Vrsta",
"timeleft": "Preostali čas"
},
"rutorrent": {
"active": "Aktiven",
"upload": "Nalaganje",
"download": "Prenašanje"
},
"transmission": {
"download": "Prenašanje",
"upload": "Nalaganje",
"leech": "Pijavk",
"seed": "Sejanje"
},
"qbittorrent": {
"download": "Prenos",
"upload": "Nalaganje",
"leech": "Pijavk",
"seed": "Sejanje"
},
"deluge": {
"download": "Prenos",
"upload": "Nalaganje",
"leech": "Pijavka",
"seed": "Sejanje"
},
"downloadstation": {
"download": "Prenos",
"upload": "Nalaganje",
"leech": "Pijavka",
"seed": "Sejanje"
},
"sonarr": {
"wanted": "Iskano",
"queued": "V vrsti",
"series": "Serije"
},
"radarr": {
"wanted": "Iskano",
"missing": "Manjkajoče",
"queued": "V vrsti",
"movies": "Filmi"
},
"lidarr": {
"wanted": "Iskano",
"queued": "V vrsti",
"albums": "Albumi"
},
"readarr": {
"wanted": "Iskano",
"queued": "V vrsti",
"books": "Knjige"
},
"bazarr": {
"missingEpisodes": "Manjkajoče epizode",
"missingMovies": "Manjkajoči filmi"
},
"ombi": {
"pending": "V teku",
"approved": "Odobreno",
"available": "Na voljo"
},
"speedtest": {
"upload": "Nalaganje",
"download": "Prenašanje",
"ping": "Ping"
},
"portainer": {
"running": "Deluje",
"stopped": "Ustavljen",
"total": "Skupaj"
},
"tdarr": {
"queue": "Vrsta",
"processed": "Procesiran",
"errored": "Z napako",
"saved": "Shranjen"
},
"npm": {
"disabled": "Onemogočen",
"total": "Skupaj",
"enabled": "Omogočen"
},
"coinmarketcap": {
"configure": "Konfigurirajte eno ali več kripto valut za sledenje",
"1hour": "1 ura",
"1day": "1 dan",
"7days": "7 dni",
"30days": "30 dni"
},
"traefik": {
"routers": "Usmerjevalniki",
"services": "Servisi",
"middleware": "Vmesna programska oprema"
},
"gotify": {
"apps": "Aplikacije",
"clients": "Klienti",
"messages": "Sporočila"
},
"navidrome": {
"nothing_streaming": "Ni aktivnega pretoka",
"please_wait": "Prosim počakajte"
},
"prowlarr": {
"enableIndexers": "Indekserji",
"numberOfGrabs": "Zajemi",
"numberOfQueries": "Poizvedbe",
"numberOfFailGrabs": "Neuspešni zajemi",
"numberOfFailQueries": "Neuspešne poizvedbe"
},
"jackett": {
"configured": "Nastavljeno",
"errored": "Z napakami"
},
"strelaysrv": {
"numActiveSessions": "Seje",
"numConnections": "Povezave",
"dataRelayed": "Preusmerjeno",
"transferRate": "Razmerje"
},
"mastodon": {
"user_count": "Uporabniki",
"status_count": "Objave",
"domain_count": "Domene"
},
"medusa": {
"wanted": "Želeno",
"queued": "V vrsti",
"series": "Serije"
},
"minecraft": {
"players": "Igralci",
"version": "Verzija",
"status": "Status",
"up": "Na spletu",
"down": "Brez povezave"
},
"miniflux": {
"read": "Prebrano",
"unread": "Neprebrano"
},
"proxmox": {
"lxc": "LXC",
"vms": "VM-ji",
"mem": "MEM",
"cpu": "CPU"
},
"glances": {
"cpu": "CPU",
"mem": "MEM",
"wait": "Prosim počakajte",
"temp": "TEMP",
"uptime": "UP",
"days": "d",
"hours": "u"
},
"authentik": {
"users": "Uporabniki",
"loginsLast24H": "Prijave (24h)",
"failedLoginsLast24H": "Neveljavne prijave (24h)"
},
"quicklaunch": {
"bookmark": "Zaznamek",
"service": "Storitev",
"search": "Iskanje",
"custom": "Po meri",
"url": "URL",
"visit": "Obišči"
},
"wmo": {
"3-night": "Oblačno",
"45-day": "Megleno",
"0-day": "Sončno",
"0-night": "Jasno",
"1-day": "Večinoma sončno",
"1-night": "Večinoma jasno",
"45-night": "Megleno",
"2-day": "Delno oblačno",
"2-night": "Delno oblačno",
"3-day": "Oblačno",
"48-day": "Megleno",
"48-night": "Megleno",
"51-day": "Rahlo rosenje",
"51-night": "Rahlo rosenje",
"53-day": "Rosenje",
"53-night": "Rosenje",
"55-day": "Močnejše rosenje",
"55-night": "Močnejše rosenje",
"56-day": "Lahko zmrzovano pršenje",
"56-night": "Lahko zmrzovano pršenje",
"57-day": "Zmrzovano pršenje",
"63-night": "Dež",
"65-day": "Močnejši dež",
"65-night": "Močnejši dež",
"66-day": "Zmrznjen dež",
"66-night": "Zmrznjen dež",
"57-night": "Zmrzovano pršenje",
"61-day": "Rahel dež",
"61-night": "Rahel dež",
"67-day": "Zmrznjen dež",
"63-day": "Dež",
"67-night": "Zmrznjen dež",
"71-day": "Rahlo sneženje",
"71-night": "Rahlo sneženje",
"73-day": "Sneg",
"73-night": "Sneg",
"75-day": "Močnejši sneg",
"75-night": "Močnejši sneg",
"77-day": "Snežna zrna",
"77-night": "Snežna zrna",
"80-day": "Rahlo pršenje",
"85-night": "Snežne plohe",
"86-day": "Snežne plohe",
"80-night": "Rahlo pršenje",
"81-day": "Nalivi",
"81-night": "Nalivi",
"82-day": "Močnejši nalivi",
"82-night": "Močnejši nalivi",
"85-day": "Snežne plohe",
"86-night": "Snežne plohe",
"95-day": "Nevihta",
"95-night": "Nevihta",
"96-day": "Nevihta s točo",
"96-night": "Nevihta s točo",
"99-day": "Nevihta s točo",
"99-night": "Nevihta s točo"
},
"homebridge": {
"child_bridges": "Otroški mostovi",
"child_bridges_status": "{{ok}}/{{total}}",
"up": "Gor",
"available_update": "Sistem",
"updates": "Posodobitve",
"update_available": "Posodobitve na voljo",
"up_to_date": "Posodobljeno",
"pending": "V teku",
"down": "Dol"
},
"healthchecks": {
"new": "Nov",
"up": "Povezan",
"grace": "V podaljšanem roku",
"down": "Ni povezan",
"paused": "Pavziran",
"status": "Status",
"last_ping": "Zadnji Ping",
"never": "Še ni pinga"
},
"watchtower": {
"containers_scanned": "Skeniran",
"containers_updated": "Posodobljen",
"containers_failed": "Neuspešno"
},
"autobrr": {
"approvedPushes": "Potrjen",
"rejectedPushes": "Zavrnjen",
"filters": "Filtri",
"indexers": "Indekserji"
},
"tubearchivist": {
"downloads": "Vrsta",
"videos": "Videi",
"channels": "Kanali",
"playlists": "Seznami predvajanja"
},
"truenas": {
"load": "Obremenitev sistema",
"uptime": "Čas delovanja",
"alerts": "Alarmi",
"time": "{{value, number(style: unit; unitDisplay: long;)}}"
},
"pyload": {
"speed": "Hitrost",
"active": "Aktiven",
"queue": "V vrsti",
"total": "Skupaj"
},
"gluetun": {
"public_ip": "Javni IP",
"region": "Regija",
"country": "Država"
},
"hdhomerun": {
"channels": "Kanali",
"hd": "HD"
},
"scrutiny": {
"passed": "Opravljeno",
"failed": "Z napako",
"unknown": "Neznano"
},
"paperlessngx": {
"inbox": "Prejeto",
"total": "Skupaj"
},
"nextdns": {
"wait": "Prosim počakajte",
"no_devices": "Podatki o napravi niso prejeti"
},
"mikrotik": {
"cpuLoad": "CPU obremenitev",
"memoryUsed": "Uporabljen spomin",
"uptime": "Čas delovanja",
"numberOfLeases": "Najemi"
},
"xteve": {
"streams_all": "Vsi pretoki",
"streams_active": "Aktivni pretoki",
"streams_xepg": "XEPG kanali"
},
"moonraker": {
"printer_state": "Stanje tiskalnika",
"print_status": "Stanje tiskanja",
"print_progress": "Napredek",
"layers": "Sloji"
},
"immich": {
"users": "Uporabniki",
"photos": "Slike",
"videos": "Videi",
"storage": "Shramba"
},
"uptimekuma": {
"up": "Povezanih strani",
"down": "Nepovezanih strani",
"uptime": "Čas delovanja",
"incident": "Težave",
"m": "m"
},
"komga": {
"libraries": "Knjižnice",
"series": "Serije",
"books": "Knjige"
},
"diskstation": {
"days": "Dni",
"uptime": "Čas delovanja",
"volumeAvailable": "Na voljo"
},
"fileflows": {
"queue": "Vrsta",
"processing": "Procesiram",
"processed": "Procesirano",
"time": "Čas"
},
"prometheus": {
"targets_up": "Tarče gor",
"targets_down": "Tarče dol",
"targets_total": "Skupaj tarč"
},
"unmanic": {
"active_workers": "Aktivne niti",
"total_workers": "Skupaj niti",
"records_total": "Dolžina vrste"
},
"ghostfolio": {
"gross_percent_today": "Danes",
"gross_percent_1y": "Eno leto",
"gross_percent_max": "Celoten čas"
},
"audiobookshelf": {
"podcasts": "Podcasti",
"books": "Knjige",
"podcastsDuration": "Dolžina",
"booksDuration": "Dolžina"
},
"homeassistant": {
"people_home": "Ljudi doma",
"lights_on": "Vklopljene luči",
"switches_on": "Vklopljena stikala"
},
"freshrss": {
"subscriptions": "Naročnine",
"unread": "Neprebrano"
},
"channelsdvrserver": {
"shows": "Epizode",
"recordings": "Posnetki",
"scheduled": "Načrtovano",
"passes": "Prehodi"
}
}

View File

@ -89,7 +89,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Rate",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Aktiva strömmar", "streams": "Aktiva strömmar",
"movies": "Filmer", "movies": "Filmer",
"tv": "TV-serier" "tv": "TV-serier",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "యాక్టివ్ స్ట్రీమ్‌లు", "streams": "యాక్టివ్ స్ట్రీమ్‌లు",
"movies": "సినిమాలు", "movies": "సినిమాలు",
"tv": "దూరదర్శిని కార్యక్రమాలు" "tv": "దూరదర్శిని కార్యక్రమాలు",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "సీపియూ", "cpu": "సీపియూ",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -156,7 +156,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Rate",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"scheduled": "Scheduled",
"passes": "Passes",
"shows": "Shows",
"recordings": "Recordings"
} }
} }

View File

@ -89,7 +89,8 @@
"plex": { "plex": {
"streams": "Aktif Akış", "streams": "Aktif Akış",
"movies": "Filmler", "movies": "Filmler",
"tv": "TV Showları" "tv": "TV Showları",
"albums": "Albums"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Oran", "rate": "Oran",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -208,7 +208,8 @@
"plex": { "plex": {
"streams": "Активні потоки", "streams": "Активні потоки",
"movies": "Фільми", "movies": "Фільми",
"tv": "TБ шоу" "tv": "TБ шоу",
"albums": "Albums"
}, },
"transmission": { "transmission": {
"download": "Завантаження", "download": "Завантаження",
@ -562,5 +563,20 @@
"books": "Книжки", "books": "Книжки",
"podcastsDuration": "Тривалість", "podcastsDuration": "Тривалість",
"booksDuration": "Тривалість" "booksDuration": "Тривалість"
},
"homeassistant": {
"people_home": "Люди вдома",
"lights_on": "Світло ввімкнено",
"switches_on": "Вмикається"
},
"freshrss": {
"subscriptions": "Передплата",
"unread": "Не прочитано"
},
"channelsdvrserver": {
"shows": "Вистави",
"recordings": "Записи",
"scheduled": "Заплановано",
"passes": "Перепустки"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "Active Streams", "streams": "Active Streams",
"movies": "Movies", "movies": "Movies",
"tv": "TV Shows" "tv": "TV Shows",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,14 +228,15 @@
"plex": { "plex": {
"streams": "活动流", "streams": "活动流",
"movies": "电影", "movies": "电影",
"tv": "电视节目" "tv": "电视节目",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "处理器", "cpu": "处理器",
"mem": "内存", "mem": "内存",
"wait": "请稍等", "wait": "请稍等",
"temp": "TEMP", "temp": "温度",
"uptime": "UP", "uptime": "运行时间",
"days": "天", "days": "天",
"hours": "时" "hours": "时"
}, },
@ -260,8 +261,8 @@
"45-night": "有雾", "45-night": "有雾",
"48-night": "有雾", "48-night": "有雾",
"51-night": "小雨", "51-night": "小雨",
"53-day": "Drizzle", "53-day": "小雨",
"53-night": "Drizzle", "53-night": "小雨",
"55-day": "毛毛雨", "55-day": "毛毛雨",
"55-night": "毛毛雨", "55-night": "毛毛雨",
"56-day": "小冻毛雨", "56-day": "小冻毛雨",
@ -562,5 +563,20 @@
"books": "图书", "books": "图书",
"podcastsDuration": "持续时间", "podcastsDuration": "持续时间",
"booksDuration": "持续时间" "booksDuration": "持续时间"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -228,7 +228,8 @@
"plex": { "plex": {
"streams": "正在播放", "streams": "正在播放",
"movies": "電影", "movies": "電影",
"tv": "影集" "tv": "影集",
"albums": "Albums"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -562,5 +563,20 @@
"books": "Books", "books": "Books",
"podcastsDuration": "Duration", "podcastsDuration": "Duration",
"booksDuration": "Duration" "booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
} }
} }

View File

@ -161,7 +161,7 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
)} type="text" autoCorrect="false" ref={searchField} value={searchString} onChange={handleSearchChange} onKeyDown={handleSearchKeyDown} /> )} type="text" autoCorrect="false" ref={searchField} value={searchString} onChange={handleSearchChange} onKeyDown={handleSearchKeyDown} />
{results.length > 0 && <ul className="max-h-[60vh] overflow-y-auto m-2"> {results.length > 0 && <ul className="max-h-[60vh] overflow-y-auto m-2">
{results.map((r, i) => ( {results.map((r, i) => (
<li key={r.name}> <li key={r.container ?? r.app ?? r.name}>
<button type="button" data-index={i} onMouseEnter={handleItemHover} className={classNames( <button type="button" data-index={i} onMouseEnter={handleItemHover} className={classNames(
"flex flex-row w-full items-center justify-between rounded-md text-sm md:text-xl py-2 px-4 cursor-pointer text-theme-700 dark:text-theme-200", "flex flex-row w-full items-center justify-between rounded-md text-sm md:text-xl py-2 px-4 cursor-pointer text-theme-700 dark:text-theme-200",
i === currentItemIndex && "bg-theme-300/50 dark:bg-theme-700/50", i === currentItemIndex && "bg-theme-300/50 dark:bg-theme-700/50",

View File

@ -3,7 +3,19 @@ import Image from "next/future/image";
export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "logo" }) { export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "logo" }) {
// direct or relative URLs // direct or relative URLs
if (icon.startsWith("http") || icon.startsWith("/")) { if (icon.startsWith("http") || icon.startsWith("/")) {
return <Image src={`${icon}`} width={width} height={height} alt={alt} />; return (
<Image
src={`${icon}`}
width={width}
height={height}
style={{
width,
height,
objectFit: "contain",
}}
alt={alt}
/>
);
} }
// mdi- prefixed, material design icons // mdi- prefixed, material design icons
@ -31,6 +43,11 @@ export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "log
src={`https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${iconName}.png`} src={`https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${iconName}.png`}
width={width} width={width}
height={height} height={height}
style={{
width,
height,
objectFit: "contain",
}}
alt={alt} alt={alt}
/> />
); );

View File

@ -3,12 +3,13 @@ import classNames from "classnames";
import List from "components/services/list"; import List from "components/services/list";
import ResolvedIcon from "components/resolvedicon"; import ResolvedIcon from "components/resolvedicon";
export default function ServicesGroup({ services, layout }) { export default function ServicesGroup({ services, layout, fiveColumns }) {
return ( return (
<div <div
key={services.name} key={services.name}
className={classNames( className={classNames(
layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4 3xl:basis-1/5", layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4",
layout?.style !== "row" && fiveColumns ? "3xl:basis-1/5" : "",
"flex-1 p-1" "flex-1 p-1"
)} )}
> >

View File

@ -14,7 +14,8 @@ import ResolvedIcon from "components/resolvedicon";
export default function Item({ service }) { export default function Item({ service }) {
const hasLink = service.href && service.href !== "#"; const hasLink = service.href && service.href !== "#";
const { settings } = useContext(SettingsContext); const { settings } = useContext(SettingsContext);
const [statsOpen, setStatsOpen] = useState(false); const showStats = (service.showStats === false) ? false : settings.showStats;
const [statsOpen, setStatsOpen] = useState(service.showStats);
const [statsClosing, setStatsClosing] = useState(false); const [statsClosing, setStatsClosing] = useState(false);
// set stats to closed after 300ms // set stats to closed after 300ms
@ -33,7 +34,7 @@ export default function Item({ service }) {
<div <div
className={`${ className={`${
hasLink ? "cursor-pointer " : " " hasLink ? "cursor-pointer " : " "
}transition-all h-15 mb-3 p-1 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10 relative`} }transition-all h-15 mb-2 p-1 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10 relative`}
> >
<div className="flex select-none"> <div className="flex select-none">
{service.icon && {service.icon &&
@ -107,21 +108,21 @@ export default function Item({ service }) {
{service.container && service.server && ( {service.container && service.server && (
<div <div
className={classNames( className={classNames(
statsOpen && !statsClosing ? "max-h-[110px] opacity-100" : " max-h-[0] opacity-0", showStats || (statsOpen && !statsClosing) ? "max-h-[110px] opacity-100" : " max-h-[0] opacity-0",
"w-full overflow-hidden transition-all duration-300 ease-in-out" "w-full overflow-hidden transition-all duration-300 ease-in-out"
)} )}
> >
{statsOpen && <Docker service={{ widget: { container: service.container, server: service.server } }} />} {(showStats || statsOpen) && <Docker service={{ widget: { container: service.container, server: service.server } }} />}
</div> </div>
)} )}
{service.app && ( {service.app && (
<div <div
className={classNames( className={classNames(
statsOpen && !statsClosing ? "max-h-[55px] opacity-100" : " max-h-[0] opacity-0", showStats || (statsOpen && !statsClosing) ? "max-h-[55px] opacity-100" : " max-h-[0] opacity-0",
"w-full overflow-hidden transition-all duration-300 ease-in-out" "w-full overflow-hidden transition-all duration-300 ease-in-out"
)} )}
> >
{statsOpen && <Kubernetes service={{ widget: { namespace: service.namespace, app: service.app, podSelector: service.podSelector } }} />} {(showStats || statsOpen) && <Kubernetes service={{ widget: { namespace: service.namespace, app: service.app, podSelector: service.podSelector } }} />}
</div> </div>
)} )}

View File

@ -23,7 +23,7 @@ export default function List({ services, layout }) {
)} )}
> >
{services.map((service) => ( {services.map((service) => (
<Item key={service.name} service={service} /> <Item key={service.container ?? service.app ?? service.name} service={service} />
))} ))}
</ul> </ul>
); );

View File

@ -25,7 +25,7 @@ export default function Ping({ service }) {
const statusText = `${service.ping}: HTTP status ${data.status}`; const statusText = `${service.ping}: HTTP status ${data.status}`;
if (data && data.status !== 200) { if (data.status > 403) {
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusText}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusText}>
<div className="text-[8px] font-bold text-rose-500/80">{data.status}</div> <div className="text-[8px] font-bold text-rose-500/80">{data.status}</div>
@ -33,12 +33,10 @@ export default function Ping({ service }) {
); );
} }
if (data && data.status === 200) { return (
return ( <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusText}>
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusText}> <div className="text-[8px] font-bold text-emerald-500/80">{t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", unitDisplay: "narrow", maximumFractionDigits: 0 })}</div>
<div className="text-[8px] font-bold text-emerald-500/80">{t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", unitDisplay: "narrow", maximumFractionDigits: 0 })}</div> </div>
</div> );
);
}
} }

View File

@ -14,7 +14,7 @@ export default function Container({ error = false, children, service }) {
// fields: [ "resources.cpu", "resources.mem", "field"] // fields: [ "resources.cpu", "resources.mem", "field"]
// or even // or even
// fields: [ "resources.cpu", "widget_type.field" ] // fields: [ "resources.cpu", "widget_type.field" ]
visibleChildren = children.filter(child => fields.some(field => { visibleChildren = children?.filter(child => fields.some(field => {
let fullField = field; let fullField = field;
if (!field.includes(".")) { if (!field.includes(".")) {
fullField = `${type}.${field}`; fullField = `${type}.${field}`;

View File

@ -6,7 +6,7 @@ import { useTranslation } from "next-i18next";
import UsageBar from "../resources/usage-bar"; import UsageBar from "../resources/usage-bar";
const cpuSensorLabels = ["cpu_thermal", "Core"]; const cpuSensorLabels = ["cpu_thermal", "Core", "Tctl"];
function convertToFahrenheit(t) { function convertToFahrenheit(t) {
return t * 9/5 + 32 return t * 9/5 + 32

View File

@ -21,7 +21,7 @@ export default async function handler(req, res) {
}); });
let endTime = performance.now(); let endTime = performance.now();
if (status >= 400) { if (status > 403) {
// try one more time as a GET in case HEAD is rejected for whatever reason // try one more time as a GET in case HEAD is rejected for whatever reason
startTime = performance.now(); startTime = performance.now();
[status] = await httpProxy(pingURL); [status] = await httpProxy(pingURL);

View File

@ -289,7 +289,7 @@ function Home({ initialSettings }) {
{services && ( {services && (
<div className="flex flex-wrap p-4 sm:p-8 sm:pt-4 items-start pb-2"> <div className="flex flex-wrap p-4 sm:p-8 sm:pt-4 items-start pb-2">
{services.map((group) => ( {services.map((group) => (
<ServicesGroup key={group.name} services={group} layout={initialSettings.layout?.[group.name]} /> <ServicesGroup key={group.name} services={group} layout={initialSettings.layout?.[group.name]} fiveColumns={settings.fiveColumns} />
))} ))}
</div> </div>
)} )}
@ -318,15 +318,26 @@ function Home({ initialSettings }) {
export default function Wrapper({ initialSettings, fallback }) { export default function Wrapper({ initialSettings, fallback }) {
const wrappedStyle = {}; const wrappedStyle = {};
let backgroundBlur = false;
let backgroundSaturate = false;
let backgroundBrightness = false;
if (initialSettings && initialSettings.background) { if (initialSettings && initialSettings.background) {
const opacity = initialSettings.backgroundOpacity ?? 1; let opacity = initialSettings.backgroundOpacity ?? 1;
let backgroundImage = initialSettings.background;
if (typeof initialSettings.background === 'object') {
backgroundImage = initialSettings.background.image;
backgroundBlur = initialSettings.background.blur !== undefined;
backgroundSaturate = initialSettings.background.saturate !== undefined;
backgroundBrightness = initialSettings.background.brightness !== undefined;
if (initialSettings.background.opacity !== undefined) opacity = initialSettings.background.opacity / 100;
}
const opacityValue = 1 - opacity; const opacityValue = 1 - opacity;
wrappedStyle.backgroundImage = ` wrappedStyle.backgroundImage = `
linear-gradient( linear-gradient(
rgb(var(--bg-color) / ${opacityValue}), rgb(var(--bg-color) / ${opacityValue}),
rgb(var(--bg-color) / ${opacityValue}) rgb(var(--bg-color) / ${opacityValue})
), ),
url(${initialSettings.background})`; url(${backgroundImage})`;
wrappedStyle.backgroundPosition = "center"; wrappedStyle.backgroundPosition = "center";
wrappedStyle.backgroundSize = "cover"; wrappedStyle.backgroundSize = "cover";
} }
@ -345,7 +356,15 @@ export default function Wrapper({ initialSettings, fallback }) {
className="fixed overflow-auto w-full h-full bg-theme-50 dark:bg-theme-800 transition-all" className="fixed overflow-auto w-full h-full bg-theme-50 dark:bg-theme-800 transition-all"
style={wrappedStyle} style={wrappedStyle}
> >
<Index initialSettings={initialSettings} fallback={fallback} /> <div
id="inner_wrapper"
className={classNames(
backgroundBlur && `backdrop-blur${initialSettings.background.blur.length ? '-' : ""}${initialSettings.background.blur}`,
backgroundSaturate && `backdrop-saturate-${initialSettings.background.saturate}`,
backgroundBrightness && `backdrop-brightness-${initialSettings.background.brightness}`,
)}>
<Index initialSettings={initialSettings} fallback={fallback} />
</div>
</div> </div>
</div> </div>
); );

View File

@ -32,6 +32,7 @@ export async function servicesFromConfig() {
services: servicesGroup[Object.keys(servicesGroup)[0]].map((entries) => ({ services: servicesGroup[Object.keys(servicesGroup)[0]].map((entries) => ({
name: Object.keys(entries)[0], name: Object.keys(entries)[0],
...entries[Object.keys(entries)[0]], ...entries[Object.keys(entries)[0]],
type: 'service'
})), })),
})); }));
@ -82,6 +83,7 @@ export async function servicesFromDocker() {
constructedService = { constructedService = {
container: container.Names[0].replace(/^\//, ""), container: container.Names[0].replace(/^\//, ""),
server: serverName, server: serverName,
type: 'service'
}; };
} }
shvl.set(constructedService, label.replace("homepage.", ""), container.Labels[label]); shvl.set(constructedService, label.replace("homepage.", ""), container.Labels[label]);
@ -183,6 +185,7 @@ export async function servicesFromKubernetes() {
icon: ingress.metadata.annotations[`${ANNOTATION_BASE}/icon`] || '', icon: ingress.metadata.annotations[`${ANNOTATION_BASE}/icon`] || '',
description: ingress.metadata.annotations[`${ANNOTATION_BASE}/description`] || '', description: ingress.metadata.annotations[`${ANNOTATION_BASE}/description`] || '',
external: false, external: false,
type: 'service'
}; };
if (ingress.metadata.annotations[`${ANNOTATION_BASE}/external`]) { if (ingress.metadata.annotations[`${ANNOTATION_BASE}/external`]) {
constructedService.external = String(ingress.metadata.annotations[`${ANNOTATION_BASE}/external`]).toLowerCase() === "true" constructedService.external = String(ingress.metadata.annotations[`${ANNOTATION_BASE}/external`]).toLowerCase() === "true"
@ -236,6 +239,7 @@ export function cleanServiceGroups(groups) {
name: serviceGroup.name, name: serviceGroup.name,
services: serviceGroup.services.map((service) => { services: serviceGroup.services.map((service) => {
const cleanedService = { ...service }; const cleanedService = { ...service };
if (cleanedService.showStats !== undefined) cleanedService.showStats = JSON.parse(cleanedService.showStats);
if (typeof service.weight === 'string') { if (typeof service.weight === 'string') {
const weight = parseInt(service.weight, 10); const weight = parseInt(service.weight, 10);
if (Number.isNaN(weight)) { if (Number.isNaN(weight)) {
@ -297,8 +301,8 @@ export function cleanServiceGroups(groups) {
if (wan) cleanedService.widget.wan = wan; if (wan) cleanedService.widget.wan = wan;
} }
if (type === "emby" || type === "jellyfin") { if (type === "emby" || type === "jellyfin") {
if (enableBlocks !== undefined) cleanedService.widget.enableBlocks = enableBlocks; if (enableBlocks !== undefined) cleanedService.widget.enableBlocks = JSON.parse(enableBlocks);
if (enableNowPlaying !== undefined) cleanedService.widget.enableNowPlaying = enableNowPlaying; if (enableNowPlaying !== undefined) cleanedService.widget.enableNowPlaying = JSON.parse(enableNowPlaying);
} }
if (type === "diskstation") { if (type === "diskstation") {
if (volume) cleanedService.widget.volume = volume; if (volume) cleanedService.widget.volume = volume;

View File

@ -67,6 +67,10 @@ export default async function credentialedProxyHandler(req, res, map) {
let resultData = data; let resultData = data;
if (resultData.error?.url) {
resultData.error.url = sanitizeErrorURL(url);
}
if (status === 204 || status === 304) { if (status === 204 || status === 304) {
return res.status(status).end(); return res.status(status).end();
} }
@ -74,16 +78,12 @@ export default async function credentialedProxyHandler(req, res, map) {
if (status >= 400) { if (status >= 400) {
logger.error("HTTP Error %d calling %s", status, url.toString()); logger.error("HTTP Error %d calling %s", status, url.toString());
} }
if (!validateWidgetData(widget, endpoint, data)) { if (status === 200) {
if (data.error && data.error.url) { if (!validateWidgetData(widget, endpoint, resultData)) {
data.error.url = sanitizeErrorURL(url); return res.status(500).json({error: {message: "Invalid data", url: sanitizeErrorURL(url), data: resultData}});
} }
return res.status(500).json({error: {message: "Invalid data", url: sanitizeErrorURL(url), data}}); if (map) resultData = map(resultData);
}
if (status === 200 && map) {
resultData = map(data);
} }
if (contentType) res.setHeader("Content-Type", contentType); if (contentType) res.setHeader("Content-Type", contentType);

View File

@ -39,15 +39,15 @@ export default async function genericProxyHandler(req, res, map) {
let resultData = data; let resultData = data;
if (!validateWidgetData(widget, endpoint, resultData)) { if (resultData.error?.url) {
if (resultData.error && resultData.error.url) { resultData.error.url = sanitizeErrorURL(url);
resultData.error.url = sanitizeErrorURL(url);
}
return res.status(status).json({error: {message: "Invalid data", url: sanitizeErrorURL(url), data: resultData}});
} }
if (status === 200 && map) { if (status === 200) {
resultData = map(data); if (!validateWidgetData(widget, endpoint, resultData)) {
return res.status(status).json({error: {message: "Invalid data", url: sanitizeErrorURL(url), data: resultData}});
}
if (map) resultData = map(resultData);
} }
if (contentType) res.setHeader("Content-Type", contentType); if (contentType) res.setHeader("Content-Type", contentType);
@ -58,7 +58,7 @@ export default async function genericProxyHandler(req, res, map) {
if (status >= 400) { if (status >= 400) {
logger.debug("HTTP Error %d calling %s//%s%s...", status, url.protocol, url.hostname, url.pathname); logger.debug("HTTP Error %d calling %s//%s%s...", status, url.protocol, url.hostname, url.pathname);
return res.status(status).json({error: {message: "HTTP Error", url: sanitizeErrorURL(url), data}}); return res.status(status).json({error: {message: "HTTP Error", url: sanitizeErrorURL(url), resultData}});
} }
return res.status(status).send(resultData); return res.status(status).send(resultData);

View File

@ -1,25 +1,34 @@
/* eslint-disable no-console */
import widgets from "widgets/widgets"; import widgets from "widgets/widgets";
export default function validateWidgetData(widget, endpoint, data) { export default function validateWidgetData(widget, endpoint, data) {
let valid = true; let valid = true;
let dataParsed; let dataParsed = data;
if (typeof data === 'object') { let error;
dataParsed = data; let mapping;
} else { if (Buffer.isBuffer(data)) {
try { try {
dataParsed = JSON.parse(data); dataParsed = JSON.parse(data);
} catch (e) { } catch (e) {
error = e;
valid = false; valid = false;
} }
} }
if (dataParsed && Object.entries(dataParsed).length) { if (dataParsed && Object.entries(dataParsed).length) {
const validate = widgets[widget.type]?.mappings?.[endpoint]?.validate; const mappings = widgets[widget.type]?.mappings;
validate?.forEach(key => { if (mappings) {
if (dataParsed[key] === undefined) { mapping = Object.values(mappings).find(m => m.endpoint === endpoint);
valid = false; mapping?.validate?.forEach(key => {
} if (dataParsed[key] === undefined) {
}); valid = false;
}
});
}
}
if (!valid) {
console.warn(`Invalid data for widget '${widget.type}' endpoint '${endpoint}':\nExpected:${mapping?.validate}\nParse error: ${error ?? "none"}\nData: ${JSON.stringify(data)}`);
} }
return valid; return valid;

View File

@ -0,0 +1,36 @@
import { useTranslation } from "next-i18next";
import Container from "components/services/widget/container";
import Block from "components/services/widget/block";
import useWidgetAPI from "utils/proxy/use-widget-api";
export default function Component({ service }) {
const { t } = useTranslation();
const { widget } = service;
const { data: channelsData, error: channelsError } = useWidgetAPI(widget, "status");
if (channelsError) {
return <Container error={channelsError} />;
}
if (!channelsData) {
return (
<Container service={service}>
<Block label="channelsdvrserver.shows" />
<Block label="channelsdvrserver.recordings" />
<Block label="channelsdvrserver.scheduled" />
<Block label="channelsdvrserver.passes" />
</Container>
);
}
return (
<Container service={service}>
<Block label="channelsdvrserver.shows" value={t("common.number", { value: channelsData.stats.groups })} />
<Block label="channelsdvrserver.recordings" value={t("common.number", { value: channelsData.stats.files })} />
<Block label="channelsdvrserver.scheduled" value={t("common.number", { value: channelsData.stats.jobs })} />
<Block label="channelsdvrserver.passes" value={t("common.number", { value: channelsData.stats.rules })} />
</Container>
);
}

View File

@ -0,0 +1,14 @@
import genericProxyHandler from "utils/proxy/handlers/generic";
const widget = {
api: "{url}/{endpoint}",
proxyHandler: genericProxyHandler,
mappings: {
status: {
endpoint: "dvr",
},
},
};
export default widget;

View File

@ -7,6 +7,7 @@ const components = {
autobrr: dynamic(() => import("./autobrr/component")), autobrr: dynamic(() => import("./autobrr/component")),
bazarr: dynamic(() => import("./bazarr/component")), bazarr: dynamic(() => import("./bazarr/component")),
changedetectionio: dynamic(() => import("./changedetectionio/component")), changedetectionio: dynamic(() => import("./changedetectionio/component")),
channelsdvrserver: dynamic(() => import("./channelsdvrserver/component")),
cloudflared: dynamic(() => import("./cloudflared/component")), cloudflared: dynamic(() => import("./cloudflared/component")),
coinmarketcap: dynamic(() => import("./coinmarketcap/component")), coinmarketcap: dynamic(() => import("./coinmarketcap/component")),
deluge: dynamic(() => import("./deluge/component")), deluge: dynamic(() => import("./deluge/component")),
@ -17,11 +18,13 @@ const components = {
emby: dynamic(() => import("./emby/component")), emby: dynamic(() => import("./emby/component")),
fileflows: dynamic(() => import("./fileflows/component")), fileflows: dynamic(() => import("./fileflows/component")),
flood: dynamic(() => import("./flood/component")), flood: dynamic(() => import("./flood/component")),
freshrss: dynamic(() => import("./freshrss/component")),
ghostfolio: dynamic(() => import("./ghostfolio/component")), ghostfolio: dynamic(() => import("./ghostfolio/component")),
gluetun: dynamic(() => import("./gluetun/component")), gluetun: dynamic(() => import("./gluetun/component")),
gotify: dynamic(() => import("./gotify/component")), gotify: dynamic(() => import("./gotify/component")),
grafana: dynamic(() => import("./grafana/component")), grafana: dynamic(() => import("./grafana/component")),
hdhomerun: dynamic(() => import("./hdhomerun/component")), hdhomerun: dynamic(() => import("./hdhomerun/component")),
homeassistant: dynamic(() => import("./homeassistant/component")),
homebridge: dynamic(() => import("./homebridge/component")), homebridge: dynamic(() => import("./homebridge/component")),
healthchecks: dynamic(() => import("./healthchecks/component")), healthchecks: dynamic(() => import("./healthchecks/component")),
immich: dynamic(() => import("./immich/component")), immich: dynamic(() => import("./immich/component")),

View File

@ -0,0 +1,33 @@
import { useTranslation } from "next-i18next";
import Container from "components/services/widget/container";
import Block from "components/services/widget/block";
import useWidgetAPI from "utils/proxy/use-widget-api";
export default function Component({ service }) {
const { t } = useTranslation();
const { widget } = service;
const { data: freshrssData, error: freshrssError } = useWidgetAPI(widget, "info");
if (freshrssError) {
return <Container error={freshrssError} />;
}
if (!freshrssData) {
return (
<Container service={service}>
<Block label="freshrss.unread" />
<Block label="freshrss.subscriptions" />
</Container>
);
}
return (
<Container service={service}>
<Block label="freshrss.unread" value={t("common.number", { value: freshrssData.unread })} />
<Block label="freshrss.subscriptions" value={t("common.number", { value: freshrssData.subscriptions })} />
</Container>
);
}

View File

@ -0,0 +1,97 @@
import cache from "memory-cache";
import { httpProxy } from "utils/proxy/http";
import { formatApiCall } from "utils/proxy/api-helpers";
import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger";
import widgets from "widgets/widgets";
const proxyName = "freshrssProxyHandler";
const sessionTokenCacheKey = `${proxyName}__sessionToken`;
const logger = createLogger(proxyName);
async function login(widget, service) {
const endpoint = "accounts/ClientLogin";
const api = widgets?.[widget.type]?.api
const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget }));
const headers = { "Content-Type": "application/x-www-form-urlencoded" };
const [, , data,] = await httpProxy(loginUrl, {
method: "POST",
body: new URLSearchParams({
Email: widget.username,
Passwd: widget.password
}).toString(),
headers,
});
try {
const [, token] = data.toString().split("\n").find(line => line.startsWith("Auth=")).split("=")
cache.put(`${sessionTokenCacheKey}.${service}`, token);
return { token };
} catch (e) {
logger.error("Unable to login to FreshRSS API: %s", e);
}
return { token: false };
}
async function apiCall(widget, endpoint, service) {
const key = `${sessionTokenCacheKey}.${service}`;
const headers = {
"Authorization": `GoogleLogin auth=${cache.get(key)}`,
}
const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));
const method = "GET";
let [status, contentType, data, responseHeaders] = await httpProxy(url, {
method,
headers,
});
if (status === 401) {
logger.debug("FreshRSS API rejected the request, attempting to obtain new session token");
const { token } = await login(widget, service);
headers.Authorization = `GoogleLogin auth=${token}`;
// retry the request, now with the new session token
[status, contentType, data, responseHeaders] = await httpProxy(url, {
method,
headers,
});
}
if (status !== 200) {
logger.error("Error getting data from FreshRSS: %s status %d. Data: %s", url, status, data);
return { status, contentType, data: null, responseHeaders };
}
return { status, contentType, data: JSON.parse(data.toString()), responseHeaders };
}
export default async function freshrssProxyHandler(req, res) {
const { group, service } = req.query;
if (!group || !service) {
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
const widget = await getServiceWidget(group, service);
if (!widget) {
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
if (!cache.get(`${sessionTokenCacheKey}.${service}`)) {
await login(widget, service);
}
const { data: subscriptionData } = await apiCall(widget, "reader/api/0/subscription/list", service);
const { data: unreadCountData } = await apiCall(widget, "reader/api/0/unread-count", service);
return res.status(200).send({
subscriptions: subscriptionData?.subscriptions.length,
unread: unreadCountData?.max
});
}

View File

@ -0,0 +1,13 @@
import freshrssProxyHandler from "./proxy";
const widget = {
api: "{url}/api/greader.php/{endpoint}?output=json",
proxyHandler: freshrssProxyHandler,
mappings: {
info: {
endpoint: "/"
}
}
};
export default widget;

View File

@ -0,0 +1,16 @@
import Container from "components/services/widget/container";
import Block from "components/services/widget/block";
import useWidgetAPI from "utils/proxy/use-widget-api";
export default function Component({ service }) {
const { widget } = service;
const { data, error } = useWidgetAPI(widget, null, { refreshInterval: 60000 });
if (error) {
return <Container error={error} />;
}
return <Container service={service}>
{data?.map(d => <Block label={d.label} value={d.value} key={d.label} />)}
</Container>;
}

View File

@ -0,0 +1,89 @@
import { httpProxy } from "utils/proxy/http";
import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger";
const logger = createLogger("homeassistantProxyHandler");
const defaultQueries = [
{
template: "{{ states.person|selectattr('state','equalto','home')|list|length }} / {{ states.person|list|length }}",
label: "homeassistant.people_home"
},
{
template: "{{ states.light|selectattr('state','equalto','on')|list|length }} / {{ states.light|list|length }}",
label: "homeassistant.lights_on"
},
{
template: "{{ states.switch|selectattr('state','equalto','on')|list|length }} / {{ states.switch|list|length }}",
label: "homeassistant.switches_on"
}
];
function formatOutput(output, data) {
return output.replace(/\{.*?\}/g,
(match) => match.replace(/\{|\}/g, "").split(".").reduce((o, p) => o ? o[p] : "", data) ?? "");
}
async function getQuery(query, { url, key }) {
const headers = { Authorization: `Bearer ${key}` };
const { state, template, label, value } = query;
if (state) {
return {
result: await httpProxy(new URL(`${url}/api/states/${state}`), {
headers,
method: "GET"
}),
output: (data) => {
const jsonData = JSON.parse(data);
return {
label: formatOutput(label ?? "{attributes.friendly_name}", jsonData),
value: formatOutput(value ?? "{state} {attributes.unit_of_measurement}", jsonData)
};
}
};
}
if (template) {
return {
result: await httpProxy(new URL(`${url}/api/template`), {
headers,
method: "POST",
body: JSON.stringify({ template })
}),
output: (data) => ({ label, value: data.toString() })
};
}
return { result: [500, null, { error: { message: `invalid query ${JSON.stringify(query)}` } }] };
}
export default async function homeassistantProxyHandler(req, res) {
const { group, service } = req.query;
if (!group || !service) {
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
const widget = await getServiceWidget(group, service);
if (!widget) {
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
let queries = defaultQueries;
if (!widget.fields && widget.custom) {
queries = widget.custom.slice(0, 4);
}
const results = await Promise.all(queries.map(q => getQuery(q, widget)));
const err = results.find(r => r.result[2]?.error);
if (err) {
const [status, , data] = err.result;
return res.status(status).send(data);
}
return res.status(200).send(results.map(r => {
const [status, , data] = r.result;
return status === 200 ? r.output(data) : { label: status, value: data.toString() };
}));
}

View File

@ -0,0 +1,7 @@
import homeassistantProxyHandler from "./proxy";
const widget = {
proxyHandler: homeassistantProxyHandler,
};
export default widget;

View File

@ -52,7 +52,7 @@ async function apiCall(widget, endpoint, service) {
if (status === 401 || status === 403) { if (status === 401 || status === 403) {
logger.debug("Homebridge API rejected the request, attempting to obtain new session token"); logger.debug("Homebridge API rejected the request, attempting to obtain new session token");
const { accessToken } = login(widget, service); const { accessToken } = await login(widget, service);
headers.Authorization = `Bearer ${accessToken}`; headers.Authorization = `Bearer ${accessToken}`;
// retry the request, now with the new session token // retry the request, now with the new session token

View File

@ -21,6 +21,7 @@ export default function Component({ service }) {
return ( return (
<Container service={service}> <Container service={service}>
<Block label="plex.streams" /> <Block label="plex.streams" />
<Block label="plex.albums" />
<Block label="plex.movies" /> <Block label="plex.movies" />
<Block label="plex.tv" /> <Block label="plex.tv" />
</Container> </Container>
@ -30,6 +31,7 @@ export default function Component({ service }) {
return ( return (
<Container service={service}> <Container service={service}>
<Block label="plex.streams" value={t("common.number", { value: plexData.streams })} /> <Block label="plex.streams" value={t("common.number", { value: plexData.streams })} />
<Block label="plex.albums" value={t("common.number", { value: plexData.albums })} />
<Block label="plex.movies" value={t("common.number", { value: plexData.movies })} /> <Block label="plex.movies" value={t("common.number", { value: plexData.movies })} />
<Block label="plex.tv" value={t("common.number", { value: plexData.tv })} /> <Block label="plex.tv" value={t("common.number", { value: plexData.tv })} />
</Container> </Container>

View File

@ -10,6 +10,7 @@ import widgets from "widgets/widgets";
const proxyName = "plexProxyHandler"; const proxyName = "plexProxyHandler";
const librariesCacheKey = `${proxyName}__libraries`; const librariesCacheKey = `${proxyName}__libraries`;
const albumsCacheKey = `${proxyName}__albums`;
const moviesCacheKey = `${proxyName}__movies`; const moviesCacheKey = `${proxyName}__movies`;
const tvCacheKey = `${proxyName}__tv`; const tvCacheKey = `${proxyName}__tv`;
const logger = createLogger(proxyName); const logger = createLogger(proxyName);
@ -87,32 +88,41 @@ export default async function plexProxyHandler(req, res) {
} }
} }
let albums = cache.get(`${albumsCacheKey}.${service}`);
let movies = cache.get(`${moviesCacheKey}.${service}`); let movies = cache.get(`${moviesCacheKey}.${service}`);
let tv = cache.get(`${tvCacheKey}.${service}`); let tv = cache.get(`${tvCacheKey}.${service}`);
if (movies === null || tv === null) { if (albums === null || movies === null || tv === null) {
albums = 0;
movies = 0; movies = 0;
tv = 0; tv = 0;
logger.debug("Getting movie + tv counts from Plex API"); logger.debug("Getting counts from Plex API");
const movieTVLibraries = libraries.filter(l => ["movie", "show"].includes(l._attributes.type)); const movieTVLibraries = libraries.filter(l => ["movie", "show", "artist"].includes(l._attributes.type));
await Promise.all(movieTVLibraries.map(async (library) => { await Promise.all(movieTVLibraries.map(async (library) => {
[status, apiData] = await fetchFromPlexAPI(`/library/sections/${library._attributes.key}/all`, widget); const libraryURL = ["movie", "show"].includes(library._attributes.type) ?
`/library/sections/${library._attributes.key}/all` : // tv + movies
`/library/sections/${library._attributes.key}/albums`; // music
[status, apiData] = await fetchFromPlexAPI(libraryURL, widget);
if (apiData && apiData.MediaContainer) { if (apiData && apiData.MediaContainer) {
const size = parseInt(apiData.MediaContainer._attributes.size, 10); const size = parseInt(apiData.MediaContainer._attributes.size, 10);
if (library._attributes.type === "movie") { if (library._attributes.type === "movie") {
movies += size; movies += size;
} else if (library._attributes.type === "show") { } else if (library._attributes.type === "show") {
tv += size; tv += size;
} else if (library._attributes.type === "artist") {
albums += size;
} }
} }
})); }));
cache.put(`${albumsCacheKey}.${service}`, albums, 1000 * 60 * 10);
cache.put(`${tvCacheKey}.${service}`, tv, 1000 * 60 * 10); cache.put(`${tvCacheKey}.${service}`, tv, 1000 * 60 * 10);
cache.put(`${moviesCacheKey}.${service}`, movies, 1000 * 60 * 10); cache.put(`${moviesCacheKey}.${service}`, movies, 1000 * 60 * 10);
} }
const data = { const data = {
streams, streams,
albums,
movies,
tv, tv,
movies
}; };
return res.status(status).send(data); return res.status(status).send(data);

View File

@ -32,8 +32,8 @@ export default function Component({ service }) {
grabsData?.indexers?.forEach((element) => { grabsData?.indexers?.forEach((element) => {
numberOfGrabs += element.numberOfGrabs; numberOfGrabs += element.numberOfGrabs;
numberOfQueries += element.numberOfQueries; numberOfQueries += element.numberOfQueries;
numberOfFailedGrabs += numberOfFailedGrabs + element.numberOfFailedGrabs; numberOfFailedGrabs += element.numberOfFailedGrabs;
numberOfFailedQueries += numberOfFailedQueries + element.numberOfFailedQueries; numberOfFailedQueries += element.numberOfFailedQueries;
}); });
return ( return (

View File

@ -33,7 +33,9 @@ export default async function transmissionProxyHandler(req, res) {
cache.put(`${headerCacheKey}.${service}`, headers); cache.put(`${headerCacheKey}.${service}`, headers);
} }
const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget })); const api = `${widget.url}${widget.rpcUrl || widgets[widget.type].rpcUrl}rpc`;
const url = new URL(formatApiCall(api, { endpoint, ...widget }));
const csrfHeaderName = "x-transmission-session-id"; const csrfHeaderName = "x-transmission-session-id";
const method = "POST"; const method = "POST";

View File

@ -1,7 +1,7 @@
import transmissionProxyHandler from "./proxy"; import transmissionProxyHandler from "./proxy";
const widget = { const widget = {
api: "{url}/transmission/rpc", rpcUrl: "/transmission/",
proxyHandler: transmissionProxyHandler, proxyHandler: transmissionProxyHandler,
}; };

View File

@ -4,6 +4,7 @@ import authentik from "./authentik/widget";
import autobrr from "./autobrr/widget"; import autobrr from "./autobrr/widget";
import bazarr from "./bazarr/widget"; import bazarr from "./bazarr/widget";
import changedetectionio from "./changedetectionio/widget"; import changedetectionio from "./changedetectionio/widget";
import channelsdvrserver from "./channelsdvrserver/widget";
import cloudflared from "./cloudflared/widget"; import cloudflared from "./cloudflared/widget";
import coinmarketcap from "./coinmarketcap/widget"; import coinmarketcap from "./coinmarketcap/widget";
import deluge from "./deluge/widget"; import deluge from "./deluge/widget";
@ -12,11 +13,13 @@ import downloadstation from "./downloadstation/widget";
import emby from "./emby/widget"; import emby from "./emby/widget";
import fileflows from "./fileflows/widget"; import fileflows from "./fileflows/widget";
import flood from "./flood/widget"; import flood from "./flood/widget";
import ghostfolio from "./ghostfolio/widget" import freshrss from "./freshrss/widget";
import ghostfolio from "./ghostfolio/widget";
import gluetun from "./gluetun/widget"; import gluetun from "./gluetun/widget";
import gotify from "./gotify/widget"; import gotify from "./gotify/widget";
import grafana from "./grafana/widget"; import grafana from "./grafana/widget";
import hdhomerun from "./hdhomerun/widget"; import hdhomerun from "./hdhomerun/widget";
import homeassistant from "./homeassistant/widget";
import homebridge from "./homebridge/widget"; import homebridge from "./homebridge/widget";
import healthchecks from "./healthchecks/widget"; import healthchecks from "./healthchecks/widget";
import immich from "./immich/widget"; import immich from "./immich/widget";
@ -82,6 +85,7 @@ const widgets = {
autobrr, autobrr,
bazarr, bazarr,
changedetectionio, changedetectionio,
channelsdvrserver,
cloudflared, cloudflared,
coinmarketcap, coinmarketcap,
deluge, deluge,
@ -90,11 +94,13 @@ const widgets = {
emby, emby,
fileflows, fileflows,
flood, flood,
freshrss,
ghostfolio, ghostfolio,
gluetun, gluetun,
gotify, gotify,
grafana, grafana,
hdhomerun, hdhomerun,
homeassistant,
homebridge, homebridge,
healthchecks, healthchecks,
immich, immich,