Merge branch 'benphelps:main' into sync

This commit is contained in:
Dimitri Cappelle 2023-07-30 11:18:23 +02:00 committed by GitHub
commit 968b7c6745
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 3053 additions and 790 deletions

View File

@ -141,7 +141,7 @@ pnpm dev
Open [http://localhost:3000](http://localhost:3000) to start.
This is a [Next.js](https://nextjs.org/) application, see their doucmentation for more information:
This is a [Next.js](https://nextjs.org/) application, see their documentation for more information:
## Contributors

View File

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

View File

@ -19,6 +19,9 @@ dependencies:
follow-redirects:
specifier: ^1.15.2
version: 1.15.2
gamedig:
specifier: ^4.0.6
version: 4.0.6
i18next:
specifier: ^21.9.2
version: 21.10.0
@ -402,12 +405,24 @@ packages:
resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==}
dev: true
/@sindresorhus/is@5.4.1:
resolution: {integrity: sha512-axlrvsHlHlFmKKMEg4VyvMzFr93JWJj4eIfXY1STVuO2fsImCa7ncaiG5gC8HKOX590AW5RtRsC41/B+OfrSqw==}
engines: {node: '>=14.16'}
dev: false
/@swc/helpers@0.4.11:
resolution: {integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==}
dependencies:
tslib: 2.5.0
dev: false
/@szmarczak/http-timer@5.0.1:
resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==}
engines: {node: '>=14.16'}
dependencies:
defer-to-connect: 2.0.1
dev: false
/@tailwindcss/forms@0.5.3(tailwindcss@3.3.0):
resolution: {integrity: sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==}
peerDependencies:
@ -424,6 +439,10 @@ packages:
hoist-non-react-statics: 3.3.2
dev: false
/@types/http-cache-semantics@4.0.1:
resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==}
dev: false
/@types/json5@0.0.29:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
dev: true
@ -531,6 +550,11 @@ packages:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
/amdefine@1.0.1:
resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==}
engines: {node: '>=0.4.2'}
dev: false
/ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@ -545,7 +569,6 @@ packages:
/any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
dev: true
/anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
@ -687,6 +710,12 @@ packages:
/balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
/barse@0.4.3:
resolution: {integrity: sha512-UEpvriJqAn8zuVinYICuKoPttZy3XxXEoqX/V2uYAL4zzJRuNzCK3+20nAu3YUIa2U7G53kf90wfBIp9/A+Odw==}
dependencies:
readable-stream: 1.0.34
dev: false
/base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
dev: false
@ -710,6 +739,10 @@ packages:
readable-stream: 3.6.2
dev: false
/boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
dev: false
/brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
@ -756,6 +789,24 @@ packages:
engines: {node: '>= 0.8'}
dev: false
/cacheable-lookup@7.0.0:
resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==}
engines: {node: '>=14.16'}
dev: false
/cacheable-request@10.2.12:
resolution: {integrity: sha512-qtWGB5kn2OLjx47pYUkWicyOpK1vy9XZhq8yRTXOy+KAmjjESSRLx6SiExnnaGGUP1NM6/vmygMu0fGylNh9tw==}
engines: {node: '>=14.16'}
dependencies:
'@types/http-cache-semantics': 4.0.1
get-stream: 6.0.1
http-cache-semantics: 4.1.1
keyv: 4.5.2
mimic-response: 4.0.0
normalize-url: 8.0.0
responselike: 3.0.0
dev: false
/call-bind@1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
dependencies:
@ -788,6 +839,30 @@ packages:
supports-color: 7.2.0
dev: true
/cheerio-select@2.1.0:
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
dependencies:
boolbase: 1.0.0
css-select: 5.1.0
css-what: 6.1.0
domelementtype: 2.3.0
domhandler: 5.0.3
domutils: 3.1.0
dev: false
/cheerio@1.0.0-rc.12:
resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==}
engines: {node: '>= 6'}
dependencies:
cheerio-select: 2.1.0
dom-serializer: 2.0.0
domhandler: 5.0.3
domutils: 3.1.0
htmlparser2: 8.0.2
parse5: 7.1.2
parse5-htmlparser2-tree-adapter: 7.0.0
dev: false
/chokidar@3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'}
@ -868,6 +943,13 @@ packages:
delayed-stream: 1.0.0
dev: false
/commander@2.8.1:
resolution: {integrity: sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==}
engines: {node: '>= 0.6.x'}
dependencies:
graceful-readlink: 1.0.1
dev: false
/commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
@ -877,6 +959,14 @@ packages:
resolution: {integrity: sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==}
dev: false
/compressjs@1.0.3:
resolution: {integrity: sha512-jpKJjBTretQACTGLNuvnozP1JdP2ZLrjdGdBgk/tz1VfXlUcBhhSZW6vEsuThmeot/yjvSrPQKEgfF3X2Lpi8Q==}
hasBin: true
dependencies:
amdefine: 1.0.1
commander: 2.8.1
dev: false
/concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@ -911,6 +1001,21 @@ packages:
shebang-command: 2.0.0
which: 2.0.2
/css-select@5.1.0:
resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
dependencies:
boolbase: 1.0.0
css-what: 6.1.0
domhandler: 5.0.3
domutils: 3.1.0
nth-check: 2.1.1
dev: false
/css-what@6.1.0:
resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
engines: {node: '>= 6'}
dev: false
/cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
@ -953,6 +1058,13 @@ packages:
dependencies:
ms: 2.1.2
/decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
dependencies:
mimic-response: 3.1.0
dev: false
/deep-equal@2.2.0:
resolution: {integrity: sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==}
dependencies:
@ -979,6 +1091,11 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
/defer-to-connect@2.0.1:
resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
engines: {node: '>=10'}
dev: false
/define-properties@1.2.0:
resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
engines: {node: '>= 0.4'}
@ -1049,6 +1166,33 @@ packages:
esutils: 2.0.3
dev: true
/dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
dependencies:
domelementtype: 2.3.0
domhandler: 5.0.3
entities: 4.5.0
dev: false
/domelementtype@2.3.0:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
dev: false
/domhandler@5.0.3:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'}
dependencies:
domelementtype: 2.3.0
dev: false
/domutils@3.1.0:
resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
dependencies:
dom-serializer: 2.0.0
domelementtype: 2.3.0
domhandler: 5.0.3
dev: false
/ecc-jsbn@0.1.2:
resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
dependencies:
@ -1074,6 +1218,11 @@ packages:
once: 1.4.0
dev: false
/entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
dev: false
/es-abstract@1.21.2:
resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==}
engines: {node: '>= 0.4'}
@ -1491,6 +1640,11 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/event-to-promise@0.7.0:
resolution: {integrity: sha512-VOBBfyaADfe378ZzG0tgkzmsvzUyeU5arehrFzNRt5yaASUDshgctTwSrPI17ocAwR3+YftsxRClHF+GBKFByQ==}
deprecated: Use promise-toolbox/fromEvent instead
dev: false
/execa@5.0.0:
resolution: {integrity: sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==}
engines: {node: '>=10'}
@ -1608,6 +1762,11 @@ packages:
resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==}
dev: false
/form-data-encoder@2.1.4:
resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==}
engines: {node: '>= 14.17'}
dev: false
/form-data@2.3.3:
resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==}
engines: {node: '>= 0.12'}
@ -1660,6 +1819,33 @@ packages:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
dev: true
/gamedig@4.0.6:
resolution: {integrity: sha512-h0k9n/e5vNrd9Mh2wyFUp2Vo7ABWbDkdBxKC6FNJLOZiU5d9Z29bntGeYbXtOkcRWoV6Q63wSAJ3jLWxYQkpZw==}
engines: {node: '>=14.0.0'}
hasBin: true
dependencies:
cheerio: 1.0.0-rc.12
compressjs: 1.0.3
gbxremote: 0.2.1
got: 12.6.1
iconv-lite: 0.6.3
long: 5.2.3
minimist: 1.2.8
punycode: 2.3.0
varint: 6.0.0
dev: false
/gbxremote@0.2.1:
resolution: {integrity: sha512-SMehu6Y6ndq2Qgp9VxAb8Np3f+UUD+RWoW2SAMaxzGS96rWXyr4T1GGkecO0HHtxeH1m7pEh4FJWB8a/6aM2XQ==}
engines: {node: '>=0.10'}
dependencies:
any-promise: 1.3.0
barse: 0.4.3
event-to-promise: 0.7.0
string-to-stream: 1.1.1
xmlrpc: 1.3.2
dev: false
/get-intrinsic@1.2.0:
resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==}
dependencies:
@ -1765,6 +1951,27 @@ packages:
get-intrinsic: 1.2.0
dev: true
/got@12.6.1:
resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==}
engines: {node: '>=14.16'}
dependencies:
'@sindresorhus/is': 5.4.1
'@szmarczak/http-timer': 5.0.1
cacheable-lookup: 7.0.0
cacheable-request: 10.2.12
decompress-response: 6.0.0
form-data-encoder: 2.1.4
get-stream: 6.0.1
http2-wrapper: 2.2.0
lowercase-keys: 3.0.0
p-cancelable: 3.0.0
responselike: 3.0.0
dev: false
/graceful-readlink@1.0.1:
resolution: {integrity: sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==}
dev: false
/grapheme-splitter@1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
dev: true
@ -1832,6 +2039,19 @@ packages:
void-elements: 3.1.0
dev: false
/htmlparser2@8.0.2:
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
dependencies:
domelementtype: 2.3.0
domhandler: 5.0.3
domutils: 3.1.0
entities: 4.5.0
dev: false
/http-cache-semantics@4.1.1:
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
dev: false
/http-errors@2.0.0:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
@ -1852,6 +2072,14 @@ packages:
sshpk: 1.17.0
dev: false
/http2-wrapper@2.2.0:
resolution: {integrity: sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==}
engines: {node: '>=10.19.0'}
dependencies:
quick-lru: 5.1.1
resolve-alpn: 1.2.1
dev: false
/human-signals@2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
@ -1874,6 +2102,13 @@ packages:
safer-buffer: 2.1.2
dev: false
/iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
dependencies:
safer-buffer: 2.1.2
dev: false
/ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: false
@ -2084,6 +2319,14 @@ packages:
get-intrinsic: 1.2.0
dev: true
/isarray@0.0.1:
resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
dev: false
/isarray@1.0.0:
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
dev: false
/isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
dev: true
@ -2128,6 +2371,10 @@ packages:
resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
dev: false
/json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
dev: false
/json-rpc-2.0@1.5.1:
resolution: {integrity: sha512-ZY/vYl/uUgKN3tNrZMq7w+CGLcoUT+8AzDO/HJZVa+K4XcwgfgES1QDa5y7ieAeh4NgRo3hLexMxgdaiEiK9aA==}
dev: false
@ -2176,6 +2423,12 @@ packages:
object.assign: 4.1.4
dev: true
/keyv@4.5.2:
resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==}
dependencies:
json-buffer: 3.0.1
dev: false
/kuler@2.0.0:
resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==}
dev: false
@ -2229,11 +2482,20 @@ packages:
triple-beam: 1.3.0
dev: false
/long@5.2.3:
resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==}
dev: false
/loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
dependencies:
js-tokens: 4.0.0
/lowercase-keys@3.0.0:
resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: false
/lru-cache@6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
@ -2278,6 +2540,16 @@ packages:
engines: {node: '>=6'}
dev: false
/mimic-response@3.1.0:
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
engines: {node: '>=10'}
dev: false
/mimic-response@4.0.0:
resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: false
/minecraft-ping-js@1.0.2:
resolution: {integrity: sha512-h9QYG2n+fBKgp520tXBwR354XRzR/w5wXe8CJCmxKm6jbLpAoLODM8Nj5+ssuIVQF8rtxkAnjwv7PH+7ehFzQQ==}
dependencies:
@ -2296,7 +2568,6 @@ packages:
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
dev: true
/minipass@3.3.6:
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
@ -2438,6 +2709,11 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/normalize-url@8.0.0:
resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==}
engines: {node: '>=14.16'}
dev: false
/npm-run-path@4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
@ -2445,6 +2721,12 @@ packages:
path-key: 3.1.1
dev: false
/nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
dependencies:
boolbase: 1.0.0
dev: false
/oauth-sign@0.9.0:
resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==}
dev: false
@ -2581,6 +2863,11 @@ packages:
dev: false
optional: true
/p-cancelable@3.0.0:
resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==}
engines: {node: '>=12.20'}
dev: false
/p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
@ -2602,6 +2889,19 @@ packages:
callsites: 3.1.0
dev: true
/parse5-htmlparser2-tree-adapter@7.0.0:
resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==}
dependencies:
domhandler: 5.0.3
parse5: 7.1.2
dev: false
/parse5@7.1.2:
resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
dependencies:
entities: 4.5.0
dev: false
/path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
@ -2746,6 +3046,10 @@ packages:
engines: {node: ^14.13.1 || >=16.0.0}
dev: false
/process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
dev: false
/prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
dependencies:
@ -2785,7 +3089,6 @@ packages:
/quick-lru@5.1.1:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
engines: {node: '>=10'}
dev: true
/raw-body@2.5.2:
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
@ -2851,6 +3154,27 @@ packages:
pify: 2.3.0
dev: true
/readable-stream@1.0.34:
resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==}
dependencies:
core-util-is: 1.0.2
inherits: 2.0.4
isarray: 0.0.1
string_decoder: 0.10.31
dev: false
/readable-stream@2.3.8:
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
dependencies:
core-util-is: 1.0.2
inherits: 2.0.4
isarray: 1.0.0
process-nextick-args: 2.0.1
safe-buffer: 5.1.2
string_decoder: 1.1.1
util-deprecate: 1.0.2
dev: false
/readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
@ -2916,6 +3240,10 @@ packages:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
dev: false
/resolve-alpn@1.2.1:
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
dev: false
/resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@ -2936,6 +3264,13 @@ packages:
supports-preserve-symlinks-flag: 1.0.0
dev: true
/responselike@3.0.0:
resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==}
engines: {node: '>=14.16'}
dependencies:
lowercase-keys: 3.0.0
dev: false
/reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
@ -2956,6 +3291,10 @@ packages:
queue-microtask: 1.2.3
dev: true
/safe-buffer@5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
dev: false
/safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
dev: false
@ -3104,6 +3443,13 @@ packages:
engines: {node: '>= 0.10.0'}
dev: false
/string-to-stream@1.1.1:
resolution: {integrity: sha512-QySF2+3Rwq0SdO3s7BAp4x+c3qsClpPQ6abAmb0DGViiSBAkT5kL6JT2iyzEVP+T1SmzHrQD1TwlP9QAHCc+Sw==}
dependencies:
inherits: 2.0.4
readable-stream: 2.3.8
dev: false
/string.prototype.matchall@4.0.8:
resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==}
dependencies:
@ -3142,6 +3488,16 @@ packages:
es-abstract: 1.21.2
dev: true
/string_decoder@0.10.31:
resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==}
dev: false
/string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
dependencies:
safe-buffer: 5.1.2
dev: false
/string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
dependencies:
@ -3601,6 +3957,19 @@ packages:
sax: 1.2.4
dev: false
/xmlbuilder@8.2.2:
resolution: {integrity: sha512-eKRAFz04jghooy8muekqzo8uCSVNeyRedbuJrp0fovbLIi7wlsYtdUn3vBAAPq2Y3/0xMz2WMEUQ8yhVVO9Stw==}
engines: {node: '>=4.0'}
dev: false
/xmlrpc@1.3.2:
resolution: {integrity: sha512-jQf5gbrP6wvzN71fgkcPPkF4bF/Wyovd7Xdff8d6/ihxYmgETQYSuTc+Hl+tsh/jmgPLro/Aro48LMFlIyEKKQ==}
engines: {node: '>=0.8', npm: '>=1.0.0'}
dependencies:
sax: 1.2.4
xmlbuilder: 8.2.2
dev: false
/yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}

View File

@ -141,7 +141,8 @@
"playing": "يشتغل",
"transcoding": "التحويل",
"bitrate": "معدل البت",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "معدل",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"approved": "Approved"
}
}

View File

@ -89,7 +89,8 @@
"playing": "Възпроизвежда",
"transcoding": "Конвертира",
"bitrate": "Честота",
"no_active": "Няма активни потоци"
"no_active": "Няма активни потоци",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Rate",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -80,7 +80,8 @@
"playing": "Reproduint",
"transcoding": "Transcodificant",
"bitrate": "Taxa de bits",
"no_active": "Sense transmissions actives"
"no_active": "Sense transmissions actives",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Taxa",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -46,8 +46,8 @@
},
"unifi": {
"users": "Uživatelé",
"uptime": "Doba provozu systému",
"days": "Dnů",
"uptime": "Doba provozu",
"days": "dní",
"wan": "WAN",
"lan": "LAN",
"wlan": "WLAN",
@ -56,8 +56,8 @@
"wlan_devices": "Zařízení WLAN",
"lan_users": "Uživatelé LAN",
"wlan_users": "Uživatelé WLAN",
"up": "BĚŽÍ",
"down": "NEBĚŽÍ",
"up": "FUNKČNÍ",
"down": "NEFUNKČNÍ",
"wait": "Počkejte prosím",
"empty_data": "Stav podsystému neznámý"
},
@ -95,7 +95,8 @@
"playing": "Přehrává",
"transcoding": "Překódovávání",
"bitrate": "Přenosová rychlost",
"no_active": "Žádný aktivní stream"
"no_active": "Žádný aktivní stream",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Rychlost",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"map": "Map",
"currentPlayers": "Current players",
"name": "Name",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -234,7 +234,8 @@
"playing": "Afspiller",
"transcoding": "Transcoder",
"bitrate": "Bitrate",
"no_active": "Ingen Aktive Streams"
"no_active": "Ingen Aktive Streams",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Rate",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -56,7 +56,8 @@
"playing": "Spielen",
"transcoding": "Transcodierung",
"bitrate": "Bitrate",
"no_active": "Keine aktiven Streams"
"no_active": "Keine aktiven Streams",
"plex_connection_error": "Check Plex Connection"
},
"rutorrent": {
"active": "Aktiv",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"bots": "Bots",
"ping": "Ping",
"maxPlayers": "Max players"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved",
"inProgress": "In Progress"
}
}

View File

@ -162,7 +162,8 @@
"playing": "Αναπαράγει",
"transcoding": "Μετακωδικοποίηση",
"bitrate": "Ρυθμός bit",
"no_active": "Δεν υπάρχουν ενεργές ροές"
"no_active": "Δεν υπάρχουν ενεργές ροές",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Ρυθμός",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"myPrs": "My PRs",
"approved": "Approved",
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs"
}
}

27
public/locales/en/common.json Executable file → Normal file
View File

@ -92,7 +92,7 @@
"episodes": "Episodes",
"songs": "Songs"
},
"evcc": {
"evcc": {
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Grid",
@ -129,7 +129,8 @@
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"omada": {
"connectedAp": "Connected APs",
@ -663,5 +664,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
}
}

View File

@ -87,7 +87,8 @@
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Rate",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -56,7 +56,8 @@
"playing": "Reproduciendo",
"transcoding": "Transcodificando",
"bitrate": "Tasa de bits",
"no_active": "Sin transmisiones activas"
"no_active": "Sin transmisiones activas",
"plex_connection_error": "Comprueba la conexión a Plex"
},
"rutorrent": {
"active": "Activo",
@ -652,7 +653,29 @@
"downloadTotalBytes": "Tamaño"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"seriesCount": "Serie",
"totalFiles": "Archivos"
},
"gamedig": {
"name": "Nombre",
"map": "Mapa",
"currentPlayers": "Jugadores actuales",
"players": "Jugadores",
"maxPlayers": "Jugadores máximos",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -0,0 +1,681 @@
{
"wmo": {
"95-night": "Thunderstorm",
"96-day": "Thunderstorm With Hail",
"96-night": "Thunderstorm With Hail",
"99-day": "Thunderstorm With Hail",
"0-day": "Sunny",
"0-night": "Clear",
"1-day": "Mainly Sunny",
"1-night": "Mainly Clear",
"2-day": "Partly Cloudy",
"2-night": "Partly Cloudy",
"3-day": "Cloudy",
"3-night": "Cloudy",
"45-day": "Foggy",
"45-night": "Foggy",
"48-day": "Foggy",
"48-night": "Foggy",
"51-day": "Light Drizzle",
"51-night": "Light Drizzle",
"53-day": "Drizzle",
"53-night": "Drizzle",
"55-day": "Heavy Drizzle",
"55-night": "Heavy Drizzle",
"56-day": "Light Freezing Drizzle",
"56-night": "Light Freezing Drizzle",
"57-day": "Freezing Drizzle",
"57-night": "Freezing Drizzle",
"61-day": "Light Rain",
"61-night": "Light Rain",
"63-day": "Rain",
"63-night": "Rain",
"65-day": "Heavy Rain",
"65-night": "Heavy Rain",
"66-day": "Freezing Rain",
"66-night": "Freezing Rain",
"67-day": "Freezing Rain",
"67-night": "Freezing Rain",
"71-day": "Light Snow",
"71-night": "Light Snow",
"73-day": "Snow",
"73-night": "Snow",
"75-day": "Heavy Snow",
"75-night": "Heavy Snow",
"77-day": "Snow Grains",
"77-night": "Snow Grains",
"80-day": "Light Showers",
"80-night": "Light Showers",
"81-day": "Showers",
"81-night": "Showers",
"82-day": "Heavy Showers",
"82-night": "Heavy Showers",
"85-day": "Snow Showers",
"85-night": "Snow Showers",
"86-day": "Snow Showers",
"86-night": "Snow Showers",
"95-day": "Thunderstorm",
"99-night": "Thunderstorm With Hail"
},
"homebridge": {
"updates": "Updates",
"available_update": "System",
"update_available": "Update Available",
"up_to_date": "Up to Date",
"child_bridges": "Child Bridges",
"child_bridges_status": "{{ok}}/{{total}}",
"up": "Up",
"pending": "Pending",
"down": "Down"
},
"common": {
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
},
"widget": {
"missing_type": "Missing Widget Type: {{type}}",
"api_error": "API Error",
"information": "Informazioa",
"status": "Status",
"url": "URL",
"raw_error": "Raw Error",
"response_data": "Response Data"
},
"weather": {
"current": "Current Location",
"allow": "Click to allow",
"updating": "Eguneratzen",
"wait": "Itxaron mesedez"
},
"search": {
"placeholder": "Bilatu…"
},
"resources": {
"cpu": "CPU",
"mem": "MEM",
"total": "Guztira",
"free": "Free",
"used": "Erabilita",
"load": "Load",
"temp": "TEMP",
"max": "Max",
"uptime": "UP",
"months": "mo",
"days": "d",
"hours": "h",
"minutes": "m"
},
"unifi": {
"users": "Users",
"uptime": "System Uptime",
"days": "Egun",
"wan": "WAN",
"lan": "LAN",
"wlan": "WLAN",
"devices": "Gailuak",
"lan_devices": "LAN Gailuak",
"wlan_devices": "WLAN Gailuak",
"lan_users": "LAN Erabiltzaileak",
"wlan_users": "WLAN Erabiltzaileak",
"up": "UP",
"down": "DOWN",
"wait": "Itxaron mesedez",
"empty_data": "Subsystem status unknown"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"running": "Running",
"offline": "Offline",
"error": "Error",
"unknown": "Ezezaguna",
"healthy": "Osasuntsu",
"starting": "Abiarazten",
"unhealthy": "Unhealthy",
"not_found": "Not Found",
"exited": "Exited",
"partial": "Partial"
},
"ping": {
"error": "Errorea",
"ping": "Ping"
},
"emby": {
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bit-tasa",
"no_active": "No Active Streams",
"movies": "Movies",
"series": "Series",
"episodes": "Episodes",
"songs": "Abestiak"
},
"evcc": {
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Grid",
"home_power": "Consumption",
"charge_power": "Charger",
"watt_hour": "Wh"
},
"flood": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Current requests",
"requests_failed": "Failed requests"
},
"changedetectionio": {
"totalObserved": "Total Observed",
"diffsDetected": "Diffs Detected"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
},
"tautulli": {
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"omada": {
"connectedAp": "Connected APs",
"activeUser": "Active devices",
"alerts": "Alerts",
"connectedGateway": "Connected gateways",
"connectedSwitches": "Connected switches"
},
"nzbget": {
"rate": "Rate",
"remaining": "Remaining",
"downloaded": "Downloaded"
},
"plex": {
"streams": "Active Streams",
"albums": "Albums",
"movies": "Movies",
"tv": "TV Shows"
},
"sabnzbd": {
"rate": "Rate",
"queue": "Queue",
"timeleft": "Time Left"
},
"rutorrent": {
"active": "Active",
"upload": "Kargatu",
"download": "Deskargatu"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"qnap": {
"cpuUsage": "CPU Usage",
"memUsage": "MEM Usage",
"systemTempC": "System Temp",
"poolUsage": "Pool Usage",
"volumeUsage": "Volume Usage",
"invalid": "Invalid"
},
"deluge": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"downloadstation": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"sonarr": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series",
"queue": "Queue",
"unknown": "Unknown"
},
"radarr": {
"wanted": "Wanted",
"missing": "Missing",
"queued": "Queued",
"movies": "Movies",
"queue": "Queue",
"unknown": "Unknown"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"artists": "Artists"
},
"readarr": {
"wanted": "Wanted",
"queued": "Queued",
"books": "Books"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
},
"ombi": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"jellyseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"overseerr": {
"pending": "Pending",
"processing": "Processing",
"approved": "Approved",
"available": "Available"
},
"pialert": {
"total": "Total",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
},
"pihole": {
"queries": "Queries",
"blocked": "Blocked",
"blocked_percent": "Blocked %",
"gravity": "Gravity"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"ping": "Ping"
},
"portainer": {
"running": "Running",
"stopped": "Stopped",
"total": "Total"
},
"tailscale": {
"address": "Address",
"expires": "Expires",
"never": "Never",
"last_seen": "Last Seen",
"now": "Now",
"years": "{{number}}y",
"weeks": "{{number}}w",
"days": "{{number}}d",
"hours": "{{number}}h",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "{{value}} Ago"
},
"tdarr": {
"queue": "Queue",
"processed": "Processed",
"errored": "Errored",
"saved": "Saved"
},
"traefik": {
"routers": "Routers",
"services": "Services",
"middleware": "Middleware"
},
"navidrome": {
"nothing_streaming": "No Active Streams",
"please_wait": "Please Wait"
},
"npm": {
"enabled": "Enabled",
"disabled": "Disabled",
"total": "Total"
},
"coinmarketcap": {
"configure": "Configure one or more crypto currencies to track",
"1hour": "1 Hour",
"1day": "1 Day",
"7days": "7 Days",
"30days": "30 Days"
},
"gotify": {
"apps": "Applications",
"clients": "Clients",
"messages": "Messages"
},
"prowlarr": {
"enableIndexers": "Indexers",
"numberOfGrabs": "Grabs",
"numberOfQueries": "Queries",
"numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries"
},
"jackett": {
"configured": "Configured",
"errored": "Errored"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"medusa": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series"
},
"minecraft": {
"players": "Jokalariak",
"version": "Version",
"status": "Status",
"up": "Online",
"down": "Offline"
},
"miniflux": {
"read": "Read",
"unread": "Unread"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
},
"proxmox": {
"mem": "MEM",
"cpu": "CPU",
"lxc": "LXC",
"vms": "VMs"
},
"glances": {
"cpu": "CPU",
"load": "Load",
"wait": "Please wait",
"temp": "TEMP",
"warn": "Warn",
"uptime": "UP",
"total": "Total",
"free": "Free",
"used": "Used",
"days": "d",
"hours": "h"
},
"quicklaunch": {
"bookmark": "Bookmark",
"service": "Service",
"search": "Search",
"custom": "Custom",
"visit": "Visit",
"url": "URL"
},
"healthchecks": {
"new": "New",
"up": "Online",
"grace": "In Grace Period",
"down": "Offline",
"paused": "Paused",
"status": "Status",
"last_ping": "Last Ping",
"never": "No pings yet"
},
"watchtower": {
"containers_scanned": "Scanned",
"containers_updated": "Updated",
"containers_failed": "Failed"
},
"autobrr": {
"approvedPushes": "Approved",
"rejectedPushes": "Rejected",
"filters": "Filters",
"indexers": "Indexers"
},
"tubearchivist": {
"downloads": "Queue",
"videos": "Videos",
"channels": "Channels",
"playlists": "Playlists"
},
"truenas": {
"load": "System Load",
"uptime": "Uptime",
"alerts": "Alerts",
"time": "{{value, number(style: unit; unitDisplay: long;)}}"
},
"pyload": {
"speed": "Speed",
"active": "Active",
"queue": "Queue",
"total": "Total"
},
"gluetun": {
"public_ip": "Public IP",
"region": "Region",
"country": "Country"
},
"hdhomerun": {
"channels": "Channels",
"hd": "HD"
},
"scrutiny": {
"passed": "Passed",
"failed": "Failed",
"unknown": "Unknown"
},
"paperlessngx": {
"inbox": "Inbox",
"total": "Total"
},
"nextdns": {
"wait": "Please Wait",
"no_devices": "No Device Data Received"
},
"mikrotik": {
"cpuLoad": "CPU Load",
"memoryUsed": "Memory Used",
"uptime": "Uptime",
"numberOfLeases": "Leases"
},
"xteve": {
"streams_all": "All Streams",
"streams_active": "Active Streams",
"streams_xepg": "XEPG Channels"
},
"opnsense": {
"cpu": "CPU Load",
"memory": "Active Memory",
"wanUpload": "WAN Upload",
"wanDownload": "WAN Download"
},
"moonraker": {
"printer_state": "Printer State",
"print_status": "Print Status",
"print_progress": "Progress",
"layers": "Layers"
},
"octoprint": {
"printer_state": "Status",
"temp_tool": "Tool temp",
"temp_bed": "Bed temp",
"job_completion": "Completion"
},
"cloudflared": {
"origin_ip": "Origin IP",
"status": "Status"
},
"pfsense": {
"load": "Load Avg",
"memory": "Mem Usage",
"wanStatus": "WAN Status",
"up": "Up",
"down": "Down",
"temp": "Temp",
"disk": "Disk Usage",
"wanIP": "WAN IP"
},
"proxmoxbackupserver": {
"datastore_usage": "Datastore",
"failed_tasks_24h": "Failed Tasks 24h",
"cpu_usage": "CPU",
"memory_usage": "Memory"
},
"immich": {
"users": "Users",
"photos": "Photos",
"videos": "Videos",
"storage": "Storage"
},
"uptimekuma": {
"up": "Sites Up",
"down": "Sites Down",
"uptime": "Uptime",
"incident": "Incident",
"m": "m"
},
"komga": {
"libraries": "Libraries",
"series": "Series",
"books": "Books"
},
"diskstation": {
"days": "Days",
"uptime": "Uptime",
"volumeAvailable": "Available"
},
"mylar": {
"series": "Series",
"issues": "Issues",
"wanted": "Wanted"
},
"photoprism": {
"albums": "Albums",
"photos": "Photos",
"videos": "Videos",
"people": "People"
},
"fileflows": {
"queue": "Queue",
"processing": "Processing",
"processed": "Processed",
"time": "Time"
},
"grafana": {
"dashboards": "Dashboards",
"datasources": "Data Sources",
"totalalerts": "Total Alerts",
"alertstriggered": "Alerts Triggered"
},
"nextcloud": {
"cpuload": "Cpu Load",
"memoryusage": "Memory Usage",
"freespace": "Free Space",
"activeusers": "Active Users",
"numfiles": "Files",
"numshares": "Shared Items"
},
"kopia": {
"status": "Status",
"size": "Size",
"lastrun": "Last Run",
"nextrun": "Next Run",
"failed": "Failed"
},
"unmanic": {
"active_workers": "Active Workers",
"total_workers": "Total Workers",
"records_total": "Queue Length"
},
"pterodactyl": {
"servers": "Servers",
"nodes": "Nodes"
},
"prometheus": {
"targets_up": "Targets Up",
"targets_down": "Targets Down",
"targets_total": "Total Targets"
},
"ghostfolio": {
"gross_percent_today": "Today",
"gross_percent_1y": "One year",
"gross_percent_max": "All time"
},
"audiobookshelf": {
"podcasts": "Podcasts",
"books": "Books",
"podcastsDuration": "Duration",
"booksDuration": "Duration"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
},
"whatsupdocker": {
"monitoring": "Monitoring",
"updates": "Updates"
},
"jdownloader": {
"downloadCount": "Queue",
"downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size",
"downloadSpeed": "Speed"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"currentPlayers": "Current players",
"name": "Name",
"map": "Map",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"notStarted": "Not Started",
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -62,7 +62,8 @@
"playing": "Toistaa",
"transcoding": "Transkoodaa",
"bitrate": "Bittinopeus",
"no_active": "Ei aktiivisia striimejä"
"no_active": "Ei aktiivisia striimejä",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Nopeus",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -5,8 +5,8 @@
"status": "Statut",
"information": "Information",
"url": "URL",
"raw_error": "Raw Error",
"response_data": "Response Data"
"raw_error": "Erreur brute",
"response_data": "Données de réponse"
},
"search": {
"placeholder": "Recherche…"
@ -56,7 +56,8 @@
"playing": "En lecture",
"transcoding": "Transcodage",
"bitrate": "Débit",
"no_active": "Aucun flux actif"
"no_active": "Aucun flux actif",
"plex_connection_error": "Vérifier la connexion à Plex"
},
"rutorrent": {
"active": "Actif",
@ -578,7 +579,7 @@
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lumières allumées",
"switches_on": "Switches On"
"switches_on": "Commutateur On"
},
"freshrss": {
"unread": "Non lu",
@ -652,7 +653,29 @@
"downloadTotalBytes": "Taille"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"seriesCount": "Séries",
"totalFiles": "Fichiers"
},
"gamedig": {
"name": "Nom",
"map": "Carte",
"currentPlayers": "Joueurs actuels",
"players": "Joueurs",
"maxPlayers": "Joueurs max",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -62,7 +62,8 @@
"playing": "מנגן",
"transcoding": "מקודד",
"bitrate": "סיביות",
"no_active": "אין הזרמות פעילות"
"no_active": "אין הזרמות פעילות",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "יחס",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"myPrs": "My PRs",
"totalPrs": "Total PRs",
"approved": "Approved"
}
}

View File

@ -117,7 +117,8 @@
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Rate",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"myPrs": "My PRs",
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"approved": "Approved"
}
}

View File

@ -104,7 +104,8 @@
"playing": "Reprodukcija",
"transcoding": "Prekodiranje",
"bitrate": "Stopa bitova",
"no_active": "Nema aktivnih prijenosa"
"no_active": "Nema aktivnih prijenosa",
"plex_connection_error": "Provjeri Plex vezu"
},
"nzbget": {
"rate": "Stopa",
@ -126,21 +127,21 @@
"wanted": "Zatraženo",
"queued": "U redu čekanja",
"series": "Serije",
"unknown": "Unknown",
"queue": "Queue"
"unknown": "Nepoznato",
"queue": "Red čekanja"
},
"radarr": {
"wanted": "Zatraženo",
"queued": "U redu čekanja",
"movies": "Filmovi",
"missing": "Nedostaje",
"queue": "Queue",
"unknown": "Unknown"
"queue": "Red čekanja",
"unknown": "Nepoznato"
},
"lidarr": {
"wanted": "Zatraženo",
"queued": "U redu čekanja",
"artists": "Artists"
"artists": "Umjetnici"
},
"readarr": {
"wanted": "Zatraženo",
@ -646,13 +647,35 @@
"down_alerts": "Obavijest o rušenju"
},
"jdownloader": {
"downloadCount": "Queue Count",
"downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size"
"downloadCount": "Red čekanja",
"downloadSpeed": "Brzina",
"downloadBytesRemaining": "Preostalo",
"downloadTotalBytes": "Veličina"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"seriesCount": "Serije",
"totalFiles": "Datoteke"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -4,15 +4,15 @@
"free": "Szabad",
"used": "Használt",
"load": "Terhelés",
"cpu": "CPU",
"cpu": "Processzor",
"mem": "MEM",
"temp": "TEMP",
"max": "Max",
"uptime": "UP",
"months": "mo",
"days": "d",
"hours": "h",
"minutes": "m"
"uptime": "FUT",
"months": "",
"days": "n",
"hours": "ó",
"minutes": "p"
},
"docker": {
"rx": "RX",
@ -20,20 +20,20 @@
"mem": "MEM",
"cpu": "CPU",
"offline": "Offline",
"error": "Error",
"unknown": "Unknown",
"unhealthy": "Unhealthy",
"running": "Running",
"starting": "Starting",
"not_found": "Not Found",
"exited": "Exited",
"partial": "Partial",
"healthy": "Healthy"
"error": "Hiba",
"unknown": "Ismeretlen",
"unhealthy": "Egészségtelen",
"running": "Futó",
"starting": "Indul",
"not_found": "Nem található",
"exited": "Kilépett",
"partial": "Részleges",
"healthy": "Egészséges"
},
"lidarr": {
"wanted": "Keresett",
"queued": "Sorban áll",
"artists": "Artists"
"artists": "Előadók"
},
"readarr": {
"wanted": "Keresett",
@ -48,16 +48,16 @@
"missing_type": "Hiányzó Widget Típus: {{type}}",
"api_error": "API Hiba",
"status": "Státusz",
"information": "Information",
"information": "Információ",
"url": "URL",
"raw_error": "Raw Error",
"response_data": "Response Data"
"raw_error": "Nyers hiba",
"response_data": "Válaszadatok"
},
"weather": {
"current": "Aktuális hely",
"allow": "Kattints az engedélyezéshez",
"updating": "Frissítés",
"wait": "Kérlek várj"
"wait": "Kérjük várjon"
},
"search": {
"placeholder": "Keresés…"
@ -76,7 +76,8 @@
"playing": "Lejátszás folyamatban",
"transcoding": "Átkódolás",
"bitrate": "Bitráta",
"no_active": "Nincs aktív lejátszás"
"no_active": "Nincs aktív lejátszás",
"plex_connection_error": "Plex kapcsolat ellenőrzése"
},
"nzbget": {
"rate": "Ráta",
@ -109,16 +110,16 @@
"wanted": "Keresett",
"queued": "Sorban áll",
"series": "Sorozat",
"queue": "Queue",
"unknown": "Unknown"
"queue": "Várólista",
"unknown": "Ismeretlen"
},
"radarr": {
"wanted": "Keresett",
"queued": "Sorban áll",
"movies": "Filmek",
"missing": "Missing",
"queue": "Queue",
"unknown": "Unknown"
"missing": "Hiányzik",
"queue": "Várólista",
"unknown": "Ismeretlen"
},
"ombi": {
"pending": "Függőben",
@ -134,13 +135,13 @@
"pending": "Függőben",
"approved": "Engedélyezett",
"available": "Elérhető",
"processing": "Processing"
"processing": "Feldolgozás"
},
"pihole": {
"queries": "Lekérdezések",
"blocked": "Blokkolt",
"gravity": "Gravitáció",
"blocked_percent": "Blocked %"
"blocked_percent": "Blokkolt %"
},
"adguard": {
"queries": "Lekérdezések",
@ -192,184 +193,184 @@
"errored": "Hibás"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
"user_count": "Felhasználók",
"status_count": "Posztok",
"domain_count": "Domainek"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
"numActiveSessions": "Munkamenetek",
"numConnections": "Csatlakozások",
"dataRelayed": "Átirányított",
"transferRate": "Ráta"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
"users": "Felhasználók",
"loginsLast24H": "Bejelentkezések (24 óra)",
"failedLoginsLast24H": "Sikertelen bejelentkezések (24h)"
},
"proxmox": {
"mem": "MEM",
"cpu": "CPU",
"mem": "RAM",
"cpu": "Processzor",
"lxc": "LXC",
"vms": "VMs"
"vms": "VM-ek"
},
"unifi": {
"users": "Users",
"uptime": "System Uptime",
"days": "Days",
"users": "Felhasználók",
"uptime": "Rendszer üzemidő",
"days": "Napok",
"wan": "WAN",
"lan_users": "LAN Users",
"wlan_users": "WLAN Users",
"up": "UP",
"down": "DOWN",
"wait": "Please wait",
"lan_users": "LAN Felhasználók",
"wlan_users": "WLAN Felhasználók",
"up": "FUT",
"down": "ÁLL",
"wait": "Kérjük várjon",
"lan": "LAN",
"wlan": "WLAN",
"devices": "Devices",
"lan_devices": "LAN Devices",
"wlan_devices": "WLAN Devices",
"empty_data": "Subsystem status unknown"
"devices": "Eszközök",
"lan_devices": "LAN Eszközök",
"wlan_devices": "WLAN Eszközök",
"empty_data": "Az alrendszer állapota ismeretlen"
},
"plex": {
"streams": "Active Streams",
"movies": "Movies",
"tv": "TV Shows",
"albums": "Albums"
"streams": "Aktív Stream-ek",
"movies": "Filmek",
"tv": "TV műsorok",
"albums": "Albumok"
},
"glances": {
"cpu": "CPU",
"wait": "Please wait",
"temp": "TEMP",
"uptime": "UP",
"days": "d",
"hours": "h",
"load": "Load",
"warn": "Warn",
"total": "Total",
"free": "Free",
"used": "Used"
"cpu": "Processzor",
"wait": "Kérjük várjon",
"temp": "HŐMÉRSÉKLET",
"uptime": "FUT",
"days": "n",
"hours": "ó",
"load": "Kapacitáskihasználás",
"warn": "Figyelmeztet",
"total": "Összes",
"free": "Szabad",
"used": "Felhasznált"
},
"changedetectionio": {
"totalObserved": "Total Observed",
"diffsDetected": "Diffs Detected"
"totalObserved": "Összes Megfigyelt",
"diffsDetected": "Észlelt különbségek"
},
"wmo": {
"0-day": "Napos",
"0-night": "Derült",
"3-day": "Cloudy",
"3-night": "Cloudy",
"45-day": "Foggy",
"53-day": "Drizzle",
"56-night": "Light Freezing Drizzle",
"57-day": "Freezing Drizzle",
"3-day": "Felhős",
"3-night": "Felhős",
"45-day": "Ködös",
"53-day": "Szitálás",
"56-night": "Enyhe fagyos szitálás",
"57-day": "Fagyos szitálás",
"1-day": "Többnyire napos",
"1-night": "Többnyire derült",
"2-day": "Partly Cloudy",
"2-night": "Partly Cloudy",
"45-night": "Foggy",
"48-day": "Foggy",
"48-night": "Foggy",
"51-day": "Light Drizzle",
"51-night": "Light Drizzle",
"57-night": "Freezing Drizzle",
"61-day": "Light Rain",
"61-night": "Light Rain",
"53-night": "Drizzle",
"55-day": "Heavy Drizzle",
"55-night": "Heavy Drizzle",
"56-day": "Light Freezing Drizzle",
"63-day": "Rain",
"63-night": "Rain",
"65-day": "Heavy Rain",
"65-night": "Heavy Rain",
"66-day": "Freezing Rain",
"66-night": "Freezing Rain",
"67-day": "Freezing Rain",
"67-night": "Freezing Rain",
"71-day": "Light Snow",
"71-night": "Light Snow",
"73-day": "Snow",
"73-night": "Snow",
"75-day": "Heavy Snow",
"75-night": "Heavy Snow",
"77-day": "Snow Grains",
"77-night": "Snow Grains",
"80-day": "Light Showers",
"80-night": "Light Showers",
"81-day": "Showers",
"81-night": "Showers",
"82-day": "Heavy Showers",
"82-night": "Heavy Showers",
"85-day": "Snow Showers",
"85-night": "Snow Showers",
"86-day": "Snow Showers",
"86-night": "Snow Showers",
"95-day": "Thunderstorm",
"95-night": "Thunderstorm",
"96-day": "Thunderstorm With Hail",
"96-night": "Thunderstorm With Hail",
"99-day": "Thunderstorm With Hail",
"99-night": "Thunderstorm With Hail"
"2-day": "Részben felhős",
"2-night": "Részben felhős",
"45-night": "Ködös",
"48-day": "Ködös",
"48-night": "Ködös",
"51-day": "Enyhe szitálás",
"51-night": "Enyhe szitálás",
"57-night": "Fagyos szitálás",
"61-day": "Enyhe eső",
"61-night": "Enyhe eső",
"53-night": "Szitálás",
"55-day": "Erős szitálás",
"55-night": "Erős szitálás",
"56-day": "Enyhe fagyos szitálás",
"63-day": "Eső",
"63-night": "Eső",
"65-day": "Heves eső",
"65-night": "Heves eső",
"66-day": "Ónos eső",
"66-night": "Ónos eső",
"67-day": "Ónos eső",
"67-night": "Ónos eső",
"71-day": "Enyhe havazás",
"71-night": "Enyhe havazás",
"73-day": "",
"73-night": "",
"75-day": "Erős havazás",
"75-night": "Erős havazás",
"77-day": "Hódara",
"77-night": "Hódara",
"80-day": "Enyhe záporok",
"80-night": "Enyhe záporok",
"81-day": "Záporok",
"81-night": "Záporok",
"82-day": "Heves záporok",
"82-night": "Heves záporok",
"85-day": "Hózáporok",
"85-night": "Hózáporok",
"86-day": "Hózáporok",
"86-night": "Hózáporok",
"95-day": "Zivatar",
"95-night": "Zivatar",
"96-day": "Zivatar jégesővel",
"96-night": "Zivatar jégesővel",
"99-day": "Zivatar jégesővel",
"99-night": "Zivatar jégesővel"
},
"quicklaunch": {
"bookmark": "Bookmark",
"service": "Service",
"search": "Search",
"custom": "Custom",
"visit": "Visit",
"bookmark": "Könyvjelző",
"service": "Szolgáltatás",
"search": "Keresés",
"custom": "Egyedi",
"visit": "Megnéz",
"url": "URL"
},
"homebridge": {
"available_update": "System",
"updates": "Updates",
"update_available": "Update Available",
"up_to_date": "Up to Date",
"child_bridges": "Child Bridges",
"available_update": "Rendszer",
"updates": "Frissítések",
"update_available": "Elérhető Frissítés",
"up_to_date": "Naprakész",
"child_bridges": "Gyerek Hidak",
"child_bridges_status": "{{ok}}/{{total}}",
"up": "Up",
"pending": "Pending",
"down": "Down"
"up": "Fut",
"pending": "Függőben",
"down": "Áll"
},
"autobrr": {
"approvedPushes": "Approved",
"rejectedPushes": "Rejected",
"filters": "Filters",
"indexers": "Indexers"
"approvedPushes": "Jóváhagyott",
"rejectedPushes": "Elutasított",
"filters": "Szűrők",
"indexers": "Indexelők"
},
"watchtower": {
"containers_scanned": "Scanned",
"containers_updated": "Updated",
"containers_failed": "Failed"
"containers_scanned": "Beolvasott",
"containers_updated": "Frissített",
"containers_failed": "Sikertelen"
},
"tubearchivist": {
"downloads": "Queue",
"videos": "Videos",
"channels": "Channels",
"playlists": "Playlists"
"downloads": "Várólista",
"videos": "Videók",
"channels": "Csatornák",
"playlists": "Lejátszási listák"
},
"truenas": {
"load": "System Load",
"uptime": "Uptime",
"alerts": "Alerts",
"load": "Rendszerterheltség",
"uptime": "Üzemidő",
"alerts": "Riasztások",
"time": "{{value, number(style: unit; unitDisplay: long;)}}"
},
"navidrome": {
"nothing_streaming": "No Active Streams",
"please_wait": "Please Wait"
"nothing_streaming": "Nincsenek Aktív Stream-ek",
"please_wait": "Kérjük Várjon"
},
"pyload": {
"speed": "Speed",
"active": "Active",
"queue": "Queue",
"total": "Total"
"speed": "Sebesség",
"active": "Aktív",
"queue": "Várólista",
"total": "Összes"
},
"gluetun": {
"public_ip": "Public IP",
"region": "Region",
"country": "Country"
"public_ip": "Nyilvános IP-cím",
"region": "Régió",
"country": "Ország"
},
"hdhomerun": {
"channels": "Channels",
"channels": "Csatornák",
"hd": "HD"
},
"ping": {
@ -377,197 +378,197 @@
"ping": "Ping"
},
"scrutiny": {
"passed": "Passed",
"failed": "Failed",
"unknown": "Unknown"
"passed": "Megfelelt",
"failed": "Sikertelen",
"unknown": "Ismeretlen"
},
"paperlessngx": {
"inbox": "Inbox",
"total": "Total"
"inbox": "Beérkezett",
"total": "Összes"
},
"deluge": {
"download": "Download",
"download": "Letöltés",
"seed": "Seed",
"upload": "Upload",
"upload": "Feltöltés",
"leech": "Leech"
},
"flood": {
"download": "Download",
"upload": "Upload",
"download": "Letöltés",
"upload": "Feltöltés",
"leech": "Leech",
"seed": "Seed"
},
"tdarr": {
"queue": "Queue",
"processed": "Processed",
"errored": "Errored",
"saved": "Saved"
"queue": "Várólista",
"processed": "Feldolgozott",
"errored": "Hibás",
"saved": "Mentett"
},
"miniflux": {
"read": "Read",
"unread": "Unread"
"read": "Olvasott",
"unread": "Olvasatlan"
},
"nextdns": {
"wait": "Please Wait",
"no_devices": "No Device Data Received"
"wait": "Kérjük Várjon",
"no_devices": "Nincs fogadott eszközadat"
},
"common": {
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
},
"omada": {
"activeUser": "Active devices",
"alerts": "Alerts",
"connectedAp": "Connected APs",
"connectedGateway": "Connected gateways",
"connectedSwitches": "Connected switches"
"activeUser": "Aktív eszközök",
"alerts": "Riasztások",
"connectedAp": "Csatlakoztatott AP-k",
"connectedGateway": "Csatlakoztatott gateway-ek",
"connectedSwitches": "Csatlakoztatott switch-ek"
},
"downloadstation": {
"download": "Download",
"upload": "Upload",
"download": "Letöltés",
"upload": "Feltöltés",
"leech": "Leech",
"seed": "Seed"
},
"mikrotik": {
"cpuLoad": "CPU Load",
"memoryUsed": "Memory Used",
"uptime": "Uptime",
"numberOfLeases": "Leases"
"cpuLoad": "Processzor Terhelés",
"memoryUsed": "Felhasznált Memória",
"uptime": "Üzemidő",
"numberOfLeases": "Bérletek"
},
"xteve": {
"streams_all": "All Streams",
"streams_active": "Active Streams",
"streams_xepg": "XEPG Channels"
"streams_all": "Minden Stream",
"streams_active": "Aktív Stream-ek",
"streams_xepg": "XEPG Csatornák"
},
"opnsense": {
"cpu": "CPU Load",
"memory": "Active Memory",
"wanUpload": "WAN Upload",
"wanDownload": "WAN Download"
"cpu": "Processzor Terhelés",
"memory": "Aktív Memória",
"wanUpload": "WAN Feltöltés",
"wanDownload": "WAN Letöltés"
},
"moonraker": {
"layers": "Layers",
"printer_state": "Printer State",
"print_status": "Print Status",
"print_progress": "Progress"
"layers": "Rétegek",
"printer_state": "Nyomtató Állapota",
"print_status": "Nyomtatás Állapota",
"print_progress": "Folyamat"
},
"medusa": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series"
"wanted": "Keresett",
"queued": "Sorba állítva",
"series": "Sorozatok"
},
"octoprint": {
"printer_state": "Status",
"temp_tool": "Tool temp",
"temp_bed": "Bed temp",
"job_completion": "Completion"
"printer_state": "Állapot",
"temp_tool": "Szerszám hőmérséklet",
"temp_bed": "Ágy Hőmérséklet",
"job_completion": "Teljesítés"
},
"cloudflared": {
"origin_ip": "Origin IP",
"status": "Status"
"origin_ip": "Eredeti IP",
"status": "Állapot"
},
"proxmoxbackupserver": {
"datastore_usage": "Datastore",
"failed_tasks_24h": "Failed Tasks 24h",
"cpu_usage": "CPU",
"memory_usage": "Memory"
"datastore_usage": "Adattár",
"failed_tasks_24h": "Sikertelen feladatok 24h",
"cpu_usage": "Processzor",
"memory_usage": "Memória"
},
"immich": {
"users": "Users",
"photos": "Photos",
"videos": "Videos",
"storage": "Storage"
"users": "Felhasználók",
"photos": "Fényképek",
"videos": "Videók",
"storage": "Tárhely"
},
"uptimekuma": {
"up": "Sites Up",
"down": "Sites Down",
"uptime": "Uptime",
"incident": "Incident",
"m": "m"
"up": "Futó Webhelyek",
"down": "Nem Elérhető Webhelyek",
"uptime": "Üzemidő",
"incident": "Incidens",
"m": "perc"
},
"komga": {
"libraries": "Libraries",
"series": "Series",
"books": "Books"
"libraries": "Könyvtárak",
"series": "Sorozatok",
"books": "Könyvek"
},
"mylar": {
"series": "Series",
"issues": "Issues",
"wanted": "Wanted"
"series": "Sorozatok",
"issues": "Problémák",
"wanted": "Keresett"
},
"photoprism": {
"albums": "Albums",
"photos": "Photos",
"videos": "Videos",
"people": "People"
"albums": "Albumok",
"photos": "Fényképek",
"videos": "Videók",
"people": "Emberek"
},
"diskstation": {
"days": "Days",
"uptime": "Uptime",
"volumeAvailable": "Available"
"days": "Napok",
"uptime": "Üzemidő",
"volumeAvailable": "Elérhető"
},
"fileflows": {
"queue": "Queue",
"processing": "Processing",
"processed": "Processed",
"time": "Time"
"queue": "Várólista",
"processing": "Feldolgozás",
"processed": "Feldolgozott",
"time": "Idő"
},
"grafana": {
"dashboards": "Dashboards",
"datasources": "Data Sources",
"totalalerts": "Total Alerts",
"alertstriggered": "Alerts Triggered"
"dashboards": "Műszerfalak",
"datasources": "Adatforrások",
"totalalerts": "Összes Riasztás",
"alertstriggered": "Aktivált riasztások"
},
"nextcloud": {
"cpuload": "Cpu Load",
"memoryusage": "Memory Usage",
"freespace": "Free Space",
"activeusers": "Active Users",
"numfiles": "Files",
"numshares": "Shared Items"
"cpuload": "Processzor Terhelés",
"memoryusage": "Memória Használat",
"freespace": "Szabad hely",
"activeusers": "Aktív Felhasználók",
"numfiles": "Fájlok",
"numshares": "Megosztott Elemek"
},
"kopia": {
"status": "Status",
"size": "Size",
"lastrun": "Last Run",
"nextrun": "Next Run",
"failed": "Failed"
"status": "Állapot",
"size": "Méret",
"lastrun": "Legutóbbi futtatás",
"nextrun": "Következő Futtatás",
"failed": "Sikertelen"
},
"unmanic": {
"active_workers": "Active Workers",
"total_workers": "Total Workers",
"records_total": "Queue Length"
"active_workers": "Aktív Dolgozók",
"total_workers": "Összes Dolgozó",
"records_total": "Várólista Hossza"
},
"healthchecks": {
"new": "New",
"new": "Új",
"up": "Online",
"grace": "In Grace Period",
"grace": "Türelmi idő alatt",
"down": "Offline",
"paused": "Paused",
"status": "Status",
"last_ping": "Last Ping",
"never": "No pings yet"
"paused": "Szünetel",
"status": "Állapot",
"last_ping": "Legutóbbi Ping",
"never": "Még nincsenek ping-ek"
},
"pterodactyl": {
"servers": "Servers",
"nodes": "Nodes"
"servers": "Szerverek",
"nodes": "Node-ok"
},
"prometheus": {
"targets_up": "Targets Up",
"targets_down": "Targets Down",
"targets_total": "Total Targets"
"targets_up": "Célpontok Futnak",
"targets_down": "Célpontok Állnak",
"targets_total": "Összes Célpont"
},
"minecraft": {
"players": "Players",
"version": "Version",
"status": "Status",
"players": "Lejátszók",
"version": "Verzió",
"status": "Állapot",
"up": "Online",
"down": "Offline"
},
"ghostfolio": {
"gross_percent_today": "Today",
"gross_percent_1y": "One year",
"gross_percent_max": "All time"
"gross_percent_today": "Ma",
"gross_percent_1y": "Egy év",
"gross_percent_max": "Mindig"
},
"audiobookshelf": {
"podcasts": "Podcast",
@ -576,83 +577,105 @@
"booksDuration": "Időtartam"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
"people_home": "Emberek otthon",
"lights_on": "Fények bekapcsolva",
"switches_on": "Kapcsolók felkapcsolva"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
"subscriptions": "Előfizetések",
"unread": "Olvasatlan"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"passes": "Passes"
"shows": "Műsorok",
"recordings": "Felvételek",
"scheduled": "Ütemezett",
"passes": "Engedélyek"
},
"whatsupdocker": {
"monitoring": "Monitoring",
"updates": "Updates"
"monitoring": "Nyomonkövetés",
"updates": "Frissítések"
},
"tailscale": {
"address": "Address",
"expires": "Expires",
"never": "Never",
"last_seen": "Last Seen",
"now": "Now",
"address": "Cím",
"expires": "Lejár",
"never": "Soha",
"last_seen": "Utoljára látott",
"now": "Most",
"years": "{{number}}y",
"weeks": "{{number}}w",
"days": "{{number}}d",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "{{value}} Ago",
"ago": "{{value}} Ezelőtt",
"hours": "{{number}}h"
},
"qnap": {
"cpuUsage": "CPU Usage",
"memUsage": "MEM Usage",
"systemTempC": "System Temp",
"poolUsage": "Pool Usage",
"volumeUsage": "Volume Usage",
"invalid": "Invalid"
"cpuUsage": "Processzor Használat",
"memUsage": "Memória Használat",
"systemTempC": "Rendszerhőmérséklet",
"poolUsage": "Pool Használat",
"volumeUsage": "Kötet Használat",
"invalid": "Érvénytelen"
},
"pfsense": {
"load": "Load Avg",
"memory": "Mem Usage",
"wanStatus": "WAN Status",
"up": "Up",
"down": "Down",
"temp": "Temp",
"disk": "Disk Usage",
"load": "Átlagos terhelés",
"memory": "RAM Használat",
"wanStatus": "WAN Állapot",
"up": "Fut",
"down": "Áll",
"temp": "Hőmérséklet",
"disk": "Lemezhasználat",
"wanIP": "WAN IP"
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Current requests",
"requests_failed": "Failed requests"
"upstreams": "Upstreamek",
"requests": "Jelenlegi kérelmek",
"requests_failed": "Sikertelen kérelmek"
},
"evcc": {
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Grid",
"home_power": "Consumption",
"charge_power": "Charger",
"pv_power": "Termelés",
"battery_soc": "Akkumulátor",
"grid_power": "Rács",
"home_power": "Fogyasztás",
"charge_power": "Töltő",
"watt_hour": "Wh"
},
"pialert": {
"total": "Total",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
"total": "Összes",
"connected": "Csatlakoztatott",
"new_devices": "Új Eszközök",
"down_alerts": "Leállási Figyelmeztetések"
},
"jdownloader": {
"downloadSpeed": "Download Speed",
"downloadCount": "Queue Count",
"downloadTotalBytes": "Size",
"downloadBytesRemaining": "Remaining"
"downloadSpeed": "Sebesség",
"downloadCount": "Összes függőben lévő",
"downloadTotalBytes": "Méret",
"downloadBytesRemaining": "Fennmaradó"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"seriesCount": "Sorozatok",
"totalFiles": "Fájlok"
},
"gamedig": {
"ping": "Ping",
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots"
},
"azuredevops": {
"status": "Status",
"myPrs": "My PRs",
"approved": "Approved",
"result": "Result",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs"
}
}

View File

@ -494,9 +494,9 @@
},
"weather": {
"wait": "Harap tunggu",
"current": "Current Location",
"allow": "Click to allow",
"updating": "Updating"
"current": "Lokasi Saat Ini",
"allow": "Klik untuk mengizinkan",
"updating": "Memperbarui"
},
"search": {
"placeholder": "Telusuri…"
@ -590,11 +590,11 @@
"cpu": "CPU",
"mem": "MEM",
"total": "Total",
"free": "Free",
"used": "Used",
"free": "Luang",
"used": "Digunakan",
"load": "Load",
"temp": "TEMP",
"max": "Max",
"max": "Maks",
"uptime": "UP",
"months": "mo",
"hours": "h",
@ -643,7 +643,8 @@
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"jdownloader": {
"downloadCount": "Queue Count",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -29,7 +29,8 @@
"playing": "In riproduzione",
"transcoding": "Transcodifica",
"bitrate": "Bitrate",
"no_active": "Nessuno Stream Attivo"
"no_active": "Nessuno Stream Attivo",
"plex_connection_error": "Check Plex Connection"
},
"speedtest": {
"upload": "Upload",
@ -112,7 +113,7 @@
"queries": "Richieste",
"blocked": "Bloccati",
"gravity": "Severità",
"blocked_percent": "Blocked %"
"blocked_percent": "Bloccato %"
},
"npm": {
"enabled": "Attivi",
@ -175,7 +176,7 @@
"missingMovies": "Film Mancanti"
},
"lidarr": {
"wanted": "Mancanti",
"wanted": "Richiesto",
"queued": "In coda",
"artists": "Artisti"
},
@ -243,11 +244,11 @@
"uptime": "UP",
"days": "d",
"hours": "h",
"load": "Load",
"warn": "Warn",
"total": "Total",
"free": "Free",
"used": "Used"
"load": "Carico",
"warn": "Avviso",
"total": "Totale",
"free": "Libero",
"used": "Usato"
},
"changedetectionio": {
"totalObserved": "Totale Osservato",
@ -314,9 +315,9 @@
"quicklaunch": {
"bookmark": "Segnalibro",
"service": "Servizio",
"search": "Search",
"custom": "Custom",
"visit": "Visit",
"search": "Cerca",
"custom": "Personalizzato",
"visit": "Visita",
"url": "URL"
},
"homebridge": {
@ -327,7 +328,7 @@
"child_bridges": "Child Bridges",
"child_bridges_status": "{{ok}}/{{total}}",
"up": "Up",
"pending": "Pending",
"pending": "In attesa",
"down": "Down"
},
"autobrr": {
@ -432,7 +433,7 @@
"cpuLoad": "Carico della CPU",
"memoryUsed": "Memoria Utilizzata",
"uptime": "Tempo di attività",
"numberOfLeases": "Lease"
"numberOfLeases": "Rilasci"
},
"xteve": {
"streams_all": "Tutti gli stream",
@ -440,145 +441,145 @@
"streams_xepg": "Canali XEPG"
},
"opnsense": {
"cpu": "Carico CPU",
"cpu": "Carico della CPU",
"memory": "Memoria in uso",
"wanUpload": "WAN Upload",
"wanDownload": "WAN Download"
},
"moonraker": {
"printer_state": "Printer State",
"print_status": "Print Status",
"print_progress": "Progress",
"layers": "Layers"
"printer_state": "Stato stampante",
"print_status": "Stato Stampante",
"print_progress": "Avanzamento",
"layers": "Livelli"
},
"medusa": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series"
"wanted": "Richiesto",
"queued": "In coda",
"series": "Serie"
},
"octoprint": {
"printer_state": "Status",
"printer_state": "Stato",
"temp_tool": "Tool temp",
"temp_bed": "Bed temp",
"job_completion": "Completion"
"job_completion": "Completamento"
},
"cloudflared": {
"origin_ip": "Origin IP",
"status": "Status"
"origin_ip": "IP sorgente",
"status": "Stato"
},
"proxmoxbackupserver": {
"datastore_usage": "Datastore",
"failed_tasks_24h": "Failed Tasks 24h",
"failed_tasks_24h": "Attività Non Riuscite 24h",
"cpu_usage": "CPU",
"memory_usage": "Memory"
"memory_usage": "Memoria"
},
"immich": {
"users": "Users",
"photos": "Photos",
"videos": "Videos",
"storage": "Storage"
"users": "Utenti",
"photos": "Foto",
"videos": "Video",
"storage": "Memoria"
},
"uptimekuma": {
"up": "Sites Up",
"down": "Sites Down",
"up": "Siti On",
"down": "Siti Down",
"uptime": "Uptime",
"incident": "Incident",
"incident": "Incidente",
"m": "m"
},
"komga": {
"libraries": "Libraries",
"series": "Series",
"books": "Books"
"libraries": "Librerie",
"series": "Serie",
"books": "Libri"
},
"mylar": {
"series": "Series",
"issues": "Issues",
"wanted": "Wanted"
"series": "Serie",
"issues": "Problemi",
"wanted": "Richiesto"
},
"photoprism": {
"albums": "Albums",
"photos": "Photos",
"videos": "Videos",
"people": "People"
"albums": "Album",
"photos": "Foto",
"videos": "Video",
"people": "Persone"
},
"diskstation": {
"days": "Days",
"days": "Giorni",
"uptime": "Uptime",
"volumeAvailable": "Available"
"volumeAvailable": "Disponibile"
},
"fileflows": {
"queue": "Queue",
"processing": "Processing",
"processed": "Processed",
"time": "Time"
"queue": "Coda",
"processing": "In Lavorazione",
"processed": "Elaborato",
"time": "Tempo"
},
"grafana": {
"dashboards": "Dashboards",
"datasources": "Data Sources",
"totalalerts": "Total Alerts",
"alertstriggered": "Alerts Triggered"
"datasources": "Origine dei Dati",
"totalalerts": "Avvisi Totali",
"alertstriggered": "Avvisi Attivati"
},
"nextcloud": {
"memoryusage": "Memory Usage",
"cpuload": "Cpu Load",
"freespace": "Free Space",
"activeusers": "Active Users",
"numfiles": "Files",
"numshares": "Shared Items"
"memoryusage": "Uso della Memoria",
"cpuload": "Carico della CPU",
"freespace": "Spazio Libero",
"activeusers": "Utenti Attivi",
"numfiles": "File",
"numshares": "Oggetti Condivisi"
},
"kopia": {
"status": "Status",
"size": "Size",
"lastrun": "Last Run",
"nextrun": "Next Run",
"failed": "Failed"
"status": "Stato",
"size": "Dimensione",
"lastrun": "Ultima esecuzione",
"nextrun": "Prossima esecuzione",
"failed": "Fallito"
},
"unmanic": {
"active_workers": "Active Workers",
"total_workers": "Total Workers",
"records_total": "Queue Length"
"active_workers": "Lavoratori Attivi",
"total_workers": "Lavoratori Totali",
"records_total": "Lunghezza della Coda"
},
"healthchecks": {
"new": "New",
"new": "Nuovo",
"up": "Online",
"grace": "In Grace Period",
"grace": "Periodo di Tolleranza",
"down": "Offline",
"paused": "Paused",
"status": "Status",
"last_ping": "Last Ping",
"never": "No pings yet"
"paused": "In Pausa",
"status": "Stato",
"last_ping": "Ultimo Ping",
"never": "Ancora nessun ping"
},
"pterodactyl": {
"servers": "Servers",
"nodes": "Nodes"
"servers": "Server",
"nodes": "Nodi"
},
"prometheus": {
"targets_up": "Targets Up",
"targets_down": "Targets Down",
"targets_total": "Total Targets"
"targets_total": "Targets Totali"
},
"minecraft": {
"players": "Players",
"version": "Version",
"status": "Status",
"players": "Giocatori",
"version": "Versione",
"status": "Stato",
"up": "Online",
"down": "Offline"
},
"ghostfolio": {
"gross_percent_today": "Today",
"gross_percent_1y": "One year",
"gross_percent_max": "All time"
"gross_percent_today": "Oggi",
"gross_percent_1y": "Un anno",
"gross_percent_max": "Sempre"
},
"audiobookshelf": {
"podcasts": "Podcasts",
"books": "Books",
"podcastsDuration": "Duration",
"booksDuration": "Duration"
"podcasts": "Podcast",
"books": "Libri",
"podcastsDuration": "Durata",
"booksDuration": "Durata"
},
"homeassistant": {
"people_home": "People Home",
"lights_on": "Lights On",
"switches_on": "Switches On"
"people_home": "Persone a Casa",
"lights_on": "Luci Accese",
"switches_on": "Switch Accesi"
},
"freshrss": {
"subscriptions": "Iscrizioni",
@ -591,21 +592,21 @@
"passes": "Tessere"
},
"whatsupdocker": {
"monitoring": "Monitoring",
"updates": "Updates"
"monitoring": "Monitoraggio",
"updates": "Aggiornamenti"
},
"tailscale": {
"never": "Never",
"address": "Address",
"expires": "Expires",
"last_seen": "Last Seen",
"now": "Now",
"never": "Mai",
"address": "Indirizzo",
"expires": "Scade",
"last_seen": "Ultima visualizzazione",
"now": "Adesso",
"years": "{{number}}y",
"weeks": "{{number}}w",
"hours": "{{number}}h",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "{{value}} Ago",
"ago": "{{value}} Fa",
"days": "{{number}}d"
},
"qnap": {
@ -617,14 +618,14 @@
"invalid": "Invalido"
},
"pfsense": {
"load": "Load Avg",
"memory": "Mem Usage",
"wanStatus": "WAN Status",
"load": "Carico Medio",
"memory": "Uso Memoria",
"wanStatus": "Stato WAN",
"up": "Up",
"down": "Down",
"temp": "Temp",
"disk": "Disk Usage",
"wanIP": "WAN IP"
"temp": "Temperatura",
"disk": "Uso Disco",
"wanIP": "IP WAN"
},
"caddy": {
"upstreams": "Upstream",
@ -641,18 +642,40 @@
},
"pialert": {
"total": "Totali",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
"connected": "Connesso",
"new_devices": "Nuovi Dispositivi",
"down_alerts": "Avvisi di Disservizio"
},
"jdownloader": {
"downloadCount": "Queue Count",
"downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size"
"downloadCount": "Coda",
"downloadSpeed": "Velocità Download",
"downloadBytesRemaining": "Residuo",
"downloadTotalBytes": "Dimensione"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"seriesCount": "Serie",
"totalFiles": "File"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"myPrs": "My PRs",
"approved": "Approved",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs"
}
}

View File

@ -136,7 +136,8 @@
"playing": "再生中",
"transcoding": "変換中",
"bitrate": "ビットレート",
"no_active": "アクティブストリームなし"
"no_active": "アクティブストリームなし",
"plex_connection_error": "Check Plex Connection"
},
"omada": {
"connectedAp": "接続されたAP",
@ -239,7 +240,7 @@
"queries": "クエリ",
"blocked": "ブロック中",
"gravity": "グラビティ",
"blocked_percent": "Blocked %"
"blocked_percent": "ブロック %"
},
"adguard": {
"queries": "クエリ",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -111,7 +111,8 @@
"playing": "재생 중",
"transcoding": "트랜스코딩",
"bitrate": "비트레이트",
"no_active": "활성 스트림 없음"
"no_active": "활성 스트림 없음",
"plex_connection_error": "Check Plex Connection"
},
"omada": {
"connectedAp": "연결된 AP",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"ping": "Ping",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -97,7 +97,8 @@
"playing": "Atskaņo",
"transcoding": "Pārkodē",
"bitrate": "Bitrate",
"no_active": "Nav aktīvu straumju"
"no_active": "Nav aktīvu straumju",
"plex_connection_error": "Check Plex Connection"
},
"omada": {
"connectedAp": "Savienotie piekļuves punkti",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed"
}
}

View File

@ -200,7 +200,8 @@
"playing": "Sedang Dimainkan",
"transcoding": "Transkoding",
"bitrate": "Kadar bit",
"no_active": "Tiada Strim Aktif"
"no_active": "Tiada Strim Aktif",
"plex_connection_error": "Check Plex Connection"
},
"plex": {
"streams": "Strim Aktif",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -56,7 +56,8 @@
"playing": "Spiller",
"transcoding": "Transkoding",
"bitrate": "Bitrate",
"no_active": "Ingen aktive strømmer"
"no_active": "Ingen aktive strømmer",
"plex_connection_error": "Check Plex Connection"
},
"rutorrent": {
"active": "Aktiv",
@ -653,6 +654,28 @@
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"totalFiles": "Filer"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -72,7 +72,8 @@
"playing": "Afspelen",
"transcoding": "Transcodering",
"bitrate": "Bitsnelheid",
"no_active": "Geen Actieve Streams"
"no_active": "Geen Actieve Streams",
"plex_connection_error": "Check Plex Connection"
},
"rutorrent": {
"active": "Actief",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -37,7 +37,8 @@
"playing": "Odtwarzanie",
"transcoding": "Transkodowanie",
"bitrate": "Bitrate",
"no_active": "Brak aktywnych strumieni"
"no_active": "Brak aktywnych strumieni",
"plex_connection_error": "Check Plex Connection"
},
"speedtest": {
"download": "Pobieranie",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"myPrs": "My PRs",
"approved": "Approved",
"result": "Result",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs"
}
}

View File

@ -90,7 +90,8 @@
"playing": "Reproduzindo",
"transcoding": "Transcodificando",
"bitrate": "Taxa de bits",
"no_active": "Sem transmissões ativas"
"no_active": "Sem transmissões ativas",
"plex_connection_error": "Verifique a conexão do Plex"
},
"nzbget": {
"rate": "Taxa",
@ -113,21 +114,21 @@
"wanted": "Desejado",
"queued": "Na fila",
"series": "Séries",
"queue": "Queue",
"unknown": "Unknown"
"queue": "Fila",
"unknown": "Desconhecido"
},
"radarr": {
"wanted": "Desejado",
"queued": "Na fila",
"movies": "Filmes",
"missing": "Faltando",
"queue": "Queue",
"unknown": "Unknown"
"queue": "Fila",
"unknown": "Desconhecido"
},
"lidarr": {
"wanted": "Desejado",
"queued": "Na fila",
"artists": "Artists"
"artists": "Artistas"
},
"readarr": {
"wanted": "Desejado",
@ -158,7 +159,7 @@
"queries": "Consultas",
"blocked": "Bloqueados",
"gravity": "Gravidade",
"blocked_percent": "Blocked %"
"blocked_percent": "Bloqueado %"
},
"adguard": {
"queries": "Consultas",
@ -243,11 +244,11 @@
"uptime": "LIGADO",
"days": "d",
"hours": "h",
"load": "Load",
"warn": "Warn",
"load": "Carga",
"warn": "Aviso",
"total": "Total",
"free": "Free",
"used": "Used"
"free": "Livre",
"used": "Usado"
},
"changedetectionio": {
"totalObserved": "Observados",
@ -523,8 +524,8 @@
"memoryusage": "Memória Utilizada",
"freespace": "Espaço Livre",
"activeusers": "Usuários Ativos",
"numfiles": "Files",
"numshares": "Shared Items"
"numfiles": "Arquivos",
"numshares": "Itens Compartilhados"
},
"kopia": {
"status": "Status",
@ -581,78 +582,100 @@
"switches_on": "Interruptores Ligados"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
"subscriptions": "Assinaturas",
"unread": "Não lida"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"recordings": "Gravações",
"scheduled": "Agendado",
"passes": "Passes"
},
"whatsupdocker": {
"monitoring": "Monitoring",
"updates": "Updates"
"monitoring": "Monitorando",
"updates": "Atualizações"
},
"tailscale": {
"address": "Address",
"expires": "Expires",
"never": "Never",
"last_seen": "Last Seen",
"now": "Now",
"years": "{{number}}y",
"weeks": "{{number}}w",
"address": "Endereço",
"expires": "Expira",
"never": "Nunca",
"last_seen": "Visto pela última vez",
"now": "Agora",
"years": "{{number}}a",
"weeks": "{{number}}s",
"hours": "{{number}}h",
"days": "{{number}}d",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "{{value}} Ago"
"ago": "{{value}} Atrás"
},
"qnap": {
"systemTempC": "System Temp",
"cpuUsage": "CPU Usage",
"memUsage": "MEM Usage",
"systemTempC": "Temp Sistema",
"cpuUsage": "Uso CPU",
"memUsage": "Uso MEM",
"poolUsage": "Pool Usage",
"volumeUsage": "Volume Usage",
"invalid": "Invalid"
"volumeUsage": "Uso Volume",
"invalid": "Invalido"
},
"pfsense": {
"load": "Load Avg",
"memory": "Mem Usage",
"load": "Média de carga",
"memory": "Uso Mem",
"wanStatus": "WAN Status",
"up": "Up",
"down": "Down",
"temp": "Temp",
"disk": "Disk Usage",
"disk": "Uso de disco",
"wanIP": "WAN IP"
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Current requests",
"requests_failed": "Failed requests"
"requests": "Solicitações atuais",
"requests_failed": "Solicitações com falha"
},
"evcc": {
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Grid",
"home_power": "Consumption",
"charge_power": "Charger",
"pv_power": "Produção",
"battery_soc": "Bateria",
"grid_power": "Grade",
"home_power": "Consumo",
"charge_power": "Carregador",
"watt_hour": "Wh"
},
"pialert": {
"total": "Total",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
"connected": "Conectado",
"new_devices": "Novos dispositivos",
"down_alerts": "Alertas de Quedas"
},
"jdownloader": {
"downloadCount": "Queue Count",
"downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size"
"downloadCount": "Fila",
"downloadSpeed": "Velocidade de download",
"downloadBytesRemaining": "Restante",
"downloadTotalBytes": "Tamanho"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"totalFiles": "Arquivos"
},
"gamedig": {
"name": "Nome",
"map": "Mapa",
"currentPlayers": "Jogadores atuais",
"players": "Jogadores",
"maxPlayers": "Jogadores Max",
"bots": "Robos",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -56,7 +56,8 @@
"playing": "Reproduzindo",
"transcoding": "Transcodificação",
"bitrate": "Taxa de bits",
"no_active": "Sem streams ativas"
"no_active": "Sem streams ativas",
"plex_connection_error": "Check Plex Connection"
},
"rutorrent": {
"active": "Ativo",
@ -663,5 +664,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"approved": "Approved",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs"
}
}

View File

@ -92,7 +92,8 @@
"no_active": "Niciun stream activ",
"playing": "Activ",
"transcoding": "Transcodare",
"bitrate": "Bitrate"
"bitrate": "Bitrate",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Rată",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved",
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed"
}
}

View File

@ -56,7 +56,8 @@
"playing": "Воспроизведение",
"transcoding": "Транскодирование",
"bitrate": "Битрейт",
"no_active": "Нет активных трансляций"
"no_active": "Нет активных трансляций",
"plex_connection_error": "Проверьте соединение с Plex"
},
"rutorrent": {
"active": "Активный",
@ -64,22 +65,22 @@
"download": "Загрузка"
},
"sonarr": {
"wanted": "Хотел",
"wanted": "Желаемое",
"queued": "В очереди",
"series": "Серии",
"queue": "Queue",
"queue": "Очередь",
"unknown": "Unknown"
},
"radarr": {
"wanted": "Хотел",
"wanted": "Желаемое",
"queued": "В очереди",
"movies": "Фильмы",
"missing": "Пропущено",
"queue": "Queue",
"queue": "Очередь",
"unknown": "Unknown"
},
"readarr": {
"wanted": "Хотел",
"wanted": "Желаемое",
"queued": "В очереди",
"books": "Книги"
},
@ -175,9 +176,9 @@
"missingMovies": "Отсутствующие фильмы"
},
"lidarr": {
"wanted": "Хотел",
"wanted": "Желаемое",
"queued": "В очереди",
"artists": "Artists"
"artists": "Артисты"
},
"adguard": {
"queries": "Запросы",
@ -612,8 +613,8 @@
"cpuUsage": "CPU Usage",
"memUsage": "MEM Usage",
"systemTempC": "System Temp",
"poolUsage": "Pool Usage",
"volumeUsage": "Volume Usage",
"poolUsage": "Использование пула",
"volumeUsage": "Использование тома",
"invalid": "Invalid"
},
"pfsense": {
@ -627,23 +628,23 @@
"temp": "Temp"
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Current requests",
"requests_failed": "Failed requests"
"upstreams": "Апстримы",
"requests": "Текущие запросы",
"requests_failed": "Неудачные запросы"
},
"evcc": {
"home_power": "Consumption",
"home_power": "Потребление",
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Grid",
"charge_power": "Charger",
"charge_power": "Зарядка",
"watt_hour": "Wh"
},
"pialert": {
"total": "Total",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
"new_devices": "Новые устройства",
"down_alerts": "Оповещения о сбоях"
},
"jdownloader": {
"downloadCount": "Queue Count",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -221,7 +221,8 @@
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"omada": {
"connectedAp": "Connected APs",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"succeeded": "Succeeded",
"notStarted": "Not Started",
"inProgress": "In Progress",
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"failed": "Failed",
"canceled": "Canceled",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -168,7 +168,8 @@
"transcoding": "Transkodira",
"bitrate": "Pasovna širina",
"playing": "Predvaja",
"no_active": "Ni aktivne vsebine"
"no_active": "Ni aktivne vsebine",
"plex_connection_error": "Check Plex Connection"
},
"flood": {
"download": "Prenos",
@ -236,21 +237,21 @@
"wanted": "Iskano",
"queued": "V vrsti",
"series": "Serije",
"queue": "Queue",
"unknown": "Unknown"
"queue": "Vrsta",
"unknown": "Neznano"
},
"radarr": {
"wanted": "Iskano",
"missing": "Manjka",
"queued": "V vrsti",
"movies": "Filmi",
"queue": "Queue",
"unknown": "Unknown"
"queue": "Vrsta",
"unknown": "Neznano"
},
"lidarr": {
"wanted": "Iskano",
"queued": "V vrsti",
"artists": "Artists"
"artists": "Avtorji"
},
"readarr": {
"wanted": "Iskano",
@ -359,11 +360,11 @@
"uptime": "UP",
"days": "d",
"hours": "u",
"free": "Free",
"load": "Load",
"warn": "Warn",
"total": "Total",
"used": "Used"
"free": "Prosto",
"load": "Obremenitev",
"warn": "Opoz.",
"total": "Skupaj",
"used": "V uporabi"
},
"authentik": {
"users": "Uporabniki",
@ -613,8 +614,8 @@
"memUsage": "MEM",
"systemTempC": "Temperatura",
"poolUsage": "Prostor",
"volumeUsage": "Volume Usage",
"invalid": "Invalid"
"volumeUsage": "Prostora",
"invalid": "Neveljavno"
},
"pfsense": {
"load": "Povp. obremenitev",
@ -640,19 +641,41 @@
"watt_hour": "Wh"
},
"pialert": {
"total": "Total",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
"total": "Skupaj",
"connected": "Povezanih",
"new_devices": "Nove naprave",
"down_alerts": "Izključeno"
},
"jdownloader": {
"downloadCount": "Queue Count",
"downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size"
"downloadCount": "Vrsta",
"downloadSpeed": "Hitrost prenosa",
"downloadBytesRemaining": "Še ostane",
"downloadTotalBytes": "Velikost"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"seriesCount": "Serije",
"totalFiles": "Datoteke"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -79,7 +79,8 @@
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Rate",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -62,7 +62,8 @@
"playing": "Spelar",
"transcoding": "Omkodning",
"bitrate": "Bitrate",
"no_active": "Inga aktiva strömmar"
"no_active": "Inga aktiva strömmar",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Hastighet",
@ -654,5 +655,27 @@
"kavita": {
"totalFiles": "Files",
"seriesCount": "Series"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"approved": "Approved",
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs"
}
}

View File

@ -79,7 +79,8 @@
"playing": "ఆడుతున్నారు",
"transcoding": "ట్రాన్స్‌కోడింగ్",
"bitrate": "బిట్రేట్",
"no_active": "యాక్టివ్ స్ట్రీమ్‌లు లేవు"
"no_active": "యాక్టివ్ స్ట్రీమ్‌లు లేవు",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "రేట్",
@ -654,5 +655,27 @@
"kavita": {
"totalFiles": "Files",
"seriesCount": "Series"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"myPrs": "My PRs",
"approved": "Approved",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs"
}
}

View File

@ -139,7 +139,8 @@
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"omada": {
"connectedAp": "Connected APs",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -79,7 +79,8 @@
"playing": "Oynatılıyor",
"transcoding": "Dönüştürülüyor",
"bitrate": "Bit Oranı",
"no_active": "Aktif akış yok"
"no_active": "Aktif akış yok",
"plex_connection_error": "Check Plex Connection"
},
"nzbget": {
"rate": "Oran",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed"
}
}

View File

@ -198,7 +198,8 @@
"playing": "Відтворення",
"transcoding": "Перекодування",
"bitrate": "Бітрейт",
"no_active": "Немає активних потоків"
"no_active": "Немає активних потоків",
"plex_connection_error": "Перевірте з'єднання Plex"
},
"nzbget": {
"rate": "Швидкість",
@ -652,7 +653,29 @@
"downloadTotalBytes": "Розмір"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
"seriesCount": "Серій",
"totalFiles": "Файлів"
},
"gamedig": {
"name": "Назва",
"map": "Мапа",
"currentPlayers": "Поточні гравці",
"players": "Гравці",
"maxPlayers": "Максимум гравців",
"bots": "Ботів",
"ping": "Пінг"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -56,7 +56,8 @@
"playing": "Đang chơi",
"transcoding": "Chuyển định dạng",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
"no_active": "No Active Streams",
"plex_connection_error": "Check Plex Connection"
},
"rutorrent": {
"active": "Hoạt động",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -13,7 +13,8 @@
"playing": "播放緊",
"no_active": "無任何活動",
"transcoding": "轉碼緊",
"bitrate": "比特率"
"bitrate": "比特率",
"plex_connection_error": "Check Plex Connection"
},
"transmission": {
"download": "下載速度",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -56,7 +56,8 @@
"playing": "播放中",
"transcoding": "转码",
"bitrate": "比特率",
"no_active": "暂无播放"
"no_active": "暂无播放",
"plex_connection_error": "Check Plex Connection"
},
"rutorrent": {
"active": "活动中",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"canceled": "Canceled",
"inProgress": "In Progress",
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -44,7 +44,8 @@
"playing": "正在播放",
"transcoding": "轉碼",
"bitrate": "位元率",
"no_active": "無播放活動"
"no_active": "無播放活動",
"plex_connection_error": "Check Plex Connection"
},
"jellyseerr": {
"pending": "待下載",
@ -654,5 +655,27 @@
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping"
},
"azuredevops": {
"result": "Result",
"status": "Status",
"buildId": "Build ID",
"succeeded": "Succeeded",
"notStarted": "Not Started",
"failed": "Failed",
"canceled": "Canceled",
"inProgress": "In Progress",
"totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Approved"
}
}

View File

@ -1,3 +1,4 @@
import { useRef } from "react";
import classNames from "classnames";
import { Disclosure, Transition } from '@headlessui/react';
import { MdKeyboardArrowDown } from "react-icons/md";
@ -6,6 +7,7 @@ import ErrorBoundary from "components/errorboundry";
import List from "components/bookmarks/list";
export default function BookmarksGroup({ group, disableCollapse }) {
const panel = useRef();
return (
<div key={group.name} className="flex-1">
<Disclosure defaultOpen>
@ -15,19 +17,24 @@ export default function BookmarksGroup({ group, disableCollapse }) {
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{group.name}</h2>
<MdKeyboardArrowDown className={classNames(
disableCollapse ? 'hidden' : '',
'transition-opacity opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl',
open ? 'rotate-180 transform' : ''
'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl',
open ? '' : 'rotate-90'
)} />
</Disclosure.Button>
<Transition
enter="transition duration-200 ease-out"
enterFrom="transform scale-75 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-75 opacity-0"
// Otherwise the transition group does display: none and cancels animation
className="!block"
unmount={false}
beforeLeave={() => {
panel.current.style.height = `${panel.current.scrollHeight}px`;
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>
<Disclosure.Panel className="transition-all overflow-hidden duration-300 ease-out" ref={panel} static>
<ErrorBoundary>
<List bookmarks={group.bookmarks} />
</ErrorBoundary>

View File

@ -33,11 +33,22 @@ export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "log
}
// check mdi- or si- prefixed icons
const prefix = icon.split("-")[0]
const prefix = icon.split("-")[0];
if (prefix in iconSetURLs) {
// get icon source
const iconName = icon.replace(`${prefix}-`, "").replace(".svg", "");
// default to theme setting
let iconName = icon.replace(`${prefix}-`, "").replace(".svg", "");
let iconColor = settings.iconStyle === "theme" ?
`rgb(var(--color-${ theme === "dark" ? 300 : 900 }) / var(--tw-text-opacity, 1))` :
"linear-gradient(180deg, rgb(var(--color-logo-start)), rgb(var(--color-logo-stop)))";
// use custom hex color if provided
const colorMatches = icon.match(/[#][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]$/i)
if (colorMatches?.length) {
iconName = icon.replace(`${prefix}-`, "").replace(".svg", "").replace(`-${colorMatches[0]}`, "");
iconColor = `${colorMatches[0]}`;
}
const iconSource = `${iconSetURLs[prefix]}${iconName}.svg`;
return (
@ -47,16 +58,13 @@ export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "log
height,
maxWidth: '100%',
maxHeight: '100%',
background: settings.iconStyle === "theme" ?
`rgb(var(--color-${ theme === "dark" ? 300 : 900 }) / var(--tw-text-opacity, 1))` :
"linear-gradient(180deg, rgb(var(--color-logo-start)), rgb(var(--color-logo-stop)))",
background: `${iconColor}`,
mask: `url(${iconSource}) no-repeat center / contain`,
WebkitMask: `url(${iconSource}) no-repeat center / contain`,
}}
/>
);
}
// fallback to dashboard-icons
if (icon.endsWith(".svg")) {

View File

@ -1,3 +1,4 @@
import { useRef } from "react";
import classNames from "classnames";
import { Disclosure, Transition } from '@headlessui/react';
import { MdKeyboardArrowDown } from "react-icons/md";
@ -7,6 +8,8 @@ import ResolvedIcon from "components/resolvedicon";
export default function ServicesGroup({ group, services, layout, fiveColumns, disableCollapse }) {
const panel = useRef();
return (
<div
key={services.name}
@ -28,19 +31,24 @@ export default function ServicesGroup({ group, services, layout, fiveColumns, di
<h2 className="flex text-theme-800 dark:text-theme-300 text-xl font-medium">{services.name}</h2>
<MdKeyboardArrowDown className={classNames(
disableCollapse ? 'hidden' : '',
'transition-opacity opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl',
open ? 'rotate-180 transform' : ''
'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl',
open ? '' : 'rotate-90'
)} />
</Disclosure.Button>
<Transition
enter="transition duration-200 ease-out"
enterFrom="transform scale-75 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-75 opacity-0"
// Otherwise the transition group does display: none and cancels animation
className="!block"
unmount={false}
beforeLeave={() => {
panel.current.style.height = `${panel.current.scrollHeight}px`;
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>
<Disclosure.Panel className="transition-all overflow-hidden duration-300 ease-out" ref={panel} static>
<List group={group} services={services.services} layout={layout} />
</Disclosure.Panel>
</Transition>

View File

@ -18,7 +18,8 @@ export default function Container({ error = false, children, service }) {
const childrenArray = Array.isArray(children) ? children : [children];
let visibleChildren = childrenArray;
const fields = service?.widget?.fields;
let fields = service?.widget?.fields;
if (typeof service.widget.fields === 'string') fields = JSON.parse(service.widget.fields);
const type = service?.widget?.type;
if (fields && type) {
// if the field contains a "." then it most likely contains a common loc value

View File

@ -37,7 +37,7 @@ export default function Widget({ options }) {
<Resource icon={FaMemory} label={t("glances.wait")} percentage="0" />
{ options.cputemp && <Resource icon={FaThermometerHalf} label={t("glances.wait")} percentage="0" /> }
{ options.disk && !Array.isArray(options.disk) && <Resource key={options.disk} icon={FiHardDrive} label={t("glances.wait")} percentage="0" /> }
{ options.disk && Array.isArray(options.disk) && options.disk.map((disk) => <Resource key={disk.mnt_point} icon={FiHardDrive} label={t("glances.wait")} percentage="0" /> )}
{ options.disk && Array.isArray(options.disk) && options.disk.map((disk) => <Resource key={`disk_${disk.mnt_point}`} icon={FiHardDrive} label={t("glances.wait")} percentage="0" /> ) }
{ options.uptime && <Resource icon={FaRegClock} label={t("glances.wait")} percentage="0" /> }
{ options.label && <WidgetLabel label={options.label} /> }
</Resources>;
@ -50,7 +50,7 @@ export default function Widget({ options }) {
if (options.cputemp && cpuSensors) {
try {
mainTemp = cpuSensors.reduce((acc, s) => acc + s.value, 0) / cpuSensors.length;
maxTemp = Math.max(cpuSensors.reduce((acc, s) => acc + s.warning, 0) / cpuSensors.length, maxTemp);
maxTemp = Math.max(cpuSensors.reduce((acc, s) => acc + (s.warning > 0 ? s.warning : 0), 0) / cpuSensors.length, maxTemp);
if (unit === "fahrenheit") {
mainTemp = convertToFahrenheit(mainTemp);
maxTemp = convertToFahrenheit(maxTemp);
@ -108,7 +108,7 @@ export default function Widget({ options }) {
expanded={options.expanded}
/>
{disks.map((disk) => (
<Resource key={disk.mnt_point}
<Resource key={`disk_${disk.mnt_point}`}
icon={FiHardDrive}
value={t("common.bytes", { value: disk.free })}
label={t("glances.free")}

View File

@ -8,58 +8,62 @@ export default function Logo({ options }) {
<Container options={options}>
<Raw>
{options.icon ?
<ResolvedIcon icon={options.icon} width={48} height={48} /> :
<div className="mr-3">
<ResolvedIcon icon={options.icon} width={48} height={48} />
</div> :
// fallback to homepage logo
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
style={{
enableBackground: "new 0 0 1024 1024",
}}
xmlSpace="preserve"
className="w-full h-full"
>
<style>
{
".st0{display:none}.st3{stroke-linecap:square}.st3,.st4{fill:none;stroke:#fff;stroke-miterlimit:10}.st6{display:inline;fill:#333}.st7{fill:#fff}"
}
</style>
<g id="Icon">
<path
d="M771.9 191c27.7 0 50.1 26.5 50.1 59.3v186.4l-100.2.3V250.3c0-32.8 22.4-59.3 50.1-59.3z"
style={{
fill: "rgba(var(--color-logo-start))",
}}
/>
<linearGradient
id="homepage_logo_gradient"
gradientUnits="userSpaceOnUse"
x1={200.746}
y1={225.015}
x2={764.986}
y2={789.255}
>
<stop
offset={0}
<div className="w-12 h-12">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
style={{
enableBackground: "new 0 0 1024 1024",
}}
xmlSpace="preserve"
className="w-full h-full"
>
<style>
{
".st0{display:none}.st3{stroke-linecap:square}.st3,.st4{fill:none;stroke:#fff;stroke-miterlimit:10}.st6{display:inline;fill:#333}.st7{fill:#fff}"
}
</style>
<g id="Icon">
<path
d="M771.9 191c27.7 0 50.1 26.5 50.1 59.3v186.4l-100.2.3V250.3c0-32.8 22.4-59.3 50.1-59.3z"
style={{
stopColor: "rgba(var(--color-logo-start))",
fill: "rgba(var(--color-logo-start))",
}}
/>
<stop
offset={1}
<linearGradient
id="homepage_logo_gradient"
gradientUnits="userSpaceOnUse"
x1={200.746}
y1={225.015}
x2={764.986}
y2={789.255}
>
<stop
offset={0}
style={{
stopColor: "rgba(var(--color-logo-start))",
}}
/>
<stop
offset={1}
style={{
stopColor: "rgba(var(--color-logo-stop))",
}}
/>
</linearGradient>
<path
d="M721.8 250.3c0-32.7 22.4-59.3 50.1-59.3H253.1c-27.7 0-50.1 26.5-50.1 59.3v582.2l90.2-75.7-.1-130.3H375v61.8l88-73.8 258.8 217.9V250.6"
style={{
stopColor: "rgba(var(--color-logo-stop))",
fill: "url(#homepage_logo_gradient)",
}}
/>
</linearGradient>
<path
d="M721.8 250.3c0-32.7 22.4-59.3 50.1-59.3H253.1c-27.7 0-50.1 26.5-50.1 59.3v582.2l90.2-75.7-.1-130.3H375v61.8l88-73.8 258.8 217.9V250.6"
style={{
fill: "url(#homepage_logo_gradient)",
}}
/>
</g>
</svg>
</g>
</svg>
</div>
}
</Raw>
</Container>

View File

@ -1,7 +0,0 @@
import mapIcon from "utils/weather/openmeteo-condition-map";
export default function Icon({ condition, timeOfDay }) {
const IconComponent = mapIcon(condition, timeOfDay);
return <IconComponent className="w-10 h-10 text-theme-800 dark:text-theme-200" />;
}

View File

@ -10,8 +10,7 @@ import ContainerButton from "../widget/container_button";
import WidgetIcon from "../widget/widget_icon";
import PrimaryText from "../widget/primary_text";
import SecondaryText from "../widget/secondary_text";
import Icon from "./icon";
import mapIcon from "../../../utils/weather/openmeteo-condition-map";
function Widget({ options }) {
const { t } = useTranslation();
@ -33,10 +32,8 @@ function Widget({ options }) {
}
const unit = options.units === "metric" ? "celsius" : "fahrenheit";
const weatherInfo = {
condition: data.current_weather.weathercode,
timeOfDay: data.current_weather.time > data.daily.sunrise[0] && data.current_weather.time < data.daily.sunset[0] ? "day" : "night"
};
const condition = data.current_weather.weathercode;
const timeOfDay = data.current_weather.time > data.daily.sunrise[0] && data.current_weather.time < data.daily.sunset[0] ? "day" : "night";
return <Container options={options}>
<PrimaryText>
@ -47,8 +44,8 @@ function Widget({ options }) {
unit,
})}
</PrimaryText>
<SecondaryText>{t(`wmo.${data.current_weather.weathercode}-${weatherInfo.timeOfDay}`)}</SecondaryText>
<WidgetIcon icon={Icon} size="xl" weatherInfo={weatherInfo} />
<SecondaryText>{t(`wmo.${data.current_weather.weathercode}-${timeOfDay}`)}</SecondaryText>
<WidgetIcon icon={mapIcon(condition, timeOfDay)} size="xl" />
</Container>;
}

View File

@ -1,7 +0,0 @@
import mapIcon from "utils/weather/owm-condition-map";
export default function Icon({ condition, timeOfDay }) {
const IconComponent = mapIcon(condition, timeOfDay);
return <IconComponent className="w-10 h-10 text-theme-800 dark:text-theme-200" />;
}

View File

@ -10,9 +10,7 @@ import ContainerButton from "../widget/container_button";
import PrimaryText from "../widget/primary_text";
import SecondaryText from "../widget/secondary_text";
import WidgetIcon from "../widget/widget_icon";
import Icon from "./icon";
import mapIcon from "../../../utils/weather/owm-condition-map";
function Widget({ options }) {
const { t, i18n } = useTranslation();
@ -35,15 +33,13 @@ function Widget({ options }) {
const unit = options.units === "metric" ? "celsius" : "fahrenheit";
const weatherInfo = {
condition: data.weather[0].id,
timeOfDay: data.dt > data.sys.sunrise && data.dt < data.sys.sunset ? "day" : "night"
};
const condition = data.weather[0].id;
const timeOfDay = data.dt > data.sys.sunrise && data.dt < data.sys.sunset ? "day" : "night";
return <Container options={options}>
<PrimaryText>{options.label && `${options.label}, ` }{t("common.number", { value: data.main.temp, style: "unit", unit })}</PrimaryText>
<SecondaryText>{data.weather[0].description}</SecondaryText>
<WidgetIcon icon={Icon} size="xl" weatherInfo={weatherInfo} />
<WidgetIcon icon={mapIcon(condition, timeOfDay)} size="xl" />
</Container>;
}

View File

@ -5,11 +5,11 @@ import { useTranslation } from "next-i18next";
import Resource from "../widget/resource";
import Error from "../widget/error";
export default function Cpu({ expanded }) {
export default function Cpu({ expanded, refresh = 1500 }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/widgets/resources?type=cpu`, {
refreshInterval: 1500,
refreshInterval: refresh,
});
if (error || data?.error) {

View File

@ -9,11 +9,11 @@ function convertToFahrenheit(t) {
return t * 9/5 + 32
}
export default function CpuTemp({ expanded, units }) {
export default function CpuTemp({ expanded, units, refresh = 1500 }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/widgets/resources?type=cputemp`, {
refreshInterval: 1500,
refreshInterval: refresh,
});
if (error || data?.error) {

View File

@ -5,11 +5,11 @@ import { useTranslation } from "next-i18next";
import Resource from "../widget/resource";
import Error from "../widget/error";
export default function Disk({ options, expanded }) {
export default function Disk({ options, expanded, refresh = 1500 }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/widgets/resources?type=disk&target=${options.disk}`, {
refreshInterval: 1500,
refreshInterval: refresh,
});
if (error || data?.error) {

View File

@ -5,11 +5,11 @@ import { useTranslation } from "next-i18next";
import Resource from "../widget/resource";
import Error from "../widget/error";
export default function Memory({ expanded }) {
export default function Memory({ expanded, refresh = 1500 }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/widgets/resources?type=memory`, {
refreshInterval: 1500,
refreshInterval: refresh,
});
if (error || data?.error) {

View File

@ -9,16 +9,18 @@ import Uptime from "./uptime";
export default function Resources({ options }) {
const { expanded, units } = options;
let { refresh } = options;
refresh = Math.max(refresh, 1000);
return <Container options={options}>
<Raw>
<div className="flex flex-row self-center flex-wrap justify-between">
{options.cpu && <Cpu expanded={expanded} />}
{options.memory && <Memory expanded={expanded} />}
{options.cpu && <Cpu expanded={expanded} refresh={refresh} />}
{options.memory && <Memory expanded={expanded} refresh={refresh} />}
{Array.isArray(options.disk)
? options.disk.map((disk) => <Disk key={disk} options={{ disk }} expanded={expanded} />)
: options.disk && <Disk options={options} expanded={expanded} />}
{options.cputemp && <CpuTemp expanded={expanded} units={units} />}
{options.uptime && <Uptime />}
? options.disk.map((disk) => <Disk key={disk} options={{ disk }} expanded={expanded} refresh={refresh} />)
: options.disk && <Disk options={options} expanded={expanded} refresh={refresh} />}
{options.cputemp && <CpuTemp expanded={expanded} units={units} refresh={refresh} />}
{options.uptime && <Uptime refresh={refresh} />}
</div>
{options.label && (
<div className="ml-6 pt-1 text-center text-theme-800 dark:text-theme-200 text-xs">{options.label}</div>

View File

@ -5,11 +5,11 @@ import { useTranslation } from "next-i18next";
import Resource from "../widget/resource";
import Error from "../widget/error";
export default function Uptime() {
export default function Uptime({ refresh = 1500 }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/widgets/resources?type=uptime`, {
refreshInterval: 1500,
refreshInterval: refresh,
});
if (error || data?.error) {

View File

@ -1,7 +0,0 @@
import mapIcon from "utils/weather/condition-map";
export default function Icon({ condition, timeOfDay }) {
const IconComponent = mapIcon(condition, timeOfDay);
return <IconComponent className="w-10 h-10 text-theme-800 dark:text-theme-200" />;
}

View File

@ -10,8 +10,7 @@ import PrimaryText from "../widget/primary_text";
import SecondaryText from "../widget/secondary_text";
import WidgetIcon from "../widget/widget_icon";
import ContainerButton from "../widget/container_button";
import Icon from "./icon";
import mapIcon from "../../../utils/weather/condition-map";
function Widget({ options }) {
const { t, i18n } = useTranslation();
@ -33,10 +32,8 @@ function Widget({ options }) {
}
const unit = options.units === "metric" ? "celsius" : "fahrenheit";
const weatherInfo = {
condition: data.current.condition.code,
timeOfDay: data.current.is_day ? "day" : "night",
};
const condition = data.current.condition.code;
const timeOfDay = data.current.is_day ? "day" : "night";
return <Container options={options}>
<PrimaryText>
@ -48,7 +45,7 @@ function Widget({ options }) {
})}
</PrimaryText>
<SecondaryText>{data.current.condition.text}</SecondaryText>
<WidgetIcon icon={Icon} size="xl" weatherInfo={weatherInfo} />
<WidgetIcon icon={mapIcon(condition, timeOfDay)} size="xl" />
</Container>;
}

View File

@ -1,6 +1,5 @@
export default function WidgetIcon({ icon, size = "s", pulse = false, weatherInfo = {} }) {
export default function WidgetIcon({ icon, size = "s", pulse = false }) {
const Icon = icon;
const { condition, timeOfDay } = weatherInfo;
let additionalClasses = "text-theme-800 dark:text-theme-200 ";
switch (size) {
@ -14,5 +13,5 @@ export default function WidgetIcon({ icon, size = "s", pulse = false, weatherInf
additionalClasses += "animate-pulse ";
}
return <Icon className={additionalClasses} condition={condition} timeOfDay={timeOfDay} />;
return <Icon className={additionalClasses} />;
}

View File

@ -2,7 +2,7 @@ import { join } from "path";
import { createHash } from "crypto";
import { readFileSync } from "fs";
import checkAndCopyConfig from "utils/config/config";
import checkAndCopyConfig, { CONF_DIR } from "utils/config/config";
const configs = ["docker.yaml", "settings.yaml", "services.yaml", "bookmarks.yaml", "widgets.yaml"];
@ -15,7 +15,7 @@ function hash(buffer) {
export default async function handler(req, res) {
const hashes = configs.map((config) => {
checkAndCopyConfig(config);
const configYaml = join(process.cwd(), "config", config);
const configYaml = join(CONF_DIR, config);
return hash(readFileSync(configYaml, "utf8"));
});

View File

@ -22,6 +22,7 @@ export default async function handler(req, res) {
if (widget?.mappings) {
const mapping = widget?.mappings?.[req.query.endpoint];
const mappingParams = mapping?.params;
const optionalParams = mapping?.optionalParams;
const map = mapping?.map;
const endpoint = mapping?.endpoint;
const endpointProxy = mapping?.proxyHandler || serviceProxyHandler;
@ -40,9 +41,17 @@ export default async function handler(req, res) {
req.query.endpoint = formatApiCall(endpoint, segments);
}
if (req.query.query && mappingParams) {
if (req.query.query && (mappingParams || optionalParams)) {
const queryParams = JSON.parse(req.query.query);
const query = new URLSearchParams(mappingParams.map((p) => [p, queryParams[p]]));
let filteredOptionalParams = []
if (optionalParams) filteredOptionalParams = optionalParams.filter(p => queryParams[p] !== undefined);
let params = [];
if (mappingParams) params = params.concat(mappingParams);
if (filteredOptionalParams) params = params.concat(filteredOptionalParams);
const query = new URLSearchParams(params.map((p) => [p, queryParams[p]]));
req.query.endpoint = `${req.query.endpoint}?${query}`;
}

View File

@ -4,7 +4,7 @@ import path from "path";
import yaml from "js-yaml";
import checkAndCopyConfig, { getSettings, substituteEnvironmentVars } from "utils/config/config";
import checkAndCopyConfig, { getSettings, substituteEnvironmentVars, CONF_DIR } from "utils/config/config";
import {
servicesFromConfig,
servicesFromDocker,
@ -27,7 +27,7 @@ function compareServices(service1, service2) {
export async function bookmarksResponse() {
checkAndCopyConfig("bookmarks.yaml");
const bookmarksYaml = path.join(process.cwd(), "config", "bookmarks.yaml");
const bookmarksYaml = path.join(CONF_DIR, "bookmarks.yaml");
const rawFileContents = await fs.readFile(bookmarksYaml, "utf8");
const fileContents = substituteEnvironmentVars(rawFileContents);
const bookmarks = yaml.load(fileContents);

View File

@ -1,6 +1,6 @@
/* eslint-disable no-console */
import { join } from "path";
import { existsSync, readFileSync, copyFileSync } from "fs";
import { copyFileSync, existsSync, mkdirSync, readFileSync } from "fs";
import cache from "memory-cache";
import yaml from "js-yaml";
@ -9,8 +9,14 @@ const cacheKey = "homepageEnvironmentVariables";
const homepageVarPrefix = "HOMEPAGE_VAR_";
const homepageFilePrefix = "HOMEPAGE_FILE_";
export const CONF_DIR = process.env.HOMEPAGE_CONFIG_DIR ? process.env.HOMEPAGE_CONFIG_DIR : join(process.cwd(), "config");
export default function checkAndCopyConfig(config) {
const configYaml = join(process.cwd(), "config", config);
if (!existsSync(CONF_DIR)) {
mkdirSync(CONF_DIR, { recursive: true });
}
const configYaml = join(CONF_DIR, config);
if (!existsSync(configYaml)) {
const configSkeleton = join(process.cwd(), "src", "skeleton", config);
try {
@ -62,7 +68,7 @@ export function substituteEnvironmentVars(str) {
export function getSettings() {
checkAndCopyConfig("settings.yaml");
const settingsYaml = join(process.cwd(), "config", "settings.yaml");
const settingsYaml = join(CONF_DIR, "settings.yaml");
const rawFileContents = readFileSync(settingsYaml, "utf8");
const fileContents = substituteEnvironmentVars(rawFileContents);
const initialSettings = yaml.load(fileContents) ?? {};
@ -79,6 +85,5 @@ export function getSettings() {
})
}
}
return initialSettings
}

View File

@ -3,12 +3,12 @@ import { readFileSync } from "fs";
import yaml from "js-yaml";
import checkAndCopyConfig, { substituteEnvironmentVars } from "utils/config/config";
import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
export default function getDockerArguments(server) {
checkAndCopyConfig("docker.yaml");
const configFile = path.join(process.cwd(), "config", "docker.yaml");
const configFile = path.join(CONF_DIR, "docker.yaml");
const rawConfigData = readFileSync(configFile, "utf8");
const configData = substituteEnvironmentVars(rawConfigData);
const servers = yaml.load(configData);
@ -37,9 +37,9 @@ export default function getDockerArguments(server) {
}
if (servers[server].tls){
res.conn.ca = readFileSync(path.join(process.cwd(), "config", servers[server].tls.caFile));
res.conn.cert = readFileSync(path.join(process.cwd(), "config", servers[server].tls.certFile));
res.conn.key = readFileSync(path.join(process.cwd(), "config", servers[server].tls.keyFile));
res.conn.ca = readFileSync(path.join(CONF_DIR, servers[server].tls.caFile));
res.conn.cert = readFileSync(path.join(CONF_DIR, servers[server].tls.certFile));
res.conn.key = readFileSync(path.join(CONF_DIR, servers[server].tls.keyFile));
}
return res;

View File

@ -4,12 +4,12 @@ import { readFileSync } from "fs";
import yaml from "js-yaml";
import { KubeConfig } from "@kubernetes/client-node";
import checkAndCopyConfig, { substituteEnvironmentVars } from "utils/config/config";
import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
export default function getKubeConfig() {
checkAndCopyConfig("kubernetes.yaml");
const configFile = path.join(process.cwd(), "config", "kubernetes.yaml");
const configFile = path.join(CONF_DIR, "kubernetes.yaml");
const rawConfigData = readFileSync(configFile, "utf8");
const configData = substituteEnvironmentVars(rawConfigData);
const config = yaml.load(configData);

View File

@ -7,7 +7,7 @@ import * as shvl from "shvl";
import { CustomObjectsApi, NetworkingV1Api } from "@kubernetes/client-node";
import createLogger from "utils/logger";
import checkAndCopyConfig, { substituteEnvironmentVars } from "utils/config/config";
import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
import getDockerArguments from "utils/config/docker";
import getKubeConfig from "utils/config/kubernetes";
@ -17,7 +17,7 @@ const logger = createLogger("service-helpers");
export async function servicesFromConfig() {
checkAndCopyConfig("services.yaml");
const servicesYaml = path.join(process.cwd(), "config", "services.yaml");
const servicesYaml = path.join(CONF_DIR, "services.yaml");
const rawFileContents = await fs.readFile(servicesYaml, "utf8");
const fileContents = substituteEnvironmentVars(rawFileContents);
const services = yaml.load(fileContents);
@ -51,7 +51,7 @@ export async function servicesFromConfig() {
export async function servicesFromDocker() {
checkAndCopyConfig("docker.yaml");
const dockerYaml = path.join(process.cwd(), "config", "docker.yaml");
const dockerYaml = path.join(CONF_DIR, "docker.yaml");
const rawDockerFileContents = await fs.readFile(dockerYaml, "utf8");
const dockerFileContents = substituteEnvironmentVars(rawDockerFileContents);
const servers = yaml.load(dockerFileContents);
@ -279,6 +279,7 @@ export function cleanServiceGroups(groups) {
container,
currency, // coinmarketcap widget
symbols,
slugs,
defaultinterval,
site, // unifi widget
namespace, // kubernetes widget
@ -289,9 +290,21 @@ export function cleanServiceGroups(groups) {
enableNowPlaying,
volume, // diskstation widget,
enableQueue, // sonarr/radarr
node, // Proxmox
snapshotHost, // kopia
snapshotPath,
userEmail, // azuredevops
repositoryId
} = cleanedService.widget;
const fieldsList = typeof fields === 'string' ? JSON.parse(fields) : fields;
let fieldsList = fields;
if (typeof fields === 'string') {
try { JSON.parse(fields) }
catch (e) {
logger.error("Invalid fields list detected in config for service '%s'", service.name);
fieldsList = null;
}
}
cleanedService.widget = {
type,
@ -301,9 +314,17 @@ export function cleanServiceGroups(groups) {
service_group: serviceGroup.name,
};
if (currency) cleanedService.widget.currency = currency;
if (symbols) cleanedService.widget.symbols = symbols;
if (defaultinterval) cleanedService.widget.defaultinterval = defaultinterval;
if (type === "azuredevops") {
if (userEmail) cleanedService.widget.userEmail = userEmail;
if (repositoryId) cleanedService.widget.repositoryId = repositoryId;
}
if (type === "coinmarketcap") {
if (currency) cleanedService.widget.currency = currency;
if (symbols) cleanedService.widget.symbols = symbols;
if (slugs) cleanedService.widget.slugs = slugs;
if (defaultinterval) cleanedService.widget.defaultinterval = defaultinterval;
}
if (type === "docker") {
if (server) cleanedService.widget.server = server;
@ -312,6 +333,9 @@ export function cleanServiceGroups(groups) {
if (type === "unifi") {
if (site) cleanedService.widget.site = site;
}
if (type === "proxmox") {
if (node) cleanedService.widget.node = node;
}
if (type === "kubernetes") {
if (namespace) cleanedService.widget.namespace = namespace;
if (app) cleanedService.widget.app = app;
@ -330,6 +354,10 @@ export function cleanServiceGroups(groups) {
if (["diskstation", "qnap"].includes(type)) {
if (volume) cleanedService.widget.volume = volume;
}
if (type === "kopia") {
if (snapshotHost) cleanedService.widget.snapshotHost = snapshotHost;
if (snapshotPath) cleanedService.widget.snapshotPath = snapshotPath;
}
}
return cleanedService;

View File

@ -3,12 +3,12 @@ import path from "path";
import yaml from "js-yaml";
import checkAndCopyConfig, { substituteEnvironmentVars } from "utils/config/config";
import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
export async function widgetsFromConfig() {
checkAndCopyConfig("widgets.yaml");
const widgetsYaml = path.join(process.cwd(), "config", "widgets.yaml");
const widgetsYaml = path.join(CONF_DIR, "widgets.yaml");
const rawFileContents = await fs.readFile(widgetsYaml, "utf8");
const fileContents = substituteEnvironmentVars(rawFileContents);
const widgets = yaml.load(fileContents);

View File

@ -1,18 +1,17 @@
/* eslint-disable no-console */
import { join } from "path";
import { format as utilFormat } from "node:util";
import winston from "winston";
import checkAndCopyConfig, { getSettings } from "utils/config/config";
import checkAndCopyConfig, { getSettings, CONF_DIR } from "utils/config/config";
let winstonLogger;
function init() {
const configPath = join(process.cwd(), "config");
checkAndCopyConfig("settings.yaml");
const settings = getSettings();
const logpath = settings.logpath || configPath;
const logpath = settings.logpath || CONF_DIR;
function combineMessageAndSplat() {
return {

View File

@ -5,7 +5,7 @@ export function formatApiCall(url, args) {
return args[key] || "";
};
return url.replace(/\/+$/, "").replace(find, replace);
return url.replace(/\/+$/, "").replace(find, replace).replace(find,replace);
}
function getURLSearchParams(widget, endpoint) {

View File

@ -61,6 +61,9 @@ export default async function credentialedProxyHandler(req, res, map) {
} else {
headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`;
}
}
else if (widget.type === "azuredevops") {
headers.Authorization = `Basic ${Buffer.from(`$:${widget.key}`).toString("base64")}`;
} else {
headers["X-API-Key"] = `${widget.key}`;
}

View File

@ -1,6 +1,6 @@
/* eslint-disable prefer-promise-reject-errors */
/* eslint-disable no-param-reassign */
import { createUnzip } from "node:zlib";
import { createUnzip, constants as zlibConstants } from "node:zlib";
import { http, https } from "follow-redirects";
@ -34,7 +34,14 @@ function handleRequest(requestor, url, params) {
let responseContent = response;
if (contentEncoding === 'gzip' || contentEncoding === 'deflate') {
responseContent = createUnzip();
// https://github.com/request/request/blob/3c0cddc7c8eb60b470e9519da85896ed7ee0081e/request.js#L1018-L1025
// Be more lenient with decoding compressed responses, in case of invalid gzip responses that are still accepted
// by common browsers.
responseContent = createUnzip({
flush: zlibConstants.Z_SYNC_FLUSH,
finishFlush: zlibConstants.Z_SYNC_FLUSH
});
// zlib errors
responseContent.on("error", (e) => {
logger.error(e);
@ -103,6 +110,6 @@ export async function httpProxy(url, params = {}) {
constructedUrl.pathname
);
logger.error(err);
return [500, "application/json", { error: {message: err?.message ?? "Unknown error", url, rawError: err} }, null];
return [500, "application/json", { error: { message: err?.message ?? "Unknown error", url, rawError: err } }, null];
}
}

View File

@ -0,0 +1,65 @@
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 { userEmail, repositoryId } = widget;
const includePR = userEmail !== undefined && repositoryId !== undefined;
const { data: prData, error: prError } = useWidgetAPI(widget, includePR ? "pr" : null);
const { data: pipelineData, error: pipelineError } = useWidgetAPI(widget, "pipeline");
if (
pipelineError ||
(includePR && (prError || prData?.errorCode !== undefined))
) {
let finalError = pipelineError ?? prError;
if (includePR && prData?.errorCode !== null) {
// pr call failed possibly with more specific message
finalError = { message: prData?.message ?? 'Error communicating with Azure API' }
}
return <Container service={service} error={finalError} />;
}
if (!pipelineData || !Array.isArray(pipelineData.value) || (includePR && !prData)) {
return (
<Container service={service}>
<Block label="azuredevops.result" />
<Block label="azuredevops.totalPrs" />
<Block label="azuredevops.myPrs" />
<Block label="azuredevops.approved" />
</Container>
);
}
return (
<Container service={service}>
{pipelineData.value[0].result ? (
<Block label="azuredevops.result" value={t(`azuredevops.${pipelineData.value[0].result.toString()}`)} />
) : (
<Block label="azuredevops.status" value={t(`azuredevops.${pipelineData.value[0].status.toString()}`)} />
)}
{includePR && <Block label="azuredevops.totalPrs" value={t("common.number", { value: prData.count })} />}
{includePR && <Block
label="azuredevops.myPrs"
value={t("common.number", {
value: prData.value?.filter((item) => item.createdBy.uniqueName.toLowerCase() === userEmail.toLowerCase())
.length,
})}
/>}
{includePR && <Block
label="azuredevops.approved"
value={t("common.number", {
value: prData.value
?.filter((item) => item.createdBy.uniqueName.toLowerCase() === userEmail.toLowerCase())
.filter((item) => item.reviewers.some((reviewer) => reviewer.vote === 10)).length,
})}
/>}
</Container>
);
}

View File

@ -0,0 +1,18 @@
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
const widget = {
api: "https://dev.azure.com/{organization}/{project}/_apis/{endpoint}",
proxyHandler: credentialedProxyHandler,
mappings: {
pr: {
endpoint: "git/repositories/{repositoryId}/pullrequests"
},
pipeline: {
endpoint: "build/Builds?branchName={branchName}&definitions={definitionId}&$top=1"
},
},
};
export default widget;

View File

@ -19,17 +19,26 @@ export default function Component({ service }) {
const { widget } = service;
const { symbols } = widget;
const { slugs } = widget;
const currencyCode = widget.currency ?? "USD";
const interval = widget.defaultinterval ?? dateRangeOptions[0].value;
const [dateRange, setDateRange] = useState(interval);
const { data: statsData, error: statsError } = useWidgetAPI(widget, "v1/cryptocurrency/quotes/latest", {
symbol: `${symbols.join(",")}`,
const params = {
convert: `${currencyCode}`,
});
}
if (!symbols || symbols.length === 0) {
// slugs >> symbols, not both
if (slugs?.length) {
params.slug = slugs.join(",");
} else if (symbols?.length) {
params.symbol = symbols.join(",");
}
const { data: statsData, error: statsError } = useWidgetAPI(widget, "v1/cryptocurrency/quotes/latest", params);
if ((!symbols && !slugs) || (symbols?.length === 0 && slugs?.length === 0)) {
return (
<Container service={service}>
<Block value={t("coinmarketcap.configure")} />
@ -50,6 +59,7 @@ export default function Component({ service }) {
}
const { data } = statsData;
const validCryptos = Object.values(data).filter(crypto => crypto.quote[currencyCode][`percent_change_${dateRange}`] !== null)
return (
<Container service={service}>
@ -58,28 +68,28 @@ export default function Component({ service }) {
</div>
<div className="flex flex-col w-full">
{symbols.map((symbol) => (
{validCryptos.map((crypto) => (
<div
key={data[symbol].symbol}
key={crypto.id}
className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs"
>
<div className="font-thin pl-2">{data[symbol].name}</div>
<div className="font-thin pl-2">{crypto.name}</div>
<div className="flex flex-row text-right">
<div className="font-bold mr-2">
{t("common.number", {
value: data[symbol].quote[currencyCode].price,
value: crypto.quote[currencyCode].price,
style: "currency",
currency: currencyCode,
})}
</div>
<div
className={`font-bold w-10 mr-2 ${
data[symbol].quote[currencyCode][`percent_change_${dateRange}`] > 0
crypto.quote[currencyCode][`percent_change_${dateRange}`] > 0
? "text-emerald-300"
: "text-rose-300"
}`}
>
{data[symbol].quote[currencyCode][`percent_change_${dateRange}`].toFixed(2)}%
{crypto.quote[currencyCode][`percent_change_${dateRange}`].toFixed(2)}%
</div>
</div>
</div>

View File

@ -7,7 +7,8 @@ const widget = {
mappings: {
"v1/cryptocurrency/quotes/latest": {
endpoint: "v1/cryptocurrency/quotes/latest",
params: ["symbol", "convert"],
params: ["convert"],
optionalParams: ["symbol", "slug"],
},
},
};

View File

@ -5,6 +5,7 @@ const components = {
audiobookshelf: dynamic(() => import("./audiobookshelf/component")),
authentik: dynamic(() => import("./authentik/component")),
autobrr: dynamic(() => import("./autobrr/component")),
azuredevops: dynamic(() => import("./azuredevops/component")),
bazarr: dynamic(() => import("./bazarr/component")),
caddy: dynamic(() => import("./caddy/component")),
changedetectionio: dynamic(() => import("./changedetectionio/component")),
@ -21,6 +22,7 @@ const components = {
fileflows: dynamic(() => import("./fileflows/component")),
flood: dynamic(() => import("./flood/component")),
freshrss: dynamic(() => import("./freshrss/component")),
gamedig: dynamic(() => import("./gamedig/component")),
ghostfolio: dynamic(() => import("./ghostfolio/component")),
gluetun: dynamic(() => import("./gluetun/component")),
gotify: dynamic(() => import("./gotify/component")),

View File

@ -0,0 +1,59 @@
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 { widget } = service;
const { data: serverData, error: serverError } = useWidgetAPI(widget, "status");
const { t } = useTranslation();
if(serverError){
return <Container service={service} error={serverError} />;
}
// Default fields
if (widget.fields == null || widget.fields.length === 0) {
widget.fields = ["map", "currentPlayers", "ping"];
}
const MAX_ALLOWED_FIELDS = 4;
// Limits max number of displayed fields
if (widget.fields != null && widget.fields.length > MAX_ALLOWED_FIELDS) {
widget.fields = widget.fields.slice(0, MAX_ALLOWED_FIELDS);
}
if (!serverData) {
return (
<Container service={service}>
<Block label="gamedig.name"/>
<Block label="gamedig.map"/>
<Block label="gamedig.currentPlayers" />
<Block label="gamedig.players" />
<Block label="gamedig.maxPlayers" />
<Block label="gamedig.bots" />
<Block label="gamedig.ping" />
</Container>
);
}
const name = serverData.online ? serverData.name : "-";
const map = serverData.online ? serverData.map : "-";
const currentPlayers = serverData.online ? `${serverData.players} / ${serverData.maxplayers}` : "-";
const players = serverData.online ? `${serverData.players}` : "-";
const maxPlayers = serverData.online ? `${serverData.maxplayers}` : "-";
const bots = serverData.online ? `${serverData.bots}` : "-";
const ping = serverData.online ? `${serverData.ping}` : 0;
return (
<Container service={service}>
<Block label="gamedig.name" value={name} />
<Block label="gamedig.map" value={map} />
<Block label="gamedig.currentPlayers" value={currentPlayers} />
<Block label="gamedig.players" value={players} />
<Block label="gamedig.maxPlayers" value={maxPlayers} />
<Block label="gamedig.bots" value={bots} />
<Block label="gamedig.ping" value={t("common.ms", { value: ping, style: "unit", unit: "millisecond" })} />
</Container>
);
}

View File

@ -0,0 +1,37 @@
import createLogger from "utils/logger";
import getServiceWidget from "utils/config/service-helpers";
const proxyName = "gamedigProxyHandler";
const logger = createLogger(proxyName);
const gamedig = require("gamedig");
export default async function gamedigProxyHandler(req, res) {
const { group, service } = req.query;
const serviceWidget = await getServiceWidget(group, service);
const url = new URL(serviceWidget.url);
try {
const serverData = await gamedig.query({
type: serviceWidget.serverType,
host: url.hostname,
port: url.port,
givenPortOnly: true,
});
res.status(200).send({
online: true,
name: serverData.name,
map: serverData.map,
players: serverData.players.length,
maxplayers: serverData.maxplayers,
bots: serverData.bots.length,
ping: serverData.ping,
});
} catch (e) {
logger.error(e);
res.status(200).send({
online: false
});
}
}

View File

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

View File

@ -41,7 +41,12 @@ export default function Component({ service }) {
return <Container service={service} error={statusError} />;
}
const source = statusData?.sources[0];
const snapshotHost = service.widget?.snapshotHost;
const snapshotPath = service.widget?.snapshotPath;
const source = statusData?.sources
.filter(el => snapshotHost ? el.source.host === snapshotHost : true)
.filter(el => snapshotPath ? el.source.path === snapshotPath : true)[0];
if (!statusData || !source) {
return (

View File

@ -4,6 +4,7 @@ import Container from "components/services/widget/container";
import Block from "components/services/widget/block";
import useWidgetAPI from "utils/proxy/use-widget-api";
function calcRunning(total, current) {
return current.status === "running" ? total + 1 : total;
}
@ -25,29 +26,40 @@ export default function Component({ service }) {
<Block label="proxmox.vms" />
<Block label="proxmox.lxc" />
<Block label="resources.cpu" />
<Block label="resources.ram" />
<Block label="resources.mem" />
</Container>
);
}
const { data } = clusterData ;
const vms = data.filter(item => item.type === "qemu" && item.template === 0) || [];
const lxc = data.filter(item => item.type === "lxc" && item.template === 0) || [];
const nodes = data.filter(item => item.type === "node") || [];
const vms = data.filter(item => item.type === "qemu" && item.template === 0 && (widget.node === undefined || widget.node === item.node)) || [];
const lxc = data.filter(item => item.type === "lxc" && item.template === 0 && (widget.node === undefined || widget.node === item.node)) || [];
const nodes = data.filter(item => item.type === "node" && (widget.node === undefined || widget.node === item.node)) || [];
const runningVMs = vms.reduce(calcRunning, 0);
const runningLXC = lxc.reduce(calcRunning, 0);
// TODO: support more than one node
// TODO: better handling of cluster with zero nodes
const node = nodes.length > 0 ? nodes[0] : { cpu: 0.0, mem: 0, maxmem: 0 };
if (nodes.length === 0) {
return (
<Container service={service}>
<Block label="proxmox.vms" value={`${runningVMs} / ${vms.length}`} />
<Block label="proxmox.lxc" value={`${runningLXC} / ${lxc.length}`} />
<Block label="resources.cpu" />
<Block label="resources.mem" />
</Container>
);
}
const maxMemory = nodes.reduce((sum, n) => n.maxmem + sum, 0);
const usedMemory = nodes.reduce((sum, n) => n.mem + sum, 0);
const maxCpu = nodes.reduce((sum, n) => n.maxcpu + sum, 0);
const usedCpu = nodes.reduce((sum, n) => (n.cpu * n.maxcpu) + sum, 0);
return (
<Container service={service}>
<Block label="proxmox.vms" value={`${runningVMs} / ${vms.length}`} />
<Block label="proxmox.lxc" value={`${runningLXC} / ${lxc.length}`} />
<Block label="resources.cpu" value={t("common.percent", { value: (node.cpu * 100) })} />
<Block label="resources.mem" value={t("common.percent", { value: ((node.mem / node.maxmem) * 100) })} />
<Block label="resources.cpu" value={t("common.percent", { value: ((usedCpu / maxCpu) * 100) })} />
<Block label="resources.mem" value={t("common.percent", { value: ((usedMemory / maxMemory) * 100) })} />
</Container>
);
}

View File

@ -122,8 +122,8 @@ export default function Component({ service }) {
refreshInterval: 5000,
});
if (activityError) {
return <Container service={service} error={activityError} />;
if (activityError || (activityData && Object.keys(activityData.response.data).length === 0)) {
return <Container service={service} error={activityError ?? { message: t("tautulli.plex_connection_error") } } />;
}
if (!activityData) {

View File

@ -2,6 +2,7 @@ import adguard from "./adguard/widget";
import audiobookshelf from "./audiobookshelf/widget";
import authentik from "./authentik/widget";
import autobrr from "./autobrr/widget";
import azuredevops from "./azuredevops/widget";
import bazarr from "./bazarr/widget";
import caddy from "./caddy/widget";
import changedetectionio from "./changedetectionio/widget";
@ -16,6 +17,7 @@ import evcc from "./evcc/widget";
import fileflows from "./fileflows/widget";
import flood from "./flood/widget";
import freshrss from "./freshrss/widget";
import gamedig from "./gamedig/widget";
import ghostfolio from "./ghostfolio/widget";
import gluetun from "./gluetun/widget";
import gotify from "./gotify/widget";
@ -91,6 +93,7 @@ const widgets = {
audiobookshelf,
authentik,
autobrr,
azuredevops,
bazarr,
caddy,
changedetectionio,
@ -105,6 +108,7 @@ const widgets = {
fileflows,
flood,
freshrss,
gamedig,
ghostfolio,
gluetun,
gotify,