Merge branch 'main' into glances-fs

This commit is contained in:
Ben Phelps 2023-09-03 17:23:08 +03:00
commit 108ca23212
75 changed files with 2336 additions and 528 deletions

2
.vscode/launch.json vendored
View File

@ -16,4 +16,4 @@
} }
} }
] ]
} }

View File

@ -85,6 +85,8 @@ services:
volumes: volumes:
- /path/to/config:/app/config # Make sure your local config directory exists - /path/to/config:/app/config # Make sure your local config directory exists
- /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations - /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations
# user: 1000:1000 optional, not compatibile with direct socket see https://gethomepage.dev/en/configs/docker/#using-socket-directly
restart: unless-stopped
``` ```
or docker run: or docker run:

10
package-lock.json generated
View File

@ -14,7 +14,7 @@
"compare-versions": "^5.0.1", "compare-versions": "^5.0.1",
"dockerode": "^3.3.4", "dockerode": "^3.3.4",
"follow-redirects": "^1.15.2", "follow-redirects": "^1.15.2",
"gamedig": "^4.0.6", "gamedig": "^4.0.7",
"i18next": "^21.9.2", "i18next": "^21.9.2",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"json-rpc-2.0": "^1.4.1", "json-rpc-2.0": "^1.4.1",
@ -2977,14 +2977,14 @@
} }
}, },
"node_modules/gamedig": { "node_modules/gamedig": {
"version": "4.0.6", "version": "4.0.7",
"resolved": "https://registry.npmjs.org/gamedig/-/gamedig-4.0.6.tgz", "resolved": "https://registry.npmjs.org/gamedig/-/gamedig-4.0.7.tgz",
"integrity": "sha512-h0k9n/e5vNrd9Mh2wyFUp2Vo7ABWbDkdBxKC6FNJLOZiU5d9Z29bntGeYbXtOkcRWoV6Q63wSAJ3jLWxYQkpZw==", "integrity": "sha512-A8bJ23ulAEp8A4ZJAHp5cMkWu4ymf6AQdOPBAa2asHQqAnf2/bIa07ClcQeeCp+bQWYqJAcW7xvUqjruSrCX4A==",
"dependencies": { "dependencies": {
"cheerio": "^1.0.0-rc.10", "cheerio": "^1.0.0-rc.10",
"compressjs": "^1.0.2", "compressjs": "^1.0.2",
"gbxremote": "^0.2.1", "gbxremote": "^0.2.1",
"got": "^12.0.3", "got": "^12.1.0",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"long": "^5.2.0", "long": "^5.2.0",
"minimist": "^1.2.6", "minimist": "^1.2.6",

View File

@ -16,7 +16,7 @@
"compare-versions": "^5.0.1", "compare-versions": "^5.0.1",
"dockerode": "^3.3.4", "dockerode": "^3.3.4",
"follow-redirects": "^1.15.2", "follow-redirects": "^1.15.2",
"gamedig": "^4.0.6", "gamedig": "^4.0.7",
"i18next": "^21.9.2", "i18next": "^21.9.2",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"json-rpc-2.0": "^1.4.1", "json-rpc-2.0": "^1.4.1",

8
pnpm-lock.yaml generated
View File

@ -24,8 +24,8 @@ dependencies:
specifier: ^1.15.2 specifier: ^1.15.2
version: 1.15.2 version: 1.15.2
gamedig: gamedig:
specifier: ^4.0.6 specifier: ^4.0.7
version: 4.0.6 version: 4.0.7
i18next: i18next:
specifier: ^21.9.2 specifier: ^21.9.2
version: 21.10.0 version: 21.10.0
@ -1972,8 +1972,8 @@ packages:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
dev: true dev: true
/gamedig@4.0.6: /gamedig@4.0.7:
resolution: {integrity: sha512-h0k9n/e5vNrd9Mh2wyFUp2Vo7ABWbDkdBxKC6FNJLOZiU5d9Z29bntGeYbXtOkcRWoV6Q63wSAJ3jLWxYQkpZw==} resolution: {integrity: sha512-A8bJ23ulAEp8A4ZJAHp5cMkWu4ymf6AQdOPBAa2asHQqAnf2/bIa07ClcQeeCp+bQWYqJAcW7xvUqjruSrCX4A==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
dependencies: dependencies:

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories",
"series": "Series"
},
"calibreweb": {
"categories": "Categories",
"series": "Series",
"books": "Books",
"authors": "Authors"
},
"uptimerobot": {
"seemsdown": "Seems Down",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -10,13 +10,13 @@
"movies": "Film", "movies": "Film",
"wanted": "Ønskede", "wanted": "Ønskede",
"missing": "Mangler", "missing": "Mangler",
"queue": "Queue", "queue": "",
"unknown": "Unknown" "unknown": "Ukendt"
}, },
"lidarr": { "lidarr": {
"wanted": "Ønsket", "wanted": "Ønsket",
"queued": "I Kø", "queued": "I Kø",
"artists": "Artists" "artists": "Artister"
}, },
"jellyseerr": { "jellyseerr": {
"available": "Tilgængelig", "available": "Tilgængelig",
@ -27,13 +27,13 @@
"pending": "Afventer", "pending": "Afventer",
"approved": "Godkendt", "approved": "Godkendt",
"available": "Tilgængelig", "available": "Tilgængelig",
"processing": "Processing" "processing": "Behandler"
}, },
"adguard": { "adguard": {
"queries": "Forespørgsler", "queries": "Forespørgsler",
"blocked": "Blokerede", "blocked": "Blokerede",
"filtered": "Filtreret", "filtered": "Filtreret",
"latency": "Latency" "latency": "Latenstid"
}, },
"speedtest": { "speedtest": {
"upload": "Upload", "upload": "Upload",
@ -48,7 +48,7 @@
"coinmarketcap": { "coinmarketcap": {
"30days": "30 Dage", "30days": "30 Dage",
"1day": "1 Dag", "1day": "1 Dag",
"configure": "Konfigurer en eller flere crypto valutaer til tracking", "configure": "Konfigurer en eller flere crypto valutaer til tracking",
"7days": "7 Dage", "7days": "7 Dage",
"1hour": "1 time" "1hour": "1 time"
}, },
@ -73,67 +73,67 @@
"wait": "Vent venligst", "wait": "Vent venligst",
"uptime": "UP", "uptime": "UP",
"days": "d", "days": "d",
"hours": "h", "hours": "t",
"temp": "TEMP", "temp": "TEMP",
"load": "Load", "load": "Load",
"warn": "Warn", "warn": "Advar",
"total": "Total", "total": "Total",
"free": "Free", "free": "Ledig",
"used": "Used", "used": "Brugt",
"crit": "Crit", "crit": "Crit",
"read": "Read", "read": "Læs",
"write": "Write", "write": "Skriv",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Ram",
"swap": "Swap" "swap": "Swap"
}, },
"wmo": { "wmo": {
"1-day": "Hovedsageligt solrigt", "1-day": "Overvejende Solrigt",
"48-day": "Tåget", "48-day": "Tåget",
"48-night": "Tåget", "48-night": "Tåget",
"51-day": "Let støvregn", "51-day": "Let Støvregn",
"51-night": "Let støvregn", "51-night": "Let Støvregn",
"66-night": "Frysende regn", "66-night": "Frysende Regn",
"67-day": "Frysende regn", "67-day": "Frysende Regn",
"67-night": "Frysende regn", "67-night": "Frysende Regn",
"71-day": "Let Sne", "71-day": "Let Sne",
"75-night": "Kraftig Sne", "75-night": "Kraftig Sne",
"86-day": "Snebyger", "86-day": "Snebyger",
"86-night": "Snebyger", "86-night": "Snebyger",
"95-day": "Tordenvejr", "95-day": "Tordenvejr",
"99-day": "Tordenvejr med hagl", "99-day": "Tordenvejr Med Hagl",
"99-night": "Tordenvejr med hagl", "99-night": "Tordenvejr Med Hagl",
"0-day": "Solrig", "0-day": "Solrig",
"0-night": "Klart", "0-night": "Klart",
"1-night": "Hovedsageligt klart", "1-night": "Overvejende Skyfrit",
"2-day": "Delvist skyet", "2-day": "Delvist Overskyet",
"2-night": "Delvist skyet", "2-night": "Delvist Overskyet",
"3-day": "Skyet", "3-day": "Skyet",
"3-night": "Skyet", "3-night": "Skyet",
"45-day": "Tåget", "45-day": "Tåget",
"65-day": "Kraftig regn", "65-day": "Kraftig Regn",
"65-night": "Kraftig regn", "65-night": "Kraftig Regn",
"45-night": "Tåget", "45-night": "Tåget",
"53-day": "Støvregn", "53-day": "Støvregn",
"53-night": "Støvregn", "53-night": "Støvregn",
"55-day": "Kraftig støvregn", "55-day": "Kraftig Støvregn",
"55-night": "Kraftig støvregn", "55-night": "Kraftig Støvregn",
"56-day": "Let frysende støvregn", "56-day": "Let Frysende Støvregn",
"56-night": "Let frysende støvregn", "56-night": "Let Frysende Støvregn",
"57-day": "Frysende støvregn", "57-day": "Frysende Støvregn",
"57-night": "Frysende støvregn", "57-night": "Frysende Støvregn",
"61-day": "Let Regn", "61-day": "Let Regn",
"61-night": "Let Regn", "61-night": "Let Regn",
"63-day": "Regn", "63-day": "Regn",
"63-night": "Regn", "63-night": "Regn",
"66-day": "Frysende regn", "66-day": "Frysende Regn",
"71-night": "Let Sne", "71-night": "Let Sne",
"73-day": "Sne", "73-day": "Sne",
"73-night": "Sne", "73-night": "Sne",
"75-day": "Kraftig Sne", "75-day": "Kraftig Sne",
"77-day": "Snekorn", "77-day": "Snekorn",
"80-day": "Lette byger", "80-day": "Lette Byger",
"80-night": "Lette byger", "80-night": "Lette Byger",
"81-day": "Byger", "81-day": "Byger",
"77-night": "Snekorn", "77-night": "Snekorn",
"81-night": "Byger", "81-night": "Byger",
@ -142,19 +142,19 @@
"85-day": "Snebyger", "85-day": "Snebyger",
"85-night": "Snebyger", "85-night": "Snebyger",
"95-night": "Tordenvejr", "95-night": "Tordenvejr",
"96-day": "Tordenvejr med hagl", "96-day": "Tordenvejr Med Hagl",
"96-night": "Tordenvejr med hagl" "96-night": "Tordenvejr Med Hagl"
}, },
"homebridge": { "homebridge": {
"available_update": "System", "available_update": "System",
"updates": "Opdateringer", "updates": "Opdateringer",
"update_available": "Opdateringer tilgængelige", "update_available": "Opdateringer Tilgængelige",
"up_to_date": "Opdateret", "up_to_date": "Opdateret",
"child_bridges": "Child Bridges", "child_bridges": "Child Bridges",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Oppe",
"pending": "Pending", "pending": "Afventer",
"down": "Down" "down": "Nede"
}, },
"widget": { "widget": {
"missing_type": "Manglende Widget Type: {{type}}", "missing_type": "Manglende Widget Type: {{type}}",
@ -162,8 +162,8 @@
"status": "Status", "status": "Status",
"information": "Information", "information": "Information",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Rå Fejl",
"response_data": "Response Data" "response_data": "Svardata"
}, },
"weather": { "weather": {
"current": "Nuværende lokation", "current": "Nuværende lokation",
@ -180,13 +180,13 @@
"free": "Fri", "free": "Fri",
"used": "Brugt", "used": "Brugt",
"load": "Belastning", "load": "Belastning",
"mem": "MEM", "mem": "RAM",
"hours": "h", "hours": "t",
"minutes": "m", "minutes": "m",
"temp": "TEMP", "temp": "TEMP",
"max": "Max", "max": "Max",
"uptime": "UP", "uptime": "UP",
"months": "mo", "months": "mdr",
"days": "d" "days": "d"
}, },
"unifi": { "unifi": {
@ -204,7 +204,7 @@
"up": "Oppe", "up": "Oppe",
"down": "NED", "down": "NED",
"wait": "Vent venligst", "wait": "Vent venligst",
"empty_data": "Subsystem status unknown" "empty_data": "Subsystem status ukendt"
}, },
"docker": { "docker": {
"cpu": "CPU", "cpu": "CPU",
@ -213,24 +213,24 @@
"mem": "RAM", "mem": "RAM",
"offline": "Offline", "offline": "Offline",
"error": "Error", "error": "Error",
"unknown": "Unknown", "unknown": "Ukendt",
"running": "Running", "running": "Kører",
"starting": "Starting", "starting": "Starter",
"unhealthy": "Unhealthy", "unhealthy": "Usund",
"not_found": "Not Found", "not_found": "Ikke Fundet",
"exited": "Exited", "exited": "Forladt",
"partial": "Partial", "partial": "Delvis",
"healthy": "Healthy" "healthy": "Sund"
}, },
"emby": { "emby": {
"playing": "Afspiller", "playing": "Afspiller",
"transcoding": "Transcoder", "transcoding": "Transcoder",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Ingen Aktive Streams", "no_active": "Ingen Aktive Streams",
"movies": "Movies", "movies": "Film",
"series": "Series", "series": "Serier",
"episodes": "Episodes", "episodes": "Episoder",
"songs": "Songs" "songs": "Sange"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observeret", "totalObserved": "Total Observeret",
@ -241,7 +241,7 @@
"transcoding": "Transcoder", "transcoding": "Transcoder",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Ingen Aktive Streams", "no_active": "Ingen Aktive Streams",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Tjek Plex-forbindelse"
}, },
"nzbget": { "nzbget": {
"rate": "Rate", "rate": "Rate",
@ -274,8 +274,8 @@
"wanted": "Ønsket", "wanted": "Ønsket",
"queued": "I Kø", "queued": "I Kø",
"series": "Serier", "series": "Serier",
"queue": "Queue", "queue": "",
"unknown": "Unknown" "unknown": "Ukendt"
}, },
"readarr": { "readarr": {
"wanted": "Ønskede", "wanted": "Ønskede",
@ -295,7 +295,7 @@
"blocked": "Blokerede", "blocked": "Blokerede",
"gravity": "Gravity", "gravity": "Gravity",
"queries": "Forespørgsler", "queries": "Forespørgsler",
"blocked_percent": "Blocked %" "blocked_percent": "Blokeret %"
}, },
"portainer": { "portainer": {
"running": "Kørende", "running": "Kørende",
@ -316,8 +316,8 @@
"enableIndexers": "Indeksører", "enableIndexers": "Indeksører",
"numberOfGrabs": "Grabs", "numberOfGrabs": "Grabs",
"numberOfQueries": "Forespørgsler", "numberOfQueries": "Forespørgsler",
"numberOfFailGrabs": "Fail Grabs", "numberOfFailGrabs": "Fejl Grabs",
"numberOfFailQueries": "Fejl forespørgsler" "numberOfFailQueries": "Fejl Forespørgsler"
}, },
"jackett": { "jackett": {
"configured": "Konfigureret", "configured": "Konfigureret",
@ -332,9 +332,9 @@
"quicklaunch": { "quicklaunch": {
"bookmark": "Bogmærker", "bookmark": "Bogmærker",
"service": "Service", "service": "Service",
"search": "Search", "search": "Søg",
"custom": "Custom", "custom": "Brugerdefinerede",
"visit": "Visit", "visit": "Besøg",
"url": "URL" "url": "URL"
}, },
"watchtower": { "watchtower": {
@ -371,25 +371,25 @@
"total": "Total" "total": "Total"
}, },
"gluetun": { "gluetun": {
"public_ip": "Public IP", "public_ip": "Offentlig IP",
"region": "Region", "region": "Region",
"country": "Country" "country": "Land"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Kanaler",
"hd": "HD" "hd": "HD"
}, },
"ping": { "ping": {
"error": "Error", "error": "Fejl",
"ping": "Ping" "ping": "Ping"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Bestået",
"failed": "Failed", "failed": "Mislykket",
"unknown": "Unknown" "unknown": "Ukendt"
}, },
"paperlessngx": { "paperlessngx": {
"inbox": "Inbox", "inbox": "Indbakke",
"total": "Total" "total": "Total"
}, },
"deluge": { "deluge": {
@ -405,29 +405,29 @@
"seed": "Seed" "seed": "Seed"
}, },
"tdarr": { "tdarr": {
"queue": "Queue", "queue": "",
"processed": "Processed", "processed": "Behandlet",
"errored": "Errored", "errored": "Fejlet",
"saved": "Saved" "saved": "Gemt"
}, },
"miniflux": { "miniflux": {
"read": "Read", "read": "Læst",
"unread": "Unread" "unread": "Ulæst"
}, },
"nextdns": { "nextdns": {
"wait": "Please Wait", "wait": "Vent Venligst",
"no_devices": "No Device Data Received" "no_devices": "Ingen Enhedsdata Modtaget"
}, },
"common": { "common": {
"bibyterate": "{{value, rate(bits: false; binary: true)}}", "bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}" "bibitrate": "{{value, rate(bits: true; binary: true)}}"
}, },
"omada": { "omada": {
"connectedAp": "Connected APs", "connectedAp": "Forbundne APs",
"activeUser": "Active devices", "activeUser": "Aktive enheder",
"alerts": "Alerts", "alerts": "Advarsler",
"connectedGateway": "Connected gateways", "connectedGateway": "Forbundne gateways",
"connectedSwitches": "Connected switches" "connectedSwitches": "Forbundne switches"
}, },
"downloadstation": { "downloadstation": {
"download": "Download", "download": "Download",
@ -436,238 +436,238 @@
"seed": "Seed" "seed": "Seed"
}, },
"mikrotik": { "mikrotik": {
"cpuLoad": "CPU Load", "cpuLoad": "CPU Belastning",
"memoryUsed": "Memory Used", "memoryUsed": "Hukommelse Brugt",
"uptime": "Uptime", "uptime": "Oppetid",
"numberOfLeases": "Leases" "numberOfLeases": "Leases"
}, },
"xteve": { "xteve": {
"streams_all": "All Streams", "streams_all": "Alle Streams",
"streams_active": "Active Streams", "streams_active": "Aktive Streams",
"streams_xepg": "XEPG Channels" "streams_xepg": "XEPG Kanaler"
}, },
"opnsense": { "opnsense": {
"cpu": "CPU Load", "cpu": "CPU Belastning",
"memory": "Active Memory", "memory": "Aktiv Hukommelse",
"wanUpload": "WAN Upload", "wanUpload": "WAN Upload",
"wanDownload": "WAN Download" "wanDownload": "WAN Download"
}, },
"moonraker": { "moonraker": {
"printer_state": "Printer State", "printer_state": "Printer Tilstand",
"print_status": "Print Status", "print_status": "Print Status",
"print_progress": "Progress", "print_progress": "Fremskridt",
"layers": "Layers" "layers": "Lag"
}, },
"medusa": { "medusa": {
"wanted": "Wanted", "wanted": "Ønskede",
"queued": "Queued", "queued": "I Kø",
"series": "Series" "series": "Serier"
}, },
"octoprint": { "octoprint": {
"printer_state": "Status", "printer_state": "Status",
"temp_tool": "Tool temp", "temp_tool": "Tool temp",
"temp_bed": "Bed temp", "temp_bed": "Bed temp",
"job_completion": "Completion" "job_completion": "Færdiggørelse"
}, },
"cloudflared": { "cloudflared": {
"origin_ip": "Origin IP", "origin_ip": "Oprindelses-IP",
"status": "Status" "status": "Status"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "Datalager",
"failed_tasks_24h": "Failed Tasks 24h", "failed_tasks_24h": "Mislykkede Opgaver 24t",
"cpu_usage": "CPU", "cpu_usage": "CPU",
"memory_usage": "Memory" "memory_usage": "Hukommelse"
}, },
"immich": { "immich": {
"users": "Users", "users": "Brugere",
"photos": "Photos", "photos": "Billeder",
"videos": "Videos", "videos": "Videoer",
"storage": "Storage" "storage": "Lager"
}, },
"uptimekuma": { "uptimekuma": {
"up": "Sites Up", "up": "Sider Oppe",
"down": "Sites Down", "down": "Sider Nede",
"uptime": "Uptime", "uptime": "Oppetid",
"incident": "Incident", "incident": "Hændelse",
"m": "m" "m": "m"
}, },
"komga": { "komga": {
"libraries": "Libraries", "libraries": "Biblioteker",
"series": "Series", "series": "Serier",
"books": "Books" "books": "Bøger"
}, },
"mylar": { "mylar": {
"series": "Series", "series": "Serier",
"issues": "Issues", "issues": "Problemer",
"wanted": "Wanted" "wanted": "Ønskede"
}, },
"photoprism": { "photoprism": {
"albums": "Albums", "albums": "Albums",
"photos": "Photos", "photos": "Billeder",
"videos": "Videos", "videos": "Videoer",
"people": "People" "people": "Mennesker"
}, },
"diskstation": { "diskstation": {
"days": "Days", "days": "Dage",
"uptime": "Uptime", "uptime": "Oppetid",
"volumeAvailable": "Available" "volumeAvailable": "Tilgængelig"
}, },
"fileflows": { "fileflows": {
"queue": "Queue", "queue": "",
"processing": "Processing", "processing": "Behandler",
"processed": "Processed", "processed": "Behandlet",
"time": "Time" "time": "Tid"
}, },
"grafana": { "grafana": {
"totalalerts": "Total Alerts", "totalalerts": "Totale Advarsler",
"dashboards": "Dashboards", "dashboards": "Dashboards",
"datasources": "Data Sources", "datasources": "Data Kilder",
"alertstriggered": "Alerts Triggered" "alertstriggered": "Advarsler Udløst"
}, },
"nextcloud": { "nextcloud": {
"memoryusage": "Memory Usage", "memoryusage": "Hukommelse Forbrug",
"cpuload": "Cpu Load", "cpuload": "Cpu Belastning",
"freespace": "Free Space", "freespace": "Ledig Plads",
"activeusers": "Active Users", "activeusers": "Aktive Brugere",
"numfiles": "Files", "numfiles": "Filer",
"numshares": "Shared Items" "numshares": "Delte Genstande"
}, },
"kopia": { "kopia": {
"status": "Status", "status": "Status",
"size": "Size", "size": "Størrelse",
"lastrun": "Last Run", "lastrun": "Sidst Kørt",
"nextrun": "Next Run", "nextrun": "Næste Kørsel",
"failed": "Failed" "failed": "Mislykket"
}, },
"unmanic": { "unmanic": {
"active_workers": "Active Workers", "active_workers": "Aktive Arbejdere",
"total_workers": "Total Workers", "total_workers": "Totale Arbejdere",
"records_total": "Queue Length" "records_total": "Kø Længde"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "Ny",
"up": "Online", "up": "Online",
"grace": "In Grace Period", "grace": "In Grace Period",
"down": "Offline", "down": "Offline",
"paused": "Paused", "paused": "Pause",
"status": "Status", "status": "Status",
"last_ping": "Last Ping", "last_ping": "Sidste Ping",
"never": "No pings yet" "never": "Ingen Pings Endnu"
}, },
"pterodactyl": { "pterodactyl": {
"servers": "Servers", "servers": "Servere",
"nodes": "Nodes" "nodes": "Noder"
}, },
"prometheus": { "prometheus": {
"targets_up": "Targets Up", "targets_up": "Mål Oppe",
"targets_down": "Targets Down", "targets_down": "Mål Nede",
"targets_total": "Total Targets" "targets_total": "Totale Mål"
}, },
"minecraft": { "minecraft": {
"players": "Players", "players": "Afspillere",
"version": "Version", "version": "Version",
"status": "Status", "status": "Status",
"up": "Online", "up": "Online",
"down": "Offline" "down": "Offline"
}, },
"ghostfolio": { "ghostfolio": {
"gross_percent_today": "Today", "gross_percent_today": "I Dag",
"gross_percent_1y": "One year", "gross_percent_1y": "Et År",
"gross_percent_max": "All time" "gross_percent_max": "Altid"
}, },
"audiobookshelf": { "audiobookshelf": {
"booksDuration": "Duration", "booksDuration": "Varighed",
"podcasts": "Podcasts", "podcasts": "Podcasts",
"books": "Books", "books": "Bøger",
"podcastsDuration": "Duration" "podcastsDuration": "Varighed"
}, },
"homeassistant": { "homeassistant": {
"people_home": "People Home", "people_home": "Personer Hjemme",
"lights_on": "Lights On", "lights_on": "Lys Tændt",
"switches_on": "Switches On" "switches_on": "Kontakter Tændt"
}, },
"freshrss": { "freshrss": {
"subscriptions": "Subscriptions", "subscriptions": "Abonnementer",
"unread": "Unread" "unread": "Ulæst"
}, },
"channelsdvrserver": { "channelsdvrserver": {
"shows": "Shows", "shows": "Shows",
"recordings": "Recordings", "recordings": "Optagelser",
"scheduled": "Scheduled", "scheduled": "Planlagt",
"passes": "Passes" "passes": "Passes"
}, },
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Monitoring", "monitoring": "Overvåger",
"updates": "Updates" "updates": "Opdateringer"
}, },
"tailscale": { "tailscale": {
"address": "Address", "address": "Adresse",
"expires": "Expires", "expires": "Udløber",
"now": "Now", "now": "Nu",
"years": "{{number}}y", "years": "{{number}}y",
"weeks": "{{number}}w", "weeks": "{{number}}w",
"days": "{{number}}d", "days": "{{number}}d",
"hours": "{{number}}h", "hours": "{{number}}h",
"minutes": "{{number}}m", "minutes": "{{number}}m",
"seconds": "{{number}}s", "seconds": "{{number}}s",
"never": "Never", "never": "Aldrig",
"last_seen": "Last Seen", "last_seen": "Sidst Set",
"ago": "{{value}} Ago" "ago": "{{value}} Siden"
}, },
"qnap": { "qnap": {
"cpuUsage": "CPU Usage", "cpuUsage": "CPU Forbrug",
"memUsage": "MEM Usage", "memUsage": "MEM Forbrug",
"systemTempC": "System Temp", "systemTempC": "System Temp",
"poolUsage": "Pool Usage", "poolUsage": "Pool Forbrug",
"volumeUsage": "Volume Usage", "volumeUsage": "Volume Forbrug",
"invalid": "Invalid" "invalid": "Ugyldig"
}, },
"pfsense": { "pfsense": {
"load": "Load Avg", "load": "Belastning Gns",
"memory": "Mem Usage", "memory": "Hukommelse Forbrug",
"wanStatus": "WAN Status", "wanStatus": "WAN Status",
"up": "Up", "up": "Op",
"down": "Down", "down": "Ned",
"temp": "Temp", "temp": "Temp",
"disk": "Disk Usage", "disk": "Disk Forbrug",
"wanIP": "WAN IP" "wanIP": "WAN IP"
}, },
"caddy": { "caddy": {
"upstreams": "Upstreams", "upstreams": "Upstreams",
"requests": "Current requests", "requests": "Aktuelle anmodninger",
"requests_failed": "Failed requests" "requests_failed": "Mislykkede anmodninger"
}, },
"evcc": { "evcc": {
"pv_power": "Production", "pv_power": "Produktion",
"battery_soc": "Battery", "battery_soc": "Batteri",
"grid_power": "Grid", "grid_power": "Gitter",
"home_power": "Consumption", "home_power": "Forbrug",
"charge_power": "Charger", "charge_power": "Oplader",
"watt_hour": "Wh" "watt_hour": "Wh"
}, },
"pialert": { "pialert": {
"total": "Total", "total": "Total",
"connected": "Connected", "connected": "Forbundet",
"new_devices": "New Devices", "new_devices": "Nye Enheder",
"down_alerts": "Down Alerts" "down_alerts": "Nedadvarsler"
}, },
"jdownloader": { "jdownloader": {
"downloadSpeed": "Download Speed", "downloadSpeed": "Hastighed",
"downloadCount": "Queue Count", "downloadCount": "",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Tilbage",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Størrelse"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "Serier",
"totalFiles": "Files" "totalFiles": "Filer"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Navn",
"map": "Map", "map": "Kort",
"currentPlayers": "Current players", "currentPlayers": "Nuværende Spillere",
"players": "Players", "players": "Spillere",
"maxPlayers": "Max players", "maxPlayers": "Maks spillere",
"bots": "Bots", "bots": "Bots",
"ping": "Ping", "ping": "Ping",
"status": "Status", "status": "Status",
@ -675,30 +675,62 @@
"offline": "Offline" "offline": "Offline"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "Resultat",
"status": "Status", "status": "Status",
"buildId": "Build ID", "buildId": "Build ID",
"succeeded": "Succeeded", "succeeded": "Lykkedes",
"notStarted": "Not Started", "notStarted": "Ikke Startet",
"failed": "Failed", "failed": "Mislykket",
"canceled": "Canceled", "canceled": "Annulleret",
"inProgress": "In Progress", "inProgress": "I Gang",
"totalPrs": "Total PRs", "totalPrs": "Total PRs",
"myPrs": "My PRs", "myPrs": "Mine PRs",
"approved": "Approved" "approved": "Godkendt"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
"errored": "Errors", "errored": "Fejl",
"noRecent": "Out of Date", "noRecent": "Uddateret",
"totalUsed": "Used Storage" "totalUsed": "Brugt Lager"
}, },
"openmediavault": { "openmediavault": {
"downloading": "Downloading", "downloading": "Downloader",
"total": "Total", "total": "Total",
"running": "Running", "running": "Kører",
"stopped": "Stopped", "stopped": "Stoppet",
"passed": "Passed", "passed": "Gennemført",
"failed": "Failed" "failed": "Mislykket"
},
"mealie": {
"recipes": "Opskrifter",
"users": "Brugere",
"categories": "Kategorier",
"tags": "Tags"
},
"atsumeru": {
"series": "Serier",
"archives": "Arkiver",
"chapters": "Kapitler",
"categories": "Kategorier"
},
"calibreweb": {
"books": "Bøger",
"authors": "Forfattere",
"categories": "Kategorier",
"series": "Serier"
},
"uptimerobot": {
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -150,9 +150,9 @@
}, },
"flood": { "flood": {
"download": "Λήξη", "download": "Λήξη",
"upload": "Φόρτωση", "upload": "Μεταφόρτωση",
"leech": "Αφαίμαξη", "leech": "Leech",
"seed": "Σπείρε" "seed": "Seed"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Συνολικά παρατηρηθείσα", "totalObserved": "Συνολικά παρατηρηθείσα",
@ -212,8 +212,8 @@
"unknown": "Άγνωστο" "unknown": "Άγνωστο"
}, },
"downloadstation": { "downloadstation": {
"download": "Μεταφόρτωση", "download": "Λήψη",
"upload": "Φόρτωση", "upload": "Μεταφόρτωση",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
@ -431,7 +431,7 @@
}, },
"pyload": { "pyload": {
"speed": "Speed", "speed": "Speed",
"active": "Active", "active": "Ενεργό",
"queue": "Queue", "queue": "Queue",
"total": "Total" "total": "Total"
}, },
@ -589,7 +589,7 @@
}, },
"freshrss": { "freshrss": {
"subscriptions": "Συνδρομές", "subscriptions": "Συνδρομές",
"unread": "Αδιάβαστο" "unread": "Μη Διαβασμένο"
}, },
"channelsdvrserver": { "channelsdvrserver": {
"shows": "Εκπομπές", "shows": "Εκπομπές",
@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"up": "Up",
"unknown": "Unknown",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"seemsdown": "Seems Down",
"down": "Down"
} }
} }

View File

@ -579,6 +579,12 @@
"incident": "Incident", "incident": "Incident",
"m": "m" "m": "m"
}, },
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"komga": { "komga": {
"libraries": "Libraries", "libraries": "Libraries",
"series": "Series", "series": "Series",
@ -661,6 +667,12 @@
"monitoring": "Monitoring", "monitoring": "Monitoring",
"updates": "Updates" "updates": "Updates"
}, },
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
@ -702,6 +714,12 @@
"noRecent": "Out of Date", "noRecent": "Out of Date",
"totalUsed": "Used Storage" "totalUsed": "Used Storage"
}, },
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"openmediavault": { "openmediavault": {
"downloading": "Downloading", "downloading": "Downloading",
"total": "Total", "total": "Total",
@ -709,5 +727,19 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"categories": "Categories",
"authors": "Authors",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"notyetchecked": "Not Yet Checked",
"downDuration": "Downtime Duration",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -48,7 +48,7 @@
"bitrate": "Tasa de bits", "bitrate": "Tasa de bits",
"no_active": "Sin transmisiones activas", "no_active": "Sin transmisiones activas",
"movies": "Películas", "movies": "Películas",
"series": "Serie", "series": "Series",
"episodes": "Episodios", "episodes": "Episodios",
"songs": "Canciones" "songs": "Canciones"
}, },
@ -234,7 +234,7 @@
"plex": { "plex": {
"streams": "Transmisiones activas", "streams": "Transmisiones activas",
"movies": "Películas", "movies": "Películas",
"tv": "Series", "tv": "Programas de televisión",
"albums": "Álbumes" "albums": "Álbumes"
}, },
"glances": { "glances": {
@ -461,7 +461,7 @@
"medusa": { "medusa": {
"wanted": "Querido", "wanted": "Querido",
"queued": "A la espera", "queued": "A la espera",
"series": "Serie" "series": "Series"
}, },
"octoprint": { "octoprint": {
"temp_bed": "Temperatura de la plataforma", "temp_bed": "Temperatura de la plataforma",
@ -659,7 +659,7 @@
"downloadTotalBytes": "Tamaño" "downloadTotalBytes": "Tamaño"
}, },
"kavita": { "kavita": {
"seriesCount": "Serie", "seriesCount": "Series",
"totalFiles": "Archivos" "totalFiles": "Archivos"
}, },
"gamedig": { "gamedig": {
@ -700,5 +700,37 @@
"stopped": "Detenido", "stopped": "Detenido",
"passed": "Aprobado", "passed": "Aprobado",
"failed": "Fallido" "failed": "Fallido"
},
"mealie": {
"recipes": "Recetas",
"users": "Usuarios",
"categories": "Categorías",
"tags": "Etiquetas"
},
"atsumeru": {
"series": "Series",
"archives": "Archivos",
"chapters": "Capítulos",
"categories": "Categorías"
},
"calibreweb": {
"books": "Libros",
"authors": "Autores",
"categories": "Categorías",
"series": "Series"
},
"uptimerobot": {
"status": "Estado",
"uptime": "Tiempo de actividad",
"lastDown": "Último periodo de inactividad",
"downDuration": "Tiempo de inactividad",
"sitesUp": "Páginas web con conexión",
"sitesDown": "Páginas web caídas",
"paused": "Pausado",
"notyetchecked": "Aún no verificado",
"up": "Arriba",
"seemsdown": "Parece caída",
"down": "Abajo",
"unknown": "Desconocido"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"uptime": "Uptime",
"status": "Status",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories",
"series": "Series"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Arrêté", "stopped": "Arrêté",
"passed": "Réussi", "passed": "Réussi",
"failed": "Échoué" "failed": "Échoué"
},
"mealie": {
"recipes": "Recettes",
"users": "Utilisateurs",
"categories": "Catégories",
"tags": "Étiquettes"
},
"atsumeru": {
"series": "Séries",
"archives": "Archives",
"chapters": "Chapitres",
"categories": "Catégories"
},
"calibreweb": {
"series": "Séries",
"books": "Ebooks",
"authors": "Auteurs",
"categories": "Catégories"
},
"uptimerobot": {
"status": "Statut",
"uptime": "Disponibilité",
"lastDown": "Dernière interruption",
"downDuration": "Durée d'interruption",
"sitesUp": "Sites en ligne",
"sitesDown": "Sites hors ligne",
"paused": "En pause",
"notyetchecked": "Non vérifié",
"up": "En ligne",
"seemsdown": "Semble hors ligne",
"down": "Hors ligne",
"unknown": "Inconnu"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"chapters": "Chapters",
"categories": "Categories",
"series": "Series",
"archives": "Archives"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"categories": "Categories",
"series": "Series",
"authors": "Authors"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"series": "Series",
"categories": "Categories"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -30,7 +30,7 @@
"transcoding": "Transcodifica", "transcoding": "Transcodifica",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Nessuno Stream Attivo", "no_active": "Nessuno Stream Attivo",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Controllo Connessione a Plex"
}, },
"speedtest": { "speedtest": {
"upload": "Upload", "upload": "Upload",
@ -116,7 +116,7 @@
"blocked_percent": "Bloccato %" "blocked_percent": "Bloccato %"
}, },
"npm": { "npm": {
"enabled": "Attivi", "enabled": "Abilitato",
"disabled": "Disabilitati", "disabled": "Disabilitati",
"total": "Totali" "total": "Totali"
}, },
@ -156,7 +156,7 @@
}, },
"prowlarr": { "prowlarr": {
"enableIndexers": "Indicizzatori", "enableIndexers": "Indicizzatori",
"numberOfGrabs": "Grabs", "numberOfGrabs": "Grab",
"numberOfQueries": "Interrogazioni", "numberOfQueries": "Interrogazioni",
"numberOfFailGrabs": "Grabs Falliti", "numberOfFailGrabs": "Grabs Falliti",
"numberOfFailQueries": "Queries Fallite" "numberOfFailQueries": "Queries Fallite"
@ -164,12 +164,12 @@
"transmission": { "transmission": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "In scaricamento",
"seed": "Seed" "seed": "Seed"
}, },
"jackett": { "jackett": {
"configured": "Configurato", "configured": "Configurato",
"errored": "Errore" "errored": "In errore"
}, },
"bazarr": { "bazarr": {
"missingEpisodes": "Episodi Mancanti", "missingEpisodes": "Episodi Mancanti",
@ -188,7 +188,7 @@
}, },
"qbittorrent": { "qbittorrent": {
"download": "Download", "download": "Download",
"leech": "Leech", "leech": "In scaricamento",
"upload": "Upload", "upload": "Upload",
"seed": "Seed" "seed": "Seed"
}, },
@ -242,18 +242,18 @@
"wait": "Attendere prego", "wait": "Attendere prego",
"temp": "TEMP", "temp": "TEMP",
"uptime": "UP", "uptime": "UP",
"days": "d", "days": "g",
"hours": "h", "hours": "o",
"load": "Carico", "load": "Carico",
"warn": "Avviso", "warn": "Avviso",
"total": "Totale", "total": "Totale",
"free": "Libero", "free": "Libero",
"used": "Usato", "used": "Usato",
"crit": "Crit", "crit": "Critico",
"read": "Read", "read": "Lettura",
"write": "Write", "write": "Scrittura",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem.",
"swap": "Swap" "swap": "Swap"
}, },
"changedetectionio": { "changedetectionio": {
@ -331,7 +331,7 @@
"updates": "Aggiornamenti", "updates": "Aggiornamenti",
"update_available": "Aggiornamento Disponibile", "update_available": "Aggiornamento Disponibile",
"up_to_date": "Aggiornato", "up_to_date": "Aggiornato",
"child_bridges": "Child Bridges", "child_bridges": "Bridge Figli",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "In attesa", "pending": "In attesa",
@ -373,7 +373,7 @@
"gluetun": { "gluetun": {
"public_ip": "IP pubblico", "public_ip": "IP pubblico",
"region": "Località", "region": "Località",
"country": "Stato" "country": "Paese"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Canali", "channels": "Canali",
@ -395,13 +395,13 @@
"deluge": { "deluge": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "In scaricamento",
"seed": "Seed" "seed": "Seed"
}, },
"flood": { "flood": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "In scaricamento",
"seed": "Seed" "seed": "Seed"
}, },
"tdarr": { "tdarr": {
@ -432,7 +432,7 @@
"downloadstation": { "downloadstation": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "In scaricamento",
"seed": "Seed" "seed": "Seed"
}, },
"mikrotik": { "mikrotik": {
@ -465,8 +465,8 @@
}, },
"octoprint": { "octoprint": {
"printer_state": "Stato", "printer_state": "Stato",
"temp_tool": "Tool temp", "temp_tool": "Temp. utensile",
"temp_bed": "Bed temp", "temp_bed": "Temp. letto",
"job_completion": "Completamento" "job_completion": "Completamento"
}, },
"cloudflared": { "cloudflared": {
@ -474,7 +474,7 @@
"status": "Stato" "status": "Stato"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "Archivio dati",
"failed_tasks_24h": "Attività Non Riuscite 24h", "failed_tasks_24h": "Attività Non Riuscite 24h",
"cpu_usage": "CPU", "cpu_usage": "CPU",
"memory_usage": "Memoria" "memory_usage": "Memoria"
@ -483,12 +483,12 @@
"users": "Utenti", "users": "Utenti",
"photos": "Foto", "photos": "Foto",
"videos": "Video", "videos": "Video",
"storage": "Memoria" "storage": "Archiviazione"
}, },
"uptimekuma": { "uptimekuma": {
"up": "Siti On", "up": "Siti On",
"down": "Siti Down", "down": "Siti Down",
"uptime": "Uptime", "uptime": "Operatività",
"incident": "Incidente", "incident": "Incidente",
"m": "m" "m": "m"
}, },
@ -510,7 +510,7 @@
}, },
"diskstation": { "diskstation": {
"days": "Giorni", "days": "Giorni",
"uptime": "Uptime", "uptime": "Periodo Attività",
"volumeAvailable": "Disponibile" "volumeAvailable": "Disponibile"
}, },
"fileflows": { "fileflows": {
@ -520,7 +520,7 @@
"time": "Tempo" "time": "Tempo"
}, },
"grafana": { "grafana": {
"dashboards": "Dashboards", "dashboards": "Dashboard",
"datasources": "Origine dei Dati", "datasources": "Origine dei Dati",
"totalalerts": "Avvisi Totali", "totalalerts": "Avvisi Totali",
"alertstriggered": "Avvisi Attivati" "alertstriggered": "Avvisi Attivati"
@ -560,8 +560,8 @@
"nodes": "Nodi" "nodes": "Nodi"
}, },
"prometheus": { "prometheus": {
"targets_up": "Targets Up", "targets_up": "Target Attivi",
"targets_down": "Targets Down", "targets_down": "Target Non Attivi",
"targets_total": "Targets Totali" "targets_total": "Targets Totali"
}, },
"minecraft": { "minecraft": {
@ -663,42 +663,74 @@
"totalFiles": "File" "totalFiles": "File"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Nome",
"map": "Map", "map": "Mappa",
"currentPlayers": "Current players", "currentPlayers": "Giocatori attuali",
"players": "Players", "players": "Giocatori",
"maxPlayers": "Max players", "maxPlayers": "Giocatori max",
"bots": "Bots", "bots": "Bot",
"ping": "Ping", "ping": "Ping",
"status": "Status", "status": "Stato",
"online": "Online", "online": "Online",
"offline": "Offline" "offline": "Offline"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "Risultato",
"myPrs": "My PRs", "myPrs": "Miei PR",
"approved": "Approved", "approved": "Approvato",
"status": "Status", "status": "Stato",
"buildId": "Build ID", "buildId": "ID Build",
"succeeded": "Succeeded", "succeeded": "Riuscito",
"notStarted": "Not Started", "notStarted": "Non Avviato",
"failed": "Failed", "failed": "Fallito",
"canceled": "Canceled", "canceled": "Cancellato",
"inProgress": "In Progress", "inProgress": "In corso",
"totalPrs": "Total PRs" "totalPrs": "PR Totali"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
"errored": "Errors", "errored": "Errori",
"noRecent": "Out of Date", "noRecent": "Obsoleto",
"totalUsed": "Used Storage" "totalUsed": "Spazio usato"
}, },
"openmediavault": { "openmediavault": {
"total": "Total", "total": "Totale",
"running": "Running", "running": "In funzione",
"downloading": "Downloading", "downloading": "Download in corso",
"stopped": "Stopped", "stopped": "Fermati",
"passed": "Passed", "passed": "Riusciti",
"failed": "Failed" "failed": "Falliti"
},
"mealie": {
"recipes": "Ricette",
"users": "Utenti",
"categories": "Categorie",
"tags": "Tag"
},
"atsumeru": {
"series": "Serie",
"archives": "Archivi",
"chapters": "Capitoli",
"categories": "Categorie"
},
"calibreweb": {
"books": "Libri",
"authors": "Autori",
"categories": "Categorie",
"series": "Serie"
},
"uptimerobot": {
"status": "Stato",
"uptime": "Tempo di attività",
"lastDown": "Ultimo periodo di inattività",
"downDuration": "Durata inattività",
"sitesUp": "Siti attivi",
"sitesDown": "Siti non attivi",
"paused": "In pausa",
"notyetchecked": "Non ancora controllati",
"up": "Attivi",
"seemsdown": "Sembrano non attivi",
"down": "Non attivi",
"unknown": "Sconosciuto"
} }
} }

View File

@ -11,7 +11,7 @@
"strelaysrv": { "strelaysrv": {
"numActiveSessions": "セッション", "numActiveSessions": "セッション",
"numConnections": "コネクション", "numConnections": "コネクション",
"dataRelayed": "Relayed", "dataRelayed": "中継",
"transferRate": "レート" "transferRate": "レート"
}, },
"glances": { "glances": {
@ -21,17 +21,17 @@
"uptime": "UP", "uptime": "UP",
"days": "日", "days": "日",
"hours": "時間", "hours": "時間",
"load": "Load", "load": "ロード",
"warn": "Warn", "warn": "警告",
"total": "Total", "total": "トータル",
"free": "Free", "free": "空き",
"used": "Used", "used": "使用中",
"crit": "Crit", "crit": "Crit",
"read": "Read", "read": "読み込み",
"write": "Write", "write": "書き込み",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "メモリ",
"swap": "Swap" "swap": "スワップ"
}, },
"autobrr": { "autobrr": {
"filters": "フィルター", "filters": "フィルター",
@ -131,7 +131,7 @@
"flood": { "flood": {
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "Leech", "leech": "リーチ",
"seed": "Seed" "seed": "Seed"
}, },
"changedetectionio": { "changedetectionio": {
@ -143,7 +143,7 @@
"transcoding": "変換中", "transcoding": "変換中",
"bitrate": "ビットレート", "bitrate": "ビットレート",
"no_active": "アクティブストリームなし", "no_active": "アクティブストリームなし",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Plex接続の確認"
}, },
"omada": { "omada": {
"connectedAp": "接続されたAP", "connectedAp": "接続されたAP",
@ -176,7 +176,7 @@
"transmission": { "transmission": {
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "Leech", "leech": "リーチ",
"seed": "Seed" "seed": "Seed"
}, },
"qbittorrent": { "qbittorrent": {
@ -201,21 +201,21 @@
"wanted": "募集中", "wanted": "募集中",
"queued": "待機中", "queued": "待機中",
"series": "シリーズ", "series": "シリーズ",
"queue": "Queue", "queue": "キュー",
"unknown": "Unknown" "unknown": "不明"
}, },
"radarr": { "radarr": {
"wanted": "募集中", "wanted": "募集中",
"missing": "不明", "missing": "不明",
"queued": "キュー", "queued": "キュー",
"movies": "映画", "movies": "映画",
"queue": "Queue", "queue": "キュー",
"unknown": "Unknown" "unknown": "Unknown"
}, },
"lidarr": { "lidarr": {
"wanted": "募集中", "wanted": "募集中",
"queued": "キュー", "queued": "キュー",
"artists": "Artists" "artists": "アーティスト"
}, },
"readarr": { "readarr": {
"wanted": "募集中", "wanted": "募集中",
@ -224,7 +224,7 @@
}, },
"bazarr": { "bazarr": {
"missingEpisodes": "欠番エピソード", "missingEpisodes": "欠番エピソード",
"missingMovies": "不明・映画" "missingMovies": "行方不明の映画"
}, },
"ombi": { "ombi": {
"pending": "保留中", "pending": "保留中",
@ -292,7 +292,7 @@
"numberOfGrabs": "Grabs", "numberOfGrabs": "Grabs",
"numberOfQueries": "クエリ", "numberOfQueries": "クエリ",
"numberOfFailGrabs": "Fail Grabs", "numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries" "numberOfFailQueries": "失敗クエリー"
}, },
"jackett": { "jackett": {
"configured": "設定済", "configured": "設定済",
@ -304,8 +304,8 @@
"domain_count": "ドメイン" "domain_count": "ドメイン"
}, },
"miniflux": { "miniflux": {
"read": "Read", "read": "既読",
"unread": "Unread" "unread": "未読"
}, },
"authentik": { "authentik": {
"users": "ユーザー", "users": "ユーザー",
@ -461,7 +461,7 @@
"medusa": { "medusa": {
"wanted": "Wanted", "wanted": "Wanted",
"queued": "Queued", "queued": "Queued",
"series": "Series" "series": "シリーズ"
}, },
"octoprint": { "octoprint": {
"temp_bed": "ベッド温度", "temp_bed": "ベッド温度",
@ -474,7 +474,7 @@
"status": "状態" "status": "状態"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "データストア",
"failed_tasks_24h": "失敗タスク(24h)", "failed_tasks_24h": "失敗タスク(24h)",
"cpu_usage": "CPU", "cpu_usage": "CPU",
"memory_usage": "メモリ" "memory_usage": "メモリ"
@ -499,7 +499,7 @@
}, },
"mylar": { "mylar": {
"series": "シリーズ", "series": "シリーズ",
"issues": "Issues", "issues": "課題",
"wanted": "Wanted" "wanted": "Wanted"
}, },
"photoprism": { "photoprism": {
@ -546,7 +546,7 @@
"records_total": "キューの長さ" "records_total": "キューの長さ"
}, },
"healthchecks": { "healthchecks": {
"never": "まだPingはありません", "never": "Pingしていません",
"new": "New", "new": "New",
"up": "オンライン", "up": "オンライン",
"grace": "猶予期間中", "grace": "猶予期間中",
@ -595,10 +595,10 @@
"shows": "ショー", "shows": "ショー",
"recordings": "レコーディング", "recordings": "レコーディング",
"scheduled": "予定済", "scheduled": "予定済",
"passes": "Passes" "passes": "パス"
}, },
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Monitoring", "monitoring": "モニタリング",
"updates": "アップデート" "updates": "アップデート"
}, },
"tailscale": { "tailscale": {
@ -621,22 +621,22 @@
"systemTempC": "システム温度", "systemTempC": "システム温度",
"poolUsage": "プール使用量", "poolUsage": "プール使用量",
"volumeUsage": "ボリューム使用量", "volumeUsage": "ボリューム使用量",
"invalid": "Invalid" "invalid": "無効"
}, },
"pfsense": { "pfsense": {
"up": "Up", "up": "アップ",
"load": "Load Avg", "load": "読み込み平均",
"memory": "Mem Usage", "memory": "メモリ使用量",
"wanStatus": "WAN Status", "wanStatus": "WANステータス",
"down": "Down", "down": "ダウン",
"temp": "Temp", "temp": "温度",
"disk": "Disk Usage", "disk": "ディスク使用量",
"wanIP": "WAN IP" "wanIP": "WAN IP"
}, },
"caddy": { "caddy": {
"upstreams": "Upstreams", "upstreams": "アップストリーム",
"requests": "Current requests", "requests": "現在のリクエスト",
"requests_failed": "Failed requests" "requests_failed": "失敗したリクエスト"
}, },
"evcc": { "evcc": {
"watt_hour": "Wh", "watt_hour": "Wh",
@ -647,58 +647,90 @@
"charge_power": "チャージャー" "charge_power": "チャージャー"
}, },
"pialert": { "pialert": {
"total": "Total", "total": "トータル",
"connected": "Connected", "connected": "接続済み",
"new_devices": "New Devices", "new_devices": "新しいデバイス",
"down_alerts": "Down Alerts" "down_alerts": "ダウンアラート"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Queue Count", "downloadCount": "キュー",
"downloadSpeed": "Download Speed", "downloadSpeed": "スピード",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "残り",
"downloadTotalBytes": "Size" "downloadTotalBytes": "サイズ"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "シリーズ",
"totalFiles": "Files" "totalFiles": "ファイル"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "名前",
"map": "Map", "map": "マップ",
"currentPlayers": "Current players", "currentPlayers": "現在のプレーヤー",
"players": "Players", "players": "プレーヤー",
"maxPlayers": "Max players", "maxPlayers": "最大プレーヤー",
"bots": "Bots", "bots": "ボット",
"ping": "Ping", "ping": "Ping",
"status": "Status", "status": "ステータス",
"online": "Online", "online": "オンライン",
"offline": "Offline" "offline": "オフライン"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "結果",
"status": "Status", "status": "ステータス",
"buildId": "Build ID", "buildId": "ビルドID",
"succeeded": "Succeeded", "succeeded": "成功",
"notStarted": "Not Started", "notStarted": "Not Started",
"failed": "Failed", "failed": "失敗",
"canceled": "Canceled", "canceled": "キャンセル",
"inProgress": "In Progress", "inProgress": "進行中",
"totalPrs": "Total PRs", "totalPrs": "合計PR数",
"myPrs": "My PRs", "myPrs": "私のPR",
"approved": "Approved" "approved": "承認"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
"errored": "Errors", "errored": "エラー",
"noRecent": "Out of Date", "noRecent": "期限切れ",
"totalUsed": "Used Storage" "totalUsed": "使用済みストレージ"
}, },
"openmediavault": { "openmediavault": {
"downloading": "Downloading", "downloading": "ダウンロード中",
"total": "Total", "total": "トータル",
"running": "Running", "running": "実行中",
"stopped": "Stopped", "stopped": "停止中",
"passed": "Passed", "passed": "合格",
"failed": "Failed" "failed": "不合格"
},
"mealie": {
"recipes": "レシピ",
"users": "ユーザー",
"categories": "カテゴリー",
"tags": "タグ"
},
"atsumeru": {
"series": "シリーズ",
"archives": "アーカイブ",
"chapters": "チャプター",
"categories": "カテゴリー"
},
"calibreweb": {
"books": "書籍",
"authors": "著者",
"categories": "カテゴリー",
"series": "シリーズ"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"chapters": "Chapters",
"categories": "Categories",
"series": "Series",
"archives": "Archives"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"chapters": "Chapters",
"series": "Series",
"archives": "Archives",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"unknown": "Unknown",
"status": "Status",
"uptime": "Uptime",
"sitesDown": "Sites Down",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down"
} }
} }

View File

@ -700,5 +700,37 @@
"downloading": "Downloading", "downloading": "Downloading",
"total": "Total", "total": "Total",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"uptime": "Uptime",
"status": "Status",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -229,7 +229,7 @@
"devices": "Apparaten", "devices": "Apparaten",
"lan_devices": "LAN Apparaten", "lan_devices": "LAN Apparaten",
"wlan_devices": "WLAN Apparaten", "wlan_devices": "WLAN Apparaten",
"empty_data": "Subsystem status unknown" "empty_data": "Subsystem status onbekend"
}, },
"plex": { "plex": {
"streams": "Actieve Streams", "streams": "Actieve Streams",
@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"uptime": "Uptime",
"status": "Status",
"up": "Up",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -709,5 +709,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up"
} }
} }

View File

@ -20,12 +20,12 @@
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline", "offline": "Offline",
"error": "Error", "error": "Eroare",
"unknown": "Unknown", "unknown": "Necunoscut",
"running": "Running", "running": "Rulează",
"starting": "Starting", "starting": "Începe",
"unhealthy": "Unhealthy", "unhealthy": "Unhealthy",
"not_found": "Not Found", "not_found": "Negăsit",
"exited": "Exited", "exited": "Exited",
"partial": "Partial", "partial": "Partial",
"healthy": "Healthy" "healthy": "Healthy"
@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"sitesDown": "Sites Down",
"paused": "Paused",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"failed": "Failed", "failed": "Failed",
"running": "Running", "running": "Running",
"stopped": "Stopped" "stopped": "Stopped"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Серии",
"archives": "Архивы",
"chapters": "Главы",
"categories": "Категории"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -169,7 +169,7 @@
"bitrate": "Pasovna širina", "bitrate": "Pasovna širina",
"playing": "Predvaja", "playing": "Predvaja",
"no_active": "Ni aktivne vsebine", "no_active": "Ni aktivne vsebine",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Preveri Plex povezavo"
}, },
"flood": { "flood": {
"download": "Prenos", "download": "Prenos",
@ -365,9 +365,9 @@
"warn": "Opoz.", "warn": "Opoz.",
"total": "Skupaj", "total": "Skupaj",
"used": "V uporabi", "used": "V uporabi",
"crit": "Crit", "crit": "Krit.",
"read": "Read", "read": "Prebrano",
"write": "Write", "write": "Zapisano",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap"
@ -663,42 +663,74 @@
"totalFiles": "Datoteke" "totalFiles": "Datoteke"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Naziv",
"map": "Map", "map": "Zemljevid",
"currentPlayers": "Current players", "currentPlayers": "Igralcev",
"players": "Players", "players": "Igralci",
"maxPlayers": "Max players", "maxPlayers": "Maks igralcev",
"bots": "Bots", "bots": "Boti",
"ping": "Ping", "ping": "Ping",
"status": "Status", "status": "Status",
"online": "Online", "online": "Na spletu",
"offline": "Offline" "offline": "Nepovezano"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "Rezultati",
"status": "Status", "status": "Status",
"buildId": "Build ID", "buildId": "ID gradnje",
"succeeded": "Succeeded", "succeeded": "Uspešnih",
"notStarted": "Not Started", "notStarted": "Ni zagnano",
"failed": "Failed", "failed": "Neuspešno",
"canceled": "Canceled", "canceled": "Preklicano",
"inProgress": "In Progress", "inProgress": "V delu",
"totalPrs": "Total PRs", "totalPrs": "Skupaj PR",
"myPrs": "My PRs", "myPrs": "Moji PR",
"approved": "Approved" "approved": "Odobreno"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "V redu",
"errored": "Errors", "errored": "Napake",
"noRecent": "Out of Date", "noRecent": "Zastarano",
"totalUsed": "Used Storage" "totalUsed": "Shramba v uporabi"
}, },
"openmediavault": { "openmediavault": {
"downloading": "Downloading", "downloading": "Prenašanje",
"total": "Total", "total": "Skupaj",
"running": "Running", "running": "V teku",
"stopped": "Stopped", "stopped": "Ustavljeno",
"passed": "Passed", "passed": "Opravljeno",
"failed": "Failed" "failed": "Neuspešno"
},
"mealie": {
"recipes": "Recepti",
"users": "Uporabniki",
"categories": "Kategorije",
"tags": "Značke"
},
"atsumeru": {
"series": "Serije",
"archives": "Arhivi",
"chapters": "Poglavja",
"categories": "Kategorije"
},
"calibreweb": {
"books": "Knjige",
"authors": "Avtorji",
"categories": "Kategorije",
"series": "Serije"
},
"uptimerobot": {
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"unknown": "Unknown",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"seemsdown": "Seems Down",
"down": "Down"
} }
} }

View File

@ -700,5 +700,37 @@
"passed": "Passed", "passed": "Passed",
"failed": "Failed", "failed": "Failed",
"downloading": "Downloading" "downloading": "Downloading"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"paused": "Paused",
"sitesDown": "Sites Down",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"running": "Running", "running": "Running",
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed" "passed": "Passed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Серії",
"archives": "Архіви",
"chapters": "Глави",
"categories": "Категорії"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"up": "Up",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -659,8 +659,8 @@
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "系列",
"totalFiles": "Files" "totalFiles": "文件"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Name",
@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "书籍",
"authors": "作者",
"categories": "分类",
"series": "丛书"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -700,5 +700,37 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"mealie": {
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
},
"atsumeru": {
"series": "Series",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"calibreweb": {
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@ -5,44 +5,64 @@ import { MdKeyboardArrowDown } from "react-icons/md";
import ErrorBoundary from "components/errorboundry"; import ErrorBoundary from "components/errorboundry";
import List from "components/bookmarks/list"; import List from "components/bookmarks/list";
import ResolvedIcon from "components/resolvedicon";
export default function BookmarksGroup({ group, disableCollapse }) { export default function BookmarksGroup({ bookmarks, layout, disableCollapse }) {
const panel = useRef(); const panel = useRef();
return ( return (
<div key={group.name} className="flex-1"> <div
<Disclosure defaultOpen> key={bookmarks.name}
{({ open }) => ( className={classNames(
<> layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/4 lg:basis-1/5 xl:basis-1/6",
<Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group"> layout?.header === false ? "flex-1 px-1 -my-1" : "flex-1 p-1"
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{group.name}</h2> )}
<MdKeyboardArrowDown className={classNames( >
disableCollapse ? 'hidden' : '', <Disclosure defaultOpen>
'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl', {({ open }) => (
open ? '' : 'rotate-90' <>
)} /> {layout?.header !== false && (
</Disclosure.Button> <Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group">
<Transition {layout?.icon && (
// Otherwise the transition group does display: none and cancels animation <div className="flex-shrink-0 mr-2 w-7 h-7">
className="!block" <ResolvedIcon icon={layout.icon} />
unmount={false} </div>
beforeLeave={() => { )}
panel.current.style.height = `${panel.current.scrollHeight}px`; <h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{bookmarks.name}</h2>
setTimeout(() => {panel.current.style.height = `0`}, 1); <MdKeyboardArrowDown
}} className={classNames(
beforeEnter={() => { disableCollapse ? "hidden" : "",
panel.current.style.height = `0px`; "transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl",
setTimeout(() => {panel.current.style.height = `${panel.current.scrollHeight}px`}, 1); open ? "" : "rotate-180"
}} )}
> />
<Disclosure.Panel className="transition-all overflow-hidden duration-300 ease-out" ref={panel} static> </Disclosure.Button>
<ErrorBoundary> )}
<List bookmarks={group.bookmarks} /> <Transition
</ErrorBoundary> // Otherwise the transition group does display: none and cancels animation
</Disclosure.Panel> className="!block"
</Transition> unmount={false}
</> beforeLeave={() => {
)} panel.current.style.height = `${panel.current.scrollHeight}px`;
</Disclosure> setTimeout(() => {
panel.current.style.height = `0`;
}, 1);
}}
beforeEnter={() => {
panel.current.style.height = `0px`;
setTimeout(() => {
panel.current.style.height = `${panel.current.scrollHeight}px`;
}, 1);
}}
>
<Disclosure.Panel className="transition-all overflow-hidden duration-300 ease-out" ref={panel} static>
<ErrorBoundary>
<List bookmarks={bookmarks.bookmarks} layout={layout} />
</ErrorBoundary>
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
</div> </div>
); );
} }

View File

@ -1,8 +1,17 @@
import classNames from "classnames";
import { columnMap } from "../../utils/layout/columns";
import Item from "components/bookmarks/item"; import Item from "components/bookmarks/item";
export default function List({ bookmarks }) { export default function List({ bookmarks, layout }) {
return ( return (
<ul className="mt-3 flex flex-col"> <ul
className={classNames(
layout?.style === "row" ? `grid ${columnMap[layout?.columns]} gap-x-2` : "flex flex-col",
"mt-3"
)}
>
{bookmarks.map((bookmark) => ( {bookmarks.map((bookmark) => (
<Item key={`${bookmark.name}-${bookmark.href}`} bookmark={bookmark} /> <Item key={`${bookmark.name}-${bookmark.href}`} bookmark={bookmark} />
))} ))}

View File

@ -61,7 +61,6 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
} }
} }
function handleItemHover(event) { function handleItemHover(event) {
setCurrentItemIndex(parseInt(event.target?.dataset?.index, 10)); setCurrentItemIndex(parseInt(event.target?.dataset?.index, 10));
} }
@ -71,6 +70,16 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
openCurrentItem(event.metaKey); openCurrentItem(event.metaKey);
} }
function handleItemKeyDown(event) {
if (!isOpen) return;
// native button handles other keys
if (event.key === "Escape") {
closeAndReset();
event.preventDefault();
}
}
useEffect(() => { useEffect(() => {
if (searchString.length === 0) setResults([]); if (searchString.length === 0) setResults([]);
else { else {
@ -162,10 +171,10 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
{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.container ?? r.app ?? `${r.name}-${r.href}`}> <li key={r.container ?? r.app ?? `${r.name}-${r.href}`}>
<button type="button" data-index={i} onMouseEnter={handleItemHover} className={classNames( <button type="button" data-index={i} onMouseEnter={handleItemHover} onClick={handleItemClick} onKeyDown={handleItemKeyDown} 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",
)} onClick={handleItemClick}> )}>
<div className="flex flex-row items-center mr-4 pointer-events-none"> <div className="flex flex-row items-center mr-4 pointer-events-none">
{(r.icon || r.abbr) && <div className="w-5 text-xs mr-4"> {(r.icon || r.abbr) && <div className="w-5 text-xs mr-4">
{r.icon && <ResolvedIcon icon={r.icon} />} {r.icon && <ResolvedIcon icon={r.icon} />}

View File

@ -33,7 +33,7 @@ export default function ServicesGroup({ group, services, layout, fiveColumns, di
<MdKeyboardArrowDown className={classNames( <MdKeyboardArrowDown className={classNames(
disableCollapse ? 'hidden' : '', disableCollapse ? 'hidden' : '',
'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl', 'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl',
open ? '' : 'rotate-90' open ? '' : 'rotate-180'
)} /> )} />
</Disclosure.Button> </Disclosure.Button>
} }

View File

@ -1,18 +1,8 @@
import classNames from "classnames"; import classNames from "classnames";
import Item from "components/services/item"; import { columnMap } from "../../utils/layout/columns";
const columnMap = [ import Item from "components/services/item";
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-2",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-5",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-6",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-7",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-8",
];
export default function List({ group, services, layout }) { export default function List({ group, services, layout }) {
return ( return (

View File

@ -7,6 +7,14 @@ import Raw from "./raw";
export function getAllClasses(options, additionalClassNames = '') { export function getAllClasses(options, additionalClassNames = '') {
if (options?.style?.header === "boxedWidgets") { if (options?.style?.header === "boxedWidgets") {
if (options?.style?.cardBlur !== undefined) {
// eslint-disable-next-line no-param-reassign
additionalClassNames = [
additionalClassNames,
`backdrop-blur${options.style.cardBlur.length ? '-' : ""}${options.style.cardBlur}`
].join(' ')
}
return classNames( return classNames(
"flex flex-col justify-center first:ml-0 ml-2 mr-2", "flex flex-col justify-center first:ml-0 ml-2 mr-2",
"mt-2 m:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-2 pl-3 pr-3", "mt-2 m:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-2 pl-3 pr-3",

View File

@ -9,7 +9,7 @@ export default function Document() {
content="A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations." content="A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations."
/> />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="manifest" href="/site.webmanifest?v=4" /> <link rel="manifest" href="/site.webmanifest?v=4" crossorigin="use-credentials" />
<link rel="mask-icon" href="/safari-pinned-tab.svg?v=4" color="#1e9cd7" /> <link rel="mask-icon" href="/safari-pinned-tab.svg?v=4" color="#1e9cd7" />
</Head> </Head>
<body> <body>

View File

@ -55,6 +55,10 @@ export default async function handler(req, res) {
req.query.endpoint = `${req.query.endpoint}?${query}`; req.query.endpoint = `${req.query.endpoint}?${query}`;
} }
if (mapping?.headers) {
req.extraHeaders = mapping.headers;
}
if (endpointProxy instanceof Function) { if (endpointProxy instanceof Function) {
return endpointProxy(req, res, map); return endpointProxy(req, res, map);
} }

View File

@ -209,12 +209,12 @@ function Home({ initialSettings }) {
searchProvider = searchProviders[searchWidget.options?.provider]; searchProvider = searchProviders[searchWidget.options?.provider];
} }
} }
const headerStyle = initialSettings?.headerStyle || "underlined"; const headerStyle = settings?.headerStyle || "underlined";
useEffect(() => { useEffect(() => {
function handleKeyDown(e) { function handleKeyDown(e) {
if (e.target.tagName === "BODY") { if (e.target.tagName === "BODY" || e.target.id === "inner_wrapper") {
if (String.fromCharCode(e.keyCode).match(/(\w|\s)/g) && !(e.altKey || e.ctrlKey || e.metaKey || e.shiftKey)) { if (e.key.match(/(\w|\s)/g) && !(e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.code === "Tab")) {
setSearching(true); setSearching(true);
} else if (e.key === "Escape") { } else if (e.key === "Escape") {
setSearchString(""); setSearchString("");
@ -233,12 +233,12 @@ function Home({ initialSettings }) {
return ( return (
<> <>
<Head> <Head>
<title>{initialSettings.title || "Homepage"}</title> <title>{settings.title || "Homepage"}</title>
{initialSettings.base && <base href={initialSettings.base} />} {settings.base && <base href={settings.base} />}
{initialSettings.favicon ? ( {settings.favicon ? (
<> <>
<link rel="apple-touch-icon" sizes="180x180" href={initialSettings.favicon} /> <link rel="apple-touch-icon" sizes="180x180" href={settings.favicon} />
<link rel="icon" href={initialSettings.favicon} /> <link rel="icon" href={settings.favicon} />
</> </>
) : ( ) : (
<> <>
@ -248,33 +248,31 @@ function Home({ initialSettings }) {
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?v=4" /> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?v=4" />
</> </>
)} )}
<meta <meta name="msapplication-TileColor" content={themes[settings.color || "slate"][settings.theme || "dark"]} />
name="msapplication-TileColor" <meta name="theme-color" content={themes[settings.color || "slate"][settings.theme || "dark"]} />
content={themes[initialSettings.color || "slate"][initialSettings.theme || "dark"]}
/>
<meta name="theme-color" content={themes[initialSettings.color || "slate"][initialSettings.theme || "dark"]} />
</Head> </Head>
<div className="relative container m-auto flex flex-col justify-start z-10 h-full"> <div className="relative container m-auto flex flex-col justify-start z-10 h-full">
<QuickLaunch
servicesAndBookmarks={servicesAndBookmarks}
searchString={searchString}
setSearchString={setSearchString}
isOpen={searching}
close={setSearching}
searchProvider={settings.quicklaunch?.hideInternetSearch ? null : searchProvider}
/>
<div <div
className={classNames( className={classNames(
"flex flex-row flex-wrap justify-between", "flex flex-row flex-wrap justify-between",
headerStyles[headerStyle] headerStyles[headerStyle],
settings.cardBlur !== undefined && headerStyle === "boxed" && `backdrop-blur${settings.cardBlur.length ? '-' : ""}${settings.cardBlur}`
)} )}
> >
<QuickLaunch
servicesAndBookmarks={servicesAndBookmarks}
searchString={searchString}
setSearchString={setSearchString}
isOpen={searching}
close={setSearching}
searchProvider={settings.quicklaunch?.hideInternetSearch ? null : searchProvider}
/>
{widgets && ( {widgets && (
<> <>
{widgets {widgets
.filter((widget) => !rightAlignedWidgets.includes(widget.type)) .filter((widget) => !rightAlignedWidgets.includes(widget.type))
.map((widget, i) => ( .map((widget, i) => (
<Widget key={i} widget={widget} style={{ header: headerStyle, isRightAligned: false}} /> <Widget key={i} widget={widget} style={{ header: headerStyle, isRightAligned: false, cardBlur: settings.cardBlur }} />
))} ))}
<div className={classNames( <div className={classNames(
@ -284,7 +282,7 @@ function Home({ initialSettings }) {
{widgets {widgets
.filter((widget) => rightAlignedWidgets.includes(widget.type)) .filter((widget) => rightAlignedWidgets.includes(widget.type))
.map((widget, i) => ( .map((widget, i) => (
<Widget key={i} widget={widget} style={{ header: headerStyle, isRightAligned: true}} /> <Widget key={i} widget={widget} style={{ header: headerStyle, isRightAligned: true, cardBlur: settings.cardBlur }} />
))} ))}
</div> </div>
</> </>
@ -292,39 +290,42 @@ function Home({ initialSettings }) {
</div> </div>
{services?.length > 0 && ( {services?.length > 0 && (
<div className="flex flex-wrap p-4 sm:p-8 sm:pt-4 items-start pb-2"> <div key="services" className="flex flex-wrap p-4 sm:p-8 sm:pt-4 items-start pb-2">
{services.map((group) => ( {services.map((group) => (
<ServicesGroup <ServicesGroup
key={group.name} key={group.name}
group={group.name} group={group.name}
services={group} services={group}
layout={initialSettings.layout?.[group.name]} layout={settings.layout?.[group.name]}
fiveColumns={settings.fiveColumns} fiveColumns={settings.fiveColumns}
disableCollapse={settings.disableCollapse} /> disableCollapse={settings.disableCollapse}
/>
))} ))}
</div> </div>
)} )}
{bookmarks?.length > 0 && ( {bookmarks?.length > 0 && (
<div className={`grow flex flex-wrap pt-0 p-4 sm:p-8 gap-2 grid-cols-1 lg:grid-cols-2 lg:grid-cols-${Math.min(6, bookmarks.length)}`}> <div key="bookmarks" className="flex flex-wrap p-4 sm:p-8 sm:pt-4 items-start pb-2">
{bookmarks.map((group) => ( {bookmarks.map((group) => (
<BookmarksGroup <BookmarksGroup
key={group.name} key={group.name}
group={group} bookmarks={group}
disableCollapse={settings.disableCollapse} /> layout={settings.layout?.[group.name]}
disableCollapse={settings.disableCollapse}
/>
))} ))}
</div> </div>
)} )}
<div className="flex flex-col mt-auto p-8 w-full"> <div className="flex flex-col mt-auto p-8 w-full">
<div className="flex w-full justify-end"> <div className="flex w-full justify-end">
{!initialSettings?.color && <ColorToggle />} {!settings?.color && <ColorToggle />}
<Revalidate /> <Revalidate />
{!initialSettings?.theme && <ThemeToggle />} {!settings.theme && <ThemeToggle />}
</div> </div>
<div className="flex mt-4 w-full justify-end"> <div className="flex mt-4 w-full justify-end">
{!initialSettings?.hideVersion && <Version />} {!settings.hideVersion && <Version />}
</div> </div>
</div> </div>
</div> </div>
@ -374,6 +375,7 @@ export default function Wrapper({ initialSettings, fallback }) {
> >
<div <div
id="inner_wrapper" id="inner_wrapper"
tabIndex="-1"
className={classNames( className={classNames(
'fixed overflow-auto w-full h-full', 'fixed overflow-auto w-full h-full',
backgroundBlur && `backdrop-blur${initialSettings.background.blur.length ? '-' : ""}${initialSettings.background.blur}`, backgroundBlur && `backdrop-blur${initialSettings.background.blur.length ? '-' : ""}${initialSettings.background.blur}`,

View File

@ -34,6 +34,16 @@ export async function bookmarksResponse() {
if (!bookmarks) return []; if (!bookmarks) return [];
let initialSettings;
try {
initialSettings = await getSettings();
} catch (e) {
console.error("Failed to load settings.yaml, please check for errors");
if (e) console.error(e.toString());
initialSettings = {};
}
// map easy to write YAML objects into easy to consume JS arrays // map easy to write YAML objects into easy to consume JS arrays
const bookmarksArray = bookmarks.map((group) => ({ const bookmarksArray = bookmarks.map((group) => ({
name: Object.keys(group)[0], name: Object.keys(group)[0],
@ -43,7 +53,21 @@ export async function bookmarksResponse() {
})), })),
})); }));
return bookmarksArray; const sortedGroups = [];
const unsortedGroups = [];
const definedLayouts = initialSettings.layout ? Object.keys(initialSettings.layout) : null;
bookmarksArray.forEach((group) => {
if (definedLayouts) {
const layoutIndex = definedLayouts.findIndex(layout => layout === group.name);
if (layoutIndex > -1) sortedGroups[layoutIndex] = group;
else unsortedGroups.push(group);
} else {
unsortedGroups.push(group);
}
});
return [...sortedGroups.filter(g => g), ...unsortedGroups];
} }
export async function widgetsResponse() { export async function widgetsResponse() {

View File

@ -158,22 +158,29 @@ export async function servicesFromKubernetes() {
return null; return null;
}); });
const traefikIngressList = await crd.listClusterCustomObject("traefik.io", "v1alpha1", "ingressroutes") const traefikIngressListContaino = await crd.listClusterCustomObject("traefik.containo.us", "v1alpha1", "ingressroutes")
.then((response) => response.body) .then((response) => response.body)
.catch(async (error) => { .catch(async (error) => {
logger.error("Error getting traefik ingresses from traefik.io: %d %s %s", error.statusCode, error.body, error.response); if (error.statusCode !== 404) {
logger.error("Error getting traefik ingresses from traefik.containo.us: %d %s %s", error.statusCode, error.body, error.response);
}
// Fallback to the old traefik CRD group return [];
const fallbackIngressList = await crd.listClusterCustomObject("traefik.containo.us", "v1alpha1", "ingressroutes")
.then((response) => response.body)
.catch((fallbackError) => {
logger.error("Error getting traefik ingresses from traefik.containo.us: %d %s %s", fallbackError.statusCode, fallbackError.body, fallbackError.response);
return null;
});
return fallbackIngressList;
}); });
const traefikIngressListIo = await crd.listClusterCustomObject("traefik.io", "v1alpha1", "ingressroutes")
.then((response) => response.body)
.catch(async (error) => {
if (error.statusCode !== 404) {
logger.error("Error getting traefik ingresses from traefik.io: %d %s %s", error.statusCode, error.body, error.response);
}
return [];
});
const traefikIngressList = [...traefikIngressListContaino, ...traefikIngressListIo];
if (traefikIngressList && traefikIngressList.items.length > 0) { if (traefikIngressList && traefikIngressList.items.length > 0) {
const traefikServices = traefikIngressList.items const traefikServices = traefikIngressList.items
.filter((ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`]) .filter((ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`])
@ -299,6 +306,8 @@ export function cleanServiceGroups(groups) {
stream, // mjpeg stream, // mjpeg
fit, fit,
method, // openmediavault widget method, // openmediavault widget
mappings, // customapi widget
refreshInterval,
} = cleanedService.widget; } = cleanedService.widget;
let fieldsList = fields; let fieldsList = fields;
@ -372,6 +381,10 @@ export function cleanServiceGroups(groups) {
if (type === "openmediavault") { if (type === "openmediavault") {
if (method) cleanedService.widget.method = method; if (method) cleanedService.widget.method = method;
} }
if (type === "customapi") {
if (mappings) cleanedService.widget.mappings = mappings;
if (refreshInterval) cleanedService.widget.refreshInterval = refreshInterval;
}
} }
return cleanedService; return cleanedService;

View File

@ -0,0 +1,12 @@
// eslint-disable-next-line import/prefer-default-export
export const columnMap = [
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-2",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-5",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-6",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-7",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-8",
];

View File

@ -32,6 +32,7 @@ export default async function credentialedProxyHandler(req, res, map) {
"authentik", "authentik",
"cloudflared", "cloudflared",
"ghostfolio", "ghostfolio",
"mealie",
"tailscale", "tailscale",
"truenas", "truenas",
"pterodactyl", "pterodactyl",

View File

@ -20,15 +20,14 @@ export default async function genericProxyHandler(req, res, map) {
if (widget) { if (widget) {
const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget })); const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));
let headers; const headers = req.extraHeaders ?? widget.headers ?? {};
if (widget.username && widget.password) { if (widget.username && widget.password) {
headers = { headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`;
Authorization: `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`,
};
} }
const params = { const params = {
method: req.method, method: widget.method ?? req.method,
headers, headers,
} }
if (req.body) { if (req.body) {

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: infoData, error: infoError } = useWidgetAPI(widget, "info");
if (infoError) {
return <Container service={service} error={infoError} />;
}
if (!infoData) {
return (
<Container service={service}>
<Block label="atsumeru.series" />
<Block label="atsumeru.archives" />
<Block label="atsumeru.chapters" />
<Block label="atsumeru.categories" />
</Container>
);
}
return (
<Container service={service}>
<Block label="atsumeru.series" value={t("common.number", { value: infoData.stats.total_series })} />
<Block label="atsumeru.archives" value={t("common.number", { value: infoData.stats.total_archives })} />
<Block label="atsumeru.chapters" value={t("common.number", { value: infoData.stats.total_chapters })} />
<Block label="atsumeru.categories" value={t("common.number", { value: infoData.stats.total_categories })} />
</Container>
);
}

View File

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

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, error } = useWidgetAPI(widget, "stats");
if (error) {
return <Container service={service} error={error} />;
}
if (!data) {
return (
<Container service={service}>
<Block label="calibreweb.books" />
<Block label="calibreweb.authors" />
<Block label="calibreweb.categories" />
<Block label="calibreweb.series" />
</Container>
);
}
return (
<Container service={service}>
<Block label="calibreweb.books" value={t("common.number", { value: data.books })} />
<Block label="calibreweb.authors" value={t("common.number", { value: data.authors })} />
<Block label="calibreweb.categories" value={t("common.number", { value: data.categories })} />
<Block label="calibreweb.series" value={t("common.number", { value: data.series })} />
</Container>
);
}

View File

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

View File

@ -2,16 +2,19 @@ import dynamic from "next/dynamic";
const components = { const components = {
adguard: dynamic(() => import("./adguard/component")), adguard: dynamic(() => import("./adguard/component")),
atsumeru: dynamic(() => import("./atsumeru/component")),
audiobookshelf: dynamic(() => import("./audiobookshelf/component")), audiobookshelf: dynamic(() => import("./audiobookshelf/component")),
authentik: dynamic(() => import("./authentik/component")), authentik: dynamic(() => import("./authentik/component")),
autobrr: dynamic(() => import("./autobrr/component")), autobrr: dynamic(() => import("./autobrr/component")),
azuredevops: dynamic(() => import("./azuredevops/component")), azuredevops: dynamic(() => import("./azuredevops/component")),
bazarr: dynamic(() => import("./bazarr/component")), bazarr: dynamic(() => import("./bazarr/component")),
caddy: dynamic(() => import("./caddy/component")), caddy: dynamic(() => import("./caddy/component")),
calibreweb: dynamic(() => import("./calibreweb/component")),
changedetectionio: dynamic(() => import("./changedetectionio/component")), changedetectionio: dynamic(() => import("./changedetectionio/component")),
channelsdvrserver: dynamic(() => import("./channelsdvrserver/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")),
customapi: dynamic(() => import("./customapi/component")),
deluge: dynamic(() => import("./deluge/component")), deluge: dynamic(() => import("./deluge/component")),
diskstation: dynamic(() => import("./diskstation/component")), diskstation: dynamic(() => import("./diskstation/component")),
downloadstation: dynamic(() => import("./downloadstation/component")), downloadstation: dynamic(() => import("./downloadstation/component")),
@ -42,6 +45,7 @@ const components = {
kopia: dynamic(() => import("./kopia/component")), kopia: dynamic(() => import("./kopia/component")),
lidarr: dynamic(() => import("./lidarr/component")), lidarr: dynamic(() => import("./lidarr/component")),
mastodon: dynamic(() => import("./mastodon/component")), mastodon: dynamic(() => import("./mastodon/component")),
mealie: dynamic(() => import("./mealie/component")),
medusa: dynamic(() => import("./medusa/component")), medusa: dynamic(() => import("./medusa/component")),
minecraft: dynamic(() => import("./minecraft/component")), minecraft: dynamic(() => import("./minecraft/component")),
miniflux: dynamic(() => import("./miniflux/component")), miniflux: dynamic(() => import("./miniflux/component")),
@ -93,6 +97,7 @@ const components = {
unifi: dynamic(() => import("./unifi/component")), unifi: dynamic(() => import("./unifi/component")),
unmanic: dynamic(() => import("./unmanic/component")), unmanic: dynamic(() => import("./unmanic/component")),
uptimekuma: dynamic(() => import("./uptimekuma/component")), uptimekuma: dynamic(() => import("./uptimekuma/component")),
uptimerobot: dynamic(() => import("./uptimerobot/component")),
urbackup: dynamic(() => import("./urbackup/component")), urbackup: dynamic(() => import("./urbackup/component")),
watchtower: dynamic(() => import("./watchtower/component")), watchtower: dynamic(() => import("./watchtower/component")),
whatsupdocker: dynamic(() => import("./whatsupdocker/component")), whatsupdocker: dynamic(() => import("./whatsupdocker/component")),

View File

@ -0,0 +1,75 @@
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";
function getValue(field, data) {
let value = data;
let lastField = field;
let key = '';
while (typeof lastField === "object") {
key = Object.keys(lastField)[0] ?? null;
if (key === null) {
break;
}
value = value[key];
lastField = lastField[key];
}
if (typeof value === 'undefined') {
return null;
}
return value[lastField] ?? null;
}
function formatValue(t, mapping, value) {
switch (mapping?.format) {
case 'number':
return t("common.number", { value: parseInt(value, 10) });
case 'float':
return t("common.number", { value });
case 'percent':
return t("common.percent", { value });
case 'text':
default:
return value;
}
}
export default function Component({ service }) {
const { t } = useTranslation();
const { widget } = service;
const { mappings = [], refreshInterval = 10000 } = widget;
const { data: customData, error: customError } = useWidgetAPI(widget, null, {
refreshInterval: Math.max(1000, refreshInterval),
});
if (customError) {
return <Container service={service} error={customError} />;
}
if (!customData) {
return (
<Container service={service}>
{ mappings.slice(0,4).map(item => <Block label={item.label} key={item.field} />) }
</Container>
);
}
return (
<Container service={service}>
{ mappings.slice(0,4).map(mapping => <Block
label={mapping.label}
key={mapping.field}
value={formatValue(t, mapping, getValue(mapping.field, customData))}
/>) }
</Container>
);
}

View File

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

View File

@ -29,17 +29,19 @@ function ticksToString(ticks) {
function SingleSessionEntry({ playCommand, session }) { function SingleSessionEntry({ playCommand, session }) {
const { const {
NowPlayingItem: { Name, SeriesName, RunTimeTicks }, NowPlayingItem: { Name, SeriesName },
PlayState: { PositionTicks, IsPaused, IsMuted }, PlayState: { PositionTicks, IsPaused, IsMuted },
} = session; } = session;
const RunTimeTicks = session.NowPlayingItem?.RunTimeTicks ?? session.NowPlayingItem?.CurrentProgram?.RunTimeTicks ?? 0;
const { IsVideoDirect, VideoDecoderIsHardware, VideoEncoderIsHardware } = session?.TranscodingInfo || { const { IsVideoDirect, VideoDecoderIsHardware, VideoEncoderIsHardware } = session?.TranscodingInfo || {
IsVideoDirect: true, IsVideoDirect: true,
VideoDecoderIsHardware: true, VideoDecoderIsHardware: true,
VideoEncoderIsHardware: true, VideoEncoderIsHardware: true,
}; };
const percent = (PositionTicks / RunTimeTicks) * 100; const percent = Math.min(1, PositionTicks / RunTimeTicks) * 100;
return ( return (
<> <>
@ -98,13 +100,15 @@ function SingleSessionEntry({ playCommand, session }) {
function SessionEntry({ playCommand, session }) { function SessionEntry({ playCommand, session }) {
const { const {
NowPlayingItem: { Name, SeriesName, RunTimeTicks }, NowPlayingItem: { Name, SeriesName },
PlayState: { PositionTicks, IsPaused, IsMuted }, PlayState: { PositionTicks, IsPaused, IsMuted },
} = session; } = session;
const RunTimeTicks = session.NowPlayingItem?.RunTimeTicks ?? session.NowPlayingItem?.CurrentProgram?.RunTimeTicks ?? 0;
const { IsVideoDirect, VideoDecoderIsHardware, VideoEncoderIsHardware } = session?.TranscodingInfo || {}; const { IsVideoDirect, VideoDecoderIsHardware, VideoEncoderIsHardware } = session?.TranscodingInfo || {};
const percent = (PositionTicks / RunTimeTicks) * 100; const percent = Math.min(1, PositionTicks / RunTimeTicks) * 100;
return ( return (
<div className="text-theme-700 dark:text-theme-200 relative h-5 w-full rounded-md bg-theme-200/50 dark:bg-theme-900/20 mt-1 flex"> <div className="text-theme-700 dark:text-theme-200 relative h-5 w-full rounded-md bg-theme-200/50 dark:bg-theme-900/20 mt-1 flex">

View File

@ -0,0 +1,33 @@
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: mealieData, error: mealieError } = useWidgetAPI(widget);
if (mealieError || mealieData?.statusCode === 401) {
return <Container service={service} error={mealieError ?? mealieData} />;
}
if (!mealieData) {
return (
<Container service={service}>
<Block label="mealie.recipes" />
<Block label="mealie.users" />
<Block label="mealie.categories" />
<Block label="mealie.tags" />
</Container>
);
}
return (
<Container service={service}>
<Block label="mealie.recipes" value={mealieData.totalRecipes} />
<Block label="mealie.users" value={mealieData.totalUsers} />
<Block label="mealie.categories" value={mealieData.totalCategories} />
<Block label="mealie.tags" value={mealieData.totalTags} />
</Container>
);
}

View File

@ -0,0 +1,8 @@
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
const widget = {
api: "{url}/api/groups/statistics",
proxyHandler: credentialedProxyHandler,
};
export default widget;

View File

@ -0,0 +1,97 @@
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";
function secondsToDhms(seconds) {
const d = Math.floor(seconds / (3600*24));
const h = Math.floor(seconds % (3600*24) / 3600);
const m = Math.floor(seconds % 3600 / 60);
const s = Math.floor(seconds % 60);
const dDisplay = d > 0 ? d + (d === 1 ? " day, " : " days, ") : "";
const hDisplay = h > 0 ? h + (h === 1 ? " hr, " : " hrs, ") : "";
let mDisplay = m > 0 && d === 0 ? m + (m === 1 ? " min" : " mins") : "";
let sDisplay = "";
if (d === 0 && h === 0) {
mDisplay = m > 0 ? m + (m === 1 ? " min, " : " mins, ") : "";
sDisplay = s > 0 ? s + (s === 1 ? " sec" : " secs") : "";
}
return (dDisplay + hDisplay + mDisplay + sDisplay).replace(/,\s*$/, "");
}
export default function Component({ service }) {
const { widget } = service;
const { t } = useTranslation();
const { data: uptimerobotData, error: uptimerobotError } = useWidgetAPI(widget, "getmonitors");
if (uptimerobotError) {
return <Container service={service} error={uptimerobotError} />;
}
if (!uptimerobotData) {
return (
<Container service={service}>
<Block label="uptimerobot.status" />
<Block label="uptimerobot.uptime" />
</Container>
);
}
// multiple monitors
if (uptimerobotData.pagination?.total > 1) {
const sitesUp = uptimerobotData.monitors.filter(m => m.status === 2).length;
return (
<Container service={service}>
<Block label="uptimerobot.sitesUp" value={sitesUp} />
<Block label="uptimerobot.sitesDown" value={uptimerobotData.pagination.total - sitesUp} />
</Container>
);
}
// single monitor
const monitor = uptimerobotData.monitors[0];
let status;
let uptime = 0;
let logIndex = 0;
switch (monitor.status) {
case 0:
status = t("uptimerobot.paused");
break;
case 1:
status = t("uptimerobot.notyetchecked");
break;
case 2:
status = t("uptimerobot.up");
uptime = secondsToDhms(monitor.logs[0].duration);
logIndex = 1;
break;
case 8:
status = t("uptimerobot.seemsdown");
break;
case 9:
status = t("uptimerobot.down");
break;
default:
status = t("uptimerobot.unknown");
break;
}
const lastDown = new Date(monitor.logs[logIndex].datetime * 1000).toLocaleString();
const downDuration = secondsToDhms(monitor.logs[logIndex].duration);
const hideDown = logIndex === 1 && monitor.logs[logIndex].type !== 1;
return (
<Container service={service}>
<Block label="uptimerobot.status" value={status} />
<Block label="uptimerobot.uptime" value={uptime} />
{!hideDown && <Block label="uptimerobot.lastDown" value={lastDown} />}
{!hideDown && <Block label="uptimerobot.downDuration" value={downDuration} />}
</Container>
);
}

View File

@ -0,0 +1,20 @@
import genericProxyHandler from "utils/proxy/handlers/generic";
const widget = {
api: "{url}/v2/{endpoint}?api_key={key}",
proxyHandler: genericProxyHandler,
mappings: {
getmonitors: {
method: "POST",
endpoint: "getMonitors",
body: 'format=json&logs=1',
headers: {
"content-type": "application/x-www-form-urlencoded",
"cache-control": "no-cache"
},
},
},
};
export default widget;

View File

@ -1,14 +1,17 @@
import adguard from "./adguard/widget"; import adguard from "./adguard/widget";
import atsumeru from "./atsumeru/widget";
import audiobookshelf from "./audiobookshelf/widget"; import audiobookshelf from "./audiobookshelf/widget";
import authentik from "./authentik/widget"; import authentik from "./authentik/widget";
import autobrr from "./autobrr/widget"; import autobrr from "./autobrr/widget";
import azuredevops from "./azuredevops/widget"; import azuredevops from "./azuredevops/widget";
import bazarr from "./bazarr/widget"; import bazarr from "./bazarr/widget";
import caddy from "./caddy/widget"; import caddy from "./caddy/widget";
import calibreweb from "./calibreweb/widget";
import changedetectionio from "./changedetectionio/widget"; import changedetectionio from "./changedetectionio/widget";
import channelsdvrserver from "./channelsdvrserver/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 customapi from "./customapi/widget";
import deluge from "./deluge/widget"; import deluge from "./deluge/widget";
import diskstation from "./diskstation/widget"; import diskstation from "./diskstation/widget";
import downloadstation from "./downloadstation/widget"; import downloadstation from "./downloadstation/widget";
@ -36,6 +39,7 @@ import komga from "./komga/widget";
import kopia from "./kopia/widget"; import kopia from "./kopia/widget";
import lidarr from "./lidarr/widget"; import lidarr from "./lidarr/widget";
import mastodon from "./mastodon/widget"; import mastodon from "./mastodon/widget";
import mealie from "./mealie/widget";
import medusa from "./medusa/widget"; import medusa from "./medusa/widget";
import minecraft from "./minecraft/widget"; import minecraft from "./minecraft/widget";
import miniflux from "./miniflux/widget"; import miniflux from "./miniflux/widget";
@ -87,6 +91,7 @@ import truenas from "./truenas/widget";
import unifi from "./unifi/widget"; import unifi from "./unifi/widget";
import unmanic from "./unmanic/widget"; import unmanic from "./unmanic/widget";
import uptimekuma from "./uptimekuma/widget"; import uptimekuma from "./uptimekuma/widget";
import uptimerobot from "./uptimerobot/widget";
import watchtower from "./watchtower/widget"; import watchtower from "./watchtower/widget";
import whatsupdocker from "./whatsupdocker/widget"; import whatsupdocker from "./whatsupdocker/widget";
import xteve from "./xteve/widget"; import xteve from "./xteve/widget";
@ -94,16 +99,19 @@ import urbackup from "./urbackup/widget";
const widgets = { const widgets = {
adguard, adguard,
atsumeru,
audiobookshelf, audiobookshelf,
authentik, authentik,
autobrr, autobrr,
azuredevops, azuredevops,
bazarr, bazarr,
caddy, caddy,
calibreweb,
changedetectionio, changedetectionio,
channelsdvrserver, channelsdvrserver,
cloudflared, cloudflared,
coinmarketcap, coinmarketcap,
customapi,
deluge, deluge,
diskstation, diskstation,
downloadstation, downloadstation,
@ -132,6 +140,7 @@ const widgets = {
kopia, kopia,
lidarr, lidarr,
mastodon, mastodon,
mealie,
medusa, medusa,
minecraft, minecraft,
miniflux, miniflux,
@ -184,6 +193,7 @@ const widgets = {
unifi_console: unifi, unifi_console: unifi,
unmanic, unmanic,
uptimekuma, uptimekuma,
uptimerobot,
urbackup, urbackup,
watchtower, watchtower,
whatsupdocker, whatsupdocker,

View File

@ -59,5 +59,16 @@ module.exports = {
'backdrop-brightness-125', 'backdrop-brightness-125',
'backdrop-brightness-150', 'backdrop-brightness-150',
'backdrop-brightness-200', 'backdrop-brightness-200',
'grid-cols-1',
'md:grid-cols-1',
'md:grid-cols-2',
'lg:grid-cols-1',
'lg:grid-cols-2',
'lg:grid-cols-3',
'lg:grid-cols-4',
'lg:grid-cols-5',
'lg:grid-cols-6',
'lg:grid-cols-7',
'lg:grid-cols-8',
], ],
} }