diff --git a/.editorconfig b/.editorconfig index a481ff77..7037b0f6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,3 +11,6 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true max_line_length = 120 + +[*.md] +trim_trailing_whitespace = false diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 683221a4..39bfee33 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,3 @@ -github: [gethomepage, benphelps, shamoon] +github: [gethomepage] open_collective: homepage +patreon: gethomepage diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..08eebdf9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,33 @@ +name: ๐Ÿ› Bug report +description: Please only raise an issue if you've been advised to do so in a GitHub discussion. Thanks! ๐Ÿ™ +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + ## โš ๏ธ Please note + The starting point for a bug report should always be a [GitHub discussion](https://github.com/gethomepage/homepage/discussions/new?category=support) + Thank you for contributing to homepage! โœŠ + - type: checkboxes + id: pre-flight + attributes: + label: Before submitting, please confirm the following + options: + - label: I confirm this was discussed, and the maintainers suggest I open an issue (note that AI bots are not maintainers). + required: true + - label: I am aware that if I create this issue without a discussion, it will be removed without a response. + required: true + - type: input + id: discussion + attributes: + label: Discussion Link + description: | + Please link to the GitHub discussion that led to this issue. + validations: + required: true + - type: textarea + id: additional + attributes: + label: Additional context + description: Optional + render: Text diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ce15fd04..22d29ff5 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,7 +2,7 @@ blank_issues_enabled: false contact_links: - name: ๐Ÿค” Questions and Help url: https://github.com/gethomepage/homepage/discussions - about: For support or general questions. + about: For support, possible bug reports or general questions. - name: ๐Ÿ’ฌ Chat url: https://discord.gg/k4ruYNrudu about: Want to discuss homepage with others? Check out our chat. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1cad352a..bf4fa386 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,12 +1,12 @@ ## Proposed change Closes # (issue) diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml index e7e473eb..ae1b3af9 100644 --- a/.github/workflows/crowdin.yml +++ b/.github/workflows/crowdin.yml @@ -19,7 +19,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: crowdin action - uses: crowdin/github-action@v1 + uses: crowdin/github-action@v2 with: upload_translations: false download_translations: true diff --git a/.github/workflows/docs-publish.yml b/.github/workflows/docs-publish.yml index 2793f28c..2f3a9501 100644 --- a/.github/workflows/docs-publish.yml +++ b/.github/workflows/docs-publish.yml @@ -2,15 +2,15 @@ name: Docs on: push: - tags: [ 'v*.*.*' ] - branches: ['main'] + tags: ["v*.*.*"] + branches: ["main"] paths: - - 'docs/**' - - 'mkdocs.yml' + - "docs/**" + - "mkdocs.yml" pull_request: paths: - - 'docs/**' - - 'mkdocs.yml' + - "docs/**" + - "mkdocs.yml" merge_group: workflow_dispatch: @@ -22,16 +22,13 @@ jobs: name: Linting Checks runs-on: ubuntu-22.04 steps: - - - name: Checkout repository + - name: Checkout repository uses: actions/checkout@v4 - - - name: Install python + - name: Install python uses: actions/setup-python@v5 with: python-version: 3.x - - - name: Check files + - name: Check files uses: pre-commit/action@v3.0.1 test: @@ -55,6 +52,7 @@ jobs: - run: sudo apt-get install pngquant - run: pip install mike - run: pip install mkdocs-material + - run: pip install "mkdocs-material[imaging]" - name: Test Docs Build run: MKINSIDERS=false mkdocs build deploy: @@ -80,6 +78,7 @@ jobs: - run: sudo apt-get install pngquant - run: pip install mike==2.0.0 - run: pip install git+https://${GH_TOKEN}@github.com/benphelps/mkdocs-material-insiders.git + - run: pip install "mkdocs-material[imaging]" - name: Set Git config run: | git config --global user.name "GitHub Action" diff --git a/.github/workflows/repo-maintenance.yml b/.github/workflows/repo-maintenance.yml index d1f7e4fd..7cf47c51 100644 --- a/.github/workflows/repo-maintenance.yml +++ b/.github/workflows/repo-maintenance.yml @@ -42,17 +42,17 @@ jobs: This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new discussion for related concerns. - See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-respoistory-maintenance) for more details. + See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-repository-maintenance) for more details. pr-comment: > This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new discussion for related concerns. - See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-respoistory-maintenance) for more details. + See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-repository-maintenance) for more details. discussion-comment: > This discussion has been automatically locked since there has not been any recent activity after it was closed. Please open a new discussion for related concerns. - See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-respoistory-maintenance) for more details. + See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-repository-maintenance) for more details. close-answered-discussions: name: 'Close Answered Discussions' runs-on: ubuntu-latest @@ -92,7 +92,7 @@ jobs: }`; const commentVariables = { discussion: discussion.id, - body: 'This discussion has been automatically closed because it was marked as answered. See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-respoistory-maintenance) for more details.', + body: 'This discussion has been automatically closed because it was marked as answered. See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-repository-maintenance) for more details.', } await github.graphql(addCommentMutation, commentVariables) @@ -182,7 +182,7 @@ jobs: }`; const commentVariables = { discussion: discussion.id, - body: 'This discussion has been automatically closed due to inactivity. See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-respoistory-maintenance) for more details.', + body: 'This discussion has been automatically closed due to inactivity. See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-repository-maintenance) for more details.', } await github.graphql(addCommentMutation, commentVariables); @@ -260,7 +260,7 @@ jobs: }`; const commentVariables = { discussion: discussion.id, - body: 'This discussion has been automatically closed due to lack of community support. See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-respoistory-maintenance) for more details.', + body: 'This discussion has been automatically closed due to lack of community support. See our [contributing guidelines](https://github.com/gethomepage/homepage/blob/main/CONTRIBUTING.md#automatic-repository-maintenance) for more details.', } await github.graphql(addCommentMutation, commentVariables); diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f2361c43..d3b07697 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ In short, when you submit code changes, your submissions are understood to be un ## Report bugs using Github [discussions](https://github.com/gethomepage/homepage/discussions) -We use GitHub discussions to triage bugs. Report a bug by [opening a new discussion](https://github.com/gethomepage/homepage/discussions/new?category=support); it's that easy! +We use GitHub discussions to triage bugs. Report a bug by [opening a new discussion](https://github.com/gethomepage/homepage/discussions/new?category=support); it's that easy! Please do not open an issue unless instructed to do so by a project maintainer. ## Write bug reports with detail, background, and sample configurations @@ -48,15 +48,18 @@ Please see information in the docs regarding [code formatting with pre-commit ho By contributing, you agree that your contributions will be licensed under its GNU General Public License. +## Use of AI for pull requests + +In general, homepage does not accept "AI-generated" PRs. If you choose to use something like that to aid the development process to generate a significant proportion of the pull request, please make sure this is explicitly stated in the PR itself. + ## References This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/main/CONTRIBUTING.md) -# Automatic Respoistory Maintenance +## Automatic Respository Maintenance The homepage team appreciates all effort and interest from the community in filing bug reports, creating feature requests, sharing ideas and helping other community members. That said, in an effort to keep the repository organized and managebale the project uses automatic handling of certain areas: -- Issues that cannot be reproduced will be marked 'stale' after 7 days of inactivity and closed after 14 further days of inactivity. - Issues, pull requests and discussions that are closed will be locked after 30 days of inactivity. - Discussions with a marked answer will be automatically closed. - Discussions in the 'General' or 'Support' categories will be closed after 180 days of inactivity. diff --git a/README.md b/README.md index 5bc61685..f14bdfad 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,13 @@ GitHub Sponsors

+

+ DigitalOcean Referral Badge +

+

+Homepage builds are kindly powered by DigitalOcean. +

+ # Features With features like quick search, bookmarks, weather support, a wide range of integrations and widgets, an elegant and modern design, and a focus on performance, Homepage is your ideal start to the day and a handy companion throughout it. @@ -41,7 +48,7 @@ With features like quick search, bookmarks, weather support, a wide range of int ## Docker Integration -Homepage has built-in support for Docker, and can automatically discover and add services to the homepage based on labels. See the [Docker](https://gethomepage.dev/latest/installation/docker/) page for more information. +Homepage has built-in support for Docker, and can automatically discover and add services to the homepage based on labels. See the [Docker Service Discovery](https://gethomepage.dev/latest/configs/docker/#automatic-service-discovery) page for more information. ## Service Widgets @@ -59,6 +66,10 @@ Homepage is highly customizable, with support for custom themes, custom CSS & JS For configuration options, examples and more, [please check out the homepage documentation](http://gethomepage.dev). +## Security Notice ๐Ÿ”’ + +Please note that when using features such as widgets, Homepage can access personal information (for example from your home automation system) and Homepage currently does not (and is not planned to) include any authentication layer itself. Thus, we recommend homepage be deployed behind a reverse proxy including authentication, SSL etc, and / or behind a VPN. + ## With Docker Using docker compose: diff --git a/docs/assets/BlossomValley.jpg b/docs/assets/BlossomValley.jpg new file mode 100644 index 00000000..8c6a6321 Binary files /dev/null and b/docs/assets/BlossomValley.jpg differ diff --git a/docs/assets/sections.png b/docs/assets/sections.png new file mode 100644 index 00000000..d1d68d5a Binary files /dev/null and b/docs/assets/sections.png differ diff --git a/docs/configs/docker.md b/docs/configs/docker.md index 4d3026db..bcd0dd61 100644 --- a/docs/configs/docker.md +++ b/docs/configs/docker.md @@ -235,4 +235,4 @@ You can show the docker stats by clicking the status indicator but this can also showStats: true ``` -Also see the settings for [show docker stats](docker.md#show-docker-stats). +Also see the settings for [show docker stats](settings.md#show-docker-stats). diff --git a/docs/configs/kubernetes.md b/docs/configs/kubernetes.md index 6ba995c4..c76813f4 100644 --- a/docs/configs/kubernetes.md +++ b/docs/configs/kubernetes.md @@ -98,6 +98,8 @@ When the Kubernetes cluster connection has been properly configured, this servic If you are using multiple instances of homepage, an `instance` annotation can be specified to limit services to a specific instance. If no instance is provided, the service will be visible on all instances. +If you have a single service that needs to be shown on multiple specific instances of homepage (but not on all of them), the service can be annotated by multiple `instance.name` annotations, where `name` can be the names of your specific multiple homepage instances. For example, a service that is annotated with `gethomepage.dev/instance.public: ""` and `gethomepage.dev/instance.internal: ""` will be shown on `public` and `internal` homepage instances. + ### Traefik IngressRoute support Homepage can also read ingresses defined using the Traefik IngressRoute custom resource definition. Due to the complex nature of Traefik routing rules, it is required for the `gethomepage.dev/href` annotation to be set: diff --git a/docs/configs/settings.md b/docs/configs/settings.md index 9ee86a85..2f387a65 100644 --- a/docs/configs/settings.md +++ b/docs/configs/settings.md @@ -85,7 +85,7 @@ Or you may pass the path to a local image relative to the `/app/public` director ## Theme -You can configure a fixed them (and disable the theme switcher) by passing the `theme` option, like so: +You can configure a fixed theme (and disable the theme switcher) by passing the `theme` option, like so: ```yaml theme: dark # or light @@ -211,13 +211,13 @@ layout: ### Five Columns -You can add a fifth column (when `style: columns` which is default) by adding: +You can add a fifth column to services (when `style: columns` which is default) by adding: ```yaml fiveColumns: true ``` -By default homepage will max out at 4 columns for column style +By default homepage will max out at 4 columns for services with `columns` style ### Collapsible sections @@ -363,7 +363,7 @@ providers: You can then pass `provider` instead of `apiKey` in your widget configuration. ```yaml -- weather: +- weatherapi: latitude: 50.449684 longitude: 30.525026 provider: weatherapi @@ -377,9 +377,10 @@ You can use the 'Quick Launch' feature to search services, perform a web search There are a few optional settings for the Quick Launch feature: -- `searchDescriptions`: which lets you control whether item descriptions are included in searches. This is off by default. When enabled, results that match the item name will be placed above those that only match the description. +- `searchDescriptions`: which lets you control whether item descriptions are included in searches. This is false by default. When enabled, results that match the item name will be placed above those that only match the description. - `hideInternetSearch`: disable automatically including the currently-selected web search (e.g. from the widget) as a Quick Launch option. This is false by default, enabling the feature. -- `showSearchSuggestions`: shows search suggestions for the internet search. This value will be inherited from the search widget if it is not specified. If it is not specified there either, it will default to false. +- `showSearchSuggestions`: show search suggestions for the internet search. If this is not specified then the setting will be inherited from the search widget. If it is not specified there either, it will default to false. For custom providers the `suggestionUrl` needs to be set in order for this to work. +- `provider`: search engine provider. If none is specified it will try to use the provider set for the Search Widget, if neither are present then internet search will be disabled. - `hideVisitURL`: disable detecting and offering an option to open URLs. This is false by default, enabling the feature. ```yaml @@ -388,6 +389,17 @@ quicklaunch: hideInternetSearch: true showSearchSuggestions: true hideVisitURL: true + provider: google # google, duckduckgo, bing, baidu, brave or custom +``` + +or for a custom search: + +```yaml +quicklaunch: + provider: custom + url: https://www.ecosia.org/search?q= + target: _blank + suggestionUrl: https://ac.ecosia.org/autocomplete?type=list&q= ``` ## Homepage Version @@ -406,6 +418,8 @@ By default the homepage logfile is written to the a `logs` subdirectory of the ` logpath: /logfile/path ``` +By default, logs are sent both to `stdout` and to a file at the path specified. This can be changed by setting the `LOG_TARGETS` environment variable to one of `both` (default), `stdout` or `file`. + ## Show Docker Stats You can show all docker stats expanded in `settings.yaml`: diff --git a/docs/index.md b/docs/index.md index 97a3704b..fe1c0adf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,3 +17,10 @@ hide: A modern, fully static, fast, secure fully proxied, highly customizable application dashboard with integrations for over 100 services and translations into multiple languages. Easily configured via YAML files or through docker label discovery. ![Alt text](assets/homepage_demo.png) + +

+ DigitalOcean Referral Badge +

+

+Homepage builds are kindly powered by DigitalOcean. +

diff --git a/docs/installation/index.md b/docs/installation/index.md index f1d317c4..beb370c1 100644 --- a/docs/installation/index.md +++ b/docs/installation/index.md @@ -7,6 +7,10 @@ description: Docs intro You have a few options for deploying homepage, depending on your needs. We offer docker images for a majority of platforms. You can also install and run homepage from source if Docker is not your thing. It can even be installed on Kubernetes with Helm.

+!!! danger + + Please note that when using features such as widgets, Homepage can access personal information (for example from your home automation system) and Homepage currently does not (and is not planned to) include any authentication layer itself. Thus, we recommend homepage be deployed behind a reverse proxy including authentication, SSL etc, and / or behind a VPN. +
diff --git a/docs/installation/k8s.md b/docs/installation/k8s.md index 685472ea..6805139b 100644 --- a/docs/installation/k8s.md +++ b/docs/installation/k8s.md @@ -361,3 +361,33 @@ spec: port: number: 3000 ``` + +### Multiple Replicas + +If you plan to deploy homepage with a replica count greater than 1, you may +want to consider enabling sticky sessions on the homepage route. This will +prevent unnecessary re-renders on page loads and window / tab focusing. The +procedure for enabling sticky sessions depends on your Ingress controller. Below +is an example using Traefik as the Ingress controller. + +``` +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: homepage.example.com +spec: + entryPoints: + - websecure + routes: + - kind: Rule + match: Host(`homepage.example.com`) + services: + - kind: Service + name: homepage + port: 3000 + sticky: + cookie: + httpOnly: true + secure: true + sameSite: none +``` diff --git a/docs/more/development.md b/docs/more/development.md index 8e3fac13..ec580cff 100644 --- a/docs/more/development.md +++ b/docs/more/development.md @@ -39,6 +39,11 @@ Once installed, hooks will run when you commit. If the formatting isn't quite ri See the [pre-commit documentation](https://pre-commit.com/#install) to get started. +## Preferring self-hosted open-source software + +In general, homepage is meant to be a dashboard for 'self-hosted' services and we believe it is a small way we can help showcase this kind of software. While exceptions are made, mostly when there is no viable +self-hosted / open-source alternative, we ask that any widgets, etc. are developed primarily for a self-hosted tool. + ## New Feature Guidelines - New features should be linked to an existing feature request with at least 10 'up-votes'. The purpose of this requirement is to avoid the addition (and maintenance) of features that might only benefit a small number of users. diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 00000000..0a5f2bc5 --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,47 @@ +{% extends "base.html" %} + +{% block site_nav %} + + {% if nav %} + {% if page.meta and page.meta.hide %} + {% set hidden = "hidden" if "navigation" in page.meta.hide %} + {% endif %} + + {% endif %} + + + {% if "toc.integrate" not in features %} + {% if page.meta and page.meta.hide %} + {% set hidden = "hidden" if "toc" in page.meta.hide %} + {% endif %} + + {% endif %} +{% endblock %} diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index e6bc9bf0..f9281da2 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -1,24 +1,44 @@ [data-md-toggle="search"]:not(:checked) ~ .md-header .md-search__form::after { - position: absolute; - top: .3rem; - right: .3rem; - display: block; - padding: .1rem .4rem; - color: var(--md-default-fg-color--lighter); - font-weight: bold; - font-size: .8rem; - border: .05rem solid var(--md-default-fg-color--lighter); - border-radius: .1rem; - content: "/"; - } + position: absolute; + top: 0.3rem; + right: 0.3rem; + display: block; + padding: 0.1rem 0.4rem; + color: var(--md-default-fg-color--lighter); + font-weight: bold; + font-size: 0.8rem; + border: 0.05rem solid var(--md-default-fg-color--lighter); + border-radius: 0.1rem; + content: "/"; +} [data-md-color-scheme="default"][data-md-color-primary="black"] { - [data-md-toggle="search"]:not(:checked) ~ .md-header .md-search__form::after { - color: var(--md-default-bg-color--lighter); - border-color: var(--md-default-bg-color--lighter); - } + [data-md-toggle="search"]:not(:checked) ~ .md-header .md-search__form::after { + color: var(--md-default-bg-color--lighter); + border-color: var(--md-default-bg-color--lighter); + } } #glimeRoot * { - font-family: var(--md-text-font) !important; + font-family: var(--md-text-font) !important; +} + +#carbonads { + margin-top: 10px; +} + +#carbon-responsive { + --carbon-padding: 1em; + --carbon-max-char: 20ch; + --carbon-bg-primary: var(--md-default-bg-color) !important; + --carbon-bg-secondary: var(--md-default-fg-color--lightest) !important; + --carbon-text-color: var(--md-typeset-color) !important; +} + +.md-typeset__table { + width: 100%; +} + +.md-typeset table:not([class]) { + display: table; } diff --git a/docs/widgets/authoring/api.md b/docs/widgets/authoring/api.md new file mode 100644 index 00000000..b700b19c --- /dev/null +++ b/docs/widgets/authoring/api.md @@ -0,0 +1,50 @@ +--- +title: API Guide +description: How to fetch data from an API in Homepage widgets. +--- + +Homepage provides the `useWidgetAPI` hook to help you fetch data from an API. This hook insures that the data is fetched using a proxy, and is critical for security. + +Here is an example of how the `useWidgetAPI` hook looks: + +```js title="Fetch data from the stats endpoint" +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { data, error } = useWidgetAPI(widget, "stats"); +} +``` + +## `useWidgetAPI` + +`useWidgetAPI` takes three possible arguments: + +- `widget`: The widget metadata object. +- `endpoint`: The name of the endpoint to fetch data from. +- `params`: An optional object containing query parameters to pass to the API. + +### `widget` + +The `widget` argument is the metadata object for the widget. It contains information about the API endpoint, proxy handler, and mappings. This object is used by the `useWidgetAPI` hook to fetch data from the API. This is generally passed in as a prop from the parent component. + +### `endpoint` + +The `endpoint` argument is the name of the endpoint to fetch data from. This is [defined in the widget metadata object](widget.md#endpoint). The `useWidgetAPI` hook uses this argument to determine which endpoint to fetch data from. + +If no endpoint is provided, the `useWidgetAPI` hook will call the API endpoint defined in the widget metadata object directly. + +### `params` + +The `params` argument is an optional object containing query parameters to pass to the API. This is useful for filtering data or passing additional information to the API. This object is passed directly to the API endpoint as query parameters. + +Here is an example of how to use the `params` argument: + +```js title="Fetch data from the stats endpoint with query parameters" +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { data, error } = useWidgetAPI(widget, "stats", { start: "2021-01-01", end: "2021-12-31" }); +} +``` + +The `params` must be [whitelisted in the widget metadata object](widget.md#params). This is done to prevent arbitrary query parameters from being passed to the API. diff --git a/docs/widgets/authoring/component.md b/docs/widgets/authoring/component.md new file mode 100644 index 00000000..e909169f --- /dev/null +++ b/docs/widgets/authoring/component.md @@ -0,0 +1,102 @@ +--- +title: Component Guide +description: How to create and configure Homepage widget components. +--- + +Homepage widgets are built using React components. These components are responsible for fetching data from the API and rendering the widget UI. Homepage provides a set of hooks and utilities to help you build your widget component. + +## A Basic Widget Component + +Here is an example of a basic widget component: + +```js +import { useTranslation } from "next-i18next"; + +import Container from "components/services/widget/container"; +import Block from "components/services/widget/block"; +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { t } = useTranslation(); + const { widget } = service; + const { data, error } = useWidgetAPI(widget, "info"); + + if (error) { + return ; + } + + if (!data) { + return ( + + + + + + ); + } + + return ( + + + + + + ); +} +``` + +### Breakdown + +We'll cover two sections of the widget component: hooks and components. + +#### Hooks + +**`useTranslation`** + +This hook is used to translate text and numerical content in widgets. Homepage provides a set of helpers to help you localize your widgets. You can learn more about translations in the [Translations Guide](translations.md). + +**`useWidgetAPI`** + +This hook is used to fetch data from the API. We cover this hook in more detail in the [API Guide](api.md). + +#### Components + +Homepage provides a set of components to help you build your widget UI. These components are designed to provide a consistent layout, and all widgets are expected to use these components. + +![Component Sections](../../assets/sections.png) + +**``** + +This component is a wrapper for the widget. It provides a consistent layout for all widgets. + +```js + +``` + +`service` is a prop that is passed to the widget component. It contains information about the service that the widget is displaying. + +If there is an error fetching data from the API, the `error` prop can be passed to the `Container` component. + +```js + +``` + +**``** + +This component is used to display a key-value pair. It takes a label and value as props. + +```js + +``` + +The `label` prop is used to look up the translation key in the translation files. The `value` prop is used to display the value of the block. To learn more about translations, please refer to the [Translations Guide](translations.md). + +If there is no data available, the `Block` component can be used to display a placeholder layout. + +```js + + + + + +``` diff --git a/docs/widgets/authoring/guide.md b/docs/widgets/authoring/guide.md new file mode 100644 index 00000000..766c8d4c --- /dev/null +++ b/docs/widgets/authoring/guide.md @@ -0,0 +1,289 @@ +--- +title: Widget Guide +description: How to create a custom widget for Homepage. +--- + +In this guide, we'll walk through the process of creating a custom widget for Homepage. We'll cover the basic structure of a widget, how to use translations, and how to fetch data from an API. By the end of this guide, you'll have a solid understanding of how to build your own custom widget. + +**Prerequisites:** + +- Basic knowledge of React and JavaScript +- Familiarity with the Homepage platform +- Understanding of JSON and API interactions + +Throughout this guide, we'll use `yourwidget` as a placeholder for the unique name of your custom widget. Replace `yourwidget` with the actual name of your widget. It should contain only lowercase letters and no spaces. + +This guide makes use of a fake API, which would return a JSON response as such, when called with the `v1/info` endpoint: + +```json +{ "key1": 123, "key2": 456, "key3": 789 } +``` + +## Set up the widget definition + +Create a new folder for your widget in the `src/widgets` directory. Name the folder `yourwidget`. + +Inside the `yourwidget` folder, create a new file named `widget.js`. This file will contain the metadata for your widget. + +Open the `widget.js` file and add the following code: + +```js title="src/widgets/yourwidget/widget.js" +import genericProxyHandler from "utils/proxy/handlers/generic"; // (1)! + +const widget = /* (2)! */ { + api: "{url}/{endpoint}" /* (3)! */, + proxyHandler: genericProxyHandler /* (1)! */, + + mappings: /* (4)! */ { + info: /* (5)! */ { + endpoint: "v1/info" /* (6)! */, + }, + }, +}; + +export default widget; +``` + +1. We import the `genericProxyHandler` from the `utils/proxy/handlers/generic` module. The `genericProxyHandler` is a generic handler that can be used to fetch data from an API. We then assign the `genericProxyHandler` to the `proxyHandler` property of the `widget` object. There are other handlers available that you can use depending on your requirements. You can also create custom handlers if needed. +2. We define a `widget` object that contains the metadata for the widget. +3. The API endpoint to fetch data from. You can use placeholders like `{url}` and `{endpoint}` to dynamically generate the API endpoint based on the widget configuration. +4. An object that contains mappings for different endpoints. Each mapping should have an `endpoint` property that specifies the endpoint to fetch data from. +5. A mapping named `info` that specifies the `v1/info` endpoint to fetch data from. This would be called from the component as such: `#!js useWidgetAPI(widget, "info");` +6. The `endpoint` property of the `info` mapping specifies the endpoint to fetch data from. There are other properties you can pass to the mapping, such as `method`, `headers`, and `body`. + +!!! warning "Important" + + All widgets that fetch data from dynamic endpoints should have either `mappings` or an `allowedEndpoints` property. + +## Set up translation strings + +Homepage uses translated and localized strings for **all text and numerical content** in widgets. English is the default language, and other languages can be added via [Crowdin](https://crowdin.com/project/gethomepage). To add the English translations for your widget, follow these steps: + +Open the `public/locales/en/common.js` file. + +Add a new object for your widget to the bottom of the list, like this: + +```json +"yourwidget": { + "key1": "Value 1", + "key2": "Value 2", + "key3": "Value 3" +} +``` + +!!! note + + Even if you nativly speak another language, you should only add English translations. You can then add translations in your native language via [Crowdin](https://crowdin.com/project/gethomepage), once your widget is merged. + +## Create the widget component + +Create a new file for your widgets component, named `component.jsx`, in the `src/widgets/yourwidget` directory. We'll build the contents of the `component.jsx` file step by step. + +First, we'll import the necessary dependencies: + +```js title="src/widgets/yourwidget/component.jsx" linenums="1" +import { useTranslation } from "next-i18next"; // (1)! + +import Container from "components/services/widget/container"; // (2)! +import Block from "components/services/widget/block"; // (3)! +import useWidgetAPI from "utils/proxy/use-widget-api"; // (4)! +``` + +1. `#!js useTranslation()` is a hook provided by `next-i18next` that allows us to access the translation strings +2. `#!jsx ` and `#!jsx ` are custom components that we'll use to structure our widget. +3. `#!jsx ` and `#!jsx ` are custom components that we'll use to structure our widget. +4. `#!js useWidgetAPI(widget, endpoint)` is a custom hook that we'll use to fetch data from an API. + +--- + +Next, we'll define a functional component named `Component` that takes a `service` prop. + +```js title="src/widgets/yourwidget/component.jsx" linenums="7" +export default function Component({ service }) {} +``` + +--- + +We grab the helper functions from the `useTranslation` hook. + +```js title="src/widgets/yourwidget/component.jsx" linenums="8" +const { t } = useTranslation(); +``` + +--- + +We destructure the `widget` object from the `service` prop. The `widget` object contains the metadata for the widget, such as the API endpoint to fetch data from. + +```js title="src/widgets/yourwidget/component.jsx" linenums="9" +const { widget } = service; +``` + +--- + +Now, the fun part! We use the `useWidgetAPI` hook to fetch data from an API. The `useWidgetAPI` hook takes two arguments: the `widget` object and the API endpoint to fetch data from. The `useWidgetAPI` hook returns an object with `data` and `error` properties. + +```js title="src/widgets/yourwidget/component.jsx" linenums="10" +const { data, error } = useWidgetAPI(widget, "info"); +``` + +!!! tip "API Tips" + + You'll see here how part of the API url is built using the `url` and `endpoint` properties from the widget definition. + + In this case, we're fetching data from the `info` endpoint. The `info` endpoint is defined in the `mappings` object. So the full API endpoint will be `"{url}/v1/info"`. + + The mapping and endpoint are often the same, but must be defined regardless. + +--- + +Next, we check if there's an error or no data. + +If there's an error, we return a `Container` and pass it the `service` and `error` as props. The `Container` component will handle displaying the error message. + +```js title="src/widgets/yourwidget/component.jsx" linenums="12" +if (error) { + return ; +} +``` + +--- + +If there's no data, we return a `Container` component with three `Block` components, each with a `label`. + +```js title="src/widgets/yourwidget/component.jsx" linenums="16" +if (!data) { + return ( + + + + + + ); +} +``` + +This will render the widget with placeholders for the data, i.e., a skeleton view. + +!!! tip "Translation Tips" + + The `label` prop in the `Block` component corresponds to the translation key we defined earlier in the `common.js` file. All text and numerical content should be translated. + +--- + +If there is data, we return a `Container` component with three `Block` components, each with a `label` and a `value`. + +Here we use the `t` function from the `useTranslation` hook to translate the data values. The `t` function takes the translation key and an object with variables to interpolate into the translation string. + +We're using the `common.number` translation key to format the data values as numbers. This allows for easy localization of numbers, such as using commas or periods as decimal separators. + +There are a large number of `common` numerical translation keys available, which you can learn more about in the [Translation Guide](translations.md). + +```js title="src/widgets/yourwidget/component.jsx" linenums="26" +return ( + + + + + +); +``` + +--- + +Here's the complete `component.jsx` file: + +```js title="src/widgets/yourwidget/component.jsx" linenums="1" +import { useTranslation } from "next-i18next"; + +import Container from "components/services/widget/container"; +import Block from "components/services/widget/block"; +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { t } = useTranslation(); + const { widget } = service; + const { data, error } = useWidgetAPI(widget, "info"); + + if (error) { + return ; + } + + if (!data) { + return ( + + + + + + ); + } + + return ( + + + + + + ); +} +``` + +## Add the widget to the Homepage + +To add your widget to the Homepage, you need to register it in the `src/widgets/widgets.js` file. + +Open the `src/widgets/widgets.js` file and import the `Component` from your widget's `component.jsx` file. Please keep the alphabetical order. + +```js +// ... +import yourwidget from "./yourwidget/widget"; +// ... +``` + +Add `yourwidget` to the `widgets` object. Please keep the alphabetical order. + +```js +const widgets = { + // ... + yourwidget: yourwidget, + // ... +}; +``` + +You also need to add the widget to the `components` object in the `src/widgets/components.js` file. + +Open the `src/widgets/components.js` file and import the `Component` from your widget's `component.jsx` file. + +Please keep the alphabetical order. + +```js +const components = { + // ... + yourwidget: dynamic(() => import("./yourwidget/component")), + // ... +}; +``` + +## Using the widget + +You can now use your custom widget in your Homepage. Open your `services.yaml` file and add a new service with the `yourwidget` widget. + +```yaml +- Services: + - Your Widget: + icon: yourwidget.svg + href: https://example.com/ + widget: + type: yourwidget + url: http://127.0.0.1:1337 +``` + +!!! tip "API Tips" + + You'll see here how part of the API url is built using the `url` and `endpoint` properties from the widget definition. + + We defined the api endpoint as `"{url}/{endpoint}"`. This is where the `url` is defined. So the full API endpoint will be `http://127.0.0.1:1337/{endpoint}`. + +--- + +That's it! You've successfully created a custom widget for Homepage. If you have any questions or need help, feel free to reach out to the Homepage community for assistance. Happy coding! diff --git a/docs/widgets/authoring/index.md b/docs/widgets/authoring/index.md new file mode 100644 index 00000000..cc9b934f --- /dev/null +++ b/docs/widgets/authoring/index.md @@ -0,0 +1,34 @@ +--- +title: Homepage Widget Guides +description: How to create and configure Homepage widgets. +--- + +Widgets are a core component of Homepage. They are used to display information about your system, services, and environment. + +## Overview + +If you are new to Homepage widgets, and are looking to create a new widget, please follow along with the guide here: [Widget Guide](guide.md). + +### Translations + +All text and numerical content in widgets should be translated and localized. English is the default language, and other languages can be added via [Crowdin](https://crowdin.com/project/gethomepage). + +The Homepage community prides itself on being multilingual, and we strongly encourage you to add translations for your widgets. + +If you are looking to learn more about translations, please refer to the guide here: [Translations Guide](translations.md). + +### Widget Component + +The widget component is the core of the widget. It is responsible for [fetching data from the API](api.md) and rendering the widget UI. Homepage provides a set of hooks and utilities to help you build your widget component. + +If you are looking to learn more about widget components, please refer to the guide here: [Component Guide](component.md). + +### Widget Metadata + +Widget metadata defines the configuration of the widget. It defines the API endpoint to fetch data from, the proxy handler to use, and any data mappings. + +If you are looking to learn more about widget metadata, endpoint and data mapping, please refer to the guide here: [Metadata Guide](widget.md). + +If you are looking to learn more about proxy handlers, please refer to the guide here: [Proxies Guide](proxies.md). + +If you are looking to learn more making API calls from inside your widget, please refer to the guide here: [API Guide](api.md). diff --git a/docs/widgets/authoring/proxies.md b/docs/widgets/authoring/proxies.md new file mode 100644 index 00000000..cf835bac --- /dev/null +++ b/docs/widgets/authoring/proxies.md @@ -0,0 +1,178 @@ +--- +title: Proxies Guide +description: How to use and create Homepage widget proxies. +--- + +Homepage includes a set of built-in proxy handlers that can be used to fetch data from an API. We will go over how to use these proxy handlers and briefly cover how to create your own. + +## Available Proxy Handlers + +Homepage comes with a few built-in proxy handlers that can be used to fetch data from an API. These handlers are located in the `utils/proxy/handlers` directory. + +### `genericProxyHandler` + +A proxy handler that makes generally unauthenticated requests to the specified API endpoint. + +```js +import genericProxyHandler from "utils/proxy/handlers/generic"; + +const widgetExample = { + api: "{url}/api/{endpoint}", + proxyHandler: genericProxyHandler, +}; +``` + +You can also pass API keys from the widget configuration to the proxy handler, for authenticated requests. + +=== "widget.js" + + ```js + import genericProxyHandler from "utils/proxy/handlers/generic"; + + const widgetExample = { + api: "{url}/api/{endpoint}?key={key}", + proxyHandler: genericProxyHandler, + }; + ``` + +=== "services.yaml" + + ```yaml + # Widget Configuration + - Your Widget: + icon: yourwidget.svg + href: https://example.com/ + widget: + type: yourwidget + url: http://example.com + key: your-api-key + ``` + +### `credentialedProxyHandler` + +A proxy handler that makes authenticated by setting request headers. Credentials are pulled from the widgets configuration. + +By default the key is passed as an `X-API-Key` header. If you need to pass the key as something else, either add a case to the credentialedProxyHandler or create a new proxy handler. + +=== "widget.js" + + ```js + import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; + + const widgetExample = { + api: "{url}/api/{endpoint}?key={key}", + proxyHandler: credentialedProxyHandler, + }; + ``` + +=== "services.yaml" + + ```yaml + - Your Widget: + icon: yourwidget.svg + href: https://example.com/ + widget: + type: yourwidget + url: http://127.0.0.1:1337 + key: your-api-key + ``` + +### `jsonrpcProxyHandler` + +A proxy handler that makes authenticated JSON-RPC requests to the specified API endpoint. Where the endpoint is the method to call. + +=== "widget.js" + + ```js + import jsonrpcProxyHandler from "utils/proxy/handlers/jsonrpc"; + + const widgetExample = { + api: "{url}/api/jsonrpc", + proxyHandler: jsonrpcProxyHandler, + + mappings: { + total: { endpoint: "total" }, + average: { endpoint: "average" }, + }, + }; + ``` + +=== "services.yaml" + + ```yaml + - Your Widget: + icon: yourwidget.svg + href: https://example.com/ + widget: + type: yourwidget + url: http://127.0.0.1:1337 + username: your-username + password: your-password + ``` + +### `synologyProxyHandler` + +A proxy handler that makes authenticated requests to the specified Synology API endpoint. This is used exclusively for Synology DSM services. + +=== "widget.js" + + ```js + import synologyProxyHandler from "utils/proxy/handlers/synology"; + + const widgetExample = { + api: "{url}/webapi/{cgiPath}?api={apiName}&version={maxVersion}&method={apiMethod}", + proxyHandler: synologyProxyHandler, + + mappings: { + system_storage: { + apiName: "SYNO.Core.System", + apiMethod: 'info&type="storage"', + endpoint: "system_storage", + } + }, + }; + ``` + +=== "services.yaml" + + ```yaml + - Your Widget: + icon: yourwidget.svg + href: https://example.com/ + widget: + type: yourwidget + url: http://127.0.0.1:1337 + username: your-username + password: your-password + ``` + +## Creating a Custom Proxy Handler + +You can create your own proxy handler to fetch data from an API. A proxy handler is a function that takes a configuration object and returns a function that makes the API request. + +The proxy handler function takes three arguments: + +- `req`: The request object. +- `res`: The response object. +- `map`: A function that maps the API response to the widget data. + +The proxy handler function should return a promise that resolves to the API response. + +Here is an example of a simple proxy handler that fetches data from an API and passes it to the widget: + +```js +import createLogger from "utils/logger"; +import { httpProxy } from "utils/proxy/http"; + +const logger = createLogger("customProxyHandler"); + +export default async function customProxyHandler(req, res, map) { + const { url } = req.query; + + const [status, contentType, data] = await httpProxy(url); + + return res.status(status).send(data); +} +``` + +Proxy handlers are a complex topic and require a good understanding of JavaScript and the Homepage codebase. If you are new to Homepage, we recommend using the built-in proxy handlers. diff --git a/docs/widgets/authoring/translations.md b/docs/widgets/authoring/translations.md new file mode 100644 index 00000000..06a6e39d --- /dev/null +++ b/docs/widgets/authoring/translations.md @@ -0,0 +1,80 @@ +--- +title: Translations Guide +description: Tips and tricks for translating and localizing Homepage widgets. +--- + +All text and numerical content in widgets should be translated and localized. English is the default language, and other languages can be added via [Crowdin](https://crowdin.com/project/gethomepage). + +The Homepage community prides itself on being multilingual, and we strongly encourage you to add translations for your widgets. + +## Translations + +Homepage uses the [next-i18next](https://github.com/i18next/next-i18next) library to handle translations. This library provides a set of hooks and utilities to help you localize your widgets, and Homepage has extended this library to support additional features. + +=== "component.jsx" + + ```js + import { useTranslation } from "next-i18next"; + + import Container from "components/services/widget/container"; + import Block from "components/services/widget/block"; + + export default function Component() { + const { t } = useTranslation(); + + return ( + + + + + + ); + } + ``` + +=== "en.json" + + ```json + "yourwidget": { + "key1": "Value 1", + "key2": "Value 2", + "key3": "Value 3" + } + ``` + +## Common Translations + +Homepage provides a set of common translations that you can use in your widgets. These translations are used to format numerical content, dates, and other common elements. + +### Numbers + +| Key | Translation | Description | +| --------------------- | --------------- | -------------------------------- | +| `common.bytes` | `1,000 B` | Format a number in bytes. | +| `common.bits` | `1,000 bit` | Format a number in bits. | +| `common.bbytes` | `1 KiB` | Format a number in binary bytes. | +| `common.bbits` | `1 Kibit` | Format a number in binary bits. | +| `common.byterate` | `1,000 B/s` | Format a byte rate. | +| `common.bibyterate` | `1 KiB/s` | Format a binary byte rate. | +| `common.bitrate` | `1,000 bit/s` | Format a bit rate. | +| `common.bibitrate` | `1 Kibit/s` | Format a binary bit rate. | +| `common.percent` | `50%` | Format a percentage. | +| `common.number` | `1,000` | Format a number. | +| `common.ms` | `1,000 ms` | Format a number in milliseconds. | +| `common.date` | `2024-01-01` | Format a date. | +| `common.relativeDate` | `1 day ago` | Format a relative date. | +| `common.uptime` | `1 day, 1 hour` | Format an uptime. | + +### Text + +| Key | Translation | Description | +| ------------------ | ----------- | ------------------ | +| `resources.cpu` | `CPU` | CPU usage. | +| `resources.mem` | `MEM` | Memory usage. | +| `resources.total` | `Total` | Total resource. | +| `resources.free` | `Free` | Free resource. | +| `resources.used` | `Used` | Used resource. | +| `resources.load` | `Load` | Load value. | +| `resources.temp` | `TEMP` | Temperature value. | +| `resources.max` | `Max` | Maximum value. | +| `resources.uptime` | `UP` | Uptime. | diff --git a/docs/widgets/authoring/widget.md b/docs/widgets/authoring/widget.md new file mode 100644 index 00000000..fd9ec062 --- /dev/null +++ b/docs/widgets/authoring/widget.md @@ -0,0 +1,310 @@ +--- +title: Metadata Guide +description: How to create and configure Homepage widget metadata. +--- + +Here, we will go over how to create and configure Homepage widget metadata. Metadata is a JS object that contains information about the widget, such as the API endpoint, proxy handler, and mappings. This metadata is used by Homepage to fetch data from the API and pass it to the widget. + +## Widgets Configuration + +Here are some examples of how to configure a widget's metadata object. + +=== "Basic Example" + + ```js + import genericProxyHandler from "utils/proxy/handlers/generic"; + + const widgetExample = { + api: "{url}/api/{endpoint}", + proxyHandler: genericProxyHandler, + + mappings: { + stats: { endpoint: "stats" } + }, + }; + ``` + +=== "Advanced Example" + + ```js + import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; + import { asJson, jsonArrayFilter } from "utils/proxy/api-helpers"; + + const widgetExample = { + api: "{url}/api/{endpoint}", + proxyHandler: credentialedProxyHandler, + + mappings: { + stats: { + endpoint: "stats", + validate: ["total", "average"], + params: ["start", "end"], + }, + notices: { + endpoint: "notices", + map: (data) => { + total: asJson(data).length; + }, + }, + warnings: { + endpoint: "notices", + map: (data) => { + total: jsonArrayFilter(data, (alert) => alert.type === "warning").length; + }, + }, + }, + }; + ``` + +A widgets metadata is quite powerful and can be configured in many different ways. + +## Configuration Properties + +### `api` + +The `api` property is a string that represents the URL of the API endpoint that the widget will use to fetch data. The URL can contain placeholders that will be replaced with actual values at runtime. For example, the `{url}` placeholder will be replaced with the URL of the configured widget, and the `{endpoint}` placeholder will be replaced with the value of the `endpoint` property in the `mappings` object. + +```js +const widgetExample = { + api: "{url}/api/{endpoint}", +}; +``` + +### `proxyHandler` + +The `proxyHandler` property is a function that will be used to make the API request. Homepage includes some built-in proxy handlers that can be used out of the box: + +Here is an example of the generic proxy handler that makes unauthenticated requests to the specified API endpoint. + +=== "widget.js" + + ```js + const widgetExample = { + api: "{url}/api/{endpoint}", + proxyHandler: genericProxyHandler, + }; + ``` + +=== "services.yaml" + + ```yaml + - Services: + - Your Widget: + icon: yourwidget.svg + href: https://example.com/ + widget: + type: yourwidget + url: http://127.0.0.1:1337 + ``` + +If you are looking to learn more about proxy handlers, please refer to the guide here: [Proxies Guide](proxies.md). + +### `mappings` + +The `mappings` property is an object that contains information about the API endpoint, such as the endpoint name, validation rules, and parameter names. The `mappings` object can contain multiple endpoints, each with its own configuration. + +!!! note "Security Note" + + The `mappings` or `allowedEndpoints` property is required for the widget to fetch data from more than a static URL. Homepage uses a whitelist approach to ensure that widgets only access allowed endpoints. + +```js +import { asJson } from "utils/proxy/api-helpers"; + +const widgetExample = { + api: "{url}/api/{endpoint}", + mappings: { + // `/api/stats?start=...&end=...` + stats: { + endpoint: "stats", + validate: ["total", "average"], + params: ["start", "end"], + }, + // `/api/notices` + notices: { + endpoint: "notices", + map: (data) => { + total: asJson(data).length; + }, + }, + }, +}; +``` + +#### `endpoint` + +The `endpoint` property is a string that represents the name of the API endpoint that the widget will use to fetch data. This value will be used to replace the `{endpoint}` placeholder in the `api` property. + +```js +const widgetExample = { + api: "{url}/api/{endpoint}", + mappings: { + // `/api/stats` + stats: { + endpoint: "stats", + }, + }, +}; +``` + +#### `validate` + +The `validate` property is an array of strings that represent the keys that should be validated in the API response. If the response does not contain all of the specified keys, the widget will not render. + +```js +const widgetExample = { + api: "{url}/api/{endpoint}", + mappings: { + // `/api/stats` + stats: { + endpoint: "stats", + validate: ["total", "average"], + }, + }, +}; +``` + +This configuration will ensure that the API response contains the `total` and `average` keys before the widget is rendered. + +#### `params` + +The `params` property is an array of strings that represent the keys that should be passed as parameters to the API endpoint. These keys will be replaced with the actual values at runtime. + +=== "widget.js" + + ```js + const widgetExample = { + api: "{url}/api/{endpoint}", + mappings: { + // `/api/stats?start=...&end=...` + stats: { + endpoint: "stats", + params: ["start", "end"], + }, + }, + }; + ``` + +=== "component.jsx" + + ```js + const { data: statsData, error: statsError } = useWidgetAPI(widget, "stats", { + start: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), + end: new Date(), + }); + ``` + +This configuration will pass the `start` and `end` keys as parameters to the API endpoint. The values are passed as an object to the `useWidgetAPI` hook. + +#### `map` + +The `map` property is a function that will be used to transform the API response before it is passed to the widget. This function is passed the raw API response and should return the transformed data. + +```js +import { asJson } from "utils/proxy/api-helpers"; + +const widgetExample = { + api: "{url}/api/{endpoint}", + mappings: { + // `/api/notices` + notices: { + endpoint: "notices", + map: (data) => { + total: asJson(data).length; + }, + }, + // `/api/notices` + warnings: { + endpoint: "notices", + map: (data) => { + total: asJson(data).filter((alert) => alert.type === "warning").length; + }, + }, + }, +}; +``` + +#### `method` + +The `method` property is a string that represents the HTTP method that should be used to make the API request. The default value is `GET`. + +```js +const widgetExample = { + api: "{url}/api/{endpoint}", + mappings: { + // `/api/stats` + stats: { + endpoint: "stats", + method: "POST", + }, + }, +}; +``` + +#### `headers` + +The `headers` property is an object that contains additional headers that should be included in the API request. If your endpoint requires specific headers, you can include them here. + +```js +const widgetExample = { + api: "{url}/api/{endpoint}", + mappings: { + // `/api/stats` + stats: { + endpoint: "stats", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + }, + }, +}; +``` + +#### `body` + +The `body` property is an object that contains the data that should be sent in the request body. This property is only used when the `method` property is set to `POST` or `PUT`. + +```js +const widgetExample = { + api: "{url}/api/{endpoint}", + mappings: { + // `/api/graphql` + stats: { + endpoint: "graphql", + method: "POST", + body: { + query: ` + query { + stats { + total + average + } + } + `, + }, + headers: { + "Content-Type": "application/json", + }, + }, + }, +}; +``` + +### `allowedEndpoints` + +The `allowedEndpoints` property is a RegExp that represents the allowed endpoints that the widget can use. If the widget tries to access an endpoint that is not allowed, the request will be blocked. + +`allowedEndpoints` can be used when endpoint validation is simple and can be done using a regular expression, and more control is not required. + +!!! note "Security Note" + + The `mappings` or `allowedEndpoints` property is required for the widget to fetch data from more than a static URL. Homepage uses a whitelist approach to ensure that widgets only access allowed endpoints. + +```js +const widgetExample = { + api: "{url}/api/{endpoint}", + allowedEndpoints: /^stats|notices$/, +}; +``` + +This configuration will only allow the widget to access the `stats` and `notices` endpoints. diff --git a/docs/widgets/info/glances.md b/docs/widgets/info/glances.md index b7fd7efd..52c5cf28 100644 --- a/docs/widgets/info/glances.md +++ b/docs/widgets/info/glances.md @@ -12,6 +12,7 @@ The Glances widget allows you to monitor the resources (CPU, memory, storage, te url: http://host.or.ip:port username: user # optional if auth enabled in Glances password: pass # optional if auth enabled in Glances + version: 4 # required only if running glances v4 or higher, defaults to 3 cpu: true # optional, enabled by default, disable by setting to false mem: true # optional, enabled by default, disable by setting to false cputemp: true # disabled by default diff --git a/docs/widgets/info/openmeteo.md b/docs/widgets/info/openmeteo.md index 4cc49e26..fb5bb171 100644 --- a/docs/widgets/info/openmeteo.md +++ b/docs/widgets/info/openmeteo.md @@ -13,6 +13,8 @@ No registration is required at all! See [https://open-meteo.com/en/docs](https:/ timezone: Europe/Kiev # optional units: metric # or imperial cache: 5 # Time in minutes to cache API responses, to stay within limits + format: # optional, Intl.NumberFormat options + maximumFractionDigits: 1 ``` You can optionally not pass a `latitude` and `longitude` and the widget will use your current location (requires a secure context, eg. HTTPS). diff --git a/docs/widgets/info/openweathermap.md b/docs/widgets/info/openweathermap.md index 04733f5d..320d5d85 100644 --- a/docs/widgets/info/openweathermap.md +++ b/docs/widgets/info/openweathermap.md @@ -14,6 +14,8 @@ The free tier "One Call API" is all that's required, you will need to [subscribe provider: openweathermap apiKey: youropenweathermapkey # required only if not using provider, this reveals api key in requests cache: 5 # Time in minutes to cache API responses, to stay within limits + format: # optional, Intl.NumberFormat options + maximumFractionDigits: 1 ``` You can optionally not pass a `latitude` and `longitude` and the widget will use your current location (requires a secure context, eg. HTTPS). diff --git a/docs/widgets/info/resources.md b/docs/widgets/info/resources.md index b4f85d69..8281cec0 100644 --- a/docs/widgets/info/resources.md +++ b/docs/widgets/info/resources.md @@ -19,6 +19,8 @@ _Note: unfortunately, the package used for getting CPU temp ([systeminformation] memory: true disk: /disk/mount/path cputemp: true + tempmin: 0 # optional, minimum cpu temp + tempmax: 100 # optional, maximum cpu temp uptime: true units: imperial # only used by cpu temp refresh: 3000 # optional, in ms diff --git a/docs/widgets/info/weather.md b/docs/widgets/info/weather.md index 6357f0c0..ab13b673 100644 --- a/docs/widgets/info/weather.md +++ b/docs/widgets/info/weather.md @@ -15,6 +15,8 @@ The free tier is all that's required, you will need to [register](https://www.we units: metric # or imperial apiKey: yourweatherapikey cache: 5 # Time in minutes to cache API responses, to stay within limits + format: # optional, Intl.NumberFormat options + maximumFractionDigits: 1 ``` You can optionally not pass a `latitude` and `longitude` and the widget will use your current location (requires a secure context, eg. HTTPS). diff --git a/docs/widgets/services/authentik.md b/docs/widgets/services/authentik.md index 3b84009f..8968f4bf 100644 --- a/docs/widgets/services/authentik.md +++ b/docs/widgets/services/authentik.md @@ -7,14 +7,13 @@ Learn more about [Authentik](https://github.com/goauthentik/authentik). This widget reads the number of active users in the system, as well as logins for the last 24 hours. -You will need to generate an API token for an existing user. To do so follow these steps: +You will need to generate an API token for an existing user under `Admin Portal` > `Directory` > `Tokens & App passwords`. +Make sure to set Intent to "API Token". -1. Navigate to the Authentik Admin Portal -2. Expand Directory, the click Tokens & App passwords -3. Click the Create button -4. Fill out the dialog making sure to set Intent to API Token -5. Click the Create button on the dialog -6. Click the copy button on the far right of the newly created API Token +The account you made the API token for also needs the following **Assigned global permissions** in Authentik: + +- authentik Core -> Can view User (Model: User) +- authentik Events -> Can view Event (Model: Event) Allowed fields: `["users", "loginsLast24H", "failedLoginsLast24H"]`. diff --git a/docs/widgets/services/azuredevops.md b/docs/widgets/services/azuredevops.md index 218007fe..78846115 100644 --- a/docs/widgets/services/azuredevops.md +++ b/docs/widgets/services/azuredevops.md @@ -7,10 +7,10 @@ Learn more about [Azure DevOps](https://azure.microsoft.com/en-us/products/devop This widget has 2 functions: -1. Pipelines: checks if the relevant pipeline is running or not, and if not, reports the last status.\ +1. Pipelines: checks if the relevant pipeline is running or not, and if not, reports the last status.
Allowed fields: `["result", "status"]`. -2. Pull Requests: returns the amount of open PRs, the amount of the PRs you have open, and how many PRs that you open are marked as 'Approved' by at least 1 person and not yet completed.\ +2. Pull Requests: returns the amount of open PRs, the amount of the PRs you have open, and how many PRs that you open are marked as 'Approved' by at least 1 person and not yet completed.
Allowed fields: `["totalPrs", "myPrs", "approved"]`. You will need to generate a personal access token for an existing user, see the [azure documentation](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#create-a-pat) diff --git a/docs/widgets/services/channelsdvrserver.md b/docs/widgets/services/channelsdvrserver.md index bedf8037..9dcafa58 100644 --- a/docs/widgets/services/channelsdvrserver.md +++ b/docs/widgets/services/channelsdvrserver.md @@ -8,5 +8,5 @@ Learn more about [Channels DVR Server](https://getchannels.com/dvr-server/). ```yaml widget: type: channelsdvrserver - url: http://192.168.1.55:8089 + url: http://server.host.or.ip:port ``` diff --git a/docs/widgets/services/crowdsec.md b/docs/widgets/services/crowdsec.md new file mode 100644 index 00000000..da15a478 --- /dev/null +++ b/docs/widgets/services/crowdsec.md @@ -0,0 +1,19 @@ +--- +title: Crowdsec +description: Crowdsec Widget Configuration +--- + +Learn more about [Crowdsec](https://crowdsec.net). + +See the [crowdsec docs](https://docs.crowdsec.net/docs/local_api/intro/#machines) for information about registering a machine, +in most instances you can use the default credentials (`/etc/crowdsec/local_api_credentials.yaml`). + +Allowed fields: `["alerts", "bans"]`. + +```yaml +widget: + type: crowdsec + url: http://crowdsechostorip:port + username: localhost # machine_id in crowdsec + password: password +``` diff --git a/docs/widgets/services/diskstation.md b/docs/widgets/services/diskstation.md index 36010bfa..55e28355 100644 --- a/docs/widgets/services/diskstation.md +++ b/docs/widgets/services/diskstation.md @@ -11,22 +11,27 @@ An optional 'volume' parameter can be supplied to specify which volume's free sp Allowed fields: `["uptime", "volumeAvailable", "resources.cpu", "resources.mem"]`. -To access these system metrics you need to connect to the DiskStation with an account that is a member of the default `Administrators` group. That is because these metrics are requested from the API's `SYNO.Core.System` part that is only available to admin users. In order to keep the security impact as small as possible we can set the account in DSM up to limit the user's permissions inside the Synology system. In DSM 7.x, for instance, follow these steps: +To access these system metrics you need to connect to the DiskStation (`DSM`) with an account that is a member of the default `Administrators` group. That is because these metrics are requested from the API's `SYNO.Core.System` part that is only available to admin users. In order to keep the security impact as small as possible we can set the account in DSM up to limit the user's permissions inside the Synology system. In DSM 7.x, for instance, follow these steps: 1. Create a new user, i.e. `remote_stats`. 2. Set up a strong password for the new user 3. Under the `User Groups` tab of the user config dialogue check the box for `Administrators`. 4. On the `Permissions` tab check the top box for `No Access`, effectively prohibiting the user from accessing anything in the shared folders. 5. Under `Applications` check the box next to `Deny` in the header to explicitly prohibit login to all applications. -6. Now _only_ allow login to the `Download Station` application, either by +6. Now _only_ allow login to the `DSM` application, either by - unchecking `Deny` in the respective row, or (if inheriting permission doesn't work because of other group settings) - checking `Allow` for this app, or - checking `By IP` for this app to limit the source of login attempts to one or more IP addresses/subnets. -7. When the `Preview` column shows `Allow` in the `Download Station` row, click `Save`. +7. When the `Preview` column shows `Allow` in the `DSM` row, click `Save`. Now configure the widget with the correct login information and test it. -If you encounter issues during testing, make sure to uncheck the option for automatic blocking due to invalid logins under `Control Panel > Security > Protection`. If desired, this setting can be reactivated once the login is established working. +If you encounter issues during testing: + +1. Make sure to uncheck the option for automatic blocking due to invalid logins under `Control Panel > Security > Protection`. + - If desired, this setting can be reactivated once the login is established working. +2. Login to your Synology DSM with the newly created account and accept terms and conditions. +3. Reattempt ```yaml widget: diff --git a/docs/widgets/services/emby.md b/docs/widgets/services/emby.md index f262bfc6..e658d73b 100644 --- a/docs/widgets/services/emby.md +++ b/docs/widgets/services/emby.md @@ -16,4 +16,7 @@ widget: key: apikeyapikeyapikeyapikeyapikey enableBlocks: true # optional, defaults to false enableNowPlaying: true # optional, defaults to true + enableUser: true # optional, defaults to false + showEpisodeNumber: true # optional, defaults to false + expandOneStreamToTwoRows: false # optional, defaults to true ``` diff --git a/docs/widgets/services/esphome.md b/docs/widgets/services/esphome.md new file mode 100644 index 00000000..e14431fd --- /dev/null +++ b/docs/widgets/services/esphome.md @@ -0,0 +1,19 @@ +--- +title: ESPHome +description: ESPHome Widget Configuration +--- + +Learn more about [ESPHome](https://esphome.io/). + +Show the number of ESPHome devices based on their state. + +Allowed fields: `["total", "online", "offline", "offline_alt", "unknown"]` (maximum of 4). + +By default ESPHome will only mark devices as `offline` if their address cannot be pinged. If it has an invalid config or its name cannot be resolved (by DNS) its status will be marked as `unknown`. +To group both `offline` and `unknown` devices together, users should use the `offline_alt` field instead. This sums all devices that are _not_ online together. + +```yaml +widget: + type: esphome + url: http://esphome.host.or.ip:port +``` diff --git a/docs/widgets/services/gitea.md b/docs/widgets/services/gitea.md index bf75aa69..140c4ee7 100644 --- a/docs/widgets/services/gitea.md +++ b/docs/widgets/services/gitea.md @@ -5,9 +5,9 @@ description: Gitea Widget Configuration Learn more about [Gitea](https://gitea.com). -API token requires `notifications` and `repository` permissions. See the [gitea documentation](https://docs.gitea.com/development/api-usage#generating-and-listing-api-tokens) for details on generating tokens. +API token requires `notifications`, `repository` and `issue` permissions. See the [gitea documentation](https://docs.gitea.com/development/api-usage#generating-and-listing-api-tokens) for details on generating tokens. -Allowed fields: ["notifications", "issues", "pulls"] +Allowed fields: `["notifications", "issues", "pulls"]`. ```yaml widget: diff --git a/docs/widgets/services/glances.md b/docs/widgets/services/glances.md index 134dcb5f..562cf57a 100644 --- a/docs/widgets/services/glances.md +++ b/docs/widgets/services/glances.md @@ -17,8 +17,11 @@ widget: url: http://glances.host.or.ip:port username: user # optional if auth enabled in Glances password: pass # optional if auth enabled in Glances + version: 4 # required only if running glances v4 or higher, defaults to 3 metric: cpu diskUnits: bytes # optional, bytes (default) or bbytes. Only applies to disk + refreshInterval: 5000 # optional - in milliseconds, defaults to 1000 or more, depending on the metric + pointsLimit: 15 # optional, defaults to 15 ``` _Please note, this widget does not need an `href`, `icon` or `description` on its parent service. To achieve the same effect as the examples above, see as an example:_ diff --git a/docs/widgets/services/homeassistant.md b/docs/widgets/services/homeassistant.md index e4e1e5b4..fc98ed88 100644 --- a/docs/widgets/services/homeassistant.md +++ b/docs/widgets/services/homeassistant.md @@ -18,7 +18,7 @@ The `custom` property will have no effect as long as the `fields` property is de - state labels and values can be user defined and may reference entity attributes in curly brackets - if no state label is defined it will default to `"{attributes.friendly_name}"` - if no state value is defined it will default to `"{state} {attributes.unit_of_measurement}"` -- `template` will query the specified template, see (Home Assistant Templating)[https://www.home-assistant.io/docs/configuration/templating] +- `template` will query the specified template, see [Home Assistant Templating](https://www.home-assistant.io/docs/configuration/templating) - if no template label is defined it will be empty ```yaml diff --git a/docs/widgets/services/homebox.md b/docs/widgets/services/homebox.md new file mode 100644 index 00000000..af9ebad5 --- /dev/null +++ b/docs/widgets/services/homebox.md @@ -0,0 +1,23 @@ +--- +title: Homebox +description: Homebox Widget Configuration +--- + +Learn more about [Homebox](https://github.com/hay-kot/homebox). + +Uses the same username and password used to login from the web. + +The `totalValue` field will attempt to format using the currency you have configured in Homebox. + +Allowed fields: `["items", "totalWithWarranty", "locations", "labels", "users", "totalValue"]`. + +If more than 4 fields are provided, only the first 4 are displayed. + +```yaml +widget: + type: homebox + url: http://homebox.host.or.ip:port + username: username + password: password + fields: ["items", "locations", "totalValue"] # optional - default fields shown +``` diff --git a/docs/widgets/services/jackett.md b/docs/widgets/services/jackett.md index 22e089a4..e102743b 100644 --- a/docs/widgets/services/jackett.md +++ b/docs/widgets/services/jackett.md @@ -5,7 +5,7 @@ description: Jackett Widget Configuration Learn more about [Jackett](https://github.com/Jackett/Jackett). -Jackett must not have any authentication for the widget to work. +If Jackett has an admin password set, you must set the `password` field for the widget to work. Allowed fields: `["configured", "errored"]`. @@ -13,5 +13,5 @@ Allowed fields: `["configured", "errored"]`. widget: type: jackett url: http://jackett.host.or.ip - key: jackettapikey + password: jackettadminpassword # optional ``` diff --git a/docs/widgets/services/jellyfin.md b/docs/widgets/services/jellyfin.md index 0428c622..b6724a15 100644 --- a/docs/widgets/services/jellyfin.md +++ b/docs/widgets/services/jellyfin.md @@ -16,4 +16,7 @@ widget: key: apikeyapikeyapikeyapikeyapikey enableBlocks: true # optional, defaults to false enableNowPlaying: true # optional, defaults to true + enableUser: true # optional, defaults to false + showEpisodeNumber: true # optional, defaults to false + expandOneStreamToTwoRows: false # optional, defaults to true ``` diff --git a/docs/widgets/services/medusa.md b/docs/widgets/services/medusa.md index e500d95f..82ec2b53 100644 --- a/docs/widgets/services/medusa.md +++ b/docs/widgets/services/medusa.md @@ -3,7 +3,7 @@ title: Medusa description: Medusa Widget Configuration --- -Learn more about [Medusa](https://github.com/medusajs/medusa). +Learn more about [Medusa](https://github.com/pymedusa/Medusa). Allowed fields: `["wanted", "queued", "series"]`. diff --git a/docs/widgets/services/mjpeg.md b/docs/widgets/services/mjpeg.md index e0e912d0..b0784ff0 100644 --- a/docs/widgets/services/mjpeg.md +++ b/docs/widgets/services/mjpeg.md @@ -3,7 +3,7 @@ title: MJPEG description: MJPEG Stream Widget Configuration --- -![camera-preview](https://github.com/gethomepage/homepage-docs/assets/82196/dc375ae3-0670-489f-8db6-83ff1f423d12) +![camera-preview](https://github.com/gethomepage/homepage/assets/4887959/dbc388d7-04a6-482c-8f36-f9534689b062) Pass the stream URL from a service like [ยตStreamer](https://github.com/pikvm/ustreamer) or [camera-streamer](https://github.com/ayufan/camera-streamer). diff --git a/docs/widgets/services/netalertx.md b/docs/widgets/services/netalertx.md new file mode 100644 index 00000000..4579d74c --- /dev/null +++ b/docs/widgets/services/netalertx.md @@ -0,0 +1,16 @@ +--- +title: NetAlertX +description: NetAlertX (formerly PiAlert) Widget Configuration +--- + +Learn more about [NetAlertX](https://github.com/jokob-sk/NetAlertX). + +_Note that the project was renamed from PiAlert to NetAlertX._ + +Allowed fields: `["total", "connected", "new_devices", "down_alerts"]`. + +```yaml +widget: + type: netalertx + url: http://ip:port +``` diff --git a/docs/widgets/services/openwrt.md b/docs/widgets/services/openwrt.md index c1c3ee94..3759d2b0 100644 --- a/docs/widgets/services/openwrt.md +++ b/docs/widgets/services/openwrt.md @@ -26,29 +26,35 @@ In order for homepage to access the OpenWRT RPC endpoints you will need to [crea Create an ACL named `homepage.json` in `/usr/share/rpcd/acl.d/`, the following permissions will suffice: -``` +```json { - "homepage": { - "description": "Homepage widget", - "read": { - "ubus": { - "network.interface.wan": ["status"], - "network.interface.lan": ["status"], - "network.device": ["status"] - "system": ["info"] - } - }, - } + "homepage": { + "description": "Homepage widget", + "read": { + "ubus": { + "network.interface.wan": ["status"], + "network.interface.lan": ["status"], + "network.device": ["status"], + "system": ["info"] + } + } + } } ``` -Then add a user that will use that ACL in `/etc/config/rpc`: +Create a `crypt(5)` password hash using the following command in the OpenWRT shell: -```config login +```sh +uhttpd -m "" +``` + +Then add a user that will use the ACL and hashed password in `/etc/config/rpcd`: + +``` +config login option username 'homepage' - option password '' + option password '' list read homepage - list write '*' ``` This username and password will be used in Homepage's services.yaml to grant access. diff --git a/docs/widgets/services/peanut.md b/docs/widgets/services/peanut.md index 63d75bbf..eca349b9 100644 --- a/docs/widgets/services/peanut.md +++ b/docs/widgets/services/peanut.md @@ -9,7 +9,7 @@ This widget adds support for [Network UPS Tools](https://networkupstools.org/) v The default ups name is `ups`. To configure more than one ups, you must create multiple peanut services. -Allowed fields: `["battery_charge", "ups_load", "ups_status"]` +Allowed fields: `["battery_charge", "ups_load", "ups_status"]`. !!! note diff --git a/docs/widgets/services/pfsense.md b/docs/widgets/services/pfsense.md index 1d9e8461..8f32a718 100644 --- a/docs/widgets/services/pfsense.md +++ b/docs/widgets/services/pfsense.md @@ -9,9 +9,9 @@ This widget requires the installation of the [pfsense-api](https://github.com/ja Once pfSense API is installed, you can set the API to be read-only in System > API > Settings. -Currently the only supported authentication mode is 'Local Database'. +There are two currently supported authentication modes: 'Local Database' and 'API Token'. For 'Local Database', use `username` and `password` with the credentials of an admin user. For 'API Token', utilize the `headers` parameter with `client_token` and `client_id` obtained from pfSense as shown below. Do not use both headers and username / password. -WAN interface to monitor can be defined by updating the `wan` param. +The interface to monitor is defined by updating the `wan` parameter. It should be referenced as it is shown under Interfaces > Assignments in pfSense. Load is returned instead of cpu utilization. This is a limitation in the pfSense API due to the complexity of this calculation. This may become available in future versions. @@ -21,7 +21,10 @@ Allowed fields: `["load", "memory", "temp", "wanStatus", "wanIP", "disk"]` (maxi widget: type: pfsense url: http://pfsense.host.or.ip:port - username: user - password: pass + username: user # optional, or API token + password: pass # optional, or API token + headers: # optional, or username/password + Authorization: client_id client_token wan: igb0 + fields: ["load", "memory", "temp", "wanStatus"] # optional ``` diff --git a/docs/widgets/services/pialert.md b/docs/widgets/services/pialert.md deleted file mode 100644 index ab8fb1e9..00000000 --- a/docs/widgets/services/pialert.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: PiAlert -description: PiAlert Widget Configuration ---- - -Learn more about [PiAlert](https://github.com/jokob-sk/Pi.Alert). - -Note that [pucherot/PiAlert](https://github.com/pucherot/Pi.Alert) has been abandoned and might not work properly. - -Allowed fields: `["total", "connected", "new_devices", "down_alerts"]`. - -```yaml -widget: - type: pialert - url: http://ip:port -``` diff --git a/docs/widgets/services/pihole.md b/docs/widgets/services/pihole.md index a12f57a8..90d5926c 100644 --- a/docs/widgets/services/pihole.md +++ b/docs/widgets/services/pihole.md @@ -9,11 +9,14 @@ As of v2022.12 [PiHole requires the use of an API key](https://pi-hole.net/blog/ Allowed fields: `["queries", "blocked", "blocked_percent", "gravity"]`. +Note: by default the "blocked" and "blocked_percent" fields are merged e.g. "1,234 (15%)" but explicitly including the "blocked_percent" field will change them to display separately. + ```yaml widget: type: pihole url: http://pi.hole.or.ip + version: 6 # required if running v6 or higher, defaults to 5 key: yourpiholeapikey # optional ``` -_Added in v0.1.0, updated in v0.6.18_ +_Added in v0.1.0, updated in v0.8.9_ diff --git a/docs/widgets/services/planit.md b/docs/widgets/services/plantit.md similarity index 82% rename from docs/widgets/services/planit.md rename to docs/widgets/services/plantit.md index d1cebfaa..f11b942b 100644 --- a/docs/widgets/services/planit.md +++ b/docs/widgets/services/plantit.md @@ -7,6 +7,8 @@ Learn more about [Plantit](https://github.com/MDeLuise/plant-it). API key can be created from the REST API. +Allowed fields: `["events", "plants", "photos", "species"]`. + ```yaml widget: type: plantit diff --git a/docs/widgets/services/plex-tautulli.md b/docs/widgets/services/plex-tautulli.md index b88f6eeb..9cacdf05 100644 --- a/docs/widgets/services/plex-tautulli.md +++ b/docs/widgets/services/plex-tautulli.md @@ -14,4 +14,7 @@ widget: type: tautulli url: http://tautulli.host.or.ip key: apikeyapikeyapikeyapikeyapikey + enableUser: true # optional, defaults to false + showEpisodeNumber: true # optional, defaults to false + expandOneStreamToTwoRows: false # optional, defaults to true ``` diff --git a/docs/widgets/services/prometheus.md b/docs/widgets/services/prometheus.md index 02560c91..beb04b5e 100644 --- a/docs/widgets/services/prometheus.md +++ b/docs/widgets/services/prometheus.md @@ -5,7 +5,7 @@ description: Prometheus Widget Configuration Learn more about [Prometheus](https://github.com/prometheus/prometheus). -Allowed fields: `["targets_up", "targets_down", "targets_total"]` +Allowed fields: `["targets_up", "targets_down", "targets_total"]`. ```yaml widget: diff --git a/docs/widgets/services/pterodactyl.md b/docs/widgets/services/pterodactyl.md index 76e0f6ce..abf5899b 100644 --- a/docs/widgets/services/pterodactyl.md +++ b/docs/widgets/services/pterodactyl.md @@ -5,7 +5,7 @@ description: Pterodactyl Widget Configuration Learn more about [Pterodactyl](https://github.com/pterodactyl). -Allowed fields: `["nodes", "servers"]` +Allowed fields: `["nodes", "servers"]`. ```yaml widget: diff --git a/docs/widgets/services/speedtest-tracker.md b/docs/widgets/services/speedtest-tracker.md index 7e250967..99b5b993 100644 --- a/docs/widgets/services/speedtest-tracker.md +++ b/docs/widgets/services/speedtest-tracker.md @@ -16,4 +16,5 @@ Allowed fields: `["download", "upload", "ping"]`. widget: type: speedtest url: http://speedtest.host.or.ip + bitratePrecision: 3 # optional, default is 0 ``` diff --git a/docs/widgets/services/stash.md b/docs/widgets/services/stash.md new file mode 100644 index 00000000..b2d3e0ef --- /dev/null +++ b/docs/widgets/services/stash.md @@ -0,0 +1,20 @@ +--- +title: Stash +description: Stash Widget Configuration +--- + +Learn more about [Stash](https://github.com/stashapp/stash). + +Find your API key from inside Stash at `Settings > Security > API Key`. Note that the API key is only required if your Stash instance has login credentials. + +Allowed fields: `["scenes", "scenesPlayed", "playCount", "playDuration", "sceneSize", "sceneDuration", "images", "imageSize", "galleries", "performers", "studios", "movies", "tags", "oCount"]`. + +If more than 4 fields are provided, only the first 4 are displayed. + +```yaml +widget: + type: stash + url: http://stash.host.or.ip + key: stashapikey + fields: ["scenes", "images"] # optional - default fields shown +``` diff --git a/docs/widgets/services/swagdashboard.md b/docs/widgets/services/swagdashboard.md new file mode 100644 index 00000000..2b6c9792 --- /dev/null +++ b/docs/widgets/services/swagdashboard.md @@ -0,0 +1,14 @@ +--- +title: SWAG Dashboard +description: SWAG Dashboard Widget Configuration +--- + +Learn more about [SWAG Dashboard](https://github.com/linuxserver/docker-mods/tree/swag-dashboard). + +Allowed fields: `["proxied", "auth", "outdated", "banned"]`. + +```yaml +widget: + type: swagdashboard + url: http://swagdashboard.host.or.ip:adminport # default port is 81 +``` diff --git a/docs/widgets/services/tandoor.md b/docs/widgets/services/tandoor.md new file mode 100644 index 00000000..134bc8fd --- /dev/null +++ b/docs/widgets/services/tandoor.md @@ -0,0 +1,15 @@ +--- +title: Tandoor +description: Tandoor Widget Configuration +--- + +Generate a user API key under `Settings > API > Generate`. For the token's scope, use `read`. + +Allowed fields: `["users", "recipes", "keywords"]`. + +```yaml +widget: + type: tandoor + url: http://tandoor-frontend.host.or.ip + key: tandoor-api-token +``` diff --git a/docs/widgets/services/truenas.md b/docs/widgets/services/truenas.md index 24350490..97bba3be 100644 --- a/docs/widgets/services/truenas.md +++ b/docs/widgets/services/truenas.md @@ -11,6 +11,8 @@ To create an API Key, follow [the official TrueNAS documentation](https://www.tr A detailed pool listing is disabled by default, but can be enabled with the `enablePools` option. +To use the `enablePools` option with TrueNAS Core, the `nasType` parameter is required. + ```yaml widget: type: truenas @@ -19,4 +21,5 @@ widget: password: pass # not required if using api key key: yourtruenasapikey # not required if using username / password enablePools: true # optional, defaults to false + nasType: scale # defaults to scale, must be set to 'core' if using enablePools with TrueNAS Core ``` diff --git a/docs/widgets/services/uptime-kuma.md b/docs/widgets/services/uptime-kuma.md index 56aa5a57..399a0eee 100644 --- a/docs/widgets/services/uptime-kuma.md +++ b/docs/widgets/services/uptime-kuma.md @@ -5,7 +5,7 @@ description: Uptime Kuma Widget Configuration Learn more about [Uptime Kuma](https://github.com/louislam/uptime-kuma). -As Uptime Kuma does not yet have a full API the widget uses data from a single "status page". As such you will need a status page setup with a group of monitored sites, which is where you get the slug (without the `/status/` portion). +As Uptime Kuma does not yet have a full API the widget uses data from a single "status page". As such you will need a status page setup with a group of monitored sites, which is where you get the slug (the url without the `/status/` portion). E.g. if your status page is URL http://uptimekuma.host/status/statuspageslug, insert `slug: statuspageslug`. Allowed fields: `["up", "down", "uptime", "incident"]`. diff --git a/docs/widgets/services/wgeasy.md b/docs/widgets/services/wgeasy.md new file mode 100644 index 00000000..c5442081 --- /dev/null +++ b/docs/widgets/services/wgeasy.md @@ -0,0 +1,20 @@ +--- +title: Wg-Easy +description: Wg-Easy Widget Configuration +--- + +Learn more about [Wg-Easy](https://github.com/wg-easy/wg-easy). + +Allowed fields: `["connected", "enabled", "disabled", "total"]`. + +Note: by default `["connected", "enabled", "total"]` are displayed. + +To detect if a device is connected the time since the last handshake is queried. `threshold` is the time to wait in minutes since the last handshake to consider a device connected. Default is 2 minutes. + +```yaml +widget: + type: wgeasy + url: http://wg.easy.or.ip + password: yourwgeasypassword + threshold: 2 # optional +``` diff --git a/docs/widgets/services/whatsupdocker.md b/docs/widgets/services/whatsupdocker.md index 25c2fabf..74eb2c97 100644 --- a/docs/widgets/services/whatsupdocker.md +++ b/docs/widgets/services/whatsupdocker.md @@ -1,11 +1,9 @@ --- -title: Whats Up Docker -description: WhatsUpDocker Widget Configuration +title: What's Up Docker +description: What's Up Docker Widget Configuration --- -Learn more about [Whats Up Docker](https://github.com/fmartinou/whats-up-docker). - -Currently requires unauthenticated whatsupdocker instance. +Learn more about [What's Up Docker](https://github.com/fmartinou/whats-up-docker). Allowed fields: `["monitoring", "updates"]`. @@ -13,4 +11,6 @@ Allowed fields: `["monitoring", "updates"]`. widget: type: whatsupdocker url: http://whatsupdocker:port + username: username # optional + password: password # optional ``` diff --git a/mkdocs.yml b/mkdocs.yml index c6ecfda9..0f440f8d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,191 +10,208 @@ edit_uri: https://github.com/gethomepage/homepage/tree/main/docs/ nav: - "Home": - - index.md + - index.md - "Installation": - - installation/index.md - - installation/docker.md - - installation/k8s.md - - installation/unraid.md - - installation/source.md + - installation/index.md + - installation/docker.md + - installation/k8s.md + - installation/unraid.md + - installation/source.md - "Configuration": - - configs/index.md - - configs/settings.md - - configs/bookmarks.md - - configs/services.md - - configs/service-widgets.md - - configs/kubernetes.md - - configs/docker.md - - configs/custom-css-js.md + - configs/index.md + - configs/settings.md + - configs/bookmarks.md + - configs/services.md + - configs/service-widgets.md + - configs/kubernetes.md + - configs/docker.md + - configs/custom-css-js.md - "Widgets": - - widgets/index.md - - "Service Widgets": - - widgets/services/index.md - - widgets/services/adguard-home.md - - widgets/services/atsumeru.md - - widgets/services/audiobookshelf.md - - widgets/services/authentik.md - - widgets/services/autobrr.md - - widgets/services/azuredevops.md - - widgets/services/bazarr.md - - widgets/services/caddy.md - - widgets/services/calendar.md - - widgets/services/calibre-web.md - - widgets/services/changedetectionio.md - - widgets/services/channelsdvrserver.md - - widgets/services/cloudflared.md - - widgets/services/coin-market-cap.md - - widgets/services/customapi.md - - widgets/services/deluge.md - - widgets/services/diskstation.md - - widgets/services/downloadstation.md - - widgets/services/emby.md - - widgets/services/evcc.md - - widgets/services/fileflows.md - - widgets/services/flood.md - - widgets/services/freshrss.md - - widgets/services/fritzbox.md - - widgets/services/gamedig.md - - widgets/services/gatus.md - - widgets/services/ghostfolio.md - - widgets/services/gitea.md - - widgets/services/glances.md - - widgets/services/gluetun.md - - widgets/services/gotify.md - - widgets/services/grafana.md - - widgets/services/hdhomerun.md - - widgets/services/healthchecks.md - - widgets/services/homeassistant.md - - widgets/services/homebridge.md - - widgets/services/iframe.md - - widgets/services/immich.md - - widgets/services/jackett.md - - widgets/services/jdownloader.md - - widgets/services/jellyfin.md - - widgets/services/jellyseerr.md - - widgets/services/kavita.md - - widgets/services/komga.md - - widgets/services/kopia.md - - widgets/services/lidarr.md - - widgets/services/mastodon.md - - widgets/services/mealie.md - - widgets/services/medusa.md - - widgets/services/mikrotik.md - - widgets/services/minecraft.md - - widgets/services/miniflux.md - - widgets/services/mjpeg.md - - widgets/services/moonraker.md - - widgets/services/mylar.md - - widgets/services/navidrome.md - - widgets/services/netdata.md - - widgets/services/nextcloud.md - - widgets/services/nextdns.md - - widgets/services/nginx-proxy-manager.md - - widgets/services/nzbget.md - - widgets/services/octoprint.md - - widgets/services/omada.md - - widgets/services/ombi.md - - widgets/services/opendtu.md - - widgets/services/openmediavault.md - - widgets/services/opnsense.md - - widgets/services/overseerr.md - - widgets/services/paperlessngx.md - - widgets/services/peanut.md - - widgets/services/pfsense.md - - widgets/services/photoprism.md - - widgets/services/pialert.md - - widgets/services/pihole.md - - widgets/services/plantit.md - - widgets/services/plex-tautulli.md - - widgets/services/plex.md - - widgets/services/portainer.md - - widgets/services/prometheus.md - - widgets/services/prowlarr.md - - widgets/services/proxmox.md - - widgets/services/proxmoxbackupserver.md - - widgets/services/pterodactyl.md - - widgets/services/pyload.md - - widgets/services/qbittorrent.md - - widgets/services/qnap.md - - widgets/services/radarr.md - - widgets/services/readarr.md - - widgets/services/romm.md - - widgets/services/rutorrent.md - - widgets/services/sabnzbd.md - - widgets/services/scrutiny.md - - widgets/services/sonarr.md - - widgets/services/speedtest-tracker.md - - widgets/services/syncthing-relay-server.md - - widgets/services/tailscale.md - - widgets/services/tdarr.md - - widgets/services/traefik.md - - widgets/services/transmission.md - - widgets/services/truenas.md - - widgets/services/tubearchivist.md - - widgets/services/unifi-controller.md - - widgets/services/unmanic.md - - widgets/services/uptime-kuma.md - - widgets/services/uptimerobot.md - - widgets/services/urbackup.md - - widgets/services/watchtower.md - - widgets/services/whatsupdocker.md - - widgets/services/xteve.md - - "Information Widgets": - - widgets/info/index.md - - widgets/info/datetime.md - - widgets/info/glances.md - - widgets/info/greeting.md - - widgets/info/kubernetes.md - - widgets/info/logo.md - - widgets/info/longhorn.md - - widgets/info/openmeteo.md - - widgets/info/openweathermap.md - - widgets/info/resources.md - - widgets/info/search.md - - widgets/info/unifi_controller.md - - widgets/info/weather.md + - widgets/index.md + - "Service Widgets": + - widgets/services/index.md + - widgets/services/adguard-home.md + - widgets/services/atsumeru.md + - widgets/services/audiobookshelf.md + - widgets/services/authentik.md + - widgets/services/autobrr.md + - widgets/services/azuredevops.md + - widgets/services/bazarr.md + - widgets/services/caddy.md + - widgets/services/calendar.md + - widgets/services/calibre-web.md + - widgets/services/changedetectionio.md + - widgets/services/channelsdvrserver.md + - widgets/services/cloudflared.md + - widgets/services/coin-market-cap.md + - widgets/services/crowdsec.md + - widgets/services/customapi.md + - widgets/services/deluge.md + - widgets/services/diskstation.md + - widgets/services/downloadstation.md + - widgets/services/emby.md + - widgets/services/esphome.md + - widgets/services/evcc.md + - widgets/services/fileflows.md + - widgets/services/flood.md + - widgets/services/freshrss.md + - widgets/services/fritzbox.md + - widgets/services/gamedig.md + - widgets/services/gatus.md + - widgets/services/ghostfolio.md + - widgets/services/gitea.md + - widgets/services/glances.md + - widgets/services/gluetun.md + - widgets/services/gotify.md + - widgets/services/grafana.md + - widgets/services/hdhomerun.md + - widgets/services/healthchecks.md + - widgets/services/homeassistant.md + - widgets/services/homebox.md + - widgets/services/homebridge.md + - widgets/services/iframe.md + - widgets/services/immich.md + - widgets/services/jackett.md + - widgets/services/jdownloader.md + - widgets/services/jellyfin.md + - widgets/services/jellyseerr.md + - widgets/services/kavita.md + - widgets/services/komga.md + - widgets/services/kopia.md + - widgets/services/lidarr.md + - widgets/services/mastodon.md + - widgets/services/mealie.md + - widgets/services/medusa.md + - widgets/services/mikrotik.md + - widgets/services/minecraft.md + - widgets/services/miniflux.md + - widgets/services/mjpeg.md + - widgets/services/moonraker.md + - widgets/services/mylar.md + - widgets/services/navidrome.md + - widgets/services/netdata.md + - widgets/services/netalertx.md + - widgets/services/nextcloud.md + - widgets/services/nextdns.md + - widgets/services/nginx-proxy-manager.md + - widgets/services/nzbget.md + - widgets/services/octoprint.md + - widgets/services/omada.md + - widgets/services/ombi.md + - widgets/services/opendtu.md + - widgets/services/openmediavault.md + - widgets/services/opnsense.md + - widgets/services/openwrt.md + - widgets/services/overseerr.md + - widgets/services/paperlessngx.md + - widgets/services/peanut.md + - widgets/services/pfsense.md + - widgets/services/photoprism.md + - widgets/services/pihole.md + - widgets/services/plantit.md + - widgets/services/plex-tautulli.md + - widgets/services/plex.md + - widgets/services/portainer.md + - widgets/services/prometheus.md + - widgets/services/prowlarr.md + - widgets/services/proxmox.md + - widgets/services/proxmoxbackupserver.md + - widgets/services/pterodactyl.md + - widgets/services/pyload.md + - widgets/services/qbittorrent.md + - widgets/services/qnap.md + - widgets/services/radarr.md + - widgets/services/readarr.md + - widgets/services/romm.md + - widgets/services/rutorrent.md + - widgets/services/sabnzbd.md + - widgets/services/scrutiny.md + - widgets/services/sonarr.md + - widgets/services/speedtest-tracker.md + - widgets/services/stash.md + - widgets/services/swagdashboard.md + - widgets/services/syncthing-relay-server.md + - widgets/services/tailscale.md + - widgets/services/tandoor.md + - widgets/services/tdarr.md + - widgets/services/traefik.md + - widgets/services/transmission.md + - widgets/services/truenas.md + - widgets/services/tubearchivist.md + - widgets/services/unifi-controller.md + - widgets/services/unmanic.md + - widgets/services/uptime-kuma.md + - widgets/services/uptimerobot.md + - widgets/services/urbackup.md + - widgets/services/watchtower.md + - widgets/services/whatsupdocker.md + - widgets/services/xteve.md + - "Information Widgets": + - widgets/info/index.md + - widgets/info/datetime.md + - widgets/info/glances.md + - widgets/info/greeting.md + - widgets/info/kubernetes.md + - widgets/info/logo.md + - widgets/info/longhorn.md + - widgets/info/openmeteo.md + - widgets/info/openweathermap.md + - widgets/info/resources.md + - widgets/info/search.md + - widgets/info/unifi_controller.md + - widgets/info/weather.md + - "Guides": + - widgets/authoring/index.md + - widgets/authoring/guide.md + - widgets/authoring/component.md + - widgets/authoring/widget.md + - widgets/authoring/proxies.md + - widgets/authoring/api.md + - widgets/authoring/translations.md - more/troubleshooting.md - "More": - - more/index.md - - more/development.md - - more/translations.md - - more/homepage-move.md + - more/index.md + - more/development.md + - more/translations.md + - more/homepage-move.md theme: name: material + custom_dir: docs/overrides language: en palette: - - media: "(prefers-color-scheme)" - toggle: - icon: material/brightness-auto - name: Switch to light mode - - media: "(prefers-color-scheme: light)" - scheme: default - primary: black - accent: black - toggle: - icon: material/brightness-7 - name: Switch to dark mode - - media: "(prefers-color-scheme: dark)" - scheme: slate - primary: black - accent: blue - toggle: - icon: material/brightness-4 - name: Switch to system preference + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: black + accent: black + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: black + accent: blue + toggle: + icon: material/brightness-4 + name: Switch to system preference logo: assets/light_squircle@2x.png favicon: assets/favicon.ico features: - - navigation.instant - - content.action.edit - - search.suggest - - search.share - - content.code.copy - - content.code.select - - navigation.tracking - - navigation.tabs - - navigation.sections - - navigation.indexes + - navigation.instant + - content.action.edit + - search.suggest + - search.share + - content.code.copy + - content.code.select + - navigation.tracking + - navigation.tabs + - navigation.sections + - navigation.indexes + - content.code.annotate extra_css: - "stylesheets/extra.css" @@ -223,6 +240,8 @@ markdown_extensions: - pymdownx.inlinehilite - pymdownx.snippets - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true - pymdownx.critic - pymdownx.caret - pymdownx.keys @@ -239,7 +258,12 @@ plugins: plugins: - optimize - typeset - - social + - social: + cards_layout: default/variant + cards_layout_options: + background_image: docs/assets/BlossomValley.jpg + background_color: "rgba(13, 29, 41, 128)" + color: "#ffffff" - tags - search: pipeline: diff --git a/package-lock.json b/package-lock.json index c89b7099..9c60309a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "classnames": "^2.5.1", "compare-versions": "^6.1.0", "dockerode": "^4.0.2", - "follow-redirects": "^1.15.5", + "follow-redirects": "^1.15.6", "gamedig": "^4.3.1", "i18next": "^21.10.0", "js-yaml": "^4.1.0", @@ -27,14 +27,14 @@ "ping": "^0.4.4", "pretty-bytes": "^6.1.1", "raw-body": "^2.5.2", - "react": "^18.2.0", + "react": "^18.3.1", "react-dom": "^18.2.0", "react-i18next": "^11.18.6", "react-icons": "^4.12.0", - "recharts": "^2.11.0", + "recharts": "^2.12.6", "rrule": "^2.8.1", "swr": "^1.3.0", - "systeminformation": "^5.21.24", + "systeminformation": "^5.22.7", "tough-cookie": "^4.1.3", "urbackup-server-api": "^0.8.9", "winston": "^3.11.0", @@ -43,20 +43,20 @@ "devDependencies": { "@tailwindcss/forms": "^0.5.7", "autoprefixer": "^10.4.17", - "eslint": "^8.56.0", + "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", - "eslint-config-next": "^12.3.4", + "eslint-config-next": "^14.2.3", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "postcss": "^8.4.33", - "prettier": "^3.2.4", + "eslint-plugin-react": "^7.34.2", + "eslint-plugin-react-hooks": "^4.6.2", + "postcss": "^8.4.38", + "prettier": "^3.2.5", "tailwind-scrollbar": "^3.0.5", - "tailwindcss": "^3.4.1", - "typescript": "^4.9.5" + "tailwindcss": "^3.4.3", + "typescript": "^5.4.5" }, "optionalDependencies": { "osx-temperature-sensor": "^1.0.8" @@ -165,9 +165,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -344,12 +344,58 @@ "integrity": "sha512-H/69Lc5Q02dq3o+dxxy5O/oNxFsZpdL6WREtOOtOM1B/weonIwDXkekr1KV5DPVPr12IHFPrMrcJQ6bgPMfn7A==" }, "node_modules/@next/eslint-plugin-next": { - "version": "12.3.4", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-12.3.4.tgz", - "integrity": "sha512-BFwj8ykJY+zc1/jWANsDprDIu2MgwPOIKxNVnrKvPs+f5TPegrVnem8uScND+1veT4B7F6VeqgaNLFW1Hzl9Og==", + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.3.tgz", + "integrity": "sha512-L3oDricIIjgj1AVnRdRor21gI7mShlSwU/1ZGHmqM3LzHhXXhdkrfeNY5zif25Bi5Dd7fiJHsbhoZCHfXYvlAw==", "dev": true, "dependencies": { - "glob": "7.1.7" + "glob": "10.3.10" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@next/swc-android-arm-eabi": { @@ -990,28 +1036,32 @@ } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -1030,6 +1080,26 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.findlastindex": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", @@ -1085,31 +1155,44 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.tosorted": { + "node_modules/array.prototype.toreversed": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", - "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", "is-shared-array-buffer": "^1.0.2" }, "engines": { @@ -1159,15 +1242,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/asynciterator.prototype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", - "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1211,10 +1285,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -1474,14 +1551,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1950,6 +2032,57 @@ "node": ">=0.10" } }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2011,17 +2144,20 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { @@ -2130,11 +2266,12 @@ } }, "node_modules/dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", "dependencies": { - "@babel/runtime": "^7.1.2" + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" } }, "node_modules/dom-serializer": { @@ -2228,6 +2365,19 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -2240,50 +2390,57 @@ } }, "node_modules/es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -2292,37 +2449,73 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-iterator-helpers": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", - "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, "dependencies": { - "asynciterator.prototype": "^1.0.0", - "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.1", - "es-set-tostringtag": "^2.0.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", + "internal-slot": "^1.0.7", "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.0.1" + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -2376,16 +2569,16 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -2471,20 +2664,20 @@ } }, "node_modules/eslint-config-next": { - "version": "12.3.4", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-12.3.4.tgz", - "integrity": "sha512-WuT3gvgi7Bwz00AOmKGhOeqnyA5P29Cdyr0iVjLyfDbk+FANQKcOjFUTZIdyYfe5Tq1x4TGcmoe4CwctGvFjHQ==", + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.3.tgz", + "integrity": "sha512-ZkNztm3Q7hjqvB1rRlOX8P9E/cXRL9ajRcs8jufEtwMfTVYRqnmtnaSu57QqHyBlovMuiB8LEzfLBkh5RYV6Fg==", "dev": true, "dependencies": { - "@next/eslint-plugin-next": "12.3.4", - "@rushstack/eslint-patch": "^1.1.3", - "@typescript-eslint/parser": "^5.21.0", + "@next/eslint-plugin-next": "14.2.3", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-import-resolver-typescript": "^2.7.1", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.31.7", - "eslint-plugin-react-hooks": "^4.5.0" + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" }, "peerDependencies": { "eslint": "^7.23.0 || ^8.0.0", @@ -2529,45 +2722,30 @@ } }, "node_modules/eslint-import-resolver-typescript": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", - "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", "dev": true, "dependencies": { "debug": "^4.3.4", - "glob": "^7.2.0", - "is-glob": "^4.0.3", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" }, "engines": { - "node": ">=4" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*" } }, - "node_modules/eslint-import-resolver-typescript/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/eslint-module-utils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", @@ -2698,27 +2876,29 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.33.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", - "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "version": "7.34.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", + "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", "dev": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.12", + "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.hasown": "^1.1.4", + "object.values": "^1.2.0", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.4", + "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.8" + "string.prototype.matchall": "^4.0.11" }, "engines": { "node": ">=4" @@ -2728,9 +2908,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "engines": { "node": ">=10" @@ -3039,9 +3219,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -3255,16 +3435,20 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3281,13 +3465,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -3296,6 +3481,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3421,6 +3618,12 @@ "url": "https://github.com/sindresorhus/got?sponsor=1" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3467,21 +3670,21 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -3503,12 +3706,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -3518,9 +3721,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { "function-bind": "^1.1.2" }, @@ -3727,12 +3930,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", + "es-errors": "^1.3.0", "hasown": "^2.0.0", "side-channel": "^1.0.4" }, @@ -3757,14 +3960,16 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3853,6 +4058,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -3935,9 +4155,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -4005,12 +4225,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4058,12 +4281,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "dependencies": { - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -4886,28 +5109,29 @@ } }, "node_modules/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -4929,27 +5153,31 @@ } }, "node_modules/object.hasown": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", - "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "dev": true, "dependencies": { - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5227,10 +5455,19 @@ "node": ">= 6" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { - "version": "8.4.33", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", - "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -5249,7 +5486,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -5339,9 +5576,9 @@ } }, "node_modules/prettier": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz", - "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -5483,9 +5720,9 @@ } }, "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -5539,38 +5776,33 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, "node_modules/react-smooth": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.5.tgz", - "integrity": "sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.0.tgz", + "integrity": "sha512-2NMXOBY1uVUQx1jBeENGA497HK20y6CPGYL1ZnJLeoQ8rrc3UfmOM82sRxtzpcoCkUMy4CS0RGylfuVhuFjBgg==", "dependencies": { - "fast-equals": "^5.0.0", - "react-transition-group": "2.9.0" + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" }, "peerDependencies": { - "prop-types": "^15.6.0", - "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "dependencies": { - "dom-helpers": "^3.4.0", + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" + "prop-types": "^15.6.2" }, "peerDependencies": { - "react": ">=15.0.0", - "react-dom": ">=15.0.0" + "react": ">=16.6.0", + "react-dom": ">=16.6.0" } }, "node_modules/read-cache": { @@ -5608,15 +5840,15 @@ } }, "node_modules/recharts": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.11.0.tgz", - "integrity": "sha512-5s+u1m5Hwxb2nh0LABkE3TS/lFqFHyWl7FnPbQhHobbQQia4ih1t3o3+ikPYr31Ns+kYe4FASIthKeKi/YYvMg==", + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.6.tgz", + "integrity": "sha512-D+7j9WI+D0NHauah3fKHuNNcRK8bOypPW7os1DERinogGBGaHI7i6tQKJ0aUF3JXyBZ63dyfKIW2WTOPJDxJ8w==", "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", - "lodash": "^4.17.19", + "lodash": "^4.17.21", "react-is": "^16.10.2", - "react-smooth": "^2.0.5", + "react-smooth": "^4.0.0", "recharts-scale": "^0.4.4", "tiny-invariant": "^1.3.1", "victory-vendor": "^36.6.8" @@ -5625,7 +5857,6 @@ "node": ">=14" }, "peerDependencies": { - "prop-types": "^15.6.0", "react": "^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" } @@ -5675,14 +5906,15 @@ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -5769,6 +6001,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/responselike": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", @@ -5849,13 +6090,13 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", - "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -5886,13 +6127,13 @@ ] }, "node_modules/safe-regex-test": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz", - "integrity": "sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, "engines": { @@ -5950,30 +6191,32 @@ } }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6020,14 +6263,18 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6056,9 +6303,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "engines": { "node": ">=0.10.0" } @@ -6248,34 +6495,41 @@ } }, "node_modules/string.prototype.matchall": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", - "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "regexp.prototype.flags": "^1.5.0", - "set-function-name": "^2.0.0", - "side-channel": "^1.0.4" + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -6285,28 +6539,31 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6494,9 +6751,9 @@ } }, "node_modules/systeminformation": { - "version": "5.21.24", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.24.tgz", - "integrity": "sha512-xQada8ByGGFoRXJaUptGgddn3i7IjtSdqNdCKzB8xkzsM7pHnfLYBWxkPdGzhZ0Z/l+W1yo+aZQZ74d2isj8kw==", + "version": "5.22.7", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.7.tgz", + "integrity": "sha512-AWxlP05KeHbpGdgvZkcudJpsmChc2Y5Eo/GvxG/iUA/Aws5LZKHAMSeAo+V+nD+nxWZaxrwpWcnx4SH3oxNL3A==", "os": [ "darwin", "linux", @@ -6531,9 +6788,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", - "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", + "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", "dev": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -6544,7 +6801,7 @@ "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.19.1", + "jiti": "^1.21.0", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", @@ -6620,6 +6877,15 @@ "node": ">=14" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tar": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", @@ -6849,29 +7115,30 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -6881,16 +7148,17 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -6900,30 +7168,36 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { @@ -7173,16 +7447,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index f56d4e45..c5dfbd39 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "classnames": "^2.5.1", "compare-versions": "^6.1.0", "dockerode": "^4.0.2", - "follow-redirects": "^1.15.5", + "follow-redirects": "^1.15.6", "gamedig": "^4.3.1", "i18next": "^21.10.0", "js-yaml": "^4.1.0", @@ -29,15 +29,15 @@ "ping": "^0.4.4", "pretty-bytes": "^6.1.1", "raw-body": "^2.5.2", - "react": "^18.2.0", + "react": "^18.3.1", "react-dom": "^18.2.0", "react-i18next": "^11.18.6", "salted-md5": "^4.0.5", "react-icons": "^4.12.0", - "recharts": "^2.11.0", + "recharts": "^2.12.6", "rrule": "^2.8.1", "swr": "^1.3.0", - "systeminformation": "^5.21.24", + "systeminformation": "^5.22.7", "tough-cookie": "^4.1.3", "urbackup-server-api": "^0.8.9", "winston": "^3.11.0", @@ -46,20 +46,20 @@ "devDependencies": { "@tailwindcss/forms": "^0.5.7", "autoprefixer": "^10.4.17", - "eslint": "^8.56.0", + "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", - "eslint-config-next": "^12.3.4", + "eslint-config-next": "^14.2.3", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "postcss": "^8.4.33", - "prettier": "^3.2.4", + "eslint-plugin-react": "^7.34.2", + "eslint-plugin-react-hooks": "^4.6.2", + "postcss": "^8.4.38", + "prettier": "^3.2.5", "tailwind-scrollbar": "^3.0.5", - "tailwindcss": "^3.4.1", - "typescript": "^4.9.5" + "tailwindcss": "^3.4.3", + "typescript": "^5.4.5" }, "optionalDependencies": { "osx-temperature-sensor": "^1.0.8" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b87aa37..3690469a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,7 +3,7 @@ lockfileVersion: '6.0' dependencies: '@headlessui/react': specifier: ^1.7.18 - version: 1.7.18(react-dom@18.2.0)(react@18.2.0) + version: 1.7.18(react-dom@18.2.0)(react@18.3.1) '@kubernetes/client-node': specifier: ^0.17.1 version: 0.17.1 @@ -20,8 +20,8 @@ dependencies: specifier: ^4.0.2 version: 4.0.2 follow-redirects: - specifier: ^1.15.5 - version: 1.15.5 + specifier: ^1.15.6 + version: 1.15.6 gamedig: specifier: ^4.3.1 version: 4.3.1 @@ -45,10 +45,10 @@ dependencies: version: 1.0.2 next: specifier: ^12.3.4 - version: 12.3.4(react-dom@18.2.0)(react@18.2.0) + version: 12.3.4(react-dom@18.2.0)(react@18.3.1) next-i18next: specifier: ^12.1.0 - version: 12.1.0(next@12.3.4)(react-dom@18.2.0)(react@18.2.0) + version: 12.1.0(next@12.3.4)(react-dom@18.2.0)(react@18.3.1) ping: specifier: ^0.4.4 version: 0.4.4 @@ -59,20 +59,20 @@ dependencies: specifier: ^2.5.2 version: 2.5.2 react: - specifier: ^18.2.0 - version: 18.2.0 + specifier: ^18.3.1 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.2.0(react@18.3.1) react-i18next: specifier: ^11.18.6 - version: 11.18.6(i18next@21.10.0)(react-dom@18.2.0)(react@18.2.0) + version: 11.18.6(i18next@21.10.0)(react-dom@18.2.0)(react@18.3.1) react-icons: specifier: ^4.12.0 - version: 4.12.0(react@18.2.0) + version: 4.12.0(react@18.3.1) recharts: - specifier: ^2.11.0 - version: 2.11.0(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + specifier: ^2.12.6 + version: 2.12.6(react-dom@18.2.0)(react@18.3.1) rrule: specifier: ^2.8.1 version: 2.8.1 @@ -81,10 +81,10 @@ dependencies: version: 4.0.5 swr: specifier: ^1.3.0 - version: 1.3.0(react@18.2.0) + version: 1.3.0(react@18.3.1) systeminformation: - specifier: ^5.21.24 - version: 5.21.24 + specifier: ^5.22.7 + version: 5.22.7 tough-cookie: specifier: ^4.1.3 version: 4.1.3 @@ -106,52 +106,52 @@ optionalDependencies: devDependencies: '@tailwindcss/forms': specifier: ^0.5.7 - version: 0.5.7(tailwindcss@3.4.1) + version: 0.5.7(tailwindcss@3.4.3) autoprefixer: specifier: ^10.4.17 - version: 10.4.17(postcss@8.4.33) + version: 10.4.17(postcss@8.4.38) eslint: - specifier: ^8.56.0 - version: 8.56.0 + specifier: ^8.57.0 + version: 8.57.0 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.56.0) + version: 19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.34.2)(eslint@8.57.0) eslint-config-next: - specifier: ^12.3.4 - version: 12.3.4(eslint@8.56.0)(typescript@4.9.5) + specifier: ^14.2.3 + version: 14.2.3(eslint@8.57.0)(typescript@5.4.5) eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@8.56.0) + version: 9.1.0(eslint@8.57.0) eslint-plugin-import: specifier: ^2.29.1 - version: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.56.0) + version: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: specifier: ^6.8.0 - version: 6.8.0(eslint@8.56.0) + version: 6.8.0(eslint@8.57.0) eslint-plugin-prettier: specifier: ^4.2.1 - version: 4.2.1(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.4) + version: 4.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) eslint-plugin-react: - specifier: ^7.33.2 - version: 7.33.2(eslint@8.56.0) + specifier: ^7.34.2 + version: 7.34.2(eslint@8.57.0) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.56.0) + specifier: ^4.6.2 + version: 4.6.2(eslint@8.57.0) postcss: - specifier: ^8.4.33 - version: 8.4.33 + specifier: ^8.4.38 + version: 8.4.38 prettier: - specifier: ^3.2.4 - version: 3.2.4 + specifier: ^3.2.5 + version: 3.2.5 tailwind-scrollbar: specifier: ^3.0.5 - version: 3.0.5(tailwindcss@3.4.1) + version: 3.0.5(tailwindcss@3.4.3) tailwindcss: - specifier: ^3.4.1 - version: 3.4.1 + specifier: ^3.4.3 + version: 3.4.3 typescript: - specifier: ^4.9.5 - version: 4.9.5 + specifier: ^5.4.5 + version: 5.4.5 packages: @@ -188,13 +188,13 @@ packages: kuler: 2.0.0 dev: false - /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.56.0 + eslint: 8.57.0 eslint-visitor-keys: 3.4.3 dev: true @@ -220,22 +220,22 @@ packages: - supports-color dev: true - /@eslint/js@8.56.0: - resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@headlessui/react@1.7.18(react-dom@18.2.0)(react@18.2.0): + /@headlessui/react@1.7.18(react-dom@18.2.0)(react@18.3.1): resolution: {integrity: sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ==} engines: {node: '>=10'} peerDependencies: react: ^16 || ^17 || ^18 react-dom: ^16 || ^17 || ^18 dependencies: - '@tanstack/react-virtual': 3.0.2(react-dom@18.2.0)(react@18.2.0) + '@tanstack/react-virtual': 3.0.2(react-dom@18.2.0)(react@18.3.1) client-only: 0.0.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) dev: false /@humanwhocodes/config-array@0.11.14: @@ -328,10 +328,10 @@ packages: resolution: {integrity: sha512-H/69Lc5Q02dq3o+dxxy5O/oNxFsZpdL6WREtOOtOM1B/weonIwDXkekr1KV5DPVPr12IHFPrMrcJQ6bgPMfn7A==} dev: false - /@next/eslint-plugin-next@12.3.4: - resolution: {integrity: sha512-BFwj8ykJY+zc1/jWANsDprDIu2MgwPOIKxNVnrKvPs+f5TPegrVnem8uScND+1veT4B7F6VeqgaNLFW1Hzl9Og==} + /@next/eslint-plugin-next@14.2.3: + resolution: {integrity: sha512-L3oDricIIjgj1AVnRdRor21gI7mShlSwU/1ZGHmqM3LzHhXXhdkrfeNY5zif25Bi5Dd7fiJHsbhoZCHfXYvlAw==} dependencies: - glob: 7.1.7 + glob: 10.3.10 dev: true /@next/swc-android-arm-eabi@12.3.4: @@ -501,24 +501,24 @@ packages: defer-to-connect: 2.0.1 dev: false - /@tailwindcss/forms@0.5.7(tailwindcss@3.4.1): + /@tailwindcss/forms@0.5.7(tailwindcss@3.4.3): resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==} peerDependencies: tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.4.1 + tailwindcss: 3.4.3 dev: true - /@tanstack/react-virtual@3.0.2(react-dom@18.2.0)(react@18.2.0): + /@tanstack/react-virtual@3.0.2(react-dom@18.2.0)(react@18.3.1): resolution: {integrity: sha512-9XbRLPKgnhMwwmuQMnJMv+5a9sitGNCSEtf/AZXzmJdesYk7XsjYHaEDny+IrJzvPNwZliIIDwCRiaUqR3zzCA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: '@tanstack/virtual-core': 3.0.0 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) dev: false /@tanstack/virtual-core@3.0.0: @@ -602,7 +602,7 @@ packages: resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} dev: false - /@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@4.9.5): + /@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.4.5): resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -614,10 +614,10 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.5) debug: 4.3.4 - eslint: 8.56.0 - typescript: 4.9.5 + eslint: 8.57.0 + typescript: 5.4.5 transitivePeerDependencies: - supports-color dev: true @@ -635,7 +635,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5): + /@typescript-eslint/typescript-estree@5.62.0(typescript@5.4.5): resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -650,8 +650,8 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 + tsutils: 3.21.0(typescript@5.4.5) + typescript: 5.4.5 transitivePeerDependencies: - supports-color dev: true @@ -736,11 +736,12 @@ packages: dequal: 2.0.3 dev: true - /array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - is-array-buffer: 3.0.2 + call-bind: 1.0.7 + is-array-buffer: 3.0.4 dev: true /array-includes@3.1.7: @@ -754,11 +755,35 @@ packages: is-string: 1.0.7 dev: true + /array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + dev: true + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true + /array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + dev: true + /array.prototype.findlastindex@1.2.3: resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} engines: {node: '>= 0.4'} @@ -784,33 +809,43 @@ packages: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 dev: true - /array.prototype.tosorted@1.1.2: - resolution: {integrity: sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==} + /array.prototype.toreversed@1.1.2: + resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 - get-intrinsic: 1.2.2 dev: true - /arraybuffer.prototype.slice@1.0.2: - resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + /array.prototype.tosorted@1.1.3: + resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + dev: true + + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} dependencies: - array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - is-array-buffer: 3.0.2 - is-shared-array-buffer: 1.0.2 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 dev: true /asn1@0.2.6: @@ -848,7 +883,7 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /autoprefixer@10.4.17(postcss@8.4.33): + /autoprefixer@10.4.17(postcss@8.4.38): resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -860,13 +895,15 @@ packages: fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.33 + postcss: 8.4.38 postcss-value-parser: 4.2.0 dev: true - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 dev: true /aws-sign2@0.7.0: @@ -1007,8 +1044,19 @@ packages: resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} dependencies: function-bind: 1.1.2 - get-intrinsic: 1.2.2 - set-function-length: 1.2.0 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + dev: true + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 dev: true /callsites@3.1.0: @@ -1304,6 +1352,33 @@ packages: assert-plus: 1.0.0 dev: false + /data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -1346,21 +1421,21 @@ packages: engines: {node: '>=10'} dev: false - /define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 + es-errors: 1.3.0 gopd: 1.0.1 - has-property-descriptors: 1.0.1 dev: true /define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 - has-property-descriptors: 1.0.1 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 object-keys: 1.1.1 dev: true @@ -1431,10 +1506,11 @@ packages: esutils: 2.0.3 dev: true - /dom-helpers@3.4.0: - resolution: {integrity: sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==} + /dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: '@babel/runtime': 7.23.9 + csstype: 3.1.3 dev: false /dom-serializer@2.0.0: @@ -1497,6 +1573,14 @@ packages: once: 1.4.0 dev: false + /enhanced-resolve@5.16.0: + resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1506,45 +1590,109 @@ packages: resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} dependencies: - array-buffer-byte-length: 1.0.0 - arraybuffer.prototype.slice: 1.0.2 - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 - es-set-tostringtag: 2.0.2 + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + es-set-tostringtag: 2.0.3 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.2 - get-symbol-description: 1.0.0 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 globalthis: 1.0.3 gopd: 1.0.1 - has-property-descriptors: 1.0.1 - has-proto: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 - internal-slot: 1.0.6 - is-array-buffer: 3.0.2 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 is-callable: 1.2.7 - is-negative-zero: 2.0.2 + is-negative-zero: 2.0.3 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 is-string: 1.0.7 - is-typed-array: 1.1.12 + is-typed-array: 1.1.13 is-weakref: 1.0.2 object-inspect: 1.13.1 object-keys: 1.1.1 object.assign: 4.1.5 - regexp.prototype.flags: 1.5.1 - safe-array-concat: 1.1.0 - safe-regex-test: 1.0.2 - string.prototype.trim: 1.2.8 - string.prototype.trimend: 1.0.7 - string.prototype.trimstart: 1.0.7 - typed-array-buffer: 1.0.0 - typed-array-byte-length: 1.0.0 - typed-array-byte-offset: 1.0.0 - typed-array-length: 1.0.4 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 unbox-primitive: 1.0.2 - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 + dev: true + + /es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + dev: true + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} dev: true /es-iterator-helpers@1.0.15: @@ -1566,19 +1714,55 @@ packages: safe-array-concat: 1.1.0 dev: true + /es-iterator-helpers@1.0.19: + resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + globalthis: 1.0.3 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + iterator.prototype: 1.1.2 + safe-array-concat: 1.1.2 + dev: true + + /es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: true + /es-set-tostringtag@2.0.2: resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 - has-tostringtag: 1.0.0 - hasown: 2.0.0 + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 dev: true /es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} dependencies: - hasown: 2.0.0 + hasown: 2.0.2 dev: true /es-to-primitive@1.2.1: @@ -1600,7 +1784,7 @@ packages: engines: {node: '>=10'} dev: true - /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1)(eslint@8.56.0): + /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1)(eslint@8.57.0): resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -1608,14 +1792,14 @@ packages: eslint-plugin-import: ^2.25.2 dependencies: confusing-browser-globals: 1.0.11 - eslint: 8.56.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.56.0) + eslint: 8.57.0 + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) object.assign: 4.1.5 object.entries: 1.1.7 semver: 6.3.1 dev: true - /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.56.0): + /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.34.2)(eslint@8.57.0): resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1625,18 +1809,18 @@ packages: eslint-plugin-react: ^7.28.0 eslint-plugin-react-hooks: ^4.3.0 dependencies: - eslint: 8.56.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.56.0) - eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0) - eslint-plugin-react: 7.33.2(eslint@8.56.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) + eslint: 8.57.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) + eslint-plugin-react: 7.34.2(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) object.assign: 4.1.5 object.entries: 1.1.7 dev: true - /eslint-config-next@12.3.4(eslint@8.56.0)(typescript@4.9.5): - resolution: {integrity: sha512-WuT3gvgi7Bwz00AOmKGhOeqnyA5P29Cdyr0iVjLyfDbk+FANQKcOjFUTZIdyYfe5Tq1x4TGcmoe4CwctGvFjHQ==} + /eslint-config-next@14.2.3(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-ZkNztm3Q7hjqvB1rRlOX8P9E/cXRL9ajRcs8jufEtwMfTVYRqnmtnaSu57QqHyBlovMuiB8LEzfLBkh5RYV6Fg==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 typescript: '>=3.3.1' @@ -1644,29 +1828,29 @@ packages: typescript: optional: true dependencies: - '@next/eslint-plugin-next': 12.3.4 + '@next/eslint-plugin-next': 14.2.3 '@rushstack/eslint-patch': 1.7.2 - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@4.9.5) - eslint: 8.56.0 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.5) + eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 2.7.1(eslint-plugin-import@2.29.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.56.0) - eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0) - eslint-plugin-react: 7.33.2(eslint@8.56.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) - typescript: 4.9.5 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) + eslint-plugin-react: 7.34.2(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + typescript: 5.4.5 transitivePeerDependencies: - eslint-import-resolver-webpack - supports-color dev: true - /eslint-config-prettier@9.1.0(eslint@8.56.0): + /eslint-config-prettier@9.1.0(eslint@8.57.0): resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.56.0 + eslint: 8.57.0 dev: true /eslint-import-resolver-node@0.3.9: @@ -1679,25 +1863,30 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript@2.7.1(eslint-plugin-import@2.29.1)(eslint@8.56.0): - resolution: {integrity: sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==} - engines: {node: '>=4'} + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: eslint: '*' eslint-plugin-import: '*' dependencies: debug: 4.3.4 - eslint: 8.56.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.56.0) - glob: 7.2.3 + enhanced-resolve: 5.16.0 + eslint: 8.57.0 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.3 + is-core-module: 2.13.1 is-glob: 4.0.3 - resolve: 1.22.8 - tsconfig-paths: 3.15.0 transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@2.7.1)(eslint@8.56.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -1718,16 +1907,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.5) debug: 3.2.7 - eslint: 8.56.0 + eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 2.7.1(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.56.0): + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: @@ -1737,16 +1926,16 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.5) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.56.0 + eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@2.7.1)(eslint@8.56.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -1762,7 +1951,7 @@ packages: - supports-color dev: true - /eslint-plugin-jsx-a11y@6.8.0(eslint@8.56.0): + /eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} engines: {node: '>=4.0'} peerDependencies: @@ -1778,7 +1967,7 @@ packages: damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 es-iterator-helpers: 1.0.15 - eslint: 8.56.0 + eslint: 8.57.0 hasown: 2.0.0 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -1787,7 +1976,7 @@ packages: object.fromentries: 2.0.7 dev: true - /eslint-plugin-prettier@4.2.1(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.4): + /eslint-plugin-prettier@4.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1798,44 +1987,46 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.56.0 - eslint-config-prettier: 9.1.0(eslint@8.56.0) - prettier: 3.2.4 + eslint: 8.57.0 + eslint-config-prettier: 9.1.0(eslint@8.57.0) + prettier: 3.2.5 prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-react-hooks@4.6.0(eslint@8.56.0): - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + /eslint-plugin-react-hooks@4.6.2(eslint@8.57.0): + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.56.0 + eslint: 8.57.0 dev: true - /eslint-plugin-react@7.33.2(eslint@8.56.0): - resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} + /eslint-plugin-react@7.34.2(eslint@8.57.0): + resolution: {integrity: sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - array-includes: 3.1.7 + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.2 - array.prototype.tosorted: 1.1.2 + array.prototype.toreversed: 1.1.2 + array.prototype.tosorted: 1.1.3 doctrine: 2.1.0 - es-iterator-helpers: 1.0.15 - eslint: 8.56.0 + es-iterator-helpers: 1.0.19 + eslint: 8.57.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 - object.entries: 1.1.7 - object.fromentries: 2.0.7 - object.hasown: 1.1.3 - object.values: 1.1.7 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.hasown: 1.1.4 + object.values: 1.2.0 prop-types: 15.8.1 resolve: 2.0.0-next.5 semver: 6.3.1 - string.prototype.matchall: 4.0.10 + string.prototype.matchall: 4.0.11 dev: true /eslint-scope@7.2.2: @@ -1851,15 +2042,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.56.0: - resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@eslint-community/regexpp': 4.10.0 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.56.0 + '@eslint/js': 8.57.0 '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -2043,8 +2234,8 @@ packages: resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} dev: false - /follow-redirects@1.15.5: - resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + /follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -2118,9 +2309,9 @@ packages: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 functions-have-names: 1.2.3 dev: true @@ -2159,9 +2350,20 @@ packages: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: function-bind: 1.1.2 - has-proto: 1.0.1 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 + hasown: 2.0.2 + dev: true + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 dev: true /get-stream@6.0.1: @@ -2169,12 +2371,19 @@ packages: engines: {node: '>=10'} dev: false - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + /get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + dev: true + + /get-tsconfig@4.7.3: + resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==} + dependencies: + resolve-pkg-maps: 1.0.0 dev: true /getpass@0.1.7: @@ -2209,17 +2418,6 @@ packages: path-scurry: 1.10.1 dev: true - /glob@7.1.7: - resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: @@ -2259,7 +2457,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 dev: true /got@12.6.1: @@ -2279,6 +2477,10 @@ packages: responselike: 3.0.0 dev: false + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true @@ -2309,7 +2511,13 @@ packages: /has-property-descriptors@1.0.1: resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 + dev: true + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 dev: true /has-proto@1.0.1: @@ -2317,13 +2525,18 @@ packages: engines: {node: '>= 0.4'} dev: true + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + dev: true + /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} dev: true - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 @@ -2335,6 +2548,13 @@ packages: dependencies: function-bind: 1.1.2 + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + /hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} dependencies: @@ -2456,8 +2676,17 @@ packages: resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 - hasown: 2.0.0 + get-intrinsic: 1.2.4 + hasown: 2.0.2 + side-channel: 1.0.4 + dev: true + + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 side-channel: 1.0.4 dev: true @@ -2471,12 +2700,12 @@ packages: engines: {node: '>= 0.10'} dev: false - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: true /is-arrayish@0.3.2: @@ -2487,7 +2716,7 @@ packages: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-bigint@1.0.4: @@ -2507,8 +2736,8 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: true /is-callable@1.2.7: @@ -2521,11 +2750,18 @@ packages: dependencies: hasown: 2.0.0 + /is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + dependencies: + is-typed-array: 1.1.13 + dev: true + /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-extglob@2.1.1: @@ -2536,7 +2772,7 @@ packages: /is-finalizationregistry@1.0.2: resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 dev: true /is-fullwidth-code-point@3.0.0: @@ -2548,7 +2784,7 @@ packages: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-glob@4.0.3: @@ -2562,8 +2798,8 @@ packages: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} dev: true - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + /is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} dev: true @@ -2571,7 +2807,7 @@ packages: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-number@7.0.0: @@ -2588,18 +2824,19 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: true /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} dev: true - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 dev: true /is-stream@2.0.1: @@ -2611,7 +2848,7 @@ packages: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-symbol@1.0.4: @@ -2621,11 +2858,11 @@ packages: has-symbols: 1.0.3 dev: true - /is-typed-array@1.1.12: - resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} dependencies: - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 dev: true /is-typedarray@1.0.0: @@ -2639,14 +2876,14 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 dev: true /is-weakset@2.0.2: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: true /isarray@0.0.1: @@ -2680,7 +2917,7 @@ packages: resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} dependencies: define-properties: 1.2.1 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 reflect.getprototypeof: 1.0.4 set-function-name: 2.0.1 @@ -2767,10 +3004,10 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} dependencies: - array-includes: 3.1.7 + array-includes: 3.1.8 array.prototype.flat: 1.3.2 object.assign: 4.1.5 - object.values: 1.1.7 + object.values: 1.2.0 dev: true /keyv@4.5.4: @@ -3013,7 +3250,7 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /next-i18next@12.1.0(next@12.3.4)(react-dom@18.2.0)(react@18.2.0): + /next-i18next@12.1.0(next@12.3.4)(react-dom@18.2.0)(react@18.3.1): resolution: {integrity: sha512-rhos/PVULmZPdC0jpec2MDBQMXdGZ3+Mbh/tZfrDtjgnVN3ucdq7k8BlwsJNww6FnqC8AC31n6dSYuqVzYsGsw==} engines: {node: '>=12'} peerDependencies: @@ -3026,15 +3263,15 @@ packages: hoist-non-react-statics: 3.3.2 i18next: 21.10.0 i18next-fs-backend: 1.2.0 - next: 12.3.4(react-dom@18.2.0)(react@18.2.0) - react: 18.2.0 - react-i18next: 11.18.6(i18next@21.10.0)(react-dom@18.2.0)(react@18.2.0) + next: 12.3.4(react-dom@18.2.0)(react@18.3.1) + react: 18.3.1 + react-i18next: 11.18.6(i18next@21.10.0)(react-dom@18.2.0)(react@18.3.1) transitivePeerDependencies: - react-dom - react-native dev: false - /next@12.3.4(react-dom@18.2.0)(react@18.2.0): + /next@12.3.4(react-dom@18.2.0)(react@18.3.1): resolution: {integrity: sha512-VcyMJUtLZBGzLKo3oMxrEF0stxh8HwuW976pAzlHhI3t8qJ4SROjCrSh1T24bhrbjw55wfZXAbXPGwPt5FLRfQ==} engines: {node: '>=12.22.0'} hasBin: true @@ -3056,10 +3293,10 @@ packages: '@swc/helpers': 0.4.11 caniuse-lite: 1.0.30001581 postcss: 8.4.14 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.0.7(react@18.2.0) - use-sync-external-store: 1.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) + styled-jsx: 5.0.7(react@18.3.1) + use-sync-external-store: 1.2.0(react@18.3.1) optionalDependencies: '@next/swc-android-arm-eabi': 12.3.4 '@next/swc-android-arm64': 12.3.4 @@ -3175,6 +3412,15 @@ packages: es-abstract: 1.22.3 dev: true + /object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + /object.fromentries@2.0.7: resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} engines: {node: '>= 0.4'} @@ -3184,6 +3430,16 @@ packages: es-abstract: 1.22.3 dev: true + /object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + /object.groupby@1.0.1: resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} dependencies: @@ -3193,11 +3449,13 @@ packages: get-intrinsic: 1.2.2 dev: true - /object.hasown@1.1.3: - resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} + /object.hasown@1.1.4: + resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} + engines: {node: '>= 0.4'} dependencies: define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 dev: true /object.values@1.1.7: @@ -3209,6 +3467,15 @@ packages: es-abstract: 1.22.3 dev: true + /object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + /oidc-token-hash@5.0.3: resolution: {integrity: sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==} engines: {node: ^10.13.0 || >=12.0.0} @@ -3360,29 +3627,34 @@ packages: engines: {node: '>= 6'} dev: true - /postcss-import@15.1.0(postcss@8.4.33): + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-import@15.1.0(postcss@8.4.38): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.33 + postcss: 8.4.38 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 dev: true - /postcss-js@4.0.1(postcss@8.4.33): + /postcss-js@4.0.1(postcss@8.4.38): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.33 + postcss: 8.4.38 dev: true - /postcss-load-config@4.0.2(postcss@8.4.33): + /postcss-load-config@4.0.2(postcss@8.4.38): resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: @@ -3395,17 +3667,17 @@ packages: optional: true dependencies: lilconfig: 3.0.0 - postcss: 8.4.33 + postcss: 8.4.38 yaml: 2.3.4 dev: true - /postcss-nested@6.0.1(postcss@8.4.33): + /postcss-nested@6.0.1(postcss@8.4.38): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.33 + postcss: 8.4.38 postcss-selector-parser: 6.0.15 dev: true @@ -3430,13 +3702,13 @@ packages: source-map-js: 1.0.2 dev: false - /postcss@8.4.33: - resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + /postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 picocolors: 1.0.0 - source-map-js: 1.0.2 + source-map-js: 1.2.0 dev: true /prelude-ls@1.2.1: @@ -3451,8 +3723,8 @@ packages: fast-diff: 1.3.0 dev: true - /prettier@3.2.4: - resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==} + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} engines: {node: '>=14'} hasBin: true dev: true @@ -3516,17 +3788,17 @@ packages: unpipe: 1.0.0 dev: false - /react-dom@18.2.0(react@18.2.0): + /react-dom@18.2.0(react@18.3.1): resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: react: ^18.2.0 dependencies: loose-envify: 1.4.0 - react: 18.2.0 + react: 18.3.1 scheduler: 0.23.0 dev: false - /react-i18next@11.18.6(i18next@21.10.0)(react-dom@18.2.0)(react@18.2.0): + /react-i18next@11.18.6(i18next@21.10.0)(react-dom@18.2.0)(react@18.3.1): resolution: {integrity: sha512-yHb2F9BiT0lqoQDt8loZ5gWP331GwctHz9tYQ8A2EIEUu+CcEdjBLQWli1USG3RdWQt3W+jqQLg/d4rrQR96LA==} peerDependencies: i18next: '>= 19.0.0' @@ -3542,55 +3814,50 @@ packages: '@babel/runtime': 7.23.9 html-parse-stringify: 3.0.1 i18next: 21.10.0 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) dev: false - /react-icons@4.12.0(react@18.2.0): + /react-icons@4.12.0(react@18.3.1): resolution: {integrity: sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==} peerDependencies: react: '*' dependencies: - react: 18.2.0 + react: 18.3.1 dev: false /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - /react-lifecycles-compat@3.0.4: - resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} - dev: false - - /react-smooth@2.0.5(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA==} + /react-smooth@4.0.0(react-dom@18.2.0)(react@18.3.1): + resolution: {integrity: sha512-2NMXOBY1uVUQx1jBeENGA497HK20y6CPGYL1ZnJLeoQ8rrc3UfmOM82sRxtzpcoCkUMy4CS0RGylfuVhuFjBgg==} peerDependencies: - prop-types: ^15.6.0 - react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 - react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: fast-equals: 5.0.1 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-transition-group: 2.9.0(react-dom@18.2.0)(react@18.2.0) + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.3.1) dev: false - /react-transition-group@2.9.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==} + /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.3.1): + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: - react: '>=15.0.0' - react-dom: '>=15.0.0' + react: '>=16.6.0' + react-dom: '>=16.6.0' dependencies: - dom-helpers: 3.4.0 + '@babel/runtime': 7.23.9 + dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-lifecycles-compat: 3.0.4 + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) dev: false - /react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + /react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 @@ -3645,22 +3912,20 @@ packages: decimal.js-light: 2.5.1 dev: false - /recharts@2.11.0(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-5s+u1m5Hwxb2nh0LABkE3TS/lFqFHyWl7FnPbQhHobbQQia4ih1t3o3+ikPYr31Ns+kYe4FASIthKeKi/YYvMg==} + /recharts@2.12.6(react-dom@18.2.0)(react@18.3.1): + resolution: {integrity: sha512-D+7j9WI+D0NHauah3fKHuNNcRK8bOypPW7os1DERinogGBGaHI7i6tQKJ0aUF3JXyBZ63dyfKIW2WTOPJDxJ8w==} engines: {node: '>=14'} peerDependencies: - prop-types: ^15.6.0 react: ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 dependencies: clsx: 2.1.0 eventemitter3: 4.0.7 lodash: 4.17.21 - prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) react-is: 16.13.1 - react-smooth: 2.0.5(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + react-smooth: 4.0.0(react-dom@18.2.0)(react@18.3.1) recharts-scale: 0.4.5 tiny-invariant: 1.3.1 victory-vendor: 36.8.4 @@ -3677,10 +3942,10 @@ packages: resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + es-abstract: 1.23.3 + get-intrinsic: 1.2.4 globalthis: 1.0.3 which-builtin-type: 1.1.3 dev: true @@ -3688,13 +3953,14 @@ packages: /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - /regexp.prototype.flags@1.5.1: - resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - set-function-name: 2.0.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 dev: true /request@2.88.2: @@ -3737,6 +4003,10 @@ packages: engines: {node: '>=4'} dev: true + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -3792,8 +4062,18 @@ packages: resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} engines: {node: '>=0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 dev: true @@ -3806,12 +4086,12 @@ packages: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: false - /safe-regex-test@1.0.2: - resolution: {integrity: sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==} + /safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 is-regex: 1.1.4 dev: true @@ -3862,24 +4142,35 @@ packages: lru-cache: 6.0.0 dev: true - /set-function-length@1.2.0: - resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==} + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.4 + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 dev: true /set-function-name@2.0.1: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.4 functions-have-names: 1.2.3 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 + dev: true + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 dev: true /setprototypeof@1.2.0: @@ -3909,8 +4200,18 @@ packages: /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + dev: true + + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 object-inspect: 1.13.1 dev: true @@ -3937,6 +4238,12 @@ packages: /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} + dev: false + + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + dev: true /split-ca@1.0.1: resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==} @@ -4009,43 +4316,49 @@ packages: strip-ansi: 7.1.0 dev: true - /string.prototype.matchall@4.0.10: - resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - has-symbols: 1.0.3 - internal-slot: 1.0.6 - regexp.prototype.flags: 1.5.1 - set-function-name: 2.0.1 - side-channel: 1.0.4 - dev: true - - /string.prototype.trim@1.2.8: - resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + /string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 + side-channel: 1.0.6 dev: true - /string.prototype.trimend@1.0.7: - resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + /string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 dev: true - /string.prototype.trimstart@1.0.7: - resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + /string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 dev: true /string_decoder@0.10.31: @@ -4093,7 +4406,7 @@ packages: engines: {node: '>=8'} dev: true - /styled-jsx@5.0.7(react@18.2.0): + /styled-jsx@5.0.7(react@18.3.1): resolution: {integrity: sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==} engines: {node: '>= 12.0.0'} peerDependencies: @@ -4106,7 +4419,7 @@ packages: babel-plugin-macros: optional: true dependencies: - react: 18.2.0 + react: 18.3.1 dev: false /sucrase@3.35.0: @@ -4134,32 +4447,32 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /swr@1.3.0(react@18.2.0): + /swr@1.3.0(react@18.3.1): resolution: {integrity: sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==} peerDependencies: react: ^16.11.0 || ^17.0.0 || ^18.0.0 dependencies: - react: 18.2.0 + react: 18.3.1 dev: false - /systeminformation@5.21.24: - resolution: {integrity: sha512-xQada8ByGGFoRXJaUptGgddn3i7IjtSdqNdCKzB8xkzsM7pHnfLYBWxkPdGzhZ0Z/l+W1yo+aZQZ74d2isj8kw==} + /systeminformation@5.22.7: + resolution: {integrity: sha512-AWxlP05KeHbpGdgvZkcudJpsmChc2Y5Eo/GvxG/iUA/Aws5LZKHAMSeAo+V+nD+nxWZaxrwpWcnx4SH3oxNL3A==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true dev: false - /tailwind-scrollbar@3.0.5(tailwindcss@3.4.1): + /tailwind-scrollbar@3.0.5(tailwindcss@3.4.3): resolution: {integrity: sha512-0ZwxTivevqq9BY9fRP9zDjHl7Tu+J5giBGbln+0O1R/7nHtBUKnjQcA1aTIhK7Oyjp6Uc/Dj6/dn8Dq58k5Uww==} engines: {node: '>=12.13.0'} peerDependencies: tailwindcss: 3.x dependencies: - tailwindcss: 3.4.1 + tailwindcss: 3.4.3 dev: true - /tailwindcss@3.4.1: - resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==} + /tailwindcss@3.4.3: + resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -4177,11 +4490,11 @@ packages: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.33 - postcss-import: 15.1.0(postcss@8.4.33) - postcss-js: 4.0.1(postcss@8.4.33) - postcss-load-config: 4.0.2(postcss@8.4.33) - postcss-nested: 6.0.1(postcss@8.4.33) + postcss: 8.4.38 + postcss-import: 15.1.0(postcss@8.4.38) + postcss-js: 4.0.1(postcss@8.4.38) + postcss-load-config: 4.0.2(postcss@8.4.38) + postcss-nested: 6.0.1(postcss@8.4.38) postcss-selector-parser: 6.0.15 resolve: 1.22.8 sucrase: 3.35.0 @@ -4189,6 +4502,11 @@ packages: - ts-node dev: true + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + /tar-fs@2.0.1: resolution: {integrity: sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==} dependencies: @@ -4318,14 +4636,14 @@ packages: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: false - /tsutils@3.21.0(typescript@4.9.5): + /tsutils@3.21.0(typescript@5.4.5): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 4.9.5 + typescript: 5.4.5 dev: true /tunnel-agent@0.6.0: @@ -4350,54 +4668,60 @@ packages: engines: {node: '>=10'} dev: true - /typed-array-buffer@1.0.0: - resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + /typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 dev: true - /typed-array-byte-length@1.0.0: - resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + /typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 dev: true - /typed-array-byte-offset@1.0.0: - resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + /typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 dev: true - /typed-array-length@1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + /typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 dev: true - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} + /typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} hasBin: true dev: true /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -4449,12 +4773,12 @@ packages: requires-port: 1.0.0 dev: false - /use-sync-external-store@1.2.0(react@18.2.0): + /use-sync-external-store@1.2.0(react@18.3.1): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - react: 18.2.0 + react: 18.3.1 dev: false /util-deprecate@1.0.2: @@ -4529,7 +4853,7 @@ packages: engines: {node: '>= 0.4'} dependencies: function.prototype.name: 1.1.6 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-async-function: 2.0.0 is-date-object: 1.0.5 is-finalizationregistry: 1.0.2 @@ -4539,7 +4863,7 @@ packages: isarray: 2.0.5 which-boxed-primitive: 1.0.2 which-collection: 1.0.1 - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 dev: true /which-collection@1.0.1: @@ -4551,15 +4875,15 @@ packages: is-weakset: 2.0.2 dev: true - /which-typed-array@1.1.13: - resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + /which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /which@2.0.2: diff --git a/public/locales/af/common.json b/public/locales/af/common.json index 102f24c4..7884acdd 100644 --- a/public/locales/af/common.json +++ b/public/locales/af/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Liedjies" }, + "esphome": { + "offline": "Vanlyn", + "offline_alt": "Vanlyn", + "online": "Aanlyn", + "total": "Totaal", + "unknown": "Onbekend" + }, "evcc": { "pv_power": "Produksie", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Goedgekeur", "available": "Beskikbaar" }, - "pialert": { + "netalertx": { "total": "Totaal", "connected": "Gekoppel", "new_devices": "Nuwe Toestelle", @@ -419,7 +426,8 @@ "search": "Soek", "custom": "Pasgemaak", "visit": "Besoek", - "url": "URL" + "url": "URL", + "searchsuggestion": "Voorstelling" }, "wmo": { "0-day": "Sonnig", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanale", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Kanaal", + "channelNetwork": "Netwerk", + "signalStrength": "Sterkte", + "signalQuality": "Kwaliteit", + "symbolQuality": "Kwaliteit", + "networkRate": "Bistempo", + "clientIP": "Kliรซnt" }, "scrutiny": { "passed": "Geslaag", @@ -694,6 +710,11 @@ "targets_down": "Teikens Af", "targets_total": "Totale Teikens" }, + "gatus": { + "up": "Werwe Op", + "down": "Werwe Af", + "uptime": "Optyd" + }, "ghostfolio": { "gross_percent_today": "Vandag", "gross_percent_1y": "Een jaar", @@ -775,6 +796,14 @@ "passed": "Geslaag", "failed": "Misluk" }, + "openwrt": { + "uptime": "Optyd", + "cpuLoad": "SVE-lading gemiddelde (5m)", + "up": "Op", + "down": "Af", + "bytesTx": "Oorgedra", + "bytesRx": "Ontvang" + }, "uptimerobot": { "status": "Status", "uptime": "Optyd", @@ -797,11 +826,67 @@ "noEventsFound": "Geen gebeure gevind nie" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platform", + "totalRoms": "Totale ROMs" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Waarskuwings", + "criticals": "Kritici" + }, + "plantit": { + "events": "Gebeure", + "plants": "Plante", + "photos": "Foto's", + "species": "Spesies" + }, + "gitea": { + "notifications": "Kennisgewings", + "issues": "Kwessies", + "pulls": "Trek Versoeke" + }, + "stash": { + "scenes": "Tonele", + "scenesPlayed": "Tonele Gekyk", + "playCount": "Totale Toneelstukke", + "playDuration": "Tyd Gekyk", + "sceneSize": "Toneel Grootte", + "sceneDuration": "Tonele Duur", + "images": "Beelde", + "imageSize": "Beeldgrootte", + "galleries": "Galerye", + "performers": "Kunstenaars", + "studios": "Ateljees", + "movies": "Flieks", + "tags": "Merkers", + "oCount": "O Tel" + }, + "tandoor": { + "users": "Gebruikers", + "recipes": "Resepte", + "keywords": "Sleutelwoorde" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "Met Waarborg", + "locations": "Plekke", + "labels": "Etikette", + "users": "Gebruikers", + "totalValue": "Totale Waarde" + }, + "crowdsec": { + "alerts": "Waarskuwings", + "bans": "Verbanne" + }, + "wgeasy": { + "connected": "Gekoppel", + "enabled": "Geaktiveer", + "disabled": "Onaktief", + "total": "Totaal" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/ar/common.json b/public/locales/ar/common.json index d81b4a95..3bb2acfc 100644 --- a/public/locales/ar/common.json +++ b/public/locales/ar/common.json @@ -107,6 +107,13 @@ "episodes": "ุญู„ู‚ุงุช", "songs": "ุฃุบุงู†ูŠ" }, + "esphome": { + "offline": "ุบูŠุฑ ู…ุชุตู„", + "offline_alt": "ุบูŠุฑ ู…ุชุตู„", + "online": "ู…ูุชู‘ุตู„", + "total": "ุงู„ู…ุฌู…ูˆุน", + "unknown": "ู…ุฌู‡ูˆู„" + }, "evcc": { "pv_power": "ุฅู†ุชุงุฌ", "battery_soc": "ุงู„ุจุทุงุฑูŠุฉ", @@ -133,7 +140,7 @@ "connectionStatusPendingDisconnect": "ููŠ ุงู†ุชุธุงุฑ ู‚ุทุน ุงู„ุงุชุตุงู„", "connectionStatusDisconnecting": "ุฌุงุฑ ู‚ุทุน ุงู„ุงุชุตุงู„", "connectionStatusDisconnected": "ุบูŠุฑ ู…ุชุตู„", - "connectionStatusConnected": "ู…ุชุตู„", + "connectionStatusConnected": "Connected", "uptime": "ู…ุฏุฉ ุงู„ุชุดุบูŠู„", "maxDown": "ุฃู‚ุตู‰ ุญุฏ ู„ู„ุชู†ุฒูŠู„", "maxUp": "ุฃู‚ุตู‰ ุญุฏ ู„ู„ุชุญู…ูŠู„", @@ -270,11 +277,11 @@ "approved": "ู…ุตุฏู‚", "available": "ู…ุชุงุญ" }, - "pialert": { + "netalertx": { "total": "ุงู„ู…ุฌู…ูˆุน", - "connected": "ู…ุชุตู„", - "new_devices": "ุฃุฌู‡ุฒุฉ ุฌุฏูŠุฏุฉ", - "down_alerts": "ุชู†ุจูŠู‡ุงุช ุชุนุทู„ ุงู„ุฎูˆุงุฏู…" + "connected": "Connected", + "new_devices": "New Devices", + "down_alerts": "Down Alerts" }, "pihole": { "queries": "ุงู„ุงุณุชุนู„ุงู…ุงุช", @@ -419,7 +426,8 @@ "search": "ุงู„ุจุญุซ", "custom": "ู…ูุฎุตู‘ุต", "visit": "ุฒูŠุงุฑุฉ", - "url": "ุงู„ุฑุงุจุท" + "url": "ุงู„ุฑุงุจุท", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "ู…ุดู…ุณ", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "ุงู„ู‚ู†ูˆุงุช", - "hd": "ุฌูˆุฏุฉ HD" + "hd": "ุฌูˆุฏุฉ HD", + "tunerCount": "Tuners", + "channelNumber": "ุงู„ู‚ู†ุงุฉ", + "channelNetwork": "ุงู„ุดุจูƒุฉ", + "signalStrength": "ุงู„ู‚ูˆุฉ", + "signalQuality": "ุงู„ุฌูˆุฏุฉ", + "symbolQuality": "ุงู„ุฌูˆุฏุฉ", + "networkRate": "ู…ุนุฏู„ ุงู„ุจุช", + "clientIP": "ุงู„ุนู…ูŠู„" }, "scrutiny": { "passed": "ุฅุฌุชุงุฒ", @@ -694,6 +710,11 @@ "targets_down": "ุงู„ุฃู‡ุฏุงู ู„ุง ุชุนู…ู„", "targets_total": "ุงู„ุฃู‡ุฏุงู ุงู„ุฅุฌู…ุงู„ูŠุฉ" }, + "gatus": { + "up": "ุงู„ู…ูˆุงู‚ุน ุชุนู…ู„", + "down": "ู…ูˆุงู‚ุน ู„ุง ุชุนู…ู„", + "uptime": "ู…ุฏุฉ ุงู„ุชุดุบูŠู„" + }, "ghostfolio": { "gross_percent_today": "ุงู„ูŠูˆู…", "gross_percent_1y": "ุณู†ุฉ", @@ -775,6 +796,14 @@ "passed": "ุฅุฌุชุงุฒ", "failed": "ูุดู„" }, + "openwrt": { + "uptime": "ู…ุฏุฉ ุงู„ุชุดุบูŠู„", + "cpuLoad": "ู…ุชูˆุณุท ุญู…ูˆู„ุฉ ุงู„ู…ุนุงู„ุฌ (5ุฏู‚)", + "up": "ูŠุนู…ู„", + "down": "ู„ุง ูŠุนู…ู„", + "bytesTx": "ู…ุฑุณู„ุฉ", + "bytesRx": "ุชู… ุงู„ุฅุณุชู„ุงู…" + }, "uptimerobot": { "status": "ุงู„ุญุงู„ุฉ", "uptime": "ู…ุฏุฉ ุงู„ุชุดุบูŠู„", @@ -797,11 +826,67 @@ "noEventsFound": "ู„ู… ูŠุชู… ุงู„ุนุซูˆุฑ ุนู„ู‰ ุฃุญุฏุงุซ" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "ุงู„ู…ูู†ุตุงุช", + "totalRoms": "ู…ุฌู…ูˆุน ุงู„ุฑูˆูˆู…ุงุช" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "ุชุญุฐูŠุฑุงุช", + "criticals": "ุญุฑุฌ" + }, + "plantit": { + "events": "ุฃุญุฏุงุซ", + "plants": "ู†ุจุงุชุงุช", + "photos": "ุงู„ุตูˆุฑ", + "species": "ุงู„ุฃู†ูˆุงุน" + }, + "gitea": { + "notifications": "ุงู„ุฅุดุนุงุฑุงุช", + "issues": "ุงู„ู…ูุดูƒูู„ุงุช", + "pulls": "ุทู„ุจุงุช ุงู„ุณุญุจ" + }, + "stash": { + "scenes": "ุงู„ู…ุดุงู‡ุฏ", + "scenesPlayed": "Scenes Played", + "playCount": "ุฅุฌู…ุงู„ูŠ ุงู„ู…ุดุบู„ุงุช", + "playDuration": "ูˆู‚ุช ุงู„ู…ุดุงู‡ุฏุฉ", + "sceneSize": "ุญุฌู… ุงู„ู…ุดุงู‡ุฏ", + "sceneDuration": "ู…ุฏุฉ ุงู„ู…ุดู‡ุฏ", + "images": "ุตูˆุฑ", + "imageSize": "ุญุฌู… ุงู„ุตูˆุฑ", + "galleries": "ุงู„ู…ุนุงุฑุถ", + "performers": "Performers", + "studios": "ุงุณุชูˆุฏูŠูˆู‡ุงุช", + "movies": "ุฃูู„ุงู…", + "tags": "ุงู„ุชุตู†ูŠูุงุช", + "oCount": "ุนุฏุฏ O" + }, + "tandoor": { + "users": "ุงู„ู…ุณุชุฎุฏู…ูˆู†", + "recipes": "ูˆุตูุงุช", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "ุงู„ู…ุณุชุฎุฏู…ูˆู†", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "ุชู†ุจูŠู‡ุงุช", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "ู…ูุนู„", + "disabled": "ู…ุนุทู„", + "total": "ุงู„ู…ุฌู…ูˆุน" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/bg/common.json b/public/locales/bg/common.json index 2bf20ccc..443c28b8 100644 --- a/public/locales/bg/common.json +++ b/public/locales/bg/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "ะ˜ะทะบะปัŽั‡ะตะฝ", + "offline_alt": "ะ˜ะทะบะปัŽั‡ะตะฝ", + "online": "Online", + "total": "ะžะฑั‰ะพ", + "unknown": "ะะตะธะทะฒ." + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -133,7 +140,7 @@ "connectionStatusPendingDisconnect": "Pending Disconnect", "connectionStatusDisconnecting": "Disconnecting", "connectionStatusDisconnected": "Disconnected", - "connectionStatusConnected": "ะกะฒัŠั€ะทะฐะฝะพ", + "connectionStatusConnected": "Connected", "uptime": "Uptime", "maxDown": "Max. Down", "maxUp": "Max. Up", @@ -270,10 +277,10 @@ "approved": "ะžะดะพะฑั€ะตะฝ", "available": "ะะฐะปะธั‡ะตะฝ" }, - "pialert": { + "netalertx": { "total": "ะžะฑั‰ะพ", - "connected": "ะกะฒัŠั€ะทะฐะฝะพ", - "new_devices": "ะะพะฒะธ ัƒัั‚ั€ะพะนัั‚ะฒะฐ", + "connected": "Connected", + "new_devices": "New Devices", "down_alerts": "Down Alerts" }, "pihole": { @@ -419,7 +426,8 @@ "search": "ะขัŠั€ัะตะฝะต", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "ะกะปัŠะฝั‡ะตะฒะพ", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "ะšะฐะฝะฐะปะธ", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "ะกั‚ะฐั‚ัƒั", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "ะคะธะปะผะธ", + "tags": "ะขะฐะณะพะฒะต", + "oCount": "O Count" + }, + "tandoor": { + "users": "ะŸะพั‚ั€ะตะฑะธั‚ะตะปะธ", + "recipes": "ะ ะตั†ะตะฟั‚ะธ", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "ะŸะพั‚ั€ะตะฑะธั‚ะตะปะธ", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "ะŸั€ะตะดัƒะฟั€ะตะถะดะตะฝะธั", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "ะะบั‚ะธะฒะธั€ะฐะฝะพ", + "disabled": "ะ”ะตะฐะบั‚ะธะฒะธั€ะฐะฝะพ", + "total": "ะžะฑั‰ะพ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/ca/common.json b/public/locales/ca/common.json index 7c638792..78a32c0d 100644 --- a/public/locales/ca/common.json +++ b/public/locales/ca/common.json @@ -14,7 +14,7 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", + "months": "mes", "days": "d", "hours": "h", "minutes": "m", @@ -46,8 +46,8 @@ "used": "Utilitzat", "load": "Cร rrega", "temp": "TEMP", - "max": "Max", - "uptime": "UP" + "max": "Mร x.", + "uptime": "ACTIU" }, "unifi": { "users": "Usuaris", @@ -61,58 +61,65 @@ "wlan_devices": "Dispositius WLAN", "lan_users": "Usuaris LAN", "wlan_users": "Usuaris WLAN", - "up": "UP", + "up": "ACTIU", "down": "INACTIU", "wait": "Si us plau, espereu", - "empty_data": "Subsystem status unknown" + "empty_data": "Estat del subsistema desconegut" }, "docker": { "rx": "Rebut", "tx": "Transmรจs", "mem": "MEM", "cpu": "CPU", - "running": "Running", + "running": "En execuciรณ", "offline": "Fora de lรญnia", "error": "Error", "unknown": "Desconegut", - "healthy": "Healthy", - "starting": "Starting", - "unhealthy": "Unhealthy", - "not_found": "Not Found", - "exited": "Exited", - "partial": "Partial" + "healthy": "Saludable", + "starting": "Iniciant", + "unhealthy": "No saludable", + "not_found": "No trobat", + "exited": "Tancat", + "partial": "Parcial" }, "ping": { "error": "Error", - "ping": "Ping", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "ping": "Latรจncia", + "down": "Inactiu", + "up": "Actiu", + "not_available": "No Disponible" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "Estat HTTP", "error": "Error", - "response": "Response", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "response": "Resposta", + "down": "Inactiu", + "up": "Actiu", + "not_available": "No Disponible" }, "emby": { "playing": "Reproduint", "transcoding": "Transcodificant", "bitrate": "Taxa de bits", "no_active": "Sense reproduccions actives", - "movies": "Movies", - "series": "Series", - "episodes": "Episodes", - "songs": "Songs" + "movies": "Pelยทlรญcules", + "series": "Sรจries", + "episodes": "Episodis", + "songs": "Canรงons" + }, + "esphome": { + "offline": "Fora de lรญnia", + "offline_alt": "Fora de lรญnia", + "online": "En lรญnia", + "total": "Total", + "unknown": "Desconegut" }, "evcc": { - "pv_power": "Production", - "battery_soc": "Battery", - "grid_power": "Grid", - "home_power": "Consumption", - "charge_power": "Charger", + "pv_power": "Producciรณ", + "battery_soc": "Bateria", + "grid_power": "Xarxa", + "home_power": "Consum", + "charge_power": "Carregador", "watt_hour": "Wh" }, "flood": { @@ -122,55 +129,55 @@ "seed": "Llavor" }, "freshrss": { - "subscriptions": "Subscriptions", - "unread": "Unread" + "subscriptions": "Subcripcions", + "unread": "Sense llegir" }, "fritzbox": { "connectionStatus": "Estat", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", - "connectionStatusConnected": "Connected", + "connectionStatusUnconfigured": "Sense configurar", + "connectionStatusConnecting": "Connectant", + "connectionStatusAuthenticating": "Autenticant", + "connectionStatusPendingDisconnect": "Desconnexiรณ pendent", + "connectionStatusDisconnecting": "Desconnectant", + "connectionStatusDisconnected": "Desconnectat", + "connectionStatusConnected": "Connectat", "uptime": "Temps actiu", - "maxDown": "Max. Down", - "maxUp": "Max. Up", - "down": "Down", - "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "maxDown": "Mร x. Descร rrega", + "maxUp": "Mร x. Cร rrega", + "down": "Inactiu", + "up": "Actiu", + "received": "Rebuts", + "sent": "Enviats", + "externalIPAddress": "IP ext." }, "caddy": { "upstreams": "Upstreams", - "requests": "Current requests", - "requests_failed": "Failed requests" + "requests": "Peticions actuals", + "requests_failed": "Peticions fallides" }, "changedetectionio": { "totalObserved": "Total d'observats", "diffsDetected": "Diferรจncies detectades" }, "channelsdvrserver": { - "shows": "Shows", - "recordings": "Recordings", - "scheduled": "Scheduled", - "passes": "Passes" + "shows": "Sรจries", + "recordings": "Gravacions", + "scheduled": "Programat", + "passes": "Aprovat" }, "tautulli": { "playing": "Reproduint", "transcoding": "Transcodificant", "bitrate": "Taxa de bits", "no_active": "Sense reproduccions actives", - "plex_connection_error": "Check Plex Connection" + "plex_connection_error": "Comprova la connexiรณ de Plex" }, "omada": { - "connectedAp": "Connected APs", - "activeUser": "Active devices", - "alerts": "Alerts", - "connectedGateway": "Connected gateways", - "connectedSwitches": "Connected switches" + "connectedAp": "AP connectats", + "activeUser": "Dispositius actius", + "alerts": "Alertes", + "connectedGateway": "Pasarelยทles connectades", + "connectedSwitches": "Conmutadors connectats" }, "nzbget": { "rate": "Taxa", @@ -180,7 +187,7 @@ "plex": { "streams": "Transmissions actives", "albums": "ร€lbums", - "movies": "Movies", + "movies": "Pelยทlรญcules", "tv": "Sรจries" }, "sabnzbd": { @@ -206,12 +213,12 @@ "seed": "Llavor" }, "qnap": { - "cpuUsage": "CPU Usage", - "memUsage": "MEM Usage", - "systemTempC": "System Temp", - "poolUsage": "Pool Usage", - "volumeUsage": "Volume Usage", - "invalid": "Invalid" + "cpuUsage": "รšs de CPU", + "memUsage": "รšs de Memรฒria", + "systemTempC": "Temp. Sistema", + "poolUsage": "รšs de les Reserves", + "volumeUsage": "รšs dels Volums", + "invalid": "No vร lid" }, "deluge": { "download": "Descarregar", @@ -228,7 +235,7 @@ "sonarr": { "wanted": "Volgut", "queued": "En cua", - "series": "Series", + "series": "Sรจries", "queue": "Cua", "unknown": "Desconegut" }, @@ -236,14 +243,14 @@ "wanted": "Volgut", "missing": "Faltant", "queued": "En cua", - "movies": "Movies", + "movies": "Pelยทlรญcules", "queue": "Cua", "unknown": "Desconegut" }, "lidarr": { "wanted": "Volgut", "queued": "En cua", - "artists": "Artists" + "artists": "Artistes" }, "readarr": { "wanted": "Volgut", @@ -270,17 +277,17 @@ "approved": "Aprovat", "available": "Disponible" }, - "pialert": { + "netalertx": { "total": "Total", - "connected": "Connected", - "new_devices": "New Devices", - "down_alerts": "Down Alerts" + "connected": "Connectat", + "new_devices": "Nous dispositius", + "down_alerts": "Alertes de caigudes" }, "pihole": { "queries": "Consultes", "blocked": "Bloquejat", - "blocked_percent": "Blocked %", - "gravity": "Gravity" + "blocked_percent": "Bloquejat %", + "gravity": "Gravetat" }, "adguard": { "queries": "Consultes", @@ -291,37 +298,37 @@ "speedtest": { "upload": "Pujada", "download": "Descarregar", - "ping": "Ping" + "ping": "Latรจncia" }, "portainer": { - "running": "Running", + "running": "En execuciรณ", "stopped": "Aturat", "total": "Total" }, "tailscale": { - "address": "Address", - "expires": "Expires", - "never": "Never", - "last_seen": "Last Seen", - "now": "Now", - "years": "{{number}}y", - "weeks": "{{number}}w", + "address": "Adreรงa", + "expires": "Caduca", + "never": "Mai", + "last_seen": "Vist per darrer cop", + "now": "Ara", + "years": "{{number}}a", + "weeks": "{{number}}set", "days": "{{number}}d", "hours": "{{number}}h", "minutes": "{{number}}m", "seconds": "{{number}}s", - "ago": "{{value}} Ago" + "ago": "Fa {{value}}" }, "tdarr": { "queue": "Cua", - "processed": "Processed", - "errored": "Errored", - "saved": "Saved" + "processed": "Processat", + "errored": "Error", + "saved": "Desat" }, "traefik": { "routers": "Encaminadors", "services": "Serveis", - "middleware": "Middleware" + "middleware": "Intermediari" }, "navidrome": { "nothing_streaming": "Sense reproduccions actives", @@ -353,7 +360,7 @@ }, "jackett": { "configured": "Configurat", - "errored": "Errored" + "errored": "Error" }, "strelaysrv": { "numActiveSessions": "Sessions", @@ -369,18 +376,18 @@ "medusa": { "wanted": "Volgut", "queued": "En cua", - "series": "Series" + "series": "Sรจries" }, "minecraft": { - "players": "Players", - "version": "Version", + "players": "Jugadors", + "version": "Versiรณ", "status": "Estat", - "up": "Online", + "up": "En lรญnia", "down": "Fora de lรญnia" }, "miniflux": { - "read": "Read", - "unread": "Unread" + "read": "Llegir", + "unread": "Sense llegir" }, "authentik": { "users": "Usuaris", @@ -399,27 +406,28 @@ "wait": "Si us plau, espereu", "temp": "TEMP", "_temp": "Temp", - "warn": "Warn", - "uptime": "UP", + "warn": "Avรญs", + "uptime": "ACTIU", "total": "Total", "free": "Lliure", "used": "Utilitzat", "days": "d", "hours": "h", - "crit": "Crit", - "read": "Read", - "write": "Write", + "crit": "Crรญtic", + "read": "Llegir", + "write": "Escriure", "gpu": "GPU", "mem": "Mem", - "swap": "Swap" + "swap": "Intercanvi" }, "quicklaunch": { "bookmark": "Marcador", "service": "Servei", - "search": "Search", - "custom": "Custom", - "visit": "Visit", - "url": "URL" + "search": "Cercar", + "custom": "Personalitzat", + "visit": "Visitar", + "url": "URL", + "searchsuggestion": "Suggeriment" }, "wmo": { "0-day": "Assolellat", @@ -484,21 +492,21 @@ "updates": "Actualitzacions", "update_available": "Actualitzaciรณ disponible", "up_to_date": "Actualitzat", - "child_bridges": "Child Bridges", + "child_bridges": "Ponts fills", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Up", + "up": "Actiu", "pending": "Pendent", - "down": "Down" + "down": "Inactiu" }, "healthchecks": { - "new": "New", - "up": "Up", - "grace": "In Grace Period", - "down": "Down", - "paused": "Paused", + "new": "Nou", + "up": "Actiu", + "grace": "En Perรญode de grร cia", + "down": "Inactiu", + "paused": "En pausa", "status": "Estat", - "last_ping": "Last Ping", - "never": "No pings yet" + "last_ping": "รšltim ping", + "never": "Sense pings" }, "watchtower": { "containers_scanned": "Escanejat", @@ -520,7 +528,7 @@ "truenas": { "load": "Cร rrega del sistema", "uptime": "Temps actiu", - "alerts": "Alerts" + "alerts": "Alertes" }, "pyload": { "speed": "Velocitat", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Canals", - "hd": "HD" + "hd": "HD", + "tunerCount": "Sintonitzadors", + "channelNumber": "Canal", + "channelNetwork": "Xarxa", + "signalStrength": "Intensitat", + "signalQuality": "Qualitat", + "symbolQuality": "Qualitat", + "networkRate": "Taxa de bits", + "clientIP": "Client" }, "scrutiny": { "passed": "Aprobat", @@ -547,94 +563,94 @@ "total": "Total" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", - "online": "Online", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "battery_charge": "Cร rrega de la bateria", + "ups_load": "Cร rrega del SAI", + "ups_status": "Estat del SAI", + "online": "En lรญnia", + "on_battery": "En Bateria", + "low_battery": "Bateria Baixa" }, "nextdns": { "wait": "Espereu si us plau", - "no_devices": "No Device Data Received" + "no_devices": "No s'han rebut dades del Dispositiu" }, "mikrotik": { - "cpuLoad": "CPU Load", - "memoryUsed": "Memory Used", + "cpuLoad": "Cร rrega de CPU", + "memoryUsed": "Memoria en รบs", "uptime": "Temps actiu", - "numberOfLeases": "Leases" + "numberOfLeases": "IPs assignades" }, "xteve": { - "streams_all": "All Streams", + "streams_all": "Tots els fluxos", "streams_active": "Transmissions actives", - "streams_xepg": "XEPG Channels" + "streams_xepg": "Canals XEPG" }, "opendtu": { - "yieldDay": "Today", - "absolutePower": "Power", - "relativePower": "Power %", - "limit": "Limit" + "yieldDay": "Avui", + "absolutePower": "Potรจncia", + "relativePower": "Potรจncia %", + "limit": "Lรญmit" }, "opnsense": { - "cpu": "CPU Load", - "memory": "Active Memory", - "wanUpload": "WAN Upload", - "wanDownload": "WAN Download" + "cpu": "Cร rrega de CPU", + "memory": "Memรฒria activa", + "wanUpload": "Pujada WAN", + "wanDownload": "Baixada WAN" }, "moonraker": { - "printer_state": "Printer State", - "print_status": "Print Status", + "printer_state": "Estat de l'impressora", + "print_status": "Estat de l'impressiรณ", "print_progress": "Progress", - "layers": "Layers" + "layers": "Capes" }, "octoprint": { "printer_state": "Estat", - "temp_tool": "Tool temp", - "temp_bed": "Bed temp", - "job_completion": "Completion" + "temp_tool": "Temperatura capรงal", + "temp_bed": "Temperatura llit", + "job_completion": "Finalitzaciรณ" }, "cloudflared": { - "origin_ip": "Origin IP", + "origin_ip": "IP Origen", "status": "Estat" }, "pfsense": { - "load": "Load Avg", - "memory": "Mem Usage", - "wanStatus": "WAN Status", - "up": "Up", - "down": "Down", + "load": "Promig Cร rrega", + "memory": "รšs Memรฒria", + "wanStatus": "Estat WAN", + "up": "Actiu", + "down": "Inactiu", "temp": "Temp", - "disk": "Disk Usage", + "disk": "รšs Disc", "wanIP": "WAN IP" }, "proxmoxbackupserver": { "datastore_usage": "Datastore", - "failed_tasks_24h": "Failed Tasks 24h", + "failed_tasks_24h": "Tasques fallides (24h)", "cpu_usage": "CPU", - "memory_usage": "Memory" + "memory_usage": "Memรฒria" }, "immich": { "users": "Usuaris", - "photos": "Photos", + "photos": "Fotos", "videos": "Vรญdeos", - "storage": "Storage" + "storage": "Emmagatzematge" }, "uptimekuma": { - "up": "Sites Up", - "down": "Sites Down", + "up": "Actius", + "down": "Caiguts", "uptime": "Temps actiu", - "incident": "Incident", + "incident": "Incidรจncia", "m": "m" }, "atsumeru": { - "series": "Series", - "archives": "Archives", - "chapters": "Chapters", + "series": "Sรจries", + "archives": "Arxius", + "chapters": "Capรญtols", "categories": "Categories" }, "komga": { - "libraries": "Libraries", - "series": "Series", + "libraries": "Biblioteques", + "series": "Sรจries", "books": "Llibres" }, "diskstation": { @@ -643,72 +659,77 @@ "volumeAvailable": "Disponible" }, "mylar": { - "series": "Series", - "issues": "Issues", + "series": "Sรจries", + "issues": "Problemes", "wanted": "Volgut" }, "photoprism": { "albums": "ร€lbums", - "photos": "Photos", + "photos": "Fotos", "videos": "Vรญdeos", - "people": "People" + "people": "Gent" }, "fileflows": { "queue": "Cua", "processing": "Processant", - "processed": "Processed", - "time": "Time" + "processed": "Processat", + "time": "Temps" }, "grafana": { - "dashboards": "Dashboards", - "datasources": "Data Sources", - "totalalerts": "Total Alerts", - "alertstriggered": "Alerts Triggered" + "dashboards": "Taulells", + "datasources": "Origen de dades", + "totalalerts": "Alertes Totals", + "alertstriggered": "Alertes disparades" }, "nextcloud": { - "cpuload": "Cpu Load", - "memoryusage": "Memory Usage", - "freespace": "Free Space", - "activeusers": "Active Users", - "numfiles": "Files", - "numshares": "Shared Items" + "cpuload": "Cร rrega de CPU", + "memoryusage": "รšs Memรฒria", + "freespace": "Espai lliure", + "activeusers": "Usuaris actius", + "numfiles": "Fitxers", + "numshares": "Elements compartits" }, "kopia": { "status": "Estat", - "size": "Size", - "lastrun": "Last Run", - "nextrun": "Next Run", + "size": "Mida", + "lastrun": "Darrera execuciรณ", + "nextrun": "Segรผent execuciรณ", "failed": "Error" }, "unmanic": { - "active_workers": "Active Workers", - "total_workers": "Total Workers", - "records_total": "Queue Length" + "active_workers": "Treballadors actius", + "total_workers": "Treballadors Totals", + "records_total": "Llargada de la Cua" }, "pterodactyl": { - "servers": "Servers", + "servers": "Servidors", "nodes": "Nodes" }, "prometheus": { - "targets_up": "Targets Up", - "targets_down": "Targets Down", - "targets_total": "Total Targets" + "targets_up": "Objectius actius", + "targets_down": "Objectius caiguts", + "targets_total": "Objectius Totals" + }, + "gatus": { + "up": "Actius", + "down": "Caiguts", + "uptime": "Temps actiu" }, "ghostfolio": { - "gross_percent_today": "Today", - "gross_percent_1y": "One year", - "gross_percent_max": "All time" + "gross_percent_today": "Avui", + "gross_percent_1y": "Un any", + "gross_percent_max": "Tot" }, "audiobookshelf": { "podcasts": "Podcasts", "books": "Llibres", - "podcastsDuration": "Duration", - "booksDuration": "Duration" + "podcastsDuration": "Durada", + "booksDuration": "Durada" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Gent a casa", + "lights_on": "Llums enceses", + "switches_on": "Endolls activats" }, "whatsupdocker": { "monitoring": "Supervisiรณ", @@ -716,92 +737,156 @@ }, "calibreweb": { "books": "Llibres", - "authors": "Authors", + "authors": "Autors", "categories": "Categories", - "series": "Series" + "series": "Sรจries" }, "jdownloader": { "downloadCount": "Cua", "downloadBytesRemaining": "Restant", - "downloadTotalBytes": "Size", + "downloadTotalBytes": "Mida", "downloadSpeed": "Velocitat" }, "kavita": { - "seriesCount": "Series", - "totalFiles": "Files" + "seriesCount": "Sรจries", + "totalFiles": "Fitxers" }, "azuredevops": { - "result": "Result", + "result": "Resultat", "status": "Estat", - "buildId": "Build ID", - "succeeded": "Succeeded", - "notStarted": "Not Started", + "buildId": "Id de compilaciรณ", + "succeeded": "Amb รจxit", + "notStarted": "No Iniciat", "failed": "Error", - "canceled": "Canceled", - "inProgress": "In Progress", - "totalPrs": "Total PRs", - "myPrs": "My PRs", + "canceled": "Cancelยทlat", + "inProgress": "En curs", + "totalPrs": "RP Totals", + "myPrs": "Els meus RP", "approved": "Aprovat" }, "gamedig": { "status": "Estat", - "online": "Online", + "online": "En lรญnia", "offline": "Fora de lรญnia", - "name": "Name", - "map": "Map", - "currentPlayers": "Current players", - "players": "Players", - "maxPlayers": "Max players", + "name": "Nom", + "map": "Mapa", + "currentPlayers": "Jugadors actuals", + "players": "Jugadors", + "maxPlayers": "Mร xim de jugadors", "bots": "Bots", - "ping": "Ping" + "ping": "Latรจncia" }, "urbackup": { "ok": "Ok", "errored": "Errors", - "noRecent": "Out of Date", - "totalUsed": "Used Storage" + "noRecent": "Obsolet", + "totalUsed": "Emmagatzematge utilitzat" }, "mealie": { - "recipes": "Recipes", + "recipes": "Receptes", "users": "Usuaris", "categories": "Categories", - "tags": "Tags" + "tags": "Etiquetes" }, "openmediavault": { - "downloading": "Downloading", + "downloading": "Descarregant", "total": "Total", - "running": "Running", + "running": "En execuciรณ", "stopped": "Aturat", "passed": "Aprobat", "failed": "Error" }, + "openwrt": { + "uptime": "Temps actiu", + "cpuLoad": "Cร rrega promig de CPU (5m)", + "up": "Actiu", + "down": "Inactiu", + "bytesTx": "Enviat", + "bytesRx": "Rebuts" + }, "uptimerobot": { "status": "Estat", "uptime": "Temps actiu", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", - "sitesUp": "Sites Up", - "sitesDown": "Sites Down", - "paused": "Paused", - "notyetchecked": "Not Yet Checked", - "up": "Up", - "seemsdown": "Seems Down", - "down": "Down", + "lastDown": "Darrera Inactivitat", + "downDuration": "Duraciรณ d'Inactivitat", + "sitesUp": "Actius", + "sitesDown": "Caiguts", + "paused": "En pausa", + "notyetchecked": "Sense verificar", + "up": "Actiu", + "seemsdown": "Sembla caigut", + "down": "Inactiu", "unknown": "Desconegut" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", - "digitalRelease": "Digital release", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "inCinemas": "En cines", + "physicalRelease": "Estrena fรญsica", + "digitalRelease": "Estrena digital", + "noEventsToday": "Cap esdeveniment per avui!", + "noEventsFound": "No s'han trobat esdeveniments" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Plataformes", + "totalRoms": "ROMs totals" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Avisos", + "criticals": "Crรญtics" + }, + "plantit": { + "events": "Esdeveniments", + "plants": "Plantes", + "photos": "Fotos", + "species": "Espรจcies" + }, + "gitea": { + "notifications": "Notificacions", + "issues": "Problemes", + "pulls": "Solยทlicitud de Canvis" + }, + "stash": { + "scenes": "Escenes", + "scenesPlayed": "Escenes reproduรฏdes", + "playCount": "Total reproduccions", + "playDuration": "Temps visionat", + "sceneSize": "Tamany Escena", + "sceneDuration": "Duraciรณ Escenes", + "images": "Imatges", + "imageSize": "Mida Imatges", + "galleries": "Biblioteques", + "performers": "Intรจrprets", + "studios": "Estudis", + "movies": "Pelยทlรญcules", + "tags": "Etiquetes", + "oCount": "O Count" + }, + "tandoor": { + "users": "Usuaris", + "recipes": "Receptes", + "keywords": "Paraules claus" + }, + "homebox": { + "items": "Elements", + "totalWithWarranty": "Amb Garantia", + "locations": "Ubicacions", + "labels": "Etiquetes", + "users": "Usuaris", + "totalValue": "Valor total" + }, + "crowdsec": { + "alerts": "Alertes", + "bans": "Prohibicions" + }, + "wgeasy": { + "connected": "Connectat", + "enabled": "Activat", + "disabled": "Desactivat", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/cs/common.json b/public/locales/cs/common.json index 3e3e540b..48030d62 100644 --- a/public/locales/cs/common.json +++ b/public/locales/cs/common.json @@ -14,7 +14,7 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", + "months": "mฤ›s.", "days": "d", "hours": "h", "minutes": "m", @@ -39,7 +39,7 @@ "placeholder": "Hledatโ€ฆ" }, "resources": { - "cpu": "Procesor", + "cpu": "CPU", "mem": "RAM", "total": "Celkem", "free": "Volnรฉ", @@ -70,7 +70,7 @@ "rx": "RX", "tx": "TX", "mem": "RAM", - "cpu": "Procesor", + "cpu": "CPU", "running": "Bฤ›ลพรญ", "offline": "Offline", "error": "Chyba", @@ -87,15 +87,15 @@ "ping": "Odezva", "down": "Down", "up": "Up", - "not_available": "Not Available" + "not_available": "Nenรญ k dispozici" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "Stav HTTP", "error": "Chyba", - "response": "Response", + "response": "Odpovฤ›ฤ", "down": "Down", "up": "Up", - "not_available": "Not Available" + "not_available": "Nenรญ k dispozici" }, "emby": { "playing": "Pล™ehrรกvรก", @@ -107,12 +107,19 @@ "episodes": "Epizody", "songs": "Skladby" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Celkem", + "unknown": "Neznรกmรฝ" + }, "evcc": { "pv_power": "Produkce", - "battery_soc": "Battery", - "grid_power": "Grid", - "home_power": "Consumption", - "charge_power": "Charger", + "battery_soc": "Baterie", + "grid_power": "Mล™รญลพka", + "home_power": "Spotล™eba", + "charge_power": "Nabรญjeฤka", "watt_hour": "Wh" }, "flood": { @@ -127,20 +134,20 @@ }, "fritzbox": { "connectionStatus": "Stav", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", + "connectionStatusUnconfigured": "Nenastaveno", + "connectionStatusConnecting": "Pล™ipojuji", + "connectionStatusAuthenticating": "Ovฤ›ล™ovรกnรญ", + "connectionStatusPendingDisconnect": "ฤŒekรก na odpojenรญ", + "connectionStatusDisconnecting": "Odpojovรกnรญ", + "connectionStatusDisconnected": "Odpojeno", "connectionStatusConnected": "Connected", "uptime": "Doba spuลกtฤ›nรญ", "maxDown": "Max. Down", "maxUp": "Max. Up", "down": "Down", "up": "Up", - "received": "Received", - "sent": "Sent", + "received": "Pล™ijatรฉ", + "sent": "Odeslanรฉ", "externalIPAddress": "Ext. IP" }, "caddy": { @@ -163,7 +170,7 @@ "transcoding": "Pล™ekรณdovรกvรกnรญ", "bitrate": "Pล™enosovรก rychlost", "no_active": "ลฝรกdnรฝ aktivnรญ stream", - "plex_connection_error": "Check Plex Connection" + "plex_connection_error": "Zkontrolujte pล™ipojenรญ Plexu" }, "omada": { "connectedAp": "Pล™ipojenรฉ APs", @@ -210,8 +217,8 @@ "memUsage": "Vyuลพitรญ pamฤ›ti", "systemTempC": "Teplota systรฉmu", "poolUsage": "Vyuลพitรญ fondu", - "volumeUsage": "Volume Usage", - "invalid": "Invalid" + "volumeUsage": "Vyuลพitรญ svazku", + "invalid": "Neplatnรฉ" }, "deluge": { "download": "Stahovรกnรญ", @@ -243,7 +250,7 @@ "lidarr": { "wanted": "Hledanรฉ", "queued": "Ve frontฤ›", - "artists": "Artists" + "artists": "Interpreti" }, "readarr": { "wanted": "Hledanรฉ", @@ -270,7 +277,7 @@ "approved": "Schvรกleno", "available": "Dostupnรฉ" }, - "pialert": { + "netalertx": { "total": "Celkem", "connected": "Connected", "new_devices": "New Devices", @@ -389,17 +396,17 @@ }, "proxmox": { "mem": "RAM", - "cpu": "Procesor", + "cpu": "CPU", "lxc": "LXC", "vms": "Virtuรกlnรญ Stroje" }, "glances": { - "cpu": "Procesor", + "cpu": "CPU", "load": "Zatรญลพenรญ", "wait": "Poฤkejte prosรญm", "temp": "TEPLOTA", "_temp": "Temp", - "warn": "Warn", + "warn": "Varovรกni", "uptime": "Bฤšลฝร", "total": "Celkem", "free": "Volnรฉ", @@ -419,7 +426,8 @@ "search": "Hledat", "custom": "Vlastnรญ", "visit": "Navลกtivte", - "url": "Odkaz" + "url": "Odkaz", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sluneฤno", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanรกly", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Pล™enosovรก rychlost", + "clientIP": "Client" }, "scrutiny": { "passed": "รšspฤ›ลกnรฉ", @@ -610,7 +626,7 @@ "proxmoxbackupserver": { "datastore_usage": "Datovรฉ รบloลพiลกtฤ›", "failed_tasks_24h": "Neรบspฤ›ลกnรฉ รบlohy 24h", - "cpu_usage": "Procesor", + "cpu_usage": "CPU", "memory_usage": "Pamฤ›ลฅ" }, "immich": { @@ -694,6 +710,11 @@ "targets_down": "Cรญle vypnutรฉ", "targets_total": "Cรญle celkem" }, + "gatus": { + "up": "Strรกnky Up", + "down": "Strรกnky Down", + "uptime": "Doba spuลกtฤ›nรญ" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "Jeden rok", @@ -775,6 +796,14 @@ "passed": "รšspฤ›ลกnรฉ", "failed": "Selhalo" }, + "openwrt": { + "uptime": "Doba spuลกtฤ›nรญ", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Pล™ijatรฉ" + }, "uptimerobot": { "status": "Stav", "uptime": "Doba spuลกtฤ›nรญ", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Fotografie", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Problรฉmy", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Filmy", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Uลพivatelรฉ", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Uลพivatelรฉ", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Upozornฤ›nรญ", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Povoleno", + "disabled": "Zakรกzรกno", + "total": "Celkem" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/da/common.json b/public/locales/da/common.json index 1bcfdc7f..e4c2e0a9 100644 --- a/public/locales/da/common.json +++ b/public/locales/da/common.json @@ -14,9 +14,9 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", + "months": "mnd", "days": "d", - "hours": "h", + "hours": "t", "minutes": "m", "seconds": "s" }, @@ -90,7 +90,7 @@ "not_available": "Ikke tilgรฆngelig" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "HTTP-status", "error": "Fejl", "response": "Response", "down": "Ned", @@ -107,6 +107,13 @@ "episodes": "Episoder", "songs": "Sange" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Total", + "unknown": "Ukendt" + }, "evcc": { "pv_power": "Produktion", "battery_soc": "Batteri", @@ -133,15 +140,15 @@ "connectionStatusPendingDisconnect": "Pending Disconnect", "connectionStatusDisconnecting": "Disconnecting", "connectionStatusDisconnected": "Disconnected", - "connectionStatusConnected": "Forbundet", + "connectionStatusConnected": "Connected", "uptime": "Oppetid", "maxDown": "Max. Down", "maxUp": "Max. Up", "down": "Ned", "up": "Op", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "received": "Modtaget", + "sent": "Sendt", + "externalIPAddress": "Ekstern IP" }, "caddy": { "upstreams": "Upstreams", @@ -270,11 +277,11 @@ "approved": "Godkendt", "available": "Tilgรฆngelig" }, - "pialert": { + "netalertx": { "total": "Total", - "connected": "Forbundet", - "new_devices": "Nye Enheder", - "down_alerts": "Nedadvarsler" + "connected": "Connected", + "new_devices": "New Devices", + "down_alerts": "Down Alerts" }, "pihole": { "queries": "Forespรธrgsler", @@ -405,7 +412,7 @@ "free": "Fri", "used": "Brugt", "days": "d", - "hours": "h", + "hours": "t", "crit": "Crit", "read": "Lรฆst", "write": "Skriv", @@ -419,7 +426,8 @@ "search": "Sรธg", "custom": "Brugerdefinerede", "visit": "Besรธg", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Solrig", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanaler", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Bestรฅet", @@ -547,12 +563,12 @@ "total": "Total" }, "peanut": { - "battery_charge": "Battery Charge", + "battery_charge": "Batteriniveau", "ups_load": "UPS Load", "ups_status": "UPS Status", "online": "Online", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "Pรฅ batteri", + "low_battery": "Lavt batteriniveau" }, "nextdns": { "wait": "Vent venligst", @@ -694,6 +710,11 @@ "targets_down": "Mรฅl Nede", "targets_total": "Totale Mรฅl" }, + "gatus": { + "up": "Sider Oppe", + "down": "Sider Nede", + "uptime": "Oppetid" + }, "ghostfolio": { "gross_percent_today": "I dag", "gross_percent_1y": "Et ร…r", @@ -775,6 +796,14 @@ "passed": "Bestรฅet", "failed": "Fejlet" }, + "openwrt": { + "uptime": "Oppetid", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Op", + "down": "Ned", + "bytesTx": "Transmitted", + "bytesRx": "Modtaget" + }, "uptimerobot": { "status": "Status", "uptime": "Oppetid", @@ -797,11 +826,67 @@ "noEventsFound": "No events found" }, "romm": { - "platforms": "Platforms", + "platforms": "Platforme", "totalRoms": "Total ROMs" }, "netdata": { - "warnings": "Warnings", + "warnings": "Advarsler", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Billeder", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Problemer", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Film", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Brugere", + "recipes": "Opskrifter", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Brugere", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Advarsler", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Aktiveret", + "disabled": "Deaktiveret", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/de/common.json b/public/locales/de/common.json index 93d41110..4a188956 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -107,6 +107,13 @@ "episodes": "Episoden", "songs": "Songs" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Gesamt", + "unknown": "Unbekannt" + }, "evcc": { "pv_power": "Erzeugung", "battery_soc": "Batterie", @@ -135,8 +142,8 @@ "connectionStatusDisconnected": "Getrennt", "connectionStatusConnected": "Verbunden", "uptime": "Betriebszeit", - "maxDown": "Max. Empfang", - "maxUp": "Max. Senden", + "maxDown": "Max. Down", + "maxUp": "Max. Up", "down": "Empfangen", "up": "Senden", "received": "Empfangen", @@ -270,7 +277,7 @@ "approved": "Genehmigt", "available": "Verfรผgbar" }, - "pialert": { + "netalertx": { "total": "Gesamt", "connected": "Verbunden", "new_devices": "Neue Gerรคte", @@ -379,13 +386,13 @@ "down": "Offline" }, "miniflux": { - "read": "Lesen", + "read": "Gelesen", "unread": "Ungelesen" }, "authentik": { "users": "Benutzer", "loginsLast24H": "Anmeldungen (24 h)", - "failedLoginsLast24H": "Fehlgeschlagene Anmeldungen (24 h)" + "failedLoginsLast24H": "Fehlversuche (24 h)" }, "proxmox": { "mem": "RAM", @@ -407,7 +414,7 @@ "days": "d", "hours": "h", "crit": "Krit", - "read": "Lesen", + "read": "Gelesen", "write": "Schreiben", "gpu": "GPU", "mem": "RAM", @@ -536,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanรคle", - "hd": "HD" + "hd": "HD", + "tunerCount": "Empfรคnger", + "channelNumber": "Kanal", + "channelNetwork": "Netzwerk", + "signalStrength": "Stรคrke", + "signalQuality": "Qualitรคt", + "symbolQuality": "Qualitรคt", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Bestanden", @@ -695,6 +710,11 @@ "targets_down": "Ziele Down", "targets_total": "Alle Ziele" }, + "gatus": { + "up": "Seiten verfรผgbar", + "down": "Seiten nicht verfรผgbar", + "uptime": "Betriebszeit" + }, "ghostfolio": { "gross_percent_today": "Heute", "gross_percent_1y": "Ein Jahr", @@ -776,6 +796,14 @@ "passed": "Bestanden", "failed": "Fehlgeschlagen" }, + "openwrt": { + "uptime": "Betriebszeit", + "cpuLoad": "CPU-Last (5 min-Durchschnitt)", + "up": "Senden", + "down": "Empfangen", + "bytesTx": "รœbertragen", + "bytesRx": "Empfangen" + }, "uptimerobot": { "status": "Status", "uptime": "Betriebszeit", @@ -798,11 +826,67 @@ "noEventsFound": "Keine Termine gefunden" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Plattformen", + "totalRoms": "ROMs gesamt" }, "netdata": { "warnings": "Warnungen", "criticals": "Kritisch" + }, + "plantit": { + "events": "Ereignisse", + "plants": "Pflanzen", + "photos": "Fotos", + "species": "Spezies" + }, + "gitea": { + "notifications": "Benachrichtigungen", + "issues": "Probleme", + "pulls": "Pull-Requests" + }, + "stash": { + "scenes": "Szenen", + "scenesPlayed": "Gespielte Szenen", + "playCount": "Wiedergaben gesamt", + "playDuration": "Zeit angesehen", + "sceneSize": "SzenengrรถรŸe", + "sceneDuration": "Szenendauer", + "images": "Bilder", + "imageSize": "BildgrรถรŸe", + "galleries": "Galerien", + "performers": "Darsteller", + "studios": "Studios", + "movies": "Filme", + "tags": "Schlagwรถrter", + "oCount": "O-Anzahl" + }, + "tandoor": { + "users": "Benutzer", + "recipes": "Rezepte", + "keywords": "Schlagwรถrter" + }, + "homebox": { + "items": "Objekte", + "totalWithWarranty": "Mit Garantie", + "locations": "Orte", + "labels": "Labels", + "users": "Benutzer", + "totalValue": "Gesamtwert" + }, + "crowdsec": { + "alerts": "Warnungen", + "bans": "Banns" + }, + "wgeasy": { + "connected": "Verbunden", + "enabled": "Aktiviert", + "disabled": "Deaktiviert", + "total": "Gesamt" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "Mit Auth", + "outdated": "Veraltet", + "banned": "Gebannt" } } diff --git a/public/locales/el/common.json b/public/locales/el/common.json index b318cfda..2ffcd522 100644 --- a/public/locales/el/common.json +++ b/public/locales/el/common.json @@ -40,14 +40,14 @@ }, "resources": { "cpu": "ฮ•ฯ€ฮตฮพฮตฯฮณฮฑฯƒฯ„ฮฎฯ‚", - "mem": "MEM", + "mem": "ฮœฮฝฮฎฮผฮท", "total": "ฮฃฯฮฝฮฟฮปฮฟ", "free": "ฮ”ฯ‰ฯฮตฮฌฮฝ", "used": "ฯ‡ฯฮทฯƒฮนฮผฮฟฯ€ฮฟฮนฮทฮผฮญฮฝฮฟ", "load": "ฮฆฯŒฯฯ„ฯ‰ฯƒฮท", - "temp": "ฮ˜ฮ•ฮกฮœฮŸฮšฮกฮ‘ฮฃฮชฮ‘", + "temp": "ฮ˜ฮตฯฮผฮฟฮบฯฮฑฯƒฮฏฮฑ", "max": "ฮœฮญฮณฮนฯƒฯ„ฮฟ", - "uptime": "ฮ ฮ‘ฮฮฉ" + "uptime": "ฮงฯฯŒฮฝฮฟฯ‚ ฮ›ฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚" }, "unifi": { "users": "ฮงฯฮฎฯƒฯ„ฮตฯ‚", @@ -61,7 +61,7 @@ "wlan_devices": "WLAN ฮฃฯ…ฯƒฮบฮตฯ…ฮญฯ‚", "lan_users": "LAN ฮงฯฮฎฯƒฯ„ฮตฯ‚", "wlan_users": "WLAN ฮงฯฮฎฯƒฯ„ฮตฯ‚", - "up": "ฮ ฮ‘ฮฮฉ", + "up": "ฮงฯฯŒฮฝฮฟฯ‚ ฮ›ฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚", "down": "ฮšฮ‘ฮคฮฉ", "wait": "ฮ ฮฑฯฮฑฮบฮฑฮปฯŽ ฯ€ฮตฯฮนฮผฮญฮฝฮตฯ„ฮต", "empty_data": "ฮ†ฮณฮฝฯ‰ฯƒฯ„ฮท ฮบฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท ฯ…ฯ€ฮฟฯƒฯ…ฯƒฯ„ฮฎฮผฮฑฯ„ฮฟฯ‚" @@ -69,7 +69,7 @@ "docker": { "rx": "RX", "tx": "TX", - "mem": "MEM", + "mem": "ฮœฮฝฮฎฮผฮท", "cpu": "ฮ•ฯ€ฮตฮพฮตฯฮณฮฑฯƒฯ„ฮฎฯ‚", "running": "ฮคฯฮญฯ‡ฯ‰ฮฝ", "offline": "ฮ•ฮบฯ„ฯŒฯ‚ ฯƒฯฮฝฮดฮตฯƒฮทฯ‚", @@ -85,16 +85,16 @@ "ping": { "error": "ฮฃฯ†ฮฌฮปฮผฮฑ", "ping": "Ping", - "down": "Down", - "up": "Up", + "down": "Ping down", + "up": "Ping up", "not_available": "ฮœฮท ฮดฮนฮฑฮธฮญฯƒฮนฮผฮฟ" }, "siteMonitor": { "http_status": "ฮšฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท HTTP", "error": "ฮฃฯ†ฮฌฮปฮผฮฑ", "response": "ฮ‘ฯ€ฯŒฮบฯฮนฯƒฮท", - "down": "Down", - "up": "Up", + "down": "Ping down", + "up": "Ping up", "not_available": "ฮœฮท ฮดฮนฮฑฮธฮญฯƒฮนฮผฮฟ" }, "emby": { @@ -107,6 +107,13 @@ "episodes": "ฮ•ฯ€ฮตฮนฯƒฯŒฮดฮนฮฑ", "songs": "ฮคฯฮฑฮณฮฟฯฮดฮนฮฑ" }, + "esphome": { + "offline": "ฮ•ฮบฯ„ฯŒฯ‚ ฯƒฯฮฝฮดฮตฯƒฮทฯ‚", + "offline_alt": "ฮ•ฮบฯ„ฯŒฯ‚ ฯƒฯฮฝฮดฮตฯƒฮทฯ‚", + "online": "ฮฃฯ…ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน", + "total": "ฮฃฯฮฝฮฟฮปฮฟ", + "unknown": "ฮ†ฮณฮฝฯ‰ฯƒฯ„ฮฟ" + }, "evcc": { "pv_power": "ฮ ฮฑฯฮฑฮณฯ‰ฮณฮฎ", "battery_soc": "ฮœฯ€ฮฑฯ„ฮฑฯฮฏฮฑ", @@ -129,19 +136,19 @@ "connectionStatus": "ฮšฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท", "connectionStatusUnconfigured": "ฮœฮท ฮกฯ…ฮธฮผฮนฯƒฮผฮญฮฝฮฟ", "connectionStatusConnecting": "ฮšฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท ฮฃฯฮฝฮดฮตฯƒฮทฯ‚", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", - "connectionStatusConnected": "Connected", + "connectionStatusAuthenticating": "ฮคฮฑฯ…ฯ„ฮฟฯ€ฮฟฮฏฮทฯƒฮท", + "connectionStatusPendingDisconnect": "ฮ•ฮบฮบฯฮตฮผฮตฮฏ ฮ‘ฯ€ฮฟฯƒฯฮฝฮดฮตฯƒฮท", + "connectionStatusDisconnecting": "ฮ‘ฯ€ฮฟฯƒฯฮฝฮดฮตฯƒฮท", + "connectionStatusDisconnected": "ฮ‘ฯ€ฮฟฯƒฯ…ฮฝฮดฮญฮธฮทฮบฮต", + "connectionStatusConnected": "ฮฃฯ…ฮฝฮดฮญฮธฮทฮบฮต", "uptime": "ฮงฯฯŒฮฝฮฟฯ‚ ฮ›ฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚", - "maxDown": "Max. Down", - "maxUp": "Max. Up", - "down": "Down", - "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "maxDown": "ฮœฮญฮณฮนฯƒฯ„ฮฟ Download", + "maxUp": "ฮœฮญฮณฮนฯƒฯ„ฮฟ Upload", + "down": "Ping down", + "up": "Ping up", + "received": "ฮ›ฮทฯ†ฮธฮญฮฝฯ„ฮฑ", + "sent": "ฮ‘ฯ€ฮตฯƒฯ„ฮฑฮปฮผฮญฮฝฮฑ", + "externalIPAddress": "ฮ•ฮพฯ‰ฯ„ฮตฯฮนฮบฮฎ IP" }, "caddy": { "upstreams": "Upstreams", @@ -210,7 +217,7 @@ "memUsage": "ฮงฯฮฎฯƒฮท ฮผฮฝฮฎฮผฮทฯ‚", "systemTempC": "ฮ˜ฮตฯฮผฮฟฮบฯฮฑฯƒฮฏฮฑ ฯƒฯ…ฯƒฯ„ฮฎฮผฮฑฯ„ฮฟฯ‚", "poolUsage": "ฮงฯฮฎฯƒฮท ฯ€ฮนฯƒฮฏฮฝฮฑฯ‚", - "volumeUsage": "Volume Usage", + "volumeUsage": "ฮงฯฮฎฯƒฮท ฮŒฮณฮบฮฟฯ…", "invalid": "ฮœฮท ฮญฮณฮบฯ…ฯฮฟ" }, "deluge": { @@ -266,15 +273,15 @@ }, "overseerr": { "pending": "ฮฃฮต ฮตฮบฮบฯฮตฮผฯŒฯ„ฮทฯ„ฮฑ", - "processing": "Processing", + "processing": "ฮฃฮต ฮตฯ€ฮตฮพฮตฯฮณฮฑฯƒฮฏฮฑ", "approved": "ฮ•ฮณฮบฯฮฏฮธฮทฮบฮต", "available": "ฮ”ฮนฮฑฮธฮญฯƒฮนฮผฮฟ" }, - "pialert": { + "netalertx": { "total": "ฮฃฯฮฝฮฟฮปฮฟ", - "connected": "Connected", - "new_devices": "New Devices", - "down_alerts": "Down Alerts" + "connected": "ฮฃฯ…ฮฝฮดฮญฮธฮทฮบฮต", + "new_devices": "ฮฮญฮตฯ‚ ฯƒฯ…ฯƒฮบฮตฯ…ฮญฯ‚", + "down_alerts": "ฮ•ฮนฮดฮฟฯ€ฮฟฮนฮฎฯƒฮตฮนฯ‚ offline" }, "pihole": { "queries": "Queries", @@ -302,26 +309,26 @@ "address": "ฮ”ฮนฮตฯฮธฯ…ฮฝฯƒฮท", "expires": "ฮ›ฮฎฮณฮตฮน", "never": "ฮ ฮฟฯ„ฮญ", - "last_seen": "Last Seen", + "last_seen": "ฮคฮตฮปฮตฯ…ฯ„ฮฑฮฏฮฑ ฮฃฯฮฝฮดฮตฯƒฮท", "now": "ฮคฯŽฯฮฑ", - "years": "{{number}}y", - "weeks": "{{number}}w", - "days": "{{number}}d", - "hours": "{{number}}h", - "minutes": "{{number}}m", - "seconds": "{{number}}s", + "years": "{{number}}ฯ‡ฯฯŒฮฝฮนฮฑ", + "weeks": "{{number}}ฮตฮฒฮดฮฟฮผฮฌฮดฮตฯ‚", + "days": "{{number}}ฮผฮญฯฮตฯ‚", + "hours": "{{number}}ฯŽฯฮตฯ‚", + "minutes": "{{number}}ฮปฮตฯ€ฯ„ฮฌ", + "seconds": "{{number}}ฮดฮตฯ…ฯ„ฮตฯฯŒฮปฮตฯ€ฯ„ฮฑ", "ago": "{{value}} ฯ€ฯฮฏฮฝ" }, "tdarr": { "queue": "ฮŸฯ…ฯฮฌ", - "processed": "Processed", - "errored": "Errored", - "saved": "Saved" + "processed": "ฮฃฮต ฮตฯ€ฮตฮพฮตฯฮณฮฑฯƒฮฏฮฑ", + "errored": "ฮฃฯ†ฮฌฮปฮผฮฑฯ„ฮฑ", + "saved": "ฮ‘ฯ€ฮฟฮธฮทฮบฮตฯฯ„ฮทฮบฮต" }, "traefik": { - "routers": "Routers", - "services": "Services", - "middleware": "Middleware" + "routers": "ฮ”ฯฮฟฮผฮฟฮปฮฟฮณฮทฯ„ฮญฯ‚", + "services": "ฮฅฯ€ฮทฯฮตฯƒฮฏฮตฯ‚", + "middleware": "ฮ•ฮฝฮดฮนฮฌฮผฮตฯƒฮฟ ฮปฮฟฮณฮนฯƒฮผฮนฮบฯŒ" }, "navidrome": { "nothing_streaming": "ฮ”ฮตฮฝ ฯ…ฯ€ฮฌฯฯ‡ฮฟฯ…ฮฝ ฮตฮฝฮตฯฮณฮญฯ‚ ฯฮฟฮญฯ‚", @@ -353,7 +360,7 @@ }, "jackett": { "configured": "ฮกฯ…ฮธฮผฮนฯƒฮผฮญฮฝฮฟ", - "errored": "Errored" + "errored": "ฮฃฯ†ฮฌฮปฮผฮฑฯ„ฮฑ" }, "strelaysrv": { "numActiveSessions": "ฮฃฯ…ฮฝฮตฮดฯฮฏฮตฯ‚", @@ -364,7 +371,7 @@ "mastodon": { "user_count": "ฮงฯฮฎฯƒฯ„ฮตฯ‚", "status_count": "ฮ”ฮทฮผฮฟฯƒฮนฮตฯฯƒฮตฮนฯ‚", - "domain_count": "Domains" + "domain_count": "ฮคฮฟฮผฮตฮฏฯ‚" }, "medusa": { "wanted": "ฮ•ฯ€ฮนฮธฯ…ฮผฮฟฯฮฝฯ„ฮต", @@ -379,7 +386,7 @@ "down": "ฮ•ฮบฯ„ฯŒฯ‚ ฯƒฯฮฝฮดฮตฯƒฮทฯ‚" }, "miniflux": { - "read": "Read", + "read": "ฮ”ฮนฮฑฮฒฮฌฯƒฯ„ฮทฮบฮต", "unread": "ฮœฮท ฮ”ฮนฮฑฮฒฮฑฯƒฮผฮญฮฝฮฟ" }, "authentik": { @@ -388,7 +395,7 @@ "failedLoginsLast24H": "ฮ‘ฯ€ฮฟฯ„ฯ…ฯ‡ฮทฮผฮญฮฝฮตฯ‚ ฮฃฯ…ฮฝฮดฮญฯƒฮตฮนฯ‚ (24h)" }, "proxmox": { - "mem": "MEM", + "mem": "ฮœฮฝฮฎฮผฮท", "cpu": "ฮ•ฯ€ฮตฮพฮตฯฮณฮฑฯƒฯ„ฮฎฯ‚", "lxc": "LXC", "vms": "VMs" @@ -397,17 +404,17 @@ "cpu": "ฮ•ฯ€ฮตฮพฮตฯฮณฮฑฯƒฯ„ฮฎฯ‚", "load": "ฮฆฯŒฯฯ„ฯ‰ฯƒฮท", "wait": "ฮ ฮฑฯฮฑฮบฮฑฮปฯŽ ฯ€ฮตฯฮนฮผฮญฮฝฮตฯ„ฮต", - "temp": "ฮ˜ฮ•ฮกฮœฮŸฮšฮกฮ‘ฮฃฮชฮ‘", + "temp": "ฮ˜ฮตฯฮผฮฟฮบฯฮฑฯƒฮฏฮฑ", "_temp": "Temp", "warn": "Warn", - "uptime": "ฮ ฮ‘ฮฮฉ", + "uptime": "ฮงฯฯŒฮฝฮฟฯ‚ ฮ›ฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚", "total": "ฮฃฯฮฝฮฟฮปฮฟ", "free": "ฮ”ฯ‰ฯฮตฮฌฮฝ", "used": "ฯ‡ฯฮทฯƒฮนฮผฮฟฯ€ฮฟฮนฮทฮผฮญฮฝฮฟ", "days": "d", "hours": "h", "crit": "Crit", - "read": "Read", + "read": "ฮ”ฮนฮฑฮฒฮฌฯƒฯ„ฮทฮบฮต", "write": "Write", "gpu": "GPU", "mem": "ฮœฮฝฮฎฮผฮท", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "ฮ›ฮนฮฑฮบฮฌฮดฮฑ", @@ -442,80 +450,80 @@ "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", - "95-night": "Thunderstorm", - "96-day": "Thunderstorm With Hail", - "96-night": "Thunderstorm With Hail", - "99-day": "Thunderstorm With Hail", - "99-night": "Thunderstorm With Hail" + "57-day": "ฮ ฮฑฮณฯ‰ฮผฮญฮฝฮฟ ฯˆฮนฯ‡ฮฌฮปฮนฯƒฮผฮฑ", + "57-night": "ฮ ฮฑฮณฯ‰ฮผฮญฮฝฮฟ ฯˆฮนฯ‡ฮฌฮปฮนฯƒฮผฮฑ", + "61-day": "ฮจฮนฮปฯŒฮฒฯฮฟฯ‡ฮฟ", + "61-night": "ฮจฮนฮปฯŒฮฒฯฮฟฯ‡ฮฟ", + "63-day": "ฮ’ฯฮฟฯ‡ฮฎ", + "63-night": "ฮ’ฯฮฟฯ‡ฮฎ", + "65-day": "ฮ”ฯ…ฮฝฮฑฯ„ฮฎ ฮฒฯฮฟฯ‡ฮฎ", + "65-night": "ฮ”ฯ…ฮฝฮฑฯ„ฮฎ ฮฒฯฮฟฯ‡ฮฎ", + "66-day": "ฮ ฮฑฮณฯ‰ฮผฮญฮฝฮท ฮฒฯฮฟฯ‡ฮฎ", + "66-night": "ฮ ฮฑฮณฯ‰ฮผฮญฮฝฮท ฮฒฯฮฟฯ‡ฮฎ", + "67-day": "ฮ ฮฑฮณฯ‰ฮผฮญฮฝฮท ฮฒฯฮฟฯ‡ฮฎ", + "67-night": "ฮ ฮฑฮณฯ‰ฮผฮญฮฝฮท ฮฒฯฮฟฯ‡ฮฎ", + "71-day": "ฮ•ฮปฮฑฯ†ฯฮนฮฌ ฮงฮนฮฟฮฝฯŒฯ€ฯ„ฯ‰ฯƒฮท", + "71-night": "ฮ•ฮปฮฑฯ†ฯฮนฮฌ ฮงฮนฮฟฮฝฯŒฯ€ฯ„ฯ‰ฯƒฮท", + "73-day": "ฮงฮนฯŒฮฝฮน", + "73-night": "ฮงฮนฯŒฮฝฮน", + "75-day": "ฮ™ฯƒฯ‡ฯ…ฯฮฎ ฯ‡ฮนฮฟฮฝฯŒฯ€ฯ„ฯ‰ฯƒฮท", + "75-night": "ฮ™ฯƒฯ‡ฯ…ฯฮฎ ฯ‡ฮนฮฟฮฝฯŒฯ€ฯ„ฯ‰ฯƒฮท", + "77-day": "ฮšฯŒฮบฮบฮฟฮน ฮงฮนฮฟฮฝฮนฮฟฯ", + "77-night": "ฮšฯŒฮบฮบฮฟฮน ฮงฮนฮฟฮฝฮนฮฟฯ", + "80-day": "ฮ‘ฯƒฮธฮตฮฝฮตฮฏฯ‚ ฮฒฯฮฟฯ‡ฮญฯ‚", + "80-night": "ฮ‘ฯƒฮธฮตฮฝฮตฮฏฯ‚ ฮฒฯฮฟฯ‡ฮญฯ‚", + "81-day": "ฮ’ฯฮฟฯ‡ฮฟฯ€ฯ„ฯŽฯƒฮตฮนฯ‚", + "81-night": "ฮ’ฯฮฟฯ‡ฮฟฯ€ฯ„ฯŽฯƒฮตฮนฯ‚", + "82-day": "ฮ™ฯƒฯ‡ฯ…ฯฮญฯ‚ ฮฒฯฮฟฯ‡ฮฟฯ€ฯ„ฯŽฯƒฮตฮนฯ‚", + "82-night": "ฮ™ฯƒฯ‡ฯ…ฯฮญฯ‚ ฮฒฯฮฟฯ‡ฮฟฯ€ฯ„ฯŽฯƒฮตฮนฯ‚", + "85-day": "ฮงฮนฮฟฮฝฮฟฯ€ฯ„ฯŽฯƒฮตฮนฯ‚", + "85-night": "ฮงฮนฮฟฮฝฮฟฯ€ฯ„ฯŽฯƒฮตฮนฯ‚", + "86-day": "ฮงฮนฮฟฮฝฮฟฯ€ฯ„ฯŽฯƒฮตฮนฯ‚", + "86-night": "ฮงฮนฮฟฮฝฮฟฯ€ฯ„ฯŽฯƒฮตฮนฯ‚", + "95-day": "ฮšฮฑฯ„ฮฑฮนฮณฮฏฮดฮฑ", + "95-night": "ฮšฮฑฯ„ฮฑฮนฮณฮฏฮดฮฑ", + "96-day": "ฮšฮฑฯ„ฮฑฮนฮณฮฏฮดฮฑ ฮœฮต ฮงฮฑฮปฮฌฮถฮน", + "96-night": "ฮšฮฑฯ„ฮฑฮนฮณฮฏฮดฮฑ ฮœฮต ฮงฮฑฮปฮฌฮถฮน", + "99-day": "ฮšฮฑฯ„ฮฑฮนฮณฮฏฮดฮฑ ฮœฮต ฮงฮฑฮปฮฌฮถฮน", + "99-night": "ฮšฮฑฯ„ฮฑฮนฮณฮฏฮดฮฑ ฮœฮต ฮงฮฑฮปฮฌฮถฮน" }, "homebridge": { - "available_update": "System", - "updates": "Updates", - "update_available": "Update Available", - "up_to_date": "Up to Date", + "available_update": "ฮฃฯฯƒฯ„ฮทฮผฮฑ", + "updates": "ฮ•ฮฝฮทฮผฮตฯฯŽฯƒฮตฮนฯ‚", + "update_available": "ฮ”ฮนฮฑฮธฮญฯƒฮนฮผฮท ฮตฮฝฮทฮผฮญฯฯ‰ฯƒฮท", + "up_to_date": "ฮ•ฮฝฮทฮผฮตฯฯ‰ฮผฮญฮฝฮฟ", "child_bridges": "Child Bridges", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Up", + "up": "Ping up", "pending": "ฮฃฮต ฮตฮบฮบฯฮตฮผฯŒฯ„ฮทฯ„ฮฑ", - "down": "Down" + "down": "Ping down" }, "healthchecks": { "new": "New", - "up": "Up", + "up": "Ping up", "grace": "In Grace Period", - "down": "Down", + "down": "Ping down", "paused": "Paused", "status": "ฮšฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท", - "last_ping": "Last Ping", - "never": "No pings yet" + "last_ping": "ฮคฮตฮปฮตฯ…ฯ„ฮฑฮฏฮฟ Ping", + "never": "ฮ”ฮตฮฝ ฯ…ฯ€ฮฌฯฯ‡ฮฟฯ…ฮฝ ping ฮฑฮบฯŒฮผฮฑ" }, "watchtower": { - "containers_scanned": "Scanned", - "containers_updated": "Updated", - "containers_failed": "Failed" + "containers_scanned": "ฮฃฮบฮฑฮฝฮฑฯฮนฯƒฮผฮญฮฝฮฟ", + "containers_updated": "ฮ•ฮฝฮทฮผฮตฯฯŽฮธฮทฮบฮต", + "containers_failed": "ฮ‘ฯ€ฮญฯ„ฯ…ฯ‡ฮต" }, "autobrr": { "approvedPushes": "ฮ•ฮณฮบฯฮฏฮธฮทฮบฮต", - "rejectedPushes": "Rejected", - "filters": "Filters", + "rejectedPushes": "ฮ‘ฯ€ฮฟฯฯฮฏฯ†ฮธฮทฮบฮต", + "filters": "ฮฆฮฏฮปฯ„ฯฮฑ", "indexers": "ฮ•ฯ…ฯฮตฯ„ฮฎฯฮนฮฑ" }, "tubearchivist": { "downloads": "ฮŸฯ…ฯฮฌ", - "videos": "Videos", - "channels": "Channels", - "playlists": "Playlists" + "videos": "ฮ’ฮฏฮฝฯ„ฮตฮฟ", + "channels": "ฮšฮฑฮฝฮฌฮปฮนฮฑ", + "playlists": "ฮ›ฮฏฯƒฯ„ฮตฯ‚ ฮฑฮฝฮฑฯ€ฮฑฯฮฑฮณฯ‰ฮณฮฎฯ‚" }, "truenas": { "load": "ฮฆฯŒฯฯ„ฮฟฯ‚ ฮฃฯ…ฯƒฯ„ฮฎฮผฮฑฯ„ฮฟฯ‚", @@ -534,16 +542,24 @@ "country": "ฮงฯŽฯฮฑ" }, "hdhomerun": { - "channels": "Channels", - "hd": "HD" + "channels": "ฮšฮฑฮฝฮฌฮปฮนฮฑ", + "hd": "HD", + "tunerCount": "ฮ”ฮญฮบฯ„ฮตฯ‚", + "channelNumber": "ฮšฮฑฮฝฮฌฮปฮน", + "channelNetwork": "ฮ”ฮฏฮบฯ„ฯ…ฮฟ", + "signalStrength": "ฮ™ฯƒฯ‡ฯฯ‚ ฯƒฮฎฮผฮฑฯ„ฮฟฯ‚", + "signalQuality": "ฮ ฮฟฮนฯŒฯ„ฮทฯ„ฮฑ", + "symbolQuality": "ฮ ฮฟฮนฯŒฯ„ฮทฯ„ฮฑ", + "networkRate": "ฮกฯ…ฮธฮผฯŒฯ‚ bit", + "clientIP": "ฮ ฮตฮปฮฌฯ„ฮทฯ‚" }, "scrutiny": { "passed": "Passed", - "failed": "Failed", + "failed": "ฮ‘ฯ€ฮญฯ„ฯ…ฯ‡ฮต", "unknown": "ฮ†ฮณฮฝฯ‰ฯƒฯ„ฮฟ" }, "paperlessngx": { - "inbox": "Inbox", + "inbox": "ฮ•ฮนฯƒฮตฯฯ‡ฯŒฮผฮตฮฝฮฑ", "total": "ฮฃฯฮฝฮฟฮปฮฟ" }, "peanut": { @@ -551,8 +567,8 @@ "ups_load": "UPS Load", "ups_status": "UPS Status", "online": "ฮฃฯ…ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "ฮฃฮต ฮผฯ€ฮฑฯ„ฮฑฯฮฏฮฑ", + "low_battery": "ฮงฮฑฮผฮทฮปฮฎ ฮผฯ€ฮฑฯ„ฮฑฯฮฏฮฑ" }, "nextdns": { "wait": "ฮ ฮฑฯฮฑฮบฮฑฮปฯŽ ฯ€ฮตฯฮนฮผฮญฮฝฮตฯ„ฮต", @@ -601,10 +617,10 @@ "load": "Load Avg", "memory": "Mem Usage", "wanStatus": "WAN Status", - "up": "Up", - "down": "Down", + "up": "Ping up", + "down": "Ping down", "temp": "Temp", - "disk": "Disk Usage", + "disk": "ฮงฯฮฎฯƒฮท ฮดฮฏฯƒฮบฮฟฯ…", "wanIP": "WAN IP" }, "proxmoxbackupserver": { @@ -615,22 +631,22 @@ }, "immich": { "users": "ฮงฯฮฎฯƒฯ„ฮตฯ‚", - "photos": "Photos", - "videos": "Videos", - "storage": "Storage" + "photos": "ฮฆฯ‰ฯ„ฮฟฮณฯฮฑฯ†ฮฏฮตฯ‚", + "videos": "ฮ’ฮฏฮฝฯ„ฮตฮฟ", + "storage": "ฮ‘ฯ€ฮฟฮธฮทฮบฮตฯ…ฯ„ฮนฮบฯŒฯ‚ ฯ‡ฯŽฯฮฟฯ‚" }, "uptimekuma": { - "up": "Sites Up", - "down": "Sites Down", + "up": "Online ฯ„ฮฟฯ€ฮฟฮธฮตฯƒฮฏฮตฯ‚", + "down": "Offline ฯ„ฮฟฯ€ฮฟฮธฮตฯƒฮฏฮตฯ‚", "uptime": "ฮงฯฯŒฮฝฮฟฯ‚ ฮ›ฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚", - "incident": "Incident", + "incident": "ฮ ฮตฯฮนฯƒฯ„ฮฑฯ„ฮนฮบฯŒ", "m": "m" }, "atsumeru": { "series": "ฮฃฮตฮนฯฮญฯ‚", "archives": "Archives", "chapters": "Chapters", - "categories": "Categories" + "categories": "ฮšฮฑฯ„ฮทฮณฮฟฯฮฏฮตฯ‚" }, "komga": { "libraries": "Libraries", @@ -649,96 +665,101 @@ }, "photoprism": { "albums": "ฮ†ฮปฮผฯ€ฮฟฯ…ฮผ", - "photos": "Photos", - "videos": "Videos", - "people": "People" + "photos": "ฮฆฯ‰ฯ„ฮฟฮณฯฮฑฯ†ฮฏฮตฯ‚", + "videos": "ฮ’ฮฏฮฝฯ„ฮตฮฟ", + "people": "ฮ†ฮฝฮธฯฯ‰ฯ€ฮฟฮน" }, "fileflows": { "queue": "ฮŸฯ…ฯฮฌ", - "processing": "Processing", - "processed": "Processed", - "time": "Time" + "processing": "ฮฃฮต ฮตฯ€ฮตฮพฮตฯฮณฮฑฯƒฮฏฮฑ", + "processed": "ฮฃฮต ฮตฯ€ฮตฮพฮตฯฮณฮฑฯƒฮฏฮฑ", + "time": "ฮฯฮฑ" }, "grafana": { - "dashboards": "Dashboards", - "datasources": "Data Sources", - "totalalerts": "Total Alerts", - "alertstriggered": "Alerts Triggered" + "dashboards": "ฮ ฮฏฮฝฮฑฮบฮฑฯ‚ ฮ•ฮปฮญฮณฯ‡ฮฟฯ…", + "datasources": "ฮ ฮทฮณฮญฯ‚ ฮ”ฮตฮดฮฟฮผฮญฮฝฯ‰ฮฝ", + "totalalerts": "ฮฃฯฮฝฮฟฮปฮฟ ฮ•ฮนฮดฮฟฯ€ฮฟฮนฮฎฯƒฮตฯ‰ฮฝ", + "alertstriggered": "ฮ•ฮฝฮตฯฮณฮฟฯ€ฮฟฮนฮทฮผฮญฮฝฮตฯ‚ ฮ•ฮนฮดฮฟฯ€ฮฟฮนฮฎฯƒฮตฮนฯ‚" }, "nextcloud": { - "cpuload": "Cpu Load", - "memoryusage": "Memory Usage", - "freespace": "Free Space", - "activeusers": "Active Users", - "numfiles": "Files", - "numshares": "Shared Items" + "cpuload": "ฮฆฯŒฯฯ„ฮฟฯ‚ CPU", + "memoryusage": "ฮงฯฮฎฯƒฮท Mฮฝฮฎฮผฮทฯ‚", + "freespace": "ฮ•ฮปฮตฯฮธฮตฯฮฟฯ‚ ฯ‡ฯŽฯฮฟฯ‚", + "activeusers": "ฮ•ฮฝฮตฯฮณฮฟฮฏ ฯ‡ฯฮฎฯƒฯ„ฮตฯ‚", + "numfiles": "ฮ‘ฯฯ‡ฮตฮฏฮฑ", + "numshares": "ฮšฮฟฮนฮฝฯŒฯ‡ฯฮทฯƒฯ„ฮฑ ฯƒฯ„ฮฟฮนฯ‡ฮตฮฏฮฑ" }, "kopia": { "status": "ฮšฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท", - "size": "Size", - "lastrun": "Last Run", - "nextrun": "Next Run", - "failed": "Failed" + "size": "ฮœฮญฮณฮตฮธฮฟฯ‚", + "lastrun": "ฮคฮตฮปฮตฯ…ฯ„ฮฑฮฏฮฑ ฮตฮบฯ„ฮญฮปฮตฯƒฮท", + "nextrun": "ฮ•ฯ€ฯŒฮผฮตฮฝฮท ฮตฮบฯ„ฮญฮปฮตฯƒฮท", + "failed": "ฮ‘ฯ€ฮญฯ„ฯ…ฯ‡ฮต" }, "unmanic": { - "active_workers": "Active Workers", + "active_workers": "ฮ•ฮฝฮตฯฮณฮฟฮฏ ฯ‡ฯฮฎฯƒฯ„ฮตฯ‚", "total_workers": "Total Workers", - "records_total": "Queue Length" + "records_total": "ฮœฮฎฮบฮฟฯ‚ ฮŸฯ…ฯฮฌฯ‚" }, "pterodactyl": { "servers": "ฮ”ฮนฮฑฮบฮฟฮผฮนฯƒฯ„ฮญฯ‚", - "nodes": "Nodes" + "nodes": "ฮšฯŒฮผฮฒฮฟฮน [Nodes]" }, "prometheus": { - "targets_up": "Targets Up", - "targets_down": "Targets Down", - "targets_total": "Total Targets" + "targets_up": "ฮฃฯ„ฯŒฯ‡ฮฟฮน ฮ ฮฌฮฝฯ‰", + "targets_down": "ฮฃฯ„ฯŒฯ‡ฮฟฮน ฮšฮฌฯ„ฯ‰", + "targets_total": "ฮฃฯ…ฮฝฮฟฮปฮนฮบฮฟฮฏ ฮฃฯ„ฯŒฯ‡ฮฟฮน" + }, + "gatus": { + "up": "Online ฯ„ฮฟฯ€ฮฟฮธฮตฯƒฮฏฮตฯ‚", + "down": "Offline ฯ„ฮฟฯ€ฮฟฮธฮตฯƒฮฏฮตฯ‚", + "uptime": "ฮงฯฯŒฮฝฮฟฯ‚ ฮ›ฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚" }, "ghostfolio": { "gross_percent_today": "ฮฃฮฎฮผฮตฯฮฑ", - "gross_percent_1y": "One year", - "gross_percent_max": "All time" + "gross_percent_1y": "ฮˆฮฝฮฑฯ‚ ฯ‡ฯฯŒฮฝฮฟฯ‚", + "gross_percent_max": "ฮ”ฮนฮฑฯ‡ฯฮฟฮฝฮนฮบฮฌ" }, "audiobookshelf": { "podcasts": "Podcasts", "books": "ฮ’ฮนฮฒฮปฮฏฮฑ", - "podcastsDuration": "Duration", - "booksDuration": "Duration" + "podcastsDuration": "ฮ”ฮนฮฌฯฮบฮตฮนฮฑ", + "booksDuration": "ฮ”ฮนฮฌฯฮบฮตฮนฮฑ" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "ฮฃฯฮฝฮฟฮปฮฟ ฮฑฮฝฮธฯฯŽฯ€ฯ‰ฮฝ ฯƒฯ„ฮฟ ฯƒฯ€ฮฏฯ„ฮน", + "lights_on": "ฮ‘ฮฝฮฑฮผฮผฮญฮฝฮฑ ฯ†ฯŽฯ„ฮฑ", + "switches_on": "ฮ‘ฮฝฮฟฮนฯ‡ฯ„ฮฟฮฏ ฮดฮนฮฑฮบฯŒฯ€ฯ„ฮตฯ‚" }, "whatsupdocker": { - "monitoring": "Monitoring", - "updates": "Updates" + "monitoring": "ฮ ฮฑฯฮฑฮบฮฟฮปฮฟฯฮธฮทฯƒฮท", + "updates": "ฮ•ฮฝฮทฮผฮตฯฯŽฯƒฮตฮนฯ‚" }, "calibreweb": { "books": "ฮ’ฮนฮฒฮปฮฏฮฑ", - "authors": "Authors", - "categories": "Categories", + "authors": "ฮฃฯ…ฮฝฯ„ฮฌฮบฯ„ฮตฯ‚", + "categories": "ฮšฮฑฯ„ฮทฮณฮฟฯฮฏฮตฯ‚", "series": "ฮฃฮตฮนฯฮญฯ‚" }, "jdownloader": { "downloadCount": "ฮŸฯ…ฯฮฌ", "downloadBytesRemaining": "ฮฅฯ€ฯŒฮปฮฟฮนฯ€ฮฟ", - "downloadTotalBytes": "Size", + "downloadTotalBytes": "ฮœฮญฮณฮตฮธฮฟฯ‚", "downloadSpeed": "ฮคฮฑฯ‡ฯฯ„ฮทฯ„ฮฑ" }, "kavita": { "seriesCount": "ฮฃฮตฮนฯฮญฯ‚", - "totalFiles": "Files" + "totalFiles": "ฮ‘ฯฯ‡ฮตฮฏฮฑ" }, "azuredevops": { - "result": "Result", + "result": "ฮ‘ฯ€ฮฟฯ„ฮญฮปฮตฯƒฮผฮฑ", "status": "ฮšฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท", "buildId": "Build ID", - "succeeded": "Succeeded", - "notStarted": "Not Started", - "failed": "Failed", - "canceled": "Canceled", - "inProgress": "In Progress", + "succeeded": "ฮ ฮญฯ„ฯ…ฯ‡ฮต", + "notStarted": "ฮ”ฮตฮฝ ฮพฮตฮบฮฏฮฝฮทฯƒฮต", + "failed": "ฮ‘ฯ€ฮญฯ„ฯ…ฯ‡ฮต", + "canceled": "ฮ‘ฮบฯ…ฯฯŽฮธฮทฮบฮต", + "inProgress": "ฮฃฮต ฮตฮพฮญฮปฮนฮพฮท", "totalPrs": "Total PRs", "myPrs": "My PRs", "approved": "ฮ•ฮณฮบฯฮฏฮธฮทฮบฮต" @@ -747,8 +768,8 @@ "status": "ฮšฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท", "online": "ฮฃฯ…ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน", "offline": "ฮ•ฮบฯ„ฯŒฯ‚ ฯƒฯฮฝฮดฮตฯƒฮทฯ‚", - "name": "Name", - "map": "Map", + "name": "ฮŒฮฝฮฟฮผฮฑ", + "map": "ฮงฮฌฯฯ„ฮทฯ‚", "currentPlayers": "Current players", "players": "ฮ ฮฑฮฏฮบฯ„ฮตฯ‚", "maxPlayers": "Max players", @@ -756,37 +777,45 @@ "ping": "Ping" }, "urbackup": { - "ok": "Ok", - "errored": "Errors", - "noRecent": "Out of Date", - "totalUsed": "Used Storage" + "ok": "ฮŸฮบ", + "errored": "ฮฃฯ†ฮฌฮปฮผฮฑฯ„ฮฑ", + "noRecent": "ฮ‘ฯ€ฮฑฯฯ‡ฮฑฮนฯ‰ฮผฮญฮฝฮท ฮญฮบฮดฮฟฯƒฮท", + "totalUsed": "ฮงฯŽฯฮฟฯ‚ ฮฑฯ€ฮฟฮธฮฎฮบฮตฯ…ฯƒฮทฯ‚ ฯƒฮต ฯ‡ฯฮฎฯƒฮท" }, "mealie": { - "recipes": "Recipes", + "recipes": "ฮฃฯ…ฮฝฯ„ฮฑฮณฮญฯ‚", "users": "ฮงฯฮฎฯƒฯ„ฮตฯ‚", - "categories": "Categories", - "tags": "Tags" + "categories": "ฮšฮฑฯ„ฮทฮณฮฟฯฮฏฮตฯ‚", + "tags": "ฮ•ฯ„ฮนฮบฮญฯ„ฮตฯ‚" }, "openmediavault": { - "downloading": "Downloading", + "downloading": "ฮ“ฮฏฮฝฮตฯ„ฮฑฮน ฮปฮฎฯˆฮท", "total": "ฮฃฯฮฝฮฟฮปฮฟ", "running": "ฮคฯฮญฯ‡ฯ‰ฮฝ", "stopped": "ฮฃฯ„ฮฑฮผฮฑฯ„ฮทฮผฮญฮฝฮฟ", "passed": "Passed", - "failed": "Failed" + "failed": "ฮ‘ฯ€ฮญฯ„ฯ…ฯ‡ฮต" + }, + "openwrt": { + "uptime": "ฮงฯฯŒฮฝฮฟฯ‚ ฮ›ฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Ping up", + "down": "Ping down", + "bytesTx": "Transmitted", + "bytesRx": "ฮ›ฮทฯ†ฮธฮญฮฝฯ„ฮฑ" }, "uptimerobot": { "status": "ฮšฮฑฯ„ฮฌฯƒฯ„ฮฑฯƒฮท", "uptime": "ฮงฯฯŒฮฝฮฟฯ‚ ฮ›ฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚", "lastDown": "Last Downtime", "downDuration": "Downtime Duration", - "sitesUp": "Sites Up", - "sitesDown": "Sites Down", + "sitesUp": "Online ฯ„ฮฟฯ€ฮฟฮธฮตฯƒฮฏฮตฯ‚", + "sitesDown": "Offline ฯ„ฮฟฯ€ฮฟฮธฮตฯƒฮฏฮตฯ‚", "paused": "Paused", "notyetchecked": "Not Yet Checked", - "up": "Up", + "up": "Ping up", "seemsdown": "Seems Down", - "down": "Down", + "down": "Ping down", "unknown": "ฮ†ฮณฮฝฯ‰ฯƒฯ„ฮฟ" }, "calendar": { @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "ฮฆฯ‰ฯ„ฮฟฮณฯฮฑฯ†ฮฏฮตฯ‚", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "ฮคฮฑฮนฮฝฮฏฮตฯ‚", + "tags": "ฮ•ฯ„ฮนฮบฮญฯ„ฮตฯ‚", + "oCount": "O Count" + }, + "tandoor": { + "users": "ฮงฯฮฎฯƒฯ„ฮตฯ‚", + "recipes": "ฮฃฯ…ฮฝฯ„ฮฑฮณฮญฯ‚", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "ฮงฯฮฎฯƒฯ„ฮตฯ‚", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "ฮ•ฮนฮดฮฟฯ€ฮฟฮนฮฎฯƒฮตฮนฯ‚", + "bans": "Bans" + }, + "wgeasy": { + "connected": "ฮฃฯ…ฮฝฮดฮญฮธฮทฮบฮต", + "enabled": "ฮ•ฮฝฮตฯฮณฮฟฯ€ฮฟฮนฮทฮผฮญฮฝฮฟ", + "disabled": "ฮ‘ฯ€ฮตฮฝฮตฯฮณฮฟฯ€ฮฟฮนฮทฮผฮญฮฝฮฟ", + "total": "ฮฃฯฮฝฮฟฮปฮฟ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/en/common.json b/public/locales/en/common.json index b804df36..dd4d3c2a 100755 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Total", + "unknown": "Unknown" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Approved", "available": "Available" }, - "pialert": { + "netalertx": { "total": "Total", "connected": "Connected", "new_devices": "New Devices", @@ -749,9 +756,6 @@ "retryCache": "Retry Cache", "feedCache": "Feed Cache" }, - "wgeasy": { - "clients": "Total Clients" - }, "kavita": { "seriesCount": "Series", "totalFiles": "Files" @@ -869,5 +873,50 @@ "serverName": "Server Name", "numberOfActiveCams": "Active Cameras", "numberOfAlerts": "Total Alerts" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Users", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Users", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Enabled", + "disabled": "Disabled", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } \ No newline at end of file diff --git a/public/locales/eo/common.json b/public/locales/eo/common.json index 42a2f460..de28af1b 100644 --- a/public/locales/eo/common.json +++ b/public/locales/eo/common.json @@ -107,6 +107,13 @@ "episodes": "Epizodoj", "songs": "Kantoj" }, + "esphome": { + "offline": "Malkonekta", + "offline_alt": "Malkonekta", + "online": "Online", + "total": "Totalo", + "unknown": "Nekonata" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Aprobita", "available": "Havebla" }, - "pialert": { + "netalertx": { "total": "Totalo", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Suna", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanaloj", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrapido", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Stato", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Filmoj", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Uzantoj", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Uzantoj", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Enabled", + "disabled": "Disabled", + "total": "Totalo" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 97dabdc2..075a4c56 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -12,7 +12,7 @@ "number": "{{value, number}}", "ms": "{{value, number}}", "date": "{{value, date}}", - "relativeDate": "{{value, relativeDate}}", + "relativeDate": "{{valor, relativaFecha}}", "uptime": "{{value, uptime}}", "months": "me", "days": "d", @@ -107,6 +107,13 @@ "episodes": "Episodios", "songs": "Canciones" }, + "esphome": { + "offline": "Desconectado", + "offline_alt": "Desconectado", + "online": "En lรญnea", + "total": "Total", + "unknown": "Desconocido" + }, "evcc": { "pv_power": "Producciรณn", "battery_soc": "Baterรญa", @@ -270,11 +277,11 @@ "approved": "Aprobado", "available": "Disponible" }, - "pialert": { + "netalertx": { "total": "Total", "connected": "Conectado", "new_devices": "Nuevos dispositivos", - "down_alerts": "Alertas de caรญdas" + "down_alerts": "Alertas de caรญda" }, "pihole": { "queries": "Consultas", @@ -419,7 +426,8 @@ "search": "Buscar", "custom": "Personalizado", "visit": "Visitar", - "url": "Enlace" + "url": "Enlace", + "searchsuggestion": "Sugerencia" }, "wmo": { "0-day": "Soleado", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Canales", - "hd": "Alta definiciรณn" + "hd": "Alta definiciรณn", + "tunerCount": "Sintonizadores", + "channelNumber": "Canal", + "channelNetwork": "Red", + "signalStrength": "Intensidad", + "signalQuality": "Calidad", + "symbolQuality": "Calidad", + "networkRate": "Tasa de bits", + "clientIP": "Cliente" }, "scrutiny": { "passed": "Aprobado", @@ -694,6 +710,11 @@ "targets_down": "Objetivos inactivos", "targets_total": "Objetivos totales" }, + "gatus": { + "up": "Sitios activos", + "down": "Sitios inactivos", + "uptime": "Tiempo activo" + }, "ghostfolio": { "gross_percent_today": "Hoy", "gross_percent_1y": "Un aรฑo", @@ -775,6 +796,14 @@ "passed": "Aprobado", "failed": "Fallido" }, + "openwrt": { + "uptime": "Tiempo activo", + "cpuLoad": "Carga promedio del CPU (5m)", + "up": "Activo", + "down": "Inactivo", + "bytesTx": "Transmitido", + "bytesRx": "Recibido" + }, "uptimerobot": { "status": "Estado", "uptime": "Tiempo activo", @@ -797,11 +826,67 @@ "noEventsFound": "No se encontraron eventos" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Plataformas", + "totalRoms": "ROMs totales" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Advertencias", + "criticals": "Crรญticos" + }, + "plantit": { + "events": "Eventos", + "plants": "Plantas", + "photos": "Fotos", + "species": "Especies" + }, + "gitea": { + "notifications": "Notificaciones", + "issues": "Nรบmeros", + "pulls": "Solicitudes de cambios" + }, + "stash": { + "scenes": "Escenas", + "scenesPlayed": "Escenas reproducidas", + "playCount": "Reproducciones totales", + "playDuration": "Tiempo visto", + "sceneSize": "Tamaรฑo de las escenas", + "sceneDuration": "Duraciรณn de las escenas", + "images": "Imรกgenes", + "imageSize": "Tamaรฑo de imagen", + "galleries": "Galerรญas", + "performers": "Intรฉrpretes", + "studios": "Estudios", + "movies": "Pelรญculas", + "tags": "Etiquetas", + "oCount": "O cuenta" + }, + "tandoor": { + "users": "Usuarios", + "recipes": "Recetas", + "keywords": "Palabras clave" + }, + "homebox": { + "items": "Objetos", + "totalWithWarranty": "Con Garantรญa", + "locations": "Ubicaciones", + "labels": "Etiquetas", + "users": "Usuarios", + "totalValue": "Valor total" + }, + "crowdsec": { + "alerts": "Alertas", + "bans": "Baneos" + }, + "wgeasy": { + "connected": "Conectado", + "enabled": "Activado", + "disabled": "Desactivado", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/eu/common.json b/public/locales/eu/common.json index a6a2402e..a4aba203 100644 --- a/public/locales/eu/common.json +++ b/public/locales/eu/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Abestiak" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Guztira", + "unknown": "Ezezaguna" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Approved", "available": "Available" }, - "pialert": { + "netalertx": { "total": "Guztira", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bit-tasa", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Status", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Users", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Users", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Enabled", + "disabled": "Disabled", + "total": "Guztira" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/fi/common.json b/public/locales/fi/common.json index 0fd030be..09639a20 100644 --- a/public/locales/fi/common.json +++ b/public/locales/fi/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Yhteensรค", + "unknown": "Unknown" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Hyvรคksytty", "available": "Saatavilla" }, - "pialert": { + "netalertx": { "total": "Yhteensรค", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bittinopeus", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Tila", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Users", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Users", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Kรคytรถssรค", + "disabled": "Poissa kรคytรถstรค", + "total": "Yhteensรค" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index 0cd5435a..beb8420c 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -15,17 +15,17 @@ "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", "months": "mo", - "days": "d", + "days": "j", "hours": "h", "minutes": "m", "seconds": "s" }, "widget": { - "missing_type": "Widget manquant: {{type}}", + "missing_type": "Type de widget manquant: {{type}}", "api_error": "Erreur API", "information": "Informations", "status": "Statut", - "url": "Url", + "url": "URL", "raw_error": "Erreur brute", "response_data": "Donnรฉes de rรฉponse" }, @@ -39,8 +39,8 @@ "placeholder": "Rechercheโ€ฆ" }, "resources": { - "cpu": "Cpu", - "mem": "Mรฉm", + "cpu": "CPU", + "mem": "Mร‰M", "total": "Total", "free": "Libre", "used": "Utilisรฉ", @@ -69,8 +69,8 @@ "docker": { "rx": "Rx", "tx": "Tx", - "mem": "Mรฉm", - "cpu": "Cpu", + "mem": "Mร‰M", + "cpu": "CPU", "running": "Dรฉmarrรฉ", "offline": "Hors ligne", "error": "Erreur", @@ -107,6 +107,13 @@ "episodes": "ร‰pisodes", "songs": "Musique" }, + "esphome": { + "offline": "Hors ligne", + "offline_alt": "Hors ligne", + "online": "En ligne", + "total": "Total", + "unknown": "Inconnu" + }, "evcc": { "pv_power": "Production", "battery_soc": "Batterie", @@ -150,7 +157,7 @@ }, "changedetectionio": { "totalObserved": "Total Observรฉ", - "diffsDetected": "Diffs Detectรฉes" + "diffsDetected": "Diffs dรฉtectรฉes" }, "channelsdvrserver": { "shows": "Affichages", @@ -166,7 +173,7 @@ "plex_connection_error": "Vรฉrifier la connexion ร  Plex" }, "omada": { - "connectedAp": "APs connectรฉes", + "connectedAp": "AP connectรฉs", "activeUser": "ร‰quipts actifs", "alerts": "Alertes", "connectedGateway": "Passerelles connectรฉes", @@ -270,11 +277,11 @@ "approved": "Validรฉ", "available": "Disponible" }, - "pialert": { + "netalertx": { "total": "Total", "connected": "Connectรฉ", - "new_devices": "Nouvel Appareil", - "down_alerts": "Alertes" + "new_devices": "Nouveaux appareils", + "down_alerts": "Alertes d'arrรชt" }, "pihole": { "queries": "Requรชtes", @@ -388,13 +395,13 @@ "failedLoginsLast24H": "Cnx. รฉchouรฉes (24h)" }, "proxmox": { - "mem": "Mรฉm", - "cpu": "Cpu", + "mem": "Mร‰M", + "cpu": "CPU", "lxc": "LxC", "vms": "VMs" }, "glances": { - "cpu": "Cpu", + "cpu": "CPU", "load": "Charge", "wait": "Veuillez patienter", "temp": "Temp", @@ -404,7 +411,7 @@ "total": "Total", "free": "Libre", "used": "Utilisรฉ", - "days": "d", + "days": "j", "hours": "h", "crit": "Crit.", "read": "Lu", @@ -419,7 +426,8 @@ "search": "Recherche", "custom": "Personnalisรฉ", "visit": "Aller vers", - "url": "Url" + "url": "URL", + "searchsuggestion": "Suggestions" }, "wmo": { "0-day": "Ensoleillรฉ", @@ -529,13 +537,21 @@ "total": "Total" }, "gluetun": { - "public_ip": "IP Publique", + "public_ip": "IP publique", "region": "Rรฉgion", "country": "Pays" }, "hdhomerun": { "channels": "Chaรฎnes", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Canal", + "channelNetwork": "Rรฉseau", + "signalStrength": "Force", + "signalQuality": "Qualitรฉ", + "symbolQuality": "Qualitรฉ", + "networkRate": "Dรฉbit", + "clientIP": "Client" }, "scrutiny": { "passed": "Rรฉussi", @@ -547,11 +563,11 @@ "total": "Total" }, "peanut": { - "battery_charge": "Battery Charge", + "battery_charge": "Charge Batterie", "ups_load": "Charge de l'UPS", "ups_status": "ร‰tat de l'UPS", "online": "En ligne", - "on_battery": "On Battery", + "on_battery": "Sur Batterie", "low_battery": "Batterie Faible" }, "nextdns": { @@ -577,7 +593,7 @@ }, "opnsense": { "cpu": "Charge CPU", - "memory": "Mรฉm. Utilisรฉe", + "memory": "Mรฉm. utilisรฉe", "wanUpload": "WAN Envoi", "wanDownload": "WAN Rรฉcep." }, @@ -610,7 +626,7 @@ "proxmoxbackupserver": { "datastore_usage": "Datastore", "failed_tasks_24h": "Tรขches รฉchouรฉes 24h", - "cpu_usage": "Cpu", + "cpu_usage": "CPU", "memory_usage": "Mรฉmoire" }, "immich": { @@ -633,7 +649,7 @@ "categories": "Catรฉgories" }, "komga": { - "libraries": "Librairies", + "libraries": "Bibliothรจques", "series": "Sรฉries TV", "books": "Livres" }, @@ -666,7 +682,7 @@ "alertstriggered": "Alertes dรฉclenchรฉes" }, "nextcloud": { - "cpuload": "Charge Cpu", + "cpuload": "Charge CPU", "memoryusage": "Utilisation Mรฉmoire", "freespace": "Libre", "activeusers": "Utilisateurs Actifs", @@ -694,6 +710,11 @@ "targets_down": "Down", "targets_total": "Total" }, + "gatus": { + "up": "En ligne", + "down": "Hors ligne", + "uptime": "Dรฉmarrรฉ depuis" + }, "ghostfolio": { "gross_percent_today": "Aujourd'hui", "gross_percent_1y": "Un an", @@ -775,6 +796,14 @@ "passed": "Rรฉussi", "failed": "ร‰chouรฉ" }, + "openwrt": { + "uptime": "Dรฉmarrรฉ depuis", + "cpuLoad": "Charge moyenne CPU (5 min)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmis", + "bytesRx": "Reรงu" + }, "uptimerobot": { "status": "Statut", "uptime": "Dรฉmarrรฉ depuis", @@ -797,11 +826,67 @@ "noEventsFound": "Aucun รฉvรฉnement trouvรฉ" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Plateformes", + "totalRoms": "Total des ROMs" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Avertissements", + "criticals": "Urgent" + }, + "plantit": { + "events": "ร‰vรฉnements", + "plants": "Plantes", + "photos": "Photos", + "species": "Espรจces" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Anomalies", + "pulls": "Demandes de tirage" + }, + "stash": { + "scenes": "Scรจnes", + "scenesPlayed": "Scรจnes jouรฉes", + "playCount": "Lectures Totales", + "playDuration": "Temps regardรฉ", + "sceneSize": "Taille des scรจnes", + "sceneDuration": "Durรฉe des scรจnes", + "images": "Images", + "imageSize": "Taille des images", + "galleries": "Galeries", + "performers": "Acteurs", + "studios": "Studios", + "movies": "Films", + "tags": "ร‰tiquettes", + "oCount": "0 Compte" + }, + "tandoor": { + "users": "Utilisateurs", + "recipes": "Recettes", + "keywords": "Mots-clรฉs" + }, + "homebox": { + "items": "Objets", + "totalWithWarranty": "Avec garantie", + "locations": "Emplacements", + "labels": "ร‰tiquettes", + "users": "Utilisateurs", + "totalValue": "Valeur Totale" + }, + "crowdsec": { + "alerts": "Alertes", + "bans": "Exclusions" + }, + "wgeasy": { + "connected": "Connectรฉ", + "enabled": "Activรฉ", + "disabled": "Dรฉsactivรฉ", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Par proxy", + "auth": "Avec authentification", + "outdated": "Obsolรจte", + "banned": "Banni" } } diff --git a/public/locales/he/common.json b/public/locales/he/common.json index 0c4caf80..fa310603 100644 --- a/public/locales/he/common.json +++ b/public/locales/he/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "ื›ื‘ื•ื™", + "offline_alt": "ื›ื‘ื•ื™", + "online": "Online", + "total": "ืกื”\"ื›", + "unknown": "Unknown" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "ืžืื•ืฉืจ", "available": "ื–ืžื™ืŸ" }, - "pialert": { + "netalertx": { "total": "ืกื”\"ื›", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "ืกื™ื‘ื™ื•ืช", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "ืกื˜ื˜ื•ืก", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Users", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Users", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "ืžื•ืคืขืœ", + "disabled": "ืžื‘ื•ื˜ืœ", + "total": "ืกื”\"ื›" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/hi/common.json b/public/locales/hi/common.json index ca628d3b..745ed8b4 100644 --- a/public/locales/hi/common.json +++ b/public/locales/hi/common.json @@ -11,14 +11,14 @@ "percent": "{{value, percent}}", "number": "{{value, number}}", "ms": "{{value, number}}", - "date": "{{value, date}}", + "date": "{value, date}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", + "months": "เคฎเคพเคน", "days": "d", - "hours": "h", + "hours": "เค˜เค‚.", "minutes": "m", - "seconds": "s" + "seconds": "เคชเคฒ" }, "widget": { "missing_type": "Missing Widget Type: {{type}}", @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Total", + "unknown": "Unknown" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Approved", "available": "Available" }, - "pialert": { + "netalertx": { "total": "Total", "connected": "Connected", "new_devices": "New Devices", @@ -405,7 +412,7 @@ "free": "Free", "used": "Used", "days": "d", - "hours": "h", + "hours": "เค˜เค‚.", "crit": "Crit", "read": "Read", "write": "Write", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Status", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Users", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Users", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Enabled", + "disabled": "Disabled", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/hr/common.json b/public/locales/hr/common.json index 5c23c742..6ffef12f 100644 --- a/public/locales/hr/common.json +++ b/public/locales/hr/common.json @@ -14,10 +14,10 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", - "days": "d", + "months": "mj", + "days": "dan(a)", "hours": "h", - "minutes": "m", + "minutes": "min", "seconds": "s" }, "widget": { @@ -46,12 +46,12 @@ "used": "Koriลกteno", "load": "Optereฤ‡enje", "temp": "TEMP", - "max": "Maks", - "uptime": "UP" + "max": "Maks.", + "uptime": "Vrijeme rada" }, "unifi": { "users": "Korisnici", - "uptime": "Radno vrijeme", + "uptime": "Vrijeme rada", "days": "Dani", "wan": "WAN", "lan": "LAN", @@ -61,8 +61,8 @@ "wlan_devices": "WLAN ureฤ‘aji", "lan_users": "LAN korisnici", "wlan_users": "WLAN korisnici", - "up": "UP", - "down": "PRIMANJE", + "up": "Vrijeme rada", + "down": "NEDOSTUPNO", "wait": "Priฤekaj", "empty_data": "Stanje podsustava nepoznato" }, @@ -85,17 +85,17 @@ "ping": { "error": "Greลกka", "ping": "Ping", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "down": "Nedostupno", + "up": "Dostupno", + "not_available": "Nije dostupno" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "Stanje HTTP-a", "error": "Greลกka", - "response": "Response", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "response": "Odgovor", + "down": "Nedostupno", + "up": "Dostupno", + "not_available": "Nije dostupno" }, "emby": { "playing": "Reprodukcija", @@ -107,13 +107,20 @@ "episodes": "Epizode", "songs": "Pjesme" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Ukupno", + "unknown": "Nepoznato" + }, "evcc": { "pv_power": "Proizvodnja", "battery_soc": "Baterija", "grid_power": "Raspored", "home_power": "Potroลกnja", "charge_power": "Punjaฤ", - "watt_hour": "Wh" + "watt_hour": "Kilovat-sat" }, "flood": { "download": "Preuzimanje", @@ -127,21 +134,21 @@ }, "fritzbox": { "connectionStatus": "Stanje", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", + "connectionStatusUnconfigured": "Nekonfigurirano", + "connectionStatusConnecting": "Povezivanje", + "connectionStatusAuthenticating": "Autentificiranje", + "connectionStatusPendingDisconnect": "Odspajanje u tijeku", + "connectionStatusDisconnecting": "Odspajanje", + "connectionStatusDisconnected": "Odspojeno", "connectionStatusConnected": "Povezano", - "uptime": "Radno vrijeme", - "maxDown": "Max. Down", - "maxUp": "Max. Up", - "down": "Down", - "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "uptime": "Vrijeme rada", + "maxDown": "Maksimum preuzimanja", + "maxUp": "Maksimum prijenosa", + "down": "Nedostupno", + "up": "Dostupno", + "received": "Primljeno", + "sent": "Poslano", + "externalIPAddress": "Eksterna IP adresa" }, "caddy": { "upstreams": "Glavne grane", @@ -255,26 +262,26 @@ "missingMovies": "Nedostajuฤ‡i filmovi" }, "ombi": { - "pending": "Predstoji", + "pending": "U tijeku", "approved": "Odobreno", "available": "Dostupno" }, "jellyseerr": { - "pending": "Predstoji", + "pending": "U tijeku", "approved": "Odobreno", "available": "Dostupno" }, "overseerr": { - "pending": "Predstoji", + "pending": "U tijeku", "processing": "Obrada", "approved": "Odobreno", "available": "Dostupno" }, - "pialert": { + "netalertx": { "total": "Ukupno", "connected": "Povezano", "new_devices": "Novi ureฤ‘aji", - "down_alerts": "Obavijest o ruลกenju" + "down_alerts": "Obavijesti o nedostupnosti" }, "pihole": { "queries": "Upiti", @@ -398,20 +405,20 @@ "load": "Optereฤ‡enje", "wait": "Priฤekaj", "temp": "TEMP", - "_temp": "Temp", + "_temp": "Temperatura", "warn": "Upozori", - "uptime": "UP", + "uptime": "Vrijeme rada", "total": "Ukupno", "free": "Slobodno", "used": "Koriลกteno", - "days": "d", + "days": "dan(a)", "hours": "h", - "crit": "Crit", + "crit": "Krritiฤno", "read": "Proฤitano", - "write": "Write", + "write": "Piลกi", "gpu": "GPU", - "mem": "Mem", - "swap": "Swap" + "mem": "Memorija", + "swap": "Virtualna memorija" }, "quicklaunch": { "bookmark": "Straniฤnik", @@ -419,7 +426,8 @@ "search": "Traลพi", "custom": "Prilagoฤ‘eno", "visit": "Posjeti", - "url": "URL" + "url": "URL", + "searchsuggestion": "Prijedlog" }, "wmo": { "0-day": "Sunฤano", @@ -486,15 +494,15 @@ "up_to_date": "Aktualno", "child_bridges": "Podreฤ‘eni mosotvi", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Up", - "pending": "Predstoji", - "down": "Down" + "up": "Dostupno", + "pending": "U tijeku", + "down": "Nedostupno" }, "healthchecks": { "new": "Novo", - "up": "Up", + "up": "Dostupno", "grace": "U razdoblju odgode", - "down": "Down", + "down": "Nedostupno", "paused": "Zaustavljeno", "status": "Stanje", "last_ping": "Zadnji ping", @@ -519,7 +527,7 @@ }, "truenas": { "load": "Optereฤ‡enje sustava", - "uptime": "Radno vrijeme", + "uptime": "Vrijeme rada", "alerts": "Upozorenja" }, "pyload": { @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanali", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuneri", + "channelNumber": "Kanal", + "channelNetwork": "Mreลพa", + "signalStrength": "Jaฤina", + "signalQuality": "Kvaliteta", + "symbolQuality": "Kvaliteta", + "networkRate": "Stopa bitova", + "clientIP": "Klijent" }, "scrutiny": { "passed": "Uspjelo", @@ -547,12 +563,12 @@ "total": "Ukupno" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "battery_charge": "Napunjenost baterije", + "ups_load": "UPS optereฤ‡enje", + "ups_status": "UPS stanje", "online": "Online", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "Koristi bateriju", + "low_battery": "Slaba baterija" }, "nextdns": { "wait": "Priฤekaj", @@ -561,7 +577,7 @@ "mikrotik": { "cpuLoad": "CPU optereฤ‡enje", "memoryUsed": "Koriลกtena memorija", - "uptime": "Radno vrijeme", + "uptime": "Vrijeme rada", "numberOfLeases": "Unajmljivanja" }, "xteve": { @@ -570,10 +586,10 @@ "streams_xepg": "XEPG kanali" }, "opendtu": { - "yieldDay": "Today", - "absolutePower": "Power", - "relativePower": "Power %", - "limit": "Limit" + "yieldDay": "Danas", + "absolutePower": "Snaga", + "relativePower": "Postotak snage", + "limit": "Ograniฤenje" }, "opnsense": { "cpu": "CPU optereฤ‡enje", @@ -601,9 +617,9 @@ "load": "Prosjeฤno optereฤ‡enje", "memory": "Koriลกtenje memorije", "wanStatus": "Stanje WAN-a", - "up": "Up", - "down": "Down", - "temp": "Temp", + "up": "Dostupno", + "down": "Nedostupno", + "temp": "Temperatura", "disk": "Koriลกtenje diska", "wanIP": "WAN IP" }, @@ -620,17 +636,17 @@ "storage": "Spremiลกte" }, "uptimekuma": { - "up": "Aktivne stranice", - "down": "Neaktivne stranice", - "uptime": "Radno vrijeme", + "up": "Dostupne stranice", + "down": "Nedostupne stranice", + "uptime": "Vrijeme rada", "incident": "Sluฤaj", - "m": "m" + "m": "min" }, "atsumeru": { "series": "Serije", - "archives": "Archives", - "chapters": "Chapters", - "categories": "Categories" + "archives": "Arhive", + "chapters": "Poglavlja", + "categories": "Kategorije" }, "komga": { "libraries": "Biblioteke", @@ -639,7 +655,7 @@ }, "diskstation": { "days": "Dani", - "uptime": "Radno vrijeme", + "uptime": "Vrijeme rada", "volumeAvailable": "Dostupno" }, "mylar": { @@ -662,7 +678,7 @@ "grafana": { "dashboards": "Pregledne ploฤe", "datasources": "Izvori podataka", - "totalalerts": "Ukupno upozorenja", + "totalalerts": "Ukupni broj upozorenja", "alertstriggered": "Aktivirana upozorenja" }, "nextcloud": { @@ -682,7 +698,7 @@ }, "unmanic": { "active_workers": "Aktivni radnici", - "total_workers": "Ukupni radnici", + "total_workers": "Ukupni broj radnika", "records_total": "Koliฤina zapisa u redu ฤekanja" }, "pterodactyl": { @@ -692,10 +708,15 @@ "prometheus": { "targets_up": "Aktivni ciljevi", "targets_down": "Neaktivni ciljevi", - "targets_total": "Ukupno ciljeva" + "targets_total": "Ukupni broj ciljeva" + }, + "gatus": { + "up": "Dostupne stranice", + "down": "Nedostupne stranice", + "uptime": "Vrijeme rada" }, "ghostfolio": { - "gross_percent_today": "Today", + "gross_percent_today": "Danas", "gross_percent_1y": "Jedna godina", "gross_percent_max": "Svo vrijeme" }, @@ -711,13 +732,13 @@ "switches_on": "Prekidaฤi ukljuฤeni" }, "whatsupdocker": { - "monitoring": "Monitoring", + "monitoring": "Praฤ‡enje", "updates": "Aktualiziranja" }, "calibreweb": { "books": "Knjige", - "authors": "Authors", - "categories": "Categories", + "authors": "Autori", + "categories": "Kategorije", "series": "Serije" }, "jdownloader": { @@ -731,77 +752,141 @@ "totalFiles": "Datoteke" }, "azuredevops": { - "result": "Result", + "result": "Rezultat", "status": "Stanje", - "buildId": "Build ID", - "succeeded": "Succeeded", - "notStarted": "Not Started", + "buildId": "ID izgradnje", + "succeeded": "Uspjelo", + "notStarted": "Nije zapoฤeto", "failed": "Neuspjelo", - "canceled": "Canceled", - "inProgress": "In Progress", - "totalPrs": "Total PRs", - "myPrs": "My PRs", + "canceled": "Prekinuto", + "inProgress": "U tijeku", + "totalPrs": "Ukupni broj PR-ova", + "myPrs": "Moji zahtjevi za preuzimanje (PR-ovi)", "approved": "Odobreno" }, "gamedig": { "status": "Stanje", "online": "Online", "offline": "Offline", - "name": "Name", - "map": "Map", - "currentPlayers": "Current players", + "name": "Ime", + "map": "Karta", + "currentPlayers": "Trenutaฤni igraฤi", "players": "Igraฤi", - "maxPlayers": "Max players", - "bots": "Bots", + "maxPlayers": "Maks. broj igraฤa", + "bots": "Botovi", "ping": "Ping" }, "urbackup": { - "ok": "Ok", - "errored": "Errors", - "noRecent": "Out of Date", - "totalUsed": "Used Storage" + "ok": "U redu", + "errored": "Greลกke", + "noRecent": "Zastarjelo", + "totalUsed": "Koriลกtena memorija" }, "mealie": { - "recipes": "Recipes", + "recipes": "Recepti", "users": "Korisnici", - "categories": "Categories", - "tags": "Tags" + "categories": "Kategorije", + "tags": "Oznake" }, "openmediavault": { - "downloading": "Downloading", + "downloading": "Preuzimanje", "total": "Ukupno", "running": "Pokrenuto", "stopped": "Prekinuto", "passed": "Uspjelo", "failed": "Neuspjelo" }, + "openwrt": { + "uptime": "Vrijeme rada", + "cpuLoad": "Prosjeฤ‡no CPU optereฤ‡enje (5m)", + "up": "Dostupno", + "down": "Nedostupno", + "bytesTx": "Preneseno", + "bytesRx": "Primljeno" + }, "uptimerobot": { "status": "Stanje", - "uptime": "Radno vrijeme", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", - "sitesUp": "Aktivne stranice", - "sitesDown": "Neaktivne stranice", + "uptime": "Vrijeme rada", + "lastDown": "Zadnja nedostupnost", + "downDuration": "Trajanje nedostupnosti", + "sitesUp": "Dostupne stranice", + "sitesDown": "Nedostupne stranice", "paused": "Zaustavljeno", - "notyetchecked": "Not Yet Checked", - "up": "Up", - "seemsdown": "Seems Down", - "down": "Down", + "notyetchecked": "Joลก nije provjereno", + "up": "Dostupno", + "seemsdown": "ฤŒini se da je nedostupno", + "down": "Nedostupno", "unknown": "Nepoznato" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", - "digitalRelease": "Digital release", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "inCinemas": "U kinima", + "physicalRelease": "Fiziฤko izdanje", + "digitalRelease": "Digitalno izdanje", + "noEventsToday": "Danas nema dogaฤ‘aja!", + "noEventsFound": "Nema dogaฤ‘aja" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platforme", + "totalRoms": "Ukupne ROM memorije" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Upozorenja", + "criticals": "Kritiฤno" + }, + "plantit": { + "events": "Dogaฤ‘aji", + "plants": "Biljke", + "photos": "Fotografije", + "species": "Vrste" + }, + "gitea": { + "notifications": "Obavijesti", + "issues": "Problemi", + "pulls": "Zahtjevi za povlaฤenje" + }, + "stash": { + "scenes": "Scene", + "scenesPlayed": "Reproducirane scene", + "playCount": "Ukupni broj reprodukcija", + "playDuration": "Vrijeme gledanja", + "sceneSize": "Veliฤina scene", + "sceneDuration": "Trajanje scene", + "images": "Slike", + "imageSize": "Veliฤina slike", + "galleries": "Galerije", + "performers": "Glumci", + "studios": "Studiji", + "movies": "Filmovi", + "tags": "Oznake", + "oCount": "O zbroj" + }, + "tandoor": { + "users": "Korisnici", + "recipes": "Recepti", + "keywords": "Kljuฤne rijeฤi" + }, + "homebox": { + "items": "Stavke", + "totalWithWarranty": "S garancijom", + "locations": "Lokacije", + "labels": "Oznake", + "users": "Korisnici", + "totalValue": "Svukupno" + }, + "crowdsec": { + "alerts": "Upozorenja", + "bans": "Zabrane" + }, + "wgeasy": { + "connected": "Povezano", + "enabled": "Aktivirano", + "disabled": "Deaktivirano", + "total": "Ukupno" + }, + "swagdashboard": { + "proxied": "Posredovano", + "auth": "S autentifikacijom", + "outdated": "Zastarjelo", + "banned": "Zabranjen pristup" } } diff --git a/public/locales/hu/common.json b/public/locales/hu/common.json index 4c047536..aed09199 100644 --- a/public/locales/hu/common.json +++ b/public/locales/hu/common.json @@ -14,18 +14,18 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", - "days": "d", - "hours": "h", - "minutes": "m", - "seconds": "s" + "months": "hรณ", + "days": "n", + "hours": "รณ", + "minutes": "p", + "seconds": "mp" }, "widget": { "missing_type": "Hiรกnyzรณ Widget Tรญpus: {{type}}", "api_error": "API Hiba", "information": "Informรกciรณ", "status": "Stรกtusz", - "url": "URL", + "url": "LINK", "raw_error": "Nyers hiba", "response_data": "Vรกlaszadatok" }, @@ -40,12 +40,12 @@ }, "resources": { "cpu": "Processzor", - "mem": "MEM", + "mem": "RAM", "total": "ร–sszes", "free": "Szabad", "used": "Hasznรกlt", "load": "Terhelรฉs", - "temp": "TEMP", + "temp": "HลM", "max": "Max", "uptime": "FUT" }, @@ -69,10 +69,10 @@ "docker": { "rx": "RX", "tx": "TX", - "mem": "MEM", + "mem": "RAM", "cpu": "Processzor", "running": "Futรณ", - "offline": "Offline", + "offline": "Nem elรฉrhetล‘", "error": "Hiba", "unknown": "Ismeretlen", "healthy": "Egรฉszsรฉges", @@ -107,6 +107,13 @@ "episodes": "Epizรณd", "songs": "Zeneszรกm" }, + "esphome": { + "offline": "Nem elรฉrhetล‘", + "offline_alt": "Nem elรฉrhetล‘", + "online": "Csatlakozva", + "total": "ร–sszes", + "unknown": "Ismeretlen" + }, "evcc": { "pv_power": "Termelรฉs", "battery_soc": "Akkumulรกtor", @@ -133,10 +140,10 @@ "connectionStatusPendingDisconnect": "Szรฉtkapcsolรกs fรผggล‘ben", "connectionStatusDisconnecting": "Kapcsolat bontรกsa", "connectionStatusDisconnected": "Kapcsolat bontva", - "connectionStatusConnected": "Csatlakoztatott", + "connectionStatusConnected": "Csatlakozva", "uptime": "รœzemidล‘", - "maxDown": "Max. Down", - "maxUp": "Max. Up", + "maxDown": "Max let.", + "maxUp": "Max felt.", "down": "Le", "up": "Fel", "received": "Fogadott", @@ -270,11 +277,11 @@ "approved": "Engedรฉlyezett", "available": "Elรฉrhetล‘" }, - "pialert": { + "netalertx": { "total": "ร–sszes", - "connected": "Csatlakoztatott", - "new_devices": "รšj Eszkรถzรถk", - "down_alerts": "Leรกllรกsi Figyelmeztetรฉsek" + "connected": "Csatlakozva", + "new_devices": "รšj eszkรถzรถk", + "down_alerts": "Leรกllรกsi riasztรกsok" }, "pihole": { "queries": "Lekรฉrdezรฉsek", @@ -304,12 +311,12 @@ "never": "Soha", "last_seen": "Utoljรกra lรกtott", "now": "Most", - "years": "{{number}}y", - "weeks": "{{number}}w", - "days": "{{number}}d", - "hours": "{{number}}h", - "minutes": "{{number}}m", - "seconds": "{{number}}s", + "years": "{{number}}รฉv", + "weeks": "{{number}}h", + "days": "{{number}}n", + "hours": "{{number}}รณ", + "minutes": "{{number}}p", + "seconds": "{{number}}mp", "ago": "{{value}} Ezelล‘tt" }, "tdarr": { @@ -376,7 +383,7 @@ "version": "Verziรณ", "status": "Stรกtusz", "up": "Csatlakozva", - "down": "Offline" + "down": "Nem elรฉrhetล‘" }, "miniflux": { "read": "Olvasott", @@ -388,30 +395,30 @@ "failedLoginsLast24H": "Sikertelen bejelentkezรฉsek (24h)" }, "proxmox": { - "mem": "MEM", + "mem": "RAM", "cpu": "Processzor", - "lxc": "LXC", + "lxc": "LXC-k", "vms": "VM-ek" }, "glances": { "cpu": "Processzor", "load": "Terhelรฉs", "wait": "Kรฉrjรผk vรกrjon", - "temp": "TEMP", + "temp": "HลM", "_temp": "Hล‘mรฉrsรฉklet", "warn": "Figyelmeztet", "uptime": "FUT", "total": "ร–sszes", "free": "Szabad", "used": "Hasznรกlt", - "days": "d", - "hours": "h", - "crit": "Crit", + "days": "n", + "hours": "รณ", + "crit": "Kritikus", "read": "Olvasott", "write": "รrรกs", "gpu": "GPU", "mem": "Memรณria", - "swap": "Swap" + "swap": "Csere" }, "quicklaunch": { "bookmark": "Kรถnyvjelzล‘", @@ -419,7 +426,8 @@ "search": "Keresรฉs", "custom": "Egyedi", "visit": "Megnรฉz", - "url": "URL" + "url": "LINK", + "searchsuggestion": "Javaslat" }, "wmo": { "0-day": "Napos", @@ -518,7 +526,7 @@ "playlists": "Lejรกtszรกsi listรกk" }, "truenas": { - "load": "Rendszerterheltsรฉg", + "load": "Rendszerterhelรฉs", "uptime": "รœzemidล‘", "alerts": "Riasztรกsok" }, @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Csatornรกk", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuner-ek", + "channelNumber": "Csatorna", + "channelNetwork": "Hรกlรณzat", + "signalStrength": "Erล‘ssรฉg", + "signalQuality": "Minล‘sรฉg", + "symbolQuality": "Minล‘sรฉg", + "networkRate": "Bitrรกta", + "clientIP": "Kliens" }, "scrutiny": { "passed": "Megfelelt", @@ -547,12 +563,12 @@ "total": "ร–sszes" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "battery_charge": "Akku tรถltรถttsรฉge", + "ups_load": "UPS terheltsรฉge", + "ups_status": "UPS รกllapot", "online": "Csatlakozva", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "Akkurรณl", + "low_battery": "Alacsony tรถltรถttsรฉg" }, "nextdns": { "wait": "Kรฉrjรผk Vรกrjon", @@ -570,10 +586,10 @@ "streams_xepg": "XEPG Csatornรกk" }, "opendtu": { - "yieldDay": "Today", - "absolutePower": "Power", - "relativePower": "Power %", - "limit": "Limit" + "yieldDay": "Ma", + "absolutePower": "Energia", + "relativePower": "Energia %", + "limit": "Korlรกt" }, "opnsense": { "cpu": "Processzor Terhelรฉs", @@ -624,13 +640,13 @@ "down": "Nem Elรฉrhetล‘ Webhelyek", "uptime": "รœzemidล‘", "incident": "Incidens", - "m": "m" + "m": "p" }, "atsumeru": { "series": "Sorozat", - "archives": "Archives", - "chapters": "Chapters", - "categories": "Categories" + "archives": "Archรญvum", + "chapters": "Fejezetek", + "categories": "Kategรณriรกk" }, "komga": { "libraries": "Kรถnyvtรกrak", @@ -694,8 +710,13 @@ "targets_down": "Cรฉlpontok รllnak", "targets_total": "ร–sszes Cรฉlpont" }, + "gatus": { + "up": "Futรณ Webhelyek", + "down": "Nem Elรฉrhetล‘ Webhelyek", + "uptime": "รœzemidล‘" + }, "ghostfolio": { - "gross_percent_today": "Today", + "gross_percent_today": "Ma", "gross_percent_1y": "Egy รฉv", "gross_percent_max": "Mindig" }, @@ -716,8 +737,8 @@ }, "calibreweb": { "books": "Kรถnyvek", - "authors": "Authors", - "categories": "Categories", + "authors": "Szerzล‘k", + "categories": "Kategรณriรกk", "series": "Sorozat" }, "jdownloader": { @@ -731,22 +752,22 @@ "totalFiles": "Fรกjlok" }, "azuredevops": { - "result": "Result", + "result": "Eredmรฉny", "status": "Stรกtusz", - "buildId": "Build ID", - "succeeded": "Succeeded", + "buildId": "Gyรกrtรกs ID", + "succeeded": "Sikerรผlt", "notStarted": "Nem indult", "failed": "Sikertelen", "canceled": "Megszakรญtva", "inProgress": "Folyamatban", - "totalPrs": "Total PRs", - "myPrs": "My PRs", + "totalPrs": "Minden PR", + "myPrs": "Sajรกt PR-ek", "approved": "Engedรฉlyezett" }, "gamedig": { "status": "Stรกtusz", "online": "Csatlakozva", - "offline": "Offline", + "offline": "Nem elรฉrhetล‘", "name": "Nรฉv", "map": "Tรฉrkรฉp", "currentPlayers": "Jelenlegi jรกtรฉkosok", @@ -764,7 +785,7 @@ "mealie": { "recipes": "Receptek", "users": "Felhasznรกlรณk", - "categories": "Categories", + "categories": "Kategรณriรกk", "tags": "Cรญmkรฉk" }, "openmediavault": { @@ -775,33 +796,97 @@ "passed": "Megfelelt", "failed": "Sikertelen" }, + "openwrt": { + "uptime": "รœzemidล‘", + "cpuLoad": "รtlag CPU terhelรฉs (5p)", + "up": "Fel", + "down": "Le", + "bytesTx": "Tovรกbbรญtott", + "bytesRx": "Fogadott" + }, "uptimerobot": { "status": "Stรกtusz", "uptime": "รœzemidล‘", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", + "lastDown": "Utolsรณ leรกllรกs", + "downDuration": "Leรกllรกs ideje", "sitesUp": "Futรณ Webhelyek", "sitesDown": "Nem Elรฉrhetล‘ Webhelyek", "paused": "Szรผnetel", - "notyetchecked": "Not Yet Checked", + "notyetchecked": "Mรฉg nincs ellenล‘rizve", "up": "Fel", - "seemsdown": "Seems Down", + "seemsdown": "Elรฉrhetetlennek tลฑnik", "down": "Le", "unknown": "Ismeretlen" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", + "inCinemas": "Mozikban", + "physicalRelease": "Fizikai kiadรกs", "digitalRelease": "Digitรกlis kiadรกs", "noEventsToday": "Ezen a napon nincsenek esemรฉnyek!", "noEventsFound": "Nem talรกlhatรณ esemรฉny" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Felรผlet", + "totalRoms": "Minden ROM" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Figyelmeztetรฉsek", + "criticals": "Kritikusok" + }, + "plantit": { + "events": "Esemรฉnyek", + "plants": "Nรถvรฉnyek", + "photos": "Fรฉnykรฉpek", + "species": "Fajok" + }, + "gitea": { + "notifications": "รœzenetek", + "issues": "Problรฉmรกk", + "pulls": "Pull request-ek" + }, + "stash": { + "scenes": "Jelenetek", + "scenesPlayed": "Lejรกtszott jelenetek", + "playCount": "ร–sszes leรกtszรกs", + "playDuration": "Nรฉzett idล‘", + "sceneSize": "Jelenetek mรฉrete", + "sceneDuration": "Jelenetek hossza", + "images": "Kรฉpek", + "imageSize": "Kรฉpek mรฉrete", + "galleries": "Galรฉriรกk", + "performers": "Elล‘adรณk", + "studios": "Stรบdiรณk", + "movies": "Film", + "tags": "Cรญmkรฉk", + "oCount": "O szรกm" + }, + "tandoor": { + "users": "Felhasznรกlรณk", + "recipes": "Receptek", + "keywords": "Kulcsszavak" + }, + "homebox": { + "items": "Tรกrgyak", + "totalWithWarranty": "Garanciรกval", + "locations": "Helyek", + "labels": "Cรญmkรฉk", + "users": "Felhasznรกlรณk", + "totalValue": "Teljes รฉrtรฉk" + }, + "crowdsec": { + "alerts": "Riasztรกsok", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Csatlakozva", + "enabled": "Bekapcsolva", + "disabled": "Kikapcsolva", + "total": "ร–sszes" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/id/common.json b/public/locales/id/common.json index c5f35e1f..9c7a0ec8 100644 --- a/public/locales/id/common.json +++ b/public/locales/id/common.json @@ -14,20 +14,20 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", - "days": "d", - "hours": "h", + "months": "bulan", + "days": "h", + "hours": "j", "minutes": "m", - "seconds": "s" + "seconds": "d" }, "widget": { - "missing_type": "Missing Widget Type: {{type}}", + "missing_type": "Widget Tidak Ditemukan: {{type}}", "api_error": "API Error", "information": "Informasi", "status": "Status", "url": "URL", - "raw_error": "Raw Error", - "response_data": "Response Data" + "raw_error": "Error Baku", + "response_data": "Data Respons" }, "weather": { "current": "Lokasi Saat Ini", @@ -44,348 +44,355 @@ "total": "Total", "free": "Luang", "used": "Digunakan", - "load": "Load", + "load": "Beban", "temp": "TEMP", "max": "Maks", - "uptime": "UP" + "uptime": "Waktu Aktif" }, "unifi": { - "users": "Users", - "uptime": "Uptime", - "days": "Days", + "users": "Pengguna", + "uptime": "Waktu Aktif", + "days": "Hari-hari", "wan": "WAN", "lan": "LAN", "wlan": "WLAN", - "devices": "Devices", - "lan_devices": "LAN Devices", - "wlan_devices": "WLAN Devices", - "lan_users": "LAN Users", - "wlan_users": "WLAN Users", - "up": "UP", - "down": "DOWN", + "devices": "Perangkat", + "lan_devices": "Perangkat LAN", + "wlan_devices": "Perangkat WLAN", + "lan_users": "Pengguna LAN", + "wlan_users": "Pengguna WLAN", + "up": "Waktu Aktif", + "down": "Mati", "wait": "Harap tunggu", - "empty_data": "Subsystem status unknown" + "empty_data": "Status subsistem tdk diketahui" }, "docker": { "rx": "RX", "tx": "TX", "mem": "MEM", "cpu": "CPU", - "running": "Running", + "running": "Berjalan", "offline": "Offline", "error": "Error", - "unknown": "Unknown", - "healthy": "Healthy", - "starting": "Starting", - "unhealthy": "Unhealthy", - "not_found": "Not Found", - "exited": "Exited", - "partial": "Partial" + "unknown": "Tidak Diketahui", + "healthy": "Lancar", + "starting": "Memulai", + "unhealthy": "Tidak Lancar", + "not_found": "Tidak Ditemukan", + "exited": "Terkeluar", + "partial": "Sebagian" }, "ping": { "error": "Error", "ping": "Ping", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "down": "Mati", + "up": "Hidup", + "not_available": "Tidak Tersedia" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "HTTP Status", "error": "Error", - "response": "Response", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "response": "Respons", + "down": "Mati", + "up": "Hidup", + "not_available": "Tidak Tersedia" }, "emby": { - "playing": "Playing", - "transcoding": "Transcoding", + "playing": "Sedang Diputar", + "transcoding": "Mentranskode", "bitrate": "Bitrate", - "no_active": "No Active Streams", - "movies": "Movies", - "series": "Series", - "episodes": "Episodes", - "songs": "Songs" + "no_active": "Tidak ada Strim Aktif", + "movies": "Film", + "series": "Seri", + "episodes": "Episode", + "songs": "Lagu" + }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Total", + "unknown": "Tidak Diketahui" }, "evcc": { - "pv_power": "Production", - "battery_soc": "Battery", + "pv_power": "Produksi", + "battery_soc": "Baterai", "grid_power": "Grid", - "home_power": "Consumption", + "home_power": "Konsumsi", "charge_power": "Charger", - "watt_hour": "Wh" + "watt_hour": "Watt/jam" }, "flood": { - "download": "Download", - "upload": "Upload", + "download": "Unduh", + "upload": "Unggah", "leech": "Leech", "seed": "Seed" }, "freshrss": { - "subscriptions": "Subscriptions", - "unread": "Unread" + "subscriptions": "Subskripsi", + "unread": "Belum Dibaca" }, "fritzbox": { "connectionStatus": "Status", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", + "connectionStatusUnconfigured": "Belum dikonfigur", + "connectionStatusConnecting": "Menyambung", + "connectionStatusAuthenticating": "Menotentikasi", + "connectionStatusPendingDisconnect": "Menunggu Terputus", + "connectionStatusDisconnecting": "Sedan Memutus", + "connectionStatusDisconnected": "Terputus", "connectionStatusConnected": "Connected", - "uptime": "Uptime", - "maxDown": "Max. Down", - "maxUp": "Max. Up", - "down": "Down", - "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "uptime": "Waktu Aktif", + "maxDown": "Maks Unduh", + "maxUp": "Maks Unggah", + "down": "Mati", + "up": "Hidup", + "received": "Diterima", + "sent": "Terkirim", + "externalIPAddress": "IP Eksternal" }, "caddy": { - "upstreams": "Upstreams", - "requests": "Current requests", - "requests_failed": "Failed requests" + "upstreams": "Strim Luar", + "requests": "Request saat ini", + "requests_failed": "Request gagal" }, "changedetectionio": { - "totalObserved": "Total Observed", - "diffsDetected": "Diffs Detected" + "totalObserved": "Total yang Diamati", + "diffsDetected": "Perbedaan yang Terdeteksi" }, "channelsdvrserver": { - "shows": "Shows", - "recordings": "Recordings", - "scheduled": "Scheduled", - "passes": "Passes" + "shows": "Acara", + "recordings": "Rekaman", + "scheduled": "Terjadwal", + "passes": "Tiket" }, "tautulli": { - "playing": "Playing", - "transcoding": "Transcoding", + "playing": "Sedang Diputar", + "transcoding": "Mentranskode", "bitrate": "Bitrate", - "no_active": "No Active Streams", - "plex_connection_error": "Check Plex Connection" + "no_active": "Tidak ada Strim Aktif", + "plex_connection_error": "Cek Koneksi ke Plex" }, "omada": { - "connectedAp": "Connected APs", - "activeUser": "Active devices", - "alerts": "Alerts", - "connectedGateway": "Connected gateways", - "connectedSwitches": "Connected switches" + "connectedAp": "AP Tersambung", + "activeUser": "Perangakat yang Aktif", + "alerts": "Peringatan", + "connectedGateway": "Gateway Tersambung", + "connectedSwitches": "Switch Tersambung" }, "nzbget": { - "rate": "Rate", - "remaining": "Remaining", - "downloaded": "Downloaded" + "rate": "Laju Bandwidth", + "remaining": "Sisa", + "downloaded": "Terunduh" }, "plex": { - "streams": "Active Streams", + "streams": "Stream Berjalan", "albums": "Albums", - "movies": "Movies", - "tv": "TV Shows" + "movies": "Film", + "tv": "Acara TV" }, "sabnzbd": { - "rate": "Rate", - "queue": "Queue", - "timeleft": "Time Left" + "rate": "Laju Bandwidth", + "queue": "Antrian", + "timeleft": "Sisa Waktu" }, "rutorrent": { - "active": "Active", - "upload": "Upload", - "download": "Download" + "active": "Aktif", + "upload": "Unggah", + "download": "Unduh" }, "transmission": { - "download": "Download", - "upload": "Upload", + "download": "Unduh", + "upload": "Unggah", "leech": "Leech", "seed": "Seed" }, "qbittorrent": { - "download": "Download", - "upload": "Upload", + "download": "Unduh", + "upload": "Unggah", "leech": "Leech", "seed": "Seed" }, "qnap": { - "cpuUsage": "CPU Usage", - "memUsage": "MEM Usage", - "systemTempC": "System Temp", - "poolUsage": "Pool Usage", - "volumeUsage": "Volume Usage", - "invalid": "Invalid" + "cpuUsage": "Penggunaan CPU", + "memUsage": "Penggunaan MEM", + "systemTempC": "Suhu Sistem", + "poolUsage": "Pengunaan Pool", + "volumeUsage": "Penggunaan Volume", + "invalid": "Tidak valid" }, "deluge": { - "download": "Download", - "upload": "Upload", + "download": "Unduh", + "upload": "Unggah", "leech": "Leech", "seed": "Seed" }, "downloadstation": { - "download": "Download", - "upload": "Upload", + "download": "Unduh", + "upload": "Unggah", "leech": "Leech", "seed": "Seed" }, "sonarr": { - "wanted": "Wanted", - "queued": "Queued", - "series": "Series", - "queue": "Queue", - "unknown": "Unknown" + "wanted": "Dicari", + "queued": "Terantrikan", + "series": "Seri", + "queue": "Antrian", + "unknown": "Tidak Diketahui" }, "radarr": { - "wanted": "Wanted", - "missing": "Missing", - "queued": "Queued", - "movies": "Movies", - "queue": "Queue", - "unknown": "Unknown" + "wanted": "Dicari", + "missing": "Tidak Ditemukan", + "queued": "Terantrikan", + "movies": "Film", + "queue": "Antrian", + "unknown": "Tidak Diketahui" }, "lidarr": { - "wanted": "Wanted", - "queued": "Queued", - "artists": "Artists" + "wanted": "Dicari", + "queued": "Terantrikan", + "artists": "Artis" }, "readarr": { - "wanted": "Wanted", - "queued": "Queued", - "books": "Books" + "wanted": "Dicari", + "queued": "Terantrikan", + "books": "Buku" }, "bazarr": { - "missingEpisodes": "Missing Episodes", - "missingMovies": "Missing Movies" + "missingEpisodes": "Episode Tidak Ditemukan", + "missingMovies": "Film Tidak Ditemukan" }, "ombi": { "pending": "Pending", - "approved": "Approved", - "available": "Available" + "approved": "Tersetujui", + "available": "Tersedia" }, "jellyseerr": { "pending": "Pending", - "approved": "Approved", - "available": "Available" + "approved": "Tersetujui", + "available": "Tersedia" }, "overseerr": { "pending": "Pending", - "processing": "Processing", - "approved": "Approved", - "available": "Available" + "processing": "Memproses", + "approved": "Tersetujui", + "available": "Tersedia" }, - "pialert": { + "netalertx": { "total": "Total", "connected": "Connected", "new_devices": "New Devices", "down_alerts": "Down Alerts" }, "pihole": { - "queries": "Queries", - "blocked": "Blocked", - "blocked_percent": "Blocked %", - "gravity": "Gravity" + "queries": "Kueri", + "blocked": "Terblokir", + "blocked_percent": "% Terblokir", + "gravity": "Gravitasi" }, "adguard": { - "queries": "Queries", - "blocked": "Blocked", - "filtered": "Filtered", - "latency": "Latency" + "queries": "Kueri", + "blocked": "Terblokir", + "filtered": "Terfilter", + "latency": "Latensi" }, "speedtest": { - "upload": "Upload", - "download": "Download", + "upload": "Unggah", + "download": "Unduh", "ping": "Ping" }, "portainer": { - "running": "Running", - "stopped": "Stopped", + "running": "Berjalan", + "stopped": "Terhenti", "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", + "address": "Alamat", + "expires": "Kadaluarsa", + "never": "Tidak Pernah", + "last_seen": "Terakhir terlihat", + "now": "Sekarang", + "years": "{{number}}thn", + "weeks": "{{number}}mgg", + "days": "{{number}}h", + "hours": "{{number}}j", "minutes": "{{number}}m", - "seconds": "{{number}}s", - "ago": "{{value}} Ago" + "seconds": "{{number}}d", + "ago": "{{value}} Yang Lalu" }, "tdarr": { - "queue": "Queue", - "processed": "Processed", - "errored": "Errored", - "saved": "Saved" + "queue": "Antrian", + "processed": "Terproses", + "errored": "Error", + "saved": "Tersimpan" }, "traefik": { - "routers": "Routers", - "services": "Services", + "routers": "Router", + "services": "Layanan", "middleware": "Middleware" }, "navidrome": { - "nothing_streaming": "No Active Streams", - "please_wait": "Please Wait" + "nothing_streaming": "Tidak ada Strim Aktif", + "please_wait": "Mohon menunggu" }, "npm": { - "enabled": "Enabled", - "disabled": "Disabled", + "enabled": "Aktif", + "disabled": "Nonaktif", "total": "Total" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track", - "1hour": "1 Hour", - "1day": "1 Day", - "7days": "7 Days", - "30days": "30 Days" + "configure": "Konfigurasikan satu atau beberapa mata uang kripto untuk dilacak", + "1hour": "1 Jam", + "1day": "1 Hari", + "7days": "7 Hari", + "30days": "30 Hari" }, "gotify": { - "apps": "Applications", - "clients": "Clients", - "messages": "Messages" + "apps": "Aplikasi", + "clients": "Klien", + "messages": "Pesan" }, "prowlarr": { - "enableIndexers": "Indexers", - "numberOfGrabs": "Grabs", - "numberOfQueries": "Queries", - "numberOfFailGrabs": "Fail Grabs", - "numberOfFailQueries": "Fail Queries" + "enableIndexers": "Pengindeks", + "numberOfGrabs": "Jumlah Ambilan", + "numberOfQueries": "Kueri", + "numberOfFailGrabs": "Ambilan Gagal", + "numberOfFailQueries": "Jumlah Kueri Gagal" }, "jackett": { - "configured": "Configured", - "errored": "Errored" + "configured": "Konfigurasi", + "errored": "Error" }, "strelaysrv": { - "numActiveSessions": "Sessions", - "numConnections": "Connections", - "dataRelayed": "Relayed", - "transferRate": "Rate" + "numActiveSessions": "Sesi", + "numConnections": "Jumlah Koneksi", + "dataRelayed": "Data Diteruskan", + "transferRate": "Laju Bandwidth" }, "mastodon": { - "user_count": "Users", - "status_count": "Posts", - "domain_count": "Domains" + "user_count": "Pengguna", + "status_count": "Jumlah Posting", + "domain_count": "Jumlah Domain" }, "medusa": { - "wanted": "Wanted", - "queued": "Queued", - "series": "Series" + "wanted": "Dicari", + "queued": "Terantrikan", + "series": "Seri" }, "minecraft": { - "players": "Players", - "version": "Version", + "players": "Jumlah Pemain", + "version": "Versi", "status": "Status", "up": "Online", "down": "Offline" }, "miniflux": { - "read": "Read", - "unread": "Unread" + "read": "Baca", + "unread": "Belum Dibaca" }, "authentik": { - "users": "Users", - "loginsLast24H": "Logins (24h)", - "failedLoginsLast24H": "Failed Logins (24h)" + "users": "Pengguna", + "loginsLast24H": "Login (24j)", + "failedLoginsLast24H": "Login Gagal (24j)" }, "proxmox": { "mem": "MEM", @@ -395,413 +402,491 @@ }, "glances": { "cpu": "CPU", - "load": "Load", + "load": "Beban", "wait": "Harap tunggu", "temp": "TEMP", - "_temp": "Temp", - "warn": "Warn", - "uptime": "UP", + "_temp": "Suhu", + "warn": "Peringatan", + "uptime": "Waktu Aktif", "total": "Total", "free": "Luang", "used": "Digunakan", - "days": "d", - "hours": "h", - "crit": "Crit", - "read": "Read", - "write": "Write", + "days": "h", + "hours": "j", + "crit": "Penting", + "read": "Baca", + "write": "Tulis", "gpu": "GPU", "mem": "Mem", "swap": "Swap" }, "quicklaunch": { - "bookmark": "Bookmark", - "service": "Service", - "search": "Search", - "custom": "Custom", - "visit": "Visit", - "url": "URL" + "bookmark": "Penanda", + "service": "Layanan", + "search": "Cari", + "custom": "Kustom", + "visit": "Kunjungi", + "url": "URL", + "searchsuggestion": "Saran" }, "wmo": { - "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", - "95-night": "Thunderstorm", - "96-day": "Thunderstorm With Hail", - "96-night": "Thunderstorm With Hail", - "99-day": "Thunderstorm With Hail", - "99-night": "Thunderstorm With Hail" + "0-day": "Cerah dan Terang", + "0-night": "Cerah", + "1-day": "Cerah", + "1-night": "Cerah", + "2-day": "Sedikit Berawan", + "2-night": "Sedikit Berawan", + "3-day": "Berawan", + "3-night": "Berawan", + "45-day": "Berkabut", + "45-night": "Berkabut", + "48-day": "Berkabut", + "48-night": "Berkabut", + "51-day": "Gerimis Ringan", + "51-night": "Gerimis Ringan", + "53-day": "Gerimis", + "53-night": "Gerimis", + "55-day": "Gerimis Lebat", + "55-night": "Gerimis Lebat", + "56-day": "Gerimis Membeku Ringan", + "56-night": "Gerimis Membeku Ringan", + "57-day": "Gerimis Membeku", + "57-night": "Gerimis Membeku", + "61-day": "Hujan Ringan", + "61-night": "Hujan Ringan", + "63-day": "Hujan", + "63-night": "Hujan", + "65-day": "Hujan Deras", + "65-night": "Hujan Deras", + "66-day": "Hujan Dingin", + "66-night": "Hujan Dingin", + "67-day": "Hujan Dingin", + "67-night": "Hujan Dingin", + "71-day": "Hujan Salju Ringan", + "71-night": "Hujan Salju Ringan", + "73-day": "Hujan Salju", + "73-night": "Hujan Salju", + "75-day": "Hujan Salju Lebat", + "75-night": "Hujan Salju Lebat", + "77-day": "Hujan Salju Butiran", + "77-night": "Hujan Salju Butiran", + "80-day": "Hujan Ringan", + "80-night": "Hujan Ringan", + "81-day": "Hujan", + "81-night": "Hujan", + "82-day": "Hujan Lebat", + "82-night": "Hujan Lebat", + "85-day": "Hujan Salju", + "85-night": "Hujan Salju", + "86-day": "Hujan Salju", + "86-night": "Hujan Salju", + "95-day": "Badai Petir", + "95-night": "Badai Petir", + "96-day": "Badai Petir Hujan Es", + "96-night": "Badai Petir Hujan Es", + "99-day": "Badai Petir Hujan Es", + "99-night": "Badai Petir Hujan Es" }, "homebridge": { - "available_update": "System", - "updates": "Updates", - "update_available": "Update Available", - "up_to_date": "Up to Date", - "child_bridges": "Child Bridges", + "available_update": "Sistem", + "updates": "Pembaruan", + "update_available": "Pembaruan Tersedia", + "up_to_date": "Terbaru", + "child_bridges": "Bridge Turunan", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Up", + "up": "Hidup", "pending": "Pending", - "down": "Down" + "down": "Mati" }, "healthchecks": { - "new": "New", - "up": "Up", - "grace": "In Grace Period", - "down": "Down", - "paused": "Paused", + "new": "Baru", + "up": "Hidup", + "grace": "Dalam Masa Tenggang", + "down": "Mati", + "paused": "Pause", "status": "Status", - "last_ping": "Last Ping", - "never": "No pings yet" + "last_ping": "Ping Terakhir", + "never": "Tidak pernah di ping" }, "watchtower": { - "containers_scanned": "Scanned", - "containers_updated": "Updated", - "containers_failed": "Failed" + "containers_scanned": "Terpindai", + "containers_updated": "Terbarui", + "containers_failed": "Gagal" }, "autobrr": { - "approvedPushes": "Approved", - "rejectedPushes": "Rejected", - "filters": "Filters", - "indexers": "Indexers" + "approvedPushes": "Tersetujui", + "rejectedPushes": "Tertolak", + "filters": "Filter", + "indexers": "Pengindeks" }, "tubearchivist": { - "downloads": "Queue", - "videos": "Videos", - "channels": "Channels", - "playlists": "Playlists" + "downloads": "Antrian", + "videos": "Video", + "channels": "Channel", + "playlists": "Daftar Putar" }, "truenas": { - "load": "System Load", - "uptime": "Uptime", - "alerts": "Alerts" + "load": "Beban Sistem", + "uptime": "Waktu Aktif", + "alerts": "Peringatan" }, "pyload": { - "speed": "Speed", - "active": "Active", - "queue": "Queue", + "speed": "Kecepatan", + "active": "Aktif", + "queue": "Antrian", "total": "Total" }, "gluetun": { - "public_ip": "Public IP", + "public_ip": "IP Publik", "region": "Region", - "country": "Country" + "country": "Negara" }, "hdhomerun": { - "channels": "Channels", - "hd": "HD" + "channels": "Channel", + "hd": "HD", + "tunerCount": "Tuner", + "channelNumber": "Channel", + "channelNetwork": "Jaringan", + "signalStrength": "Kekuatan Signal", + "signalQuality": "Kualitas", + "symbolQuality": "Kualitas", + "networkRate": "Bitrate", + "clientIP": "Klien" }, "scrutiny": { - "passed": "Passed", - "failed": "Failed", - "unknown": "Unknown" + "passed": "Sukses", + "failed": "Gagal", + "unknown": "Tidak Diketahui" }, "paperlessngx": { - "inbox": "Inbox", + "inbox": "Kotak Masuk", "total": "Total" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "battery_charge": "Sisa Baterai", + "ups_load": "Beban UPS", + "ups_status": "Status UPS", "online": "Online", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "Memakai Baterai", + "low_battery": "Baterai Lemah" }, "nextdns": { - "wait": "Please Wait", - "no_devices": "No Device Data Received" + "wait": "Mohon menunggu", + "no_devices": "Tidak ada Data Perangkat Diterima" }, "mikrotik": { - "cpuLoad": "CPU Load", - "memoryUsed": "Memory Used", - "uptime": "Uptime", + "cpuLoad": "Beban CPU", + "memoryUsed": "Memori Terpakai", + "uptime": "Waktu Aktif", "numberOfLeases": "Leases" }, "xteve": { - "streams_all": "All Streams", - "streams_active": "Active Streams", - "streams_xepg": "XEPG Channels" + "streams_all": "Semua Strim", + "streams_active": "Stream Berjalan", + "streams_xepg": "Channel XEPG" }, "opendtu": { - "yieldDay": "Today", - "absolutePower": "Power", - "relativePower": "Power %", - "limit": "Limit" + "yieldDay": "Hari ini", + "absolutePower": "Daya", + "relativePower": "% Daya", + "limit": "Batas" }, "opnsense": { - "cpu": "CPU Load", - "memory": "Active Memory", - "wanUpload": "WAN Upload", - "wanDownload": "WAN Download" + "cpu": "Beban CPU", + "memory": "Memori Aktif", + "wanUpload": "WAN Unggan", + "wanDownload": "WAN Unduh" }, "moonraker": { - "printer_state": "Printer State", - "print_status": "Print Status", - "print_progress": "Progress", - "layers": "Layers" + "printer_state": "Status Printer", + "print_status": "Status Cetakan", + "print_progress": "Progres", + "layers": "Layer" }, "octoprint": { "printer_state": "Status", - "temp_tool": "Tool temp", - "temp_bed": "Bed temp", - "job_completion": "Completion" + "temp_tool": "Suhu Alat", + "temp_bed": "Suhu Fondasi", + "job_completion": "Tugas Selesai" }, "cloudflared": { - "origin_ip": "Origin IP", + "origin_ip": "Sumber 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" + "load": "Beban Rata-rata", + "memory": "Penggunaan Memory", + "wanStatus": "Status WAN", + "up": "Hidup", + "down": "Mati", + "temp": "Suhu", + "disk": "Penggunaan Disk", + "wanIP": "IP WAN" }, "proxmoxbackupserver": { "datastore_usage": "Datastore", - "failed_tasks_24h": "Failed Tasks 24h", + "failed_tasks_24h": "Tugas Gagal (24j)", "cpu_usage": "CPU", "memory_usage": "Memory" }, "immich": { - "users": "Users", - "photos": "Photos", - "videos": "Videos", - "storage": "Storage" + "users": "Pengguna", + "photos": "Foto", + "videos": "Video", + "storage": "Penyimpanan" }, "uptimekuma": { - "up": "Sites Up", - "down": "Sites Down", - "uptime": "Uptime", - "incident": "Incident", + "up": "Situs Hidup", + "down": "Situs Mati", + "uptime": "Waktu Aktif", + "incident": "Insiden", "m": "m" }, "atsumeru": { - "series": "Series", - "archives": "Archives", - "chapters": "Chapters", - "categories": "Categories" + "series": "Seri", + "archives": "Arsip", + "chapters": "Bab", + "categories": "Kategori" }, "komga": { - "libraries": "Libraries", - "series": "Series", - "books": "Books" + "libraries": "Perpustakaan", + "series": "Seri", + "books": "Buku" }, "diskstation": { - "days": "Days", - "uptime": "Uptime", - "volumeAvailable": "Available" + "days": "Hari-hari", + "uptime": "Waktu Aktif", + "volumeAvailable": "Tersedia" }, "mylar": { - "series": "Series", - "issues": "Issues", - "wanted": "Wanted" + "series": "Seri", + "issues": "Isu", + "wanted": "Dicari" }, "photoprism": { "albums": "Albums", - "photos": "Photos", - "videos": "Videos", - "people": "People" + "photos": "Foto", + "videos": "Video", + "people": "Orang" }, "fileflows": { - "queue": "Queue", - "processing": "Processing", - "processed": "Processed", - "time": "Time" + "queue": "Antrian", + "processing": "Memproses", + "processed": "Terproses", + "time": "Waktu" }, "grafana": { - "dashboards": "Dashboards", - "datasources": "Data Sources", - "totalalerts": "Total Alerts", - "alertstriggered": "Alerts Triggered" + "dashboards": "Dasbor", + "datasources": "Sumber Data", + "totalalerts": "Jumlah Peringatan", + "alertstriggered": "Peringatan Terpicu" }, "nextcloud": { - "cpuload": "Cpu Load", - "memoryusage": "Memory Usage", - "freespace": "Free Space", - "activeusers": "Active Users", - "numfiles": "Files", - "numshares": "Shared Items" + "cpuload": "Beban CPU", + "memoryusage": "Beban Memory", + "freespace": "Space Tersedia", + "activeusers": "Pengguna Aktif", + "numfiles": "File", + "numshares": "Item yang Dibagikan" }, "kopia": { "status": "Status", - "size": "Size", - "lastrun": "Last Run", - "nextrun": "Next Run", - "failed": "Failed" + "size": "Ukuran", + "lastrun": "Terakhir Dijalankan", + "nextrun": "Akan Dijalankan Dalam", + "failed": "Gagal" }, "unmanic": { - "active_workers": "Active Workers", - "total_workers": "Total Workers", - "records_total": "Queue Length" + "active_workers": "Pengguna Aktif", + "total_workers": "Pengguna Total", + "records_total": "Panjang Antrian" }, "pterodactyl": { - "servers": "Servers", - "nodes": "Nodes" + "servers": "Server", + "nodes": "Node" }, "prometheus": { - "targets_up": "Targets Up", - "targets_down": "Targets Down", - "targets_total": "Total Targets" + "targets_up": "Target Aktif", + "targets_down": "Target Nonaktif", + "targets_total": "Target Total" + }, + "gatus": { + "up": "Situs Hidup", + "down": "Situs Mati", + "uptime": "Waktu Aktif" }, "ghostfolio": { - "gross_percent_today": "Today", - "gross_percent_1y": "One year", - "gross_percent_max": "All time" + "gross_percent_today": "Hari ini", + "gross_percent_1y": "Satu Tahun", + "gross_percent_max": "Sepanjang Masa" }, "audiobookshelf": { - "podcasts": "Podcasts", - "books": "Books", - "podcastsDuration": "Duration", - "booksDuration": "Duration" + "podcasts": "Podcast", + "books": "Buku", + "podcastsDuration": "Durasi", + "booksDuration": "Durasi" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Orang Di Rumah", + "lights_on": "Lampu Nyala", + "switches_on": "Sakelar Nyala" }, "whatsupdocker": { - "monitoring": "Monitoring", - "updates": "Updates" + "monitoring": "Pengawasan", + "updates": "Pembaruan" }, "calibreweb": { - "books": "Books", - "authors": "Authors", - "categories": "Categories", - "series": "Series" + "books": "Buku", + "authors": "Penulis", + "categories": "Kategori", + "series": "Seri" }, "jdownloader": { - "downloadCount": "Queue", - "downloadBytesRemaining": "Remaining", - "downloadTotalBytes": "Size", - "downloadSpeed": "Speed" + "downloadCount": "Antrian", + "downloadBytesRemaining": "Sisa", + "downloadTotalBytes": "Ukuran", + "downloadSpeed": "Kecepatan" }, "kavita": { - "seriesCount": "Series", - "totalFiles": "Files" + "seriesCount": "Seri", + "totalFiles": "File" }, "azuredevops": { - "result": "Result", + "result": "Hasil", "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" + "succeeded": "Berhasil", + "notStarted": "Belum Dimulai", + "failed": "Gagal", + "canceled": "Dibatalkan", + "inProgress": "Sedang Berlangsung", + "totalPrs": "PR Total", + "myPrs": "PR Saya", + "approved": "Tersetujui" }, "gamedig": { "status": "Status", "online": "Online", "offline": "Offline", - "name": "Name", - "map": "Map", - "currentPlayers": "Current players", - "players": "Players", - "maxPlayers": "Max players", - "bots": "Bots", + "name": "Nama", + "map": "Peta", + "currentPlayers": "Jumlah pemain", + "players": "Jumlah Pemain", + "maxPlayers": "Maksimum pemain", + "bots": "Bot", "ping": "Ping" }, "urbackup": { "ok": "Ok", - "errored": "Errors", - "noRecent": "Out of Date", - "totalUsed": "Used Storage" + "errored": "Error", + "noRecent": "Tertinggal Versi", + "totalUsed": "Storage Terpakai" }, "mealie": { - "recipes": "Recipes", - "users": "Users", - "categories": "Categories", - "tags": "Tags" + "recipes": "Resep", + "users": "Pengguna", + "categories": "Kategori", + "tags": "Tag" }, "openmediavault": { - "downloading": "Downloading", + "downloading": "Mengunduh", "total": "Total", - "running": "Running", - "stopped": "Stopped", - "passed": "Passed", - "failed": "Failed" + "running": "Berjalan", + "stopped": "Terhenti", + "passed": "Sukses", + "failed": "Gagal" + }, + "openwrt": { + "uptime": "Waktu Aktif", + "cpuLoad": "Beban rata2 CPU (5m)", + "up": "Hidup", + "down": "Mati", + "bytesTx": "Tersalur", + "bytesRx": "Diterima" }, "uptimerobot": { "status": "Status", - "uptime": "Uptime", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", - "sitesUp": "Sites Up", - "sitesDown": "Sites Down", - "paused": "Paused", - "notyetchecked": "Not Yet Checked", - "up": "Up", - "seemsdown": "Seems Down", - "down": "Down", - "unknown": "Unknown" + "uptime": "Waktu Aktif", + "lastDown": "Terakhir Terhenti", + "downDuration": "Jumlah Waktu Terhenti", + "sitesUp": "Situs Hidup", + "sitesDown": "Situs Mati", + "paused": "Pause", + "notyetchecked": "Belum Di Cek", + "up": "Hidup", + "seemsdown": "Sepertinya Mati", + "down": "Mati", + "unknown": "Tidak Diketahui" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", - "digitalRelease": "Digital release", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "inCinemas": "Tersedia Di Bioskop", + "physicalRelease": "Rilis Fisik", + "digitalRelease": "Rilis Digital", + "noEventsToday": "Tidak ada acara untuk hari ini!", + "noEventsFound": "Tidak ada acara yang ditemukan" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platform", + "totalRoms": "ROM Total" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Peringatan", + "criticals": "Kritis" + }, + "plantit": { + "events": "Acara", + "plants": "Tanaman", + "photos": "Foto", + "species": "Spesies" + }, + "gitea": { + "notifications": "Notifikasi", + "issues": "Isu", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Film", + "tags": "Tag", + "oCount": "O Count" + }, + "tandoor": { + "users": "Pengguna", + "recipes": "Resep", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Pengguna", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Peringatan", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Aktif", + "disabled": "Nonaktif", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/it/common.json b/public/locales/it/common.json index e61fff8b..1c4115f7 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -15,8 +15,8 @@ "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", "months": "mo", - "days": "d", - "hours": "h", + "days": "g", + "hours": "o", "minutes": "m", "seconds": "s" }, @@ -107,6 +107,13 @@ "episodes": "Episodi", "songs": "Canzoni" }, + "esphome": { + "offline": "Non in linea", + "offline_alt": "Non in linea", + "online": "Online", + "total": "Totale", + "unknown": "Sconosciuto" + }, "evcc": { "pv_power": "Produzione", "battery_soc": "Batteria", @@ -127,21 +134,21 @@ }, "fritzbox": { "connectionStatus": "Stato", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", + "connectionStatusUnconfigured": "Non configurato", + "connectionStatusConnecting": "Connessione in corso", + "connectionStatusAuthenticating": "In fase di autenticazione", + "connectionStatusPendingDisconnect": "In attesa di disconnessione", + "connectionStatusDisconnecting": "Disconnessione in corso", + "connectionStatusDisconnected": "Disconnesso", "connectionStatusConnected": "Connesso", "uptime": "Tempo di attivitร ", "maxDown": "Max. Down", "maxUp": "Max. Up", "down": "Down", "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "received": "Ricevuti", + "sent": "Inviati", + "externalIPAddress": "IP Esterno" }, "caddy": { "upstreams": "Upstream", @@ -270,7 +277,7 @@ "approved": "Approvati", "available": "Disponibili" }, - "pialert": { + "netalertx": { "total": "Totale", "connected": "Connesso", "new_devices": "Nuovi Dispositivi", @@ -404,8 +411,8 @@ "total": "Totale", "free": "Libero", "used": "In utilizzo", - "days": "d", - "hours": "h", + "days": "g", + "hours": "o", "crit": "Critico", "read": "Letti", "write": "Scrittura", @@ -419,7 +426,8 @@ "search": "Cerca", "custom": "Personalizzato", "visit": "Visita", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggerimenti" }, "wmo": { "0-day": "Soleggiato", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Canali", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Rete", + "signalStrength": "Intensitร ", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Passati", @@ -694,6 +710,11 @@ "targets_down": "Target Non Attivi", "targets_total": "Targets Totali" }, + "gatus": { + "up": "Siti On", + "down": "Siti Down", + "uptime": "Tempo di attivitร " + }, "ghostfolio": { "gross_percent_today": "Oggi", "gross_percent_1y": "Un anno", @@ -775,6 +796,14 @@ "passed": "Passati", "failed": "Fallito" }, + "openwrt": { + "uptime": "Tempo di attivitร ", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Ricevuti" + }, "uptimerobot": { "status": "Stato", "uptime": "Tempo di attivitร ", @@ -801,13 +830,63 @@ "totalRoms": "Total ROMs" }, "netdata": { - "warnings": "Warnings", + "warnings": "Avvisi", "criticals": "Criticals" }, "plantit": { - "events": "Eventi", - "plants": "Piante", - "species": "Specie", - "images": "Immagini" + "events": "Events", + "plants": "Plants", + "photos": "Foto", + "species": "Specie" + }, + "gitea": { + "notifications": "Notifiche", + "issues": "Problemi", + "pulls": "Richieste di Pull" + }, + "stash": { + "scenes": "Scene", + "scenesPlayed": "Scene Riprodotte", + "playCount": "Totale Riproduzioni", + "playDuration": "Tempo Guardato", + "sceneSize": "Dimensione Delle Scene", + "sceneDuration": "Durata Delle Scene", + "images": "Immagini", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Esecutori", + "studios": "Studi", + "movies": "Film", + "tags": "Tag", + "oCount": "O Count" + }, + "tandoor": { + "users": "Utenti", + "recipes": "Ricette", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Utenti", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Allarmi", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connesso", + "enabled": "Abilitato", + "disabled": "Disabilitati", + "total": "Totale" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/ja/common.json b/public/locales/ja/common.json index 9725e59b..80bb4506 100644 --- a/public/locales/ja/common.json +++ b/public/locales/ja/common.json @@ -14,11 +14,11 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", - "days": "d", - "hours": "h", - "minutes": "m", - "seconds": "s" + "months": "ๆœˆ", + "days": "ๆ—ฅ", + "hours": "ๆ™‚้–“", + "minutes": "ๅˆ†", + "seconds": "็ง’" }, "widget": { "missing_type": "่ฆ‹ใคใ‹ใ‚‰ใชใ„ใ‚ฆใ‚ฃใ‚ธใ‚งใƒƒใƒˆใ‚ฟใ‚คใƒ—: {{type}}", @@ -47,7 +47,7 @@ "load": "ใƒญใƒผใƒ‰", "temp": "ๆธฉๅบฆ", "max": "ๆœ€ๅคง", - "uptime": "ไธŠใธ" + "uptime": "UP" }, "unifi": { "users": "ใƒฆใƒผใ‚ถ", @@ -61,40 +61,40 @@ "wlan_devices": "WLAN ใƒ‡ใƒใ‚คใ‚น", "lan_users": "LAN ใƒฆใƒผใ‚ถ", "wlan_users": "WLAN ใƒฆใƒผใ‚ถ", - "up": "ไธŠใธ", + "up": "UP", "down": "ไธ‹ใธ", "wait": "ใŠๅพ…ใกใใ ใ•ใ„", - "empty_data": "ใ‚ตใƒ–ใ‚ทใ‚นใƒ†ใƒ ็Šถๆ…‹ใƒปไธๆ˜Ž" + "empty_data": "ใ‚ตใƒ–ใ‚ทใ‚นใƒ†ใƒ ใฎ็Šถๆ…‹ใฏไธๆ˜Ž" }, "docker": { - "rx": "RX", - "tx": "TX", + "rx": "ๅ—ไฟกๆธˆใฟ", + "tx": "้€ไฟกๆธˆใฟ", "mem": "MEM", "cpu": "CPU", "running": "่ตทๅ‹•ไธญ", "offline": "ใ‚ชใƒ•ใƒฉใ‚คใƒณ", "error": "ใ‚จใƒฉใƒผ", "unknown": "ไธๆ˜Ž", - "healthy": "ๅฅๅ…จ", + "healthy": "ๆญฃๅธธ", "starting": "่ตทๅ‹•ไธญ", "unhealthy": "้žๅฅๅ…จ", "not_found": "ไธๆ˜Ž", - "exited": "็ต‚ไบ†", + "exited": "ๅœๆญขใ—ใพใ—ใŸ", "partial": "้ƒจๅˆ†็š„" }, "ping": { "error": "ใ‚จใƒฉใƒผ", "ping": "Ping", "down": "ไธ‹ใธ", - "up": "ไธŠใธ", + "up": "็จผๅƒ", "not_available": "ๅˆฉ็”จใงใใพใ›ใ‚“ใ€‚" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "HTTP ใ‚นใƒ†ใƒผใ‚ฟใ‚น", "error": "ใ‚จใƒฉใƒผ", - "response": "Response", + "response": "ๅฟœ็ญ”", "down": "ไธ‹ใธ", - "up": "ไธŠใธ", + "up": "็จผๅƒ", "not_available": "ๅˆฉ็”จใงใใพใ›ใ‚“ใ€‚" }, "emby": { @@ -107,6 +107,13 @@ "episodes": "ใ‚จใƒ”ใ‚ฝใƒผใƒ‰", "songs": "ๆ›ฒ" }, + "esphome": { + "offline": "ใ‚ชใƒ•ใƒฉใ‚คใƒณ", + "offline_alt": "ใ‚ชใƒ•ใƒฉใ‚คใƒณ", + "online": "ใ‚ชใƒณใƒฉใ‚คใƒณ", + "total": "ๅˆ่จˆ", + "unknown": "ไธๆ˜Ž" + }, "evcc": { "pv_power": "็™บ้›ป้‡", "battery_soc": "ใƒใƒƒใƒ†ใƒชใƒผ", @@ -127,21 +134,21 @@ }, "fritzbox": { "connectionStatus": "็Šถๆ…‹", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", - "connectionStatusConnected": "ๆŽฅ็ถšๆธˆใฟ", + "connectionStatusUnconfigured": "ๆœช่จญๅฎš", + "connectionStatusConnecting": "ๆŽฅ็ถšไธญ", + "connectionStatusAuthenticating": "่ช่จผไธญ", + "connectionStatusPendingDisconnect": "ๆŽฅ็ถšใ‚’ๅˆ‡ๆ–ญใ™ใ‚‹", + "connectionStatusDisconnecting": "ๆŽฅ็ถšใ‚’ๅˆ‡ๆ–ญไธญ", + "connectionStatusDisconnected": "ๅˆ‡ๆ–ญใ•ใ‚Œใพใ—ใŸ", + "connectionStatusConnected": "ๆŽฅ็ถšๆธˆ", "uptime": "็จผๅƒๆ™‚้–“", - "maxDown": "Max. Down", - "maxUp": "Max. Up", + "maxDown": "ๆœ€ๅคงใƒ€ใ‚ฆใƒณ", + "maxUp": "ๆœ€ๅคงใ‚ขใƒƒใƒ—", "down": "ไธ‹ใธ", - "up": "ไธŠใธ", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "up": "็จผๅƒ", + "received": "ๅ—ไฟกๆธˆใฟ", + "sent": "้€ไฟกๆธˆใฟ", + "externalIPAddress": "้€€ๅ‡บID" }, "caddy": { "upstreams": "ใ‚ขใƒƒใƒ—ใ‚นใƒˆใƒชใƒผใƒ ", @@ -270,10 +277,10 @@ "approved": "ๆ‰ฟ่ชๆธˆ", "available": "ๅˆฉ็”จๅฏ" }, - "pialert": { + "netalertx": { "total": "ๅˆ่จˆ", - "connected": "ๆŽฅ็ถšๆธˆใฟ", - "new_devices": "ๆ–ฐใ—ใ„ใƒ‡ใƒใ‚คใ‚น", + "connected": "ๆŽฅ็ถšๆธˆ", + "new_devices": "ๆ–ฐ่ฆใƒ‡ใƒใ‚คใ‚น", "down_alerts": "ใƒ€ใ‚ฆใƒณใ‚ขใƒฉใƒผใƒˆ" }, "pihole": { @@ -400,12 +407,12 @@ "temp": "ๆธฉๅบฆ", "_temp": "ๆธฉๅบฆ", "warn": "่ญฆๅ‘Š", - "uptime": "ไธŠใธ", + "uptime": "UP", "total": "ๅˆ่จˆ", "free": "็ฉบใ", "used": "ไฝฟ็”จ", - "days": "d", - "hours": "h", + "days": "ๆ—ฅ", + "hours": "ๆ™‚้–“", "crit": "ใ‚ฏใƒชใƒ†ใ‚ฃใ‚ซใƒซ", "read": "ๆ—ข่ชญ", "write": "ๆ›ธใ่พผใฟ", @@ -419,7 +426,8 @@ "search": "ๆคœ็ดข", "custom": "ใ‚ซใ‚นใ‚ฟใƒ ", "visit": "่จชๅ•", - "url": "URL" + "url": "URL", + "searchsuggestion": "ๆๆกˆ" }, "wmo": { "0-day": "ๆ™ดใ‚Œ", @@ -486,13 +494,13 @@ "up_to_date": "ๆœ€ๆ–ฐ", "child_bridges": "ๅญใƒ–ใƒชใƒƒใ‚ธ", "child_bridges_status": "{{ok}}/{{total}}", - "up": "ไธŠใธ", + "up": "็จผๅƒ", "pending": "ไฟ็•™ไธญ", "down": "ไธ‹ใธ" }, "healthchecks": { "new": "ๆ–ฐ็€", - "up": "ไธŠใธ", + "up": "็จผๅƒ", "grace": "็ŒถไบˆๆœŸ้–“ไธญ", "down": "ไธ‹ใธ", "paused": "ไธ€ๆ™‚ๅœๆญขไธญ", @@ -523,7 +531,7 @@ "alerts": "ใ‚ขใƒฉใƒผใƒˆ" }, "pyload": { - "speed": "ใ‚นใƒ”ใƒผใƒ‰", + "speed": "้€Ÿๅบฆ", "active": "ใ‚ขใ‚ฏใƒ†ใ‚ฃใƒ–", "queue": "ใ‚ญใƒฅใƒผ", "total": "ๅˆ่จˆ" @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "ใƒใƒฃใƒณใƒใƒซ", - "hd": "HD" + "hd": "HD", + "tunerCount": "ใƒใƒฅใƒผใƒŠใƒผ", + "channelNumber": "ใƒใƒฃใƒณใƒใƒซ", + "channelNetwork": "ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏ", + "signalStrength": "ๅผทใ•", + "signalQuality": "ใ‚ฏใ‚ชใƒชใƒ†ใ‚ฃ", + "symbolQuality": "ใ‚ฏใ‚ชใƒชใƒ†ใ‚ฃ", + "networkRate": "ใƒ“ใƒƒใƒˆใƒฌใƒผใƒˆ", + "clientIP": "ใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆ IP" }, "scrutiny": { "passed": "ๅˆๆ ผ", @@ -547,12 +563,12 @@ "total": "ๅˆ่จˆ" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "battery_charge": "ใƒใƒƒใƒ†ใƒชใƒผๅ……้›ป", + "ups_load": "UPS ่ฒ ่ท", + "ups_status": "UPS ็Šถๆ…‹", "online": "ใ‚ชใƒณใƒฉใ‚คใƒณ", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "ใƒใƒƒใƒ†ใƒชใƒผ็จผๅƒไธญ", + "low_battery": "ใƒใƒƒใƒ†ใƒชใƒผๆฎ‹้‡ไฝŽไธ‹" }, "nextdns": { "wait": "ใŠๅพ…ใกใใ ใ•ใ„", @@ -560,7 +576,7 @@ }, "mikrotik": { "cpuLoad": "CPU่ฒ ่ท", - "memoryUsed": "ไฝฟ็”จๆธˆใฟใƒกใƒขใƒช", + "memoryUsed": "ใƒกใƒขใƒชไฝฟ็”จ้‡", "uptime": "็จผๅƒๆ™‚้–“", "numberOfLeases": "ใƒชใƒผใ‚น" }, @@ -601,7 +617,7 @@ "load": "่ชญใฟ่พผใฟๅนณๅ‡", "memory": "ใƒกใƒขใƒชไฝฟ็”จ้‡", "wanStatus": "WANใ‚นใƒ†ใƒผใ‚ฟใ‚น", - "up": "ไธŠใธ", + "up": "็จผๅƒ", "down": "ไธ‹ใธ", "temp": "ๆธฉๅบฆ", "disk": "ใƒ‡ใ‚ฃใ‚นใ‚ฏไฝฟ็”จ้‡", @@ -623,8 +639,8 @@ "up": "ใ‚ตใ‚คใƒˆUp", "down": "ใ‚ตใ‚คใƒˆDown", "uptime": "็จผๅƒๆ™‚้–“", - "incident": "ใ‚คใƒณใ‚ทใƒ‡ใƒณใƒˆ", - "m": "m" + "incident": "ไบ‹ไปถ", + "m": "ๅˆ†" }, "atsumeru": { "series": "ใ‚ทใƒชใƒผใ‚บ", @@ -694,6 +710,11 @@ "targets_down": "ใ‚ฟใƒผใ‚ฒใƒƒใƒˆ Down", "targets_total": "ใ‚ฟใƒผใ‚ฒใƒƒใƒˆๅˆ่จˆ" }, + "gatus": { + "up": "ใ‚ตใ‚คใƒˆUp", + "down": "ใ‚ตใ‚คใƒˆDown", + "uptime": "็จผๅƒๆ™‚้–“" + }, "ghostfolio": { "gross_percent_today": "ไปŠๆ—ฅ", "gross_percent_1y": "1ๅนด", @@ -724,7 +745,7 @@ "downloadCount": "ใ‚ญใƒฅใƒผ", "downloadBytesRemaining": "ๆฎ‹ใ‚Š", "downloadTotalBytes": "ใ‚ตใ‚คใ‚บ", - "downloadSpeed": "ใ‚นใƒ”ใƒผใƒ‰" + "downloadSpeed": "้€Ÿๅบฆ" }, "kavita": { "seriesCount": "ใ‚ทใƒชใƒผใ‚บ", @@ -775,16 +796,24 @@ "passed": "ๅˆๆ ผ", "failed": "ๅคฑๆ•—" }, + "openwrt": { + "uptime": "็จผๅƒๆ™‚้–“", + "cpuLoad": "CPU ๅนณๅ‡่ฒ ่ท๏ผˆ5 ๅˆ†๏ผ‰", + "up": "็จผๅƒ", + "down": "ไธ‹ใธ", + "bytesTx": "้€ไฟกๆธˆใฟ", + "bytesRx": "ๅ—ไฟกๆธˆใฟ" + }, "uptimerobot": { "status": "็Šถๆ…‹", "uptime": "็จผๅƒๆ™‚้–“", "lastDown": "ๆœ€ๅพŒใฎใƒ€ใ‚ฆใƒณใ‚ฟใ‚คใƒ ", - "downDuration": "ใƒ€ใ‚ฆใƒณใ‚ฟใ‚คใƒ ๆ„Ÿ่ฆš", + "downDuration": "ใƒ€ใ‚ฆใƒณใ‚ฟใ‚คใƒ ๆ™‚้–“", "sitesUp": "ใ‚ตใ‚คใƒˆUp", "sitesDown": "ใ‚ตใ‚คใƒˆDown", "paused": "ไธ€ๆ™‚ๅœๆญขไธญ", "notyetchecked": "ใƒใ‚งใƒƒใ‚ฏใ•ใ‚Œใฆใ„ใพใ›ใ‚“", - "up": "ไธŠใธ", + "up": "็จผๅƒ", "seemsdown": "ใƒ€ใ‚ฆใƒณใ—ใฆใ„ใ‚‹ใ‚ˆใ†ใงใ™", "down": "ไธ‹ใธ", "unknown": "ไธๆ˜Ž" @@ -793,15 +822,71 @@ "inCinemas": "ๆ˜ ็”ป้คจๅ†…", "physicalRelease": "็‰ฉ็†็š„ใชใƒชใƒชใƒผใ‚น", "digitalRelease": "ใƒ‡ใ‚ธใ‚ฟใƒซใƒปใƒชใƒชใƒผใ‚น", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "noEventsToday": "ๆœฌๆ—ฅใฎไบˆๅฎšใชใ—", + "noEventsFound": "ไบˆๅฎšใŒ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "ใƒ—ใƒฉใƒƒใƒˆใƒ•ใ‚ฉใƒผใƒ ", + "totalRoms": "ROMใฎๅˆ่จˆ" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "่ญฆๅ‘Š", + "criticals": "้‡ๅคง" + }, + "plantit": { + "events": "ใ‚คใƒ™ใƒณใƒˆ", + "plants": "ๆค็‰ฉ", + "photos": "ๅ†™็œŸ", + "species": "็จฎ" + }, + "gitea": { + "notifications": "้€š็Ÿฅ", + "issues": "่ชฒ้กŒ", + "pulls": "ใƒ—ใƒซใƒชใ‚ฏใ‚จใ‚นใƒˆ" + }, + "stash": { + "scenes": "ใ‚ทใƒผใƒณ", + "scenesPlayed": "ๅ†็”Ÿใ•ใ‚ŒใŸใ‚ทใƒผใƒณ", + "playCount": "ๅˆ่จˆๅ†็”Ÿๆ•ฐ", + "playDuration": "่ฆ–่ดๆ™‚้–“", + "sceneSize": "ใ‚ทใƒผใƒณใ‚ตใ‚คใ‚บ", + "sceneDuration": "ใ‚ทใƒผใƒณใฎ้•ทใ•", + "images": "็”ปๅƒ", + "imageSize": "็”ปๅƒใ‚ตใ‚คใ‚บ", + "galleries": "ใ‚ฎใƒฃใƒฉใƒชใƒผ", + "performers": "ๅ‡บๆผ”่€…", + "studios": "ใ‚นใ‚ฟใ‚ธใ‚ช", + "movies": "ๆ˜ ็”ป", + "tags": "ใ‚ฟใ‚ฐ", + "oCount": "O ใ‚ซใ‚ฆใƒณใƒˆ" + }, + "tandoor": { + "users": "ใƒฆใƒผใ‚ถ", + "recipes": "ใƒฌใ‚ทใƒ”", + "keywords": "ใ‚ญใƒผใƒฏใƒผใƒ‰" + }, + "homebox": { + "items": "ใ‚ขใ‚คใƒ†ใƒ ", + "totalWithWarranty": "ไฟ่จผไป˜ใ", + "locations": "ๅ ดๆ‰€", + "labels": "ใƒฉใƒ™ใƒซ", + "users": "ใƒฆใƒผใ‚ถ", + "totalValue": "ๅˆ่จˆๅ€ค" + }, + "crowdsec": { + "alerts": "ใ‚ขใƒฉใƒผใƒˆ", + "bans": "็ฆๆญข" + }, + "wgeasy": { + "connected": "ๆŽฅ็ถšๆธˆ", + "enabled": "ๆœ‰ๅŠน", + "disabled": "็„กๅŠน", + "total": "ๅˆ่จˆ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/ko/common.json b/public/locales/ko/common.json index 13961129..342d1e37 100644 --- a/public/locales/ko/common.json +++ b/public/locales/ko/common.json @@ -107,6 +107,13 @@ "episodes": "์—ํ”ผ์†Œ๋“œ", "songs": "์Œ์•…" }, + "esphome": { + "offline": "์ค‘์ง€", + "offline_alt": "์ค‘์ง€", + "online": "Online", + "total": "์ดํ•ฉ", + "unknown": "์•Œ ์ˆ˜ ์—†์Œ" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "์Šน์ธ๋จ", "available": "์ด์šฉ ๊ฐ€๋Šฅ" }, - "pialert": { + "netalertx": { "total": "์ดํ•ฉ", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "๋น„ํŠธ๋ ˆ์ดํŠธ", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "์ƒํƒœ", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "์˜ํ™”", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "์‚ฌ์šฉ์ž", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "์‚ฌ์šฉ์ž", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "๊ฒฝ๊ณ ", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "ํ™œ์„ฑ", + "disabled": "๋น„ํ™œ์„ฑ", + "total": "์ดํ•ฉ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/lv/common.json b/public/locales/lv/common.json index 1c35a7f2..e9b8b20a 100644 --- a/public/locales/lv/common.json +++ b/public/locales/lv/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "Bezsaistฤ“", + "offline_alt": "Bezsaistฤ“", + "online": "Online", + "total": "Kopฤ", + "unknown": "Nezinฤms" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Approved", "available": "Available" }, - "pialert": { + "netalertx": { "total": "Kopฤ", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Saulains", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Statuss", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Lietotฤji", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Lietotฤji", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Paziล†ojumi", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Enabled", + "disabled": "Disabled", + "total": "Kopฤ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/ms/common.json b/public/locales/ms/common.json index c62138cb..c05b7079 100644 --- a/public/locales/ms/common.json +++ b/public/locales/ms/common.json @@ -14,9 +14,9 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", - "days": "d", - "hours": "h", + "months": "bln", + "days": "h", + "hours": "j", "minutes": "m", "seconds": "s" }, @@ -45,9 +45,9 @@ "free": "Bebas", "used": "Telah diguna", "load": "Beban", - "temp": "TEMP", - "max": "Max", - "uptime": "UP" + "temp": "SUHU", + "max": "Tertinggi", + "uptime": "HIDUP" }, "unifi": { "users": "Pengguna", @@ -61,102 +61,109 @@ "wlan_devices": "Peranti WLAN", "lan_users": "Pengguna LAN", "wlan_users": "Pengguna WLAN", - "up": "UP", + "up": "HIDUP", "down": "MATI", "wait": "Sila tunggu", - "empty_data": "Subsystem status unknown" + "empty_data": "Status subsistem tak diketahui" }, "docker": { "rx": "RX", "tx": "TX", "mem": "MEM", "cpu": "CPU", - "running": "Running", + "running": "Sedang jalan", "offline": "Luar talian", "error": "Ralat", "unknown": "Tidak Diketahui", - "healthy": "Healthy", - "starting": "Starting", - "unhealthy": "Unhealthy", - "not_found": "Not Found", - "exited": "Exited", - "partial": "Partial" + "healthy": "Sihat", + "starting": "Bermula", + "unhealthy": "Kurang sihat", + "not_found": "Tidak dijumpai", + "exited": "Dimatikan", + "partial": "Sebahagian" }, "ping": { "error": "Ralat", "ping": "Ping", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "down": "Mati", + "up": "Hidup", + "not_available": "Tidak dijumpai" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "Status HTTP", "error": "Ralat", - "response": "Response", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "response": "Tindak balas", + "down": "Mati", + "up": "Hidup", + "not_available": "Tidak dijumpai" }, "emby": { "playing": "Sedang dimainkan", "transcoding": "Transkoding", "bitrate": "Kadar bit", "no_active": "Tiada Strim Aktif", - "movies": "Movies", - "series": "Series", - "episodes": "Episodes", - "songs": "Songs" + "movies": "Filem", + "series": "Siri", + "episodes": "Episod", + "songs": "Lagu" + }, + "esphome": { + "offline": "Luar talian", + "offline_alt": "Luar talian", + "online": "Dalam Talian", + "total": "Jumlah", + "unknown": "Tidak Diketahui" }, "evcc": { - "pv_power": "Production", - "battery_soc": "Battery", + "pv_power": "Produksi", + "battery_soc": "Bateri", "grid_power": "Grid", - "home_power": "Consumption", - "charge_power": "Charger", - "watt_hour": "Wh" + "home_power": "Penggunaan", + "charge_power": "Pengecas", + "watt_hour": "Wj" }, "flood": { - "download": "Download", - "upload": "Upload", + "download": "Muat turun", + "upload": "Muat naik", "leech": "Leech", "seed": "Seed" }, "freshrss": { - "subscriptions": "Subscriptions", - "unread": "Unread" + "subscriptions": "Langganan", + "unread": "Belum dibaca" }, "fritzbox": { "connectionStatus": "Status", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", + "connectionStatusUnconfigured": "Belum disuai", + "connectionStatusConnecting": "Menyambung", + "connectionStatusAuthenticating": "Pengesahan", + "connectionStatusPendingDisconnect": "Tunggu untuk Putus", + "connectionStatusDisconnecting": "Putuskan", + "connectionStatusDisconnected": "Sambungan Terputus", "connectionStatusConnected": "Connected", "uptime": "Masa Hidup", - "maxDown": "Max. Down", - "maxUp": "Max. Up", - "down": "Down", - "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "maxDown": "Mati Maksima", + "maxUp": "Hidup Maksima", + "down": "Mati", + "up": "Hidup", + "received": "Diterima", + "sent": "Telah dihantar", + "externalIPAddress": "IP Luaran" }, "caddy": { "upstreams": "Upstreams", - "requests": "Current requests", - "requests_failed": "Failed requests" + "requests": "Permintaan semasa", + "requests_failed": "Permintaan gagal" }, "changedetectionio": { "totalObserved": "Jumlah Diperhatikan", "diffsDetected": "Perbezaan Dikesan" }, "channelsdvrserver": { - "shows": "Shows", - "recordings": "Recordings", - "scheduled": "Scheduled", - "passes": "Passes" + "shows": "Papar", + "recordings": "Rakaman", + "scheduled": "Dijadualkan", + "passes": "Lulus" }, "tautulli": { "playing": "Sedang dimainkan", @@ -180,7 +187,7 @@ "plex": { "streams": "Strim Aktif", "albums": "Albums", - "movies": "Movies", + "movies": "Filem", "tv": "Rancangan TV" }, "sabnzbd": { @@ -190,18 +197,18 @@ }, "rutorrent": { "active": "Aktif", - "upload": "Upload", - "download": "Download" + "upload": "Muat naik", + "download": "Muat turun" }, "transmission": { - "download": "Download", - "upload": "Upload", + "download": "Muat turun", + "upload": "Muat naik", "leech": "Leech", "seed": "Seed" }, "qbittorrent": { - "download": "Download", - "upload": "Upload", + "download": "Muat turun", + "upload": "Muat naik", "leech": "Leech", "seed": "Seed" }, @@ -214,21 +221,21 @@ "invalid": "Invalid" }, "deluge": { - "download": "Download", - "upload": "Upload", + "download": "Muat turun", + "upload": "Muat naik", "leech": "Leech", "seed": "Seed" }, "downloadstation": { - "download": "Download", - "upload": "Upload", + "download": "Muat turun", + "upload": "Muat naik", "leech": "Leech", "seed": "Seed" }, "sonarr": { "wanted": "Mahu", "queued": "Dibaris Gilir", - "series": "Series", + "series": "Siri", "queue": "Barisan", "unknown": "Tidak Diketahui" }, @@ -236,7 +243,7 @@ "wanted": "Mahu", "missing": "Hilang", "queued": "Dibaris Gilir", - "movies": "Movies", + "movies": "Filem", "queue": "Barisan", "unknown": "Tidak Diketahui" }, @@ -270,7 +277,7 @@ "approved": "Lulus", "available": "Sudah Ada" }, - "pialert": { + "netalertx": { "total": "Jumlah", "connected": "Connected", "new_devices": "New Devices", @@ -289,12 +296,12 @@ "latency": "Kependaman" }, "speedtest": { - "upload": "Upload", - "download": "Download", + "upload": "Muat naik", + "download": "Muat turun", "ping": "Ping" }, "portainer": { - "running": "Running", + "running": "Sedang jalan", "stopped": "Terhenti", "total": "Jumlah" }, @@ -310,13 +317,13 @@ "hours": "{{number}}h", "minutes": "{{number}}m", "seconds": "{{number}}s", - "ago": "{{value}} Ago" + "ago": "{{value}} Lepas" }, "tdarr": { "queue": "Barisan", - "processed": "Processed", - "errored": "Errored", - "saved": "Saved" + "processed": "Sudah diprosess", + "errored": "Ralat", + "saved": "Simpan" }, "traefik": { "routers": "Router", @@ -353,7 +360,7 @@ }, "jackett": { "configured": "Telah Dikonfigurasi", - "errored": "Errored" + "errored": "Ralat" }, "strelaysrv": { "numActiveSessions": "Sesi", @@ -369,18 +376,18 @@ "medusa": { "wanted": "Mahu", "queued": "Dibaris Gilir", - "series": "Series" + "series": "Siri" }, "minecraft": { - "players": "Players", - "version": "Version", + "players": "Senarai pemain", + "version": "Versi", "status": "Status", - "up": "Online", + "up": "Dalam Talian", "down": "Luar talian" }, "miniflux": { - "read": "Read", - "unread": "Unread" + "read": "Baca", + "unread": "Belum dibaca" }, "authentik": { "users": "Pengguna", @@ -390,36 +397,37 @@ "proxmox": { "mem": "MEM", "cpu": "CPU", - "lxc": "LXC", + "lxc": "LCX", "vms": "Mesin Maya" }, "glances": { "cpu": "CPU", "load": "Beban", "wait": "Sila tunggu", - "temp": "TEMP", - "_temp": "Temp", - "warn": "Warn", - "uptime": "UP", + "temp": "SUHU", + "_temp": "Suhu", + "warn": "Amaran", + "uptime": "HIDUP", "total": "Jumlah", "free": "Bebas", "used": "Telah diguna", - "days": "d", - "hours": "h", - "crit": "Crit", - "read": "Read", - "write": "Write", + "days": "h", + "hours": "j", + "crit": "Krit", + "read": "Baca", + "write": "Tulis", "gpu": "GPU", "mem": "Mem", - "swap": "Swap" + "swap": "Penukaran" }, "quicklaunch": { "bookmark": "Tandabuku", "service": "Servis", - "search": "Search", - "custom": "Custom", - "visit": "Visit", - "url": "URL" + "search": "Carian", + "custom": "Khusus", + "visit": "Lawat", + "url": "URL", + "searchsuggestion": "Cadangan" }, "wmo": { "0-day": "Terik", @@ -486,19 +494,19 @@ "up_to_date": "Terkemaskini", "child_bridges": "Jambatan Anak", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Up", + "up": "Hidup", "pending": "Tertunda", - "down": "Down" + "down": "Mati" }, "healthchecks": { - "new": "New", - "up": "Up", - "grace": "In Grace Period", - "down": "Down", - "paused": "Paused", + "new": "Baharu", + "up": "Hidup", + "grace": "Tempoh Aman", + "down": "Mati", + "paused": "Tangguh", "status": "Status", - "last_ping": "Last Ping", - "never": "No pings yet" + "last_ping": "Ping terakhir", + "never": "Tiada ping" }, "watchtower": { "containers_scanned": "Terimbas", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Saluran", - "hd": "HD" + "hd": "HD", + "tunerCount": "Penala", + "channelNumber": "Saluran", + "channelNetwork": "Rangkaian", + "signalStrength": "Kekuatan", + "signalQuality": "Kualiti", + "symbolQuality": "Kualiti", + "networkRate": "Kadar bit", + "clientIP": "Klien" }, "scrutiny": { "passed": "Lulus", @@ -547,36 +563,36 @@ "total": "Jumlah" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", - "online": "Online", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "battery_charge": "Bateri dicas", + "ups_load": "Beban UPS", + "ups_status": "Status UPS", + "online": "Dalam Talian", + "on_battery": "Guna bateri", + "low_battery": "Bateri lemah" }, "nextdns": { "wait": "Sila tunggu", - "no_devices": "No Device Data Received" + "no_devices": "Tiada Data Diterima Peranti" }, "mikrotik": { - "cpuLoad": "CPU Load", - "memoryUsed": "Memory Used", + "cpuLoad": "Beban CPU", + "memoryUsed": "Penggunaan memori", "uptime": "Masa Hidup", - "numberOfLeases": "Leases" + "numberOfLeases": "Sewaan" }, "xteve": { - "streams_all": "All Streams", + "streams_all": "Semua Strim", "streams_active": "Strim Aktif", - "streams_xepg": "XEPG Channels" + "streams_xepg": "Saluran XEPG" }, "opendtu": { - "yieldDay": "Today", - "absolutePower": "Power", - "relativePower": "Power %", - "limit": "Limit" + "yieldDay": "Hari ini", + "absolutePower": "Kuasa", + "relativePower": "Kuasa %", + "limit": "Had/Batas" }, "opnsense": { - "cpu": "CPU Load", + "cpu": "Beban CPU", "memory": "Active Memory", "wanUpload": "WAN Upload", "wanDownload": "WAN Download" @@ -601,9 +617,9 @@ "load": "Load Avg", "memory": "Mem Usage", "wanStatus": "WAN Status", - "up": "Up", - "down": "Down", - "temp": "Temp", + "up": "Hidup", + "down": "Mati", + "temp": "Suhu", "disk": "Disk Usage", "wanIP": "WAN IP" }, @@ -627,14 +643,14 @@ "m": "m" }, "atsumeru": { - "series": "Series", + "series": "Siri", "archives": "Archives", "chapters": "Chapters", "categories": "Categories" }, "komga": { "libraries": "Libraries", - "series": "Series", + "series": "Siri", "books": "Buku" }, "diskstation": { @@ -643,7 +659,7 @@ "volumeAvailable": "Sudah Ada" }, "mylar": { - "series": "Series", + "series": "Siri", "issues": "Issues", "wanted": "Mahu" }, @@ -656,7 +672,7 @@ "fileflows": { "queue": "Barisan", "processing": "Processing", - "processed": "Processed", + "processed": "Sudah diprosess", "time": "Time" }, "grafana": { @@ -691,34 +707,39 @@ }, "prometheus": { "targets_up": "Targets Up", - "targets_down": "Targets Down", - "targets_total": "Total Targets" + "targets_down": "Sasaran Mati", + "targets_total": "Jumlah Sasaran" + }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Masa Hidup" }, "ghostfolio": { - "gross_percent_today": "Today", - "gross_percent_1y": "One year", - "gross_percent_max": "All time" + "gross_percent_today": "Hari ini", + "gross_percent_1y": "Satu tahun", + "gross_percent_max": "Sepanjang masa" }, "audiobookshelf": { - "podcasts": "Podcasts", + "podcasts": "Podkas", "books": "Buku", - "podcastsDuration": "Duration", - "booksDuration": "Duration" + "podcastsDuration": "Tempoh", + "booksDuration": "Tempoh" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Orang Dirumah", + "lights_on": "Hidupkan Lampu", + "switches_on": "Hidupkan Suis" }, "whatsupdocker": { - "monitoring": "Monitoring", + "monitoring": "Pemantauan", "updates": "Kemaskini" }, "calibreweb": { "books": "Buku", - "authors": "Authors", + "authors": "Pengarang/Penulis", "categories": "Categories", - "series": "Series" + "series": "Siri" }, "jdownloader": { "downloadCount": "Barisan", @@ -727,81 +748,145 @@ "downloadSpeed": "Kelajuan" }, "kavita": { - "seriesCount": "Series", + "seriesCount": "Siri", "totalFiles": "Files" }, "azuredevops": { - "result": "Result", + "result": "Keputusan", "status": "Status", - "buildId": "Build ID", - "succeeded": "Succeeded", - "notStarted": "Not Started", + "buildId": "ID Binaan", + "succeeded": "Berjaya", + "notStarted": "Belum Bermula", "failed": "Gagal", - "canceled": "Canceled", - "inProgress": "In Progress", - "totalPrs": "Total PRs", - "myPrs": "My PRs", + "canceled": "Dibatalkan", + "inProgress": "Sedang Diproses", + "totalPrs": "Jumlah PR", + "myPrs": "PR Sendiri", "approved": "Lulus" }, "gamedig": { "status": "Status", - "online": "Online", + "online": "Dalam Talian", "offline": "Luar talian", - "name": "Name", - "map": "Map", - "currentPlayers": "Current players", - "players": "Players", - "maxPlayers": "Max players", - "bots": "Bots", + "name": "Nama", + "map": "Peta", + "currentPlayers": "Pemain Semasa", + "players": "Senarai pemain", + "maxPlayers": "Bilangan peserta maksimum", + "bots": "Bot", "ping": "Ping" }, "urbackup": { "ok": "Ok", - "errored": "Errors", - "noRecent": "Out of Date", - "totalUsed": "Used Storage" + "errored": "Ralat", + "noRecent": "Luput tarikh", + "totalUsed": "Storan digunakan" }, "mealie": { - "recipes": "Recipes", + "recipes": "Resipi", "users": "Pengguna", "categories": "Categories", - "tags": "Tags" + "tags": "Tanda nama" }, "openmediavault": { - "downloading": "Downloading", + "downloading": "Sedang muat turun", "total": "Jumlah", - "running": "Running", + "running": "Sedang jalan", "stopped": "Terhenti", "passed": "Lulus", "failed": "Gagal" }, + "openwrt": { + "uptime": "Masa Hidup", + "cpuLoad": "Purata Beban CPU (5m)", + "up": "Hidup", + "down": "Mati", + "bytesTx": "Terpancar", + "bytesRx": "Diterima" + }, "uptimerobot": { "status": "Status", "uptime": "Masa Hidup", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", + "lastDown": "Masa Mati Terakhir", + "downDuration": "Jangkamasa Kematian", "sitesUp": "Sites Up", "sitesDown": "Sites Down", - "paused": "Paused", - "notyetchecked": "Not Yet Checked", - "up": "Up", - "seemsdown": "Seems Down", - "down": "Down", + "paused": "Tangguh", + "notyetchecked": "Belum Disemak", + "up": "Hidup", + "seemsdown": "Seperti Mati", + "down": "Mati", "unknown": "Tidak Diketahui" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", - "digitalRelease": "Digital release", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "inCinemas": "Di pawagam", + "physicalRelease": "Edaran fizikal", + "digitalRelease": "Edaran digital", + "noEventsToday": "Tiada agenda untuk hari ini!", + "noEventsFound": "Tiada agenda dijumpai" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platform", + "totalRoms": "Jumlah ROM" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Amaran", + "criticals": "Kritikal" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Filem", + "tags": "Tanda nama", + "oCount": "O Count" + }, + "tandoor": { + "users": "Pengguna", + "recipes": "Resipi", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Pengguna", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Didayakan", + "disabled": "Dinyahdayakan", + "total": "Jumlah" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json index c2fac214..6910c07a 100644 --- a/public/locales/nl/common.json +++ b/public/locales/nl/common.json @@ -107,6 +107,13 @@ "episodes": "Afleveringen", "songs": "Nummers" }, + "esphome": { + "offline": "Onbereikbaar", + "offline_alt": "Onbereikbaar", + "online": "Bereikbaar", + "total": "Totaal", + "unknown": "Onbekend" + }, "evcc": { "pv_power": "Productie", "battery_soc": "Batterij", @@ -270,7 +277,7 @@ "approved": "Goedgekeurd", "available": "Beschikbaar" }, - "pialert": { + "netalertx": { "total": "Totaal", "connected": "Verbonden", "new_devices": "Nieuwe Apparaten", @@ -419,7 +426,8 @@ "search": "Zoek", "custom": "Aangepast", "visit": "Bezoek", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestie" }, "wmo": { "0-day": "Zonnig", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanalen", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Kanaal", + "channelNetwork": "Netwerk", + "signalStrength": "Sterkte", + "signalQuality": "Kwaliteit", + "symbolQuality": "Kwaliteit", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Geslaagd", @@ -694,6 +710,11 @@ "targets_down": "Doelen onbereikbaar", "targets_total": "Totaal aantal doelen" }, + "gatus": { + "up": "Sites Bereikbaar", + "down": "Sites Onbereikbaar", + "uptime": "Online" + }, "ghostfolio": { "gross_percent_today": "Vandaag", "gross_percent_1y": "Een jaar", @@ -775,6 +796,14 @@ "passed": "Geslaagd", "failed": "Gefaald" }, + "openwrt": { + "uptime": "Online", + "cpuLoad": "CPU Load Gem. (5m)", + "up": "Online", + "down": "Offline", + "bytesTx": "Verzonden", + "bytesRx": "Ontvangen" + }, "uptimerobot": { "status": "Status", "uptime": "Online", @@ -797,11 +826,67 @@ "noEventsFound": "Geen gebeurtenissen gevonden" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platformen", + "totalRoms": "Totale ROM's" }, "netdata": { "warnings": "Waarschuwingen", "criticals": "Kritiek" + }, + "plantit": { + "events": "Gebeurtenissen", + "plants": "Planten", + "photos": "Foto's", + "species": "Soorten" + }, + "gitea": { + "notifications": "Notificaties", + "issues": "Problemen", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scรจnes", + "scenesPlayed": "Afgespeelde scรจnes", + "playCount": "Totaal aantal keer gespeeld", + "playDuration": "Tijd Bekeken", + "sceneSize": "Grootte Scรจnes", + "sceneDuration": "Duur scรจnes", + "images": "Afbeeldingen", + "imageSize": "Afbeeldingsgrootte", + "galleries": "Galerijen", + "performers": "Uitvoerenden", + "studios": "Studio's", + "movies": "Films", + "tags": "Label", + "oCount": "O Aantal" + }, + "tandoor": { + "users": "Gebruikers", + "recipes": "Recepten", + "keywords": "Trefwoorden" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "Met garantie", + "locations": "Locaties", + "labels": "Labels", + "users": "Gebruikers", + "totalValue": "Totale waarde" + }, + "crowdsec": { + "alerts": "Meldingen", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Verbonden", + "enabled": "Ingeschakeld", + "disabled": "Uitgeschakeld", + "total": "Totaal" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/no/common.json b/public/locales/no/common.json index ca628d3b..74f97249 100644 --- a/public/locales/no/common.json +++ b/public/locales/no/common.json @@ -14,296 +14,303 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", + "months": "mnd", "days": "d", - "hours": "h", + "hours": "t", "minutes": "m", "seconds": "s" }, "widget": { - "missing_type": "Missing Widget Type: {{type}}", - "api_error": "API Error", - "information": "Information", + "missing_type": "Manglende Widget Type: {{type}}", + "api_error": "API-feil", + "information": "Informasjon", "status": "Status", - "url": "URL", - "raw_error": "Raw Error", - "response_data": "Response Data" + "url": "Nettadresse", + "raw_error": "Rรฅ feil", + "response_data": "Responsdata" }, "weather": { - "current": "Current Location", - "allow": "Click to allow", - "updating": "Updating", - "wait": "Please wait" + "current": "Gjeldende posisjon", + "allow": "Trykk for รฅ tillate", + "updating": "Oppdaterer", + "wait": "Vennligst vent" }, "search": { - "placeholder": "Searchโ€ฆ" + "placeholder": "Sรธkโ€ฆ" }, "resources": { "cpu": "CPU", "mem": "MEM", - "total": "Total", - "free": "Free", - "used": "Used", - "load": "Load", + "total": "Totalt", + "free": "Ledig", + "used": "Brukt", + "load": "Last", "temp": "TEMP", - "max": "Max", - "uptime": "UP" + "max": "Maks", + "uptime": "OPP" }, "unifi": { - "users": "Users", - "uptime": "Uptime", - "days": "Days", + "users": "Brukere", + "uptime": "Oppetid", + "days": "Dager", "wan": "WAN", "lan": "LAN", "wlan": "WLAN", - "devices": "Devices", - "lan_devices": "LAN Devices", - "wlan_devices": "WLAN Devices", - "lan_users": "LAN Users", - "wlan_users": "WLAN Users", - "up": "UP", - "down": "DOWN", - "wait": "Please wait", - "empty_data": "Subsystem status unknown" + "devices": "Enheter", + "lan_devices": "LAN-enheter", + "wlan_devices": "WLAN-enheter", + "lan_users": "LAN Brukere", + "wlan_users": "WLAN Brukere", + "up": "OPP", + "down": "NEDE", + "wait": "Vennligst vent", + "empty_data": "Ukjent undersystemstatus" }, "docker": { "rx": "RX", "tx": "TX", "mem": "MEM", "cpu": "CPU", - "running": "Running", - "offline": "Offline", - "error": "Error", - "unknown": "Unknown", - "healthy": "Healthy", - "starting": "Starting", - "unhealthy": "Unhealthy", + "running": "Kjรธrer", + "offline": "Frakoblet", + "error": "Feil", + "unknown": "Ukjent", + "healthy": "Friskt", + "starting": "Starter", + "unhealthy": "Usunn", "not_found": "Not Found", "exited": "Exited", - "partial": "Partial" + "partial": "Delvis" }, "ping": { - "error": "Error", - "ping": "Ping", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "error": "Feil", + "ping": "Responstid", + "down": "Nede", + "up": "Oppe", + "not_available": "Ikke tilgjengelig" }, "siteMonitor": { "http_status": "HTTP status", - "error": "Error", - "response": "Response", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "error": "Feil", + "response": "Svar", + "down": "Nede", + "up": "Oppe", + "not_available": "Ikke tilgjengelig" }, "emby": { - "playing": "Playing", - "transcoding": "Transcoding", + "playing": "Spiller", + "transcoding": "Transkoding", "bitrate": "Bitrate", - "no_active": "No Active Streams", - "movies": "Movies", - "series": "Series", - "episodes": "Episodes", - "songs": "Songs" + "no_active": "Ingen aktive strรธmminger", + "movies": "Film", + "series": "Serie", + "episodes": "Episoder", + "songs": "Sanger" + }, + "esphome": { + "offline": "Frakoblet", + "offline_alt": "Frakoblet", + "online": "Pรฅ nett", + "total": "Totalt", + "unknown": "Ukjent" }, "evcc": { - "pv_power": "Production", - "battery_soc": "Battery", - "grid_power": "Grid", - "home_power": "Consumption", - "charge_power": "Charger", - "watt_hour": "Wh" + "pv_power": "Produksjon", + "battery_soc": "Batteri", + "grid_power": "Nett", + "home_power": "Forbruk", + "charge_power": "Lader", + "watt_hour": "W/t" }, "flood": { - "download": "Download", - "upload": "Upload", + "download": "Last ned", + "upload": "Opplastning", "leech": "Leech", "seed": "Seed" }, "freshrss": { - "subscriptions": "Subscriptions", - "unread": "Unread" + "subscriptions": "Abonnementer", + "unread": "Ulest" }, "fritzbox": { "connectionStatus": "Status", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", - "connectionStatusConnected": "Connected", - "uptime": "Uptime", - "maxDown": "Max. Down", - "maxUp": "Max. Up", - "down": "Down", - "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "connectionStatusUnconfigured": "Ikke konfigurert", + "connectionStatusConnecting": "Kobler til", + "connectionStatusAuthenticating": "Autentisering", + "connectionStatusPendingDisconnect": "Venter pรฅ frakobling", + "connectionStatusDisconnecting": "Kobler fra", + "connectionStatusDisconnected": "Frakoblet", + "connectionStatusConnected": "Tilkoblet", + "uptime": "Oppetid", + "maxDown": "Maks. Ned", + "maxUp": "Max. Opp", + "down": "Nede", + "up": "Oppe", + "received": "Mottatt", + "sent": "Sendt", + "externalIPAddress": "Ekstern IP" }, "caddy": { - "upstreams": "Upstreams", - "requests": "Current requests", - "requests_failed": "Failed requests" + "upstreams": "Oppstrรธms", + "requests": "Aktuelle forespรธrsler", + "requests_failed": "Mislykkede forespรธrsler" }, "changedetectionio": { - "totalObserved": "Total Observed", - "diffsDetected": "Diffs Detected" + "totalObserved": "Totalt sett", + "diffsDetected": "Diffs oppdaget" }, "channelsdvrserver": { "shows": "Shows", - "recordings": "Recordings", - "scheduled": "Scheduled", - "passes": "Passes" + "recordings": "Opptak", + "scheduled": "Tidsplan", + "passes": "Pasninger" }, "tautulli": { - "playing": "Playing", - "transcoding": "Transcoding", + "playing": "Spiller", + "transcoding": "Transkoding", "bitrate": "Bitrate", - "no_active": "No Active Streams", - "plex_connection_error": "Check Plex Connection" + "no_active": "Ingen aktive strรธmminger", + "plex_connection_error": "Kontroller Plex tilkoblingen" }, "omada": { - "connectedAp": "Connected APs", - "activeUser": "Active devices", - "alerts": "Alerts", - "connectedGateway": "Connected gateways", - "connectedSwitches": "Connected switches" + "connectedAp": "Tilkoblede AP'er", + "activeUser": "Aktive enheter", + "alerts": "Varsler", + "connectedGateway": "Tilkoblede gateways", + "connectedSwitches": "Tilkoblede switcher" }, "nzbget": { - "rate": "Rate", - "remaining": "Remaining", - "downloaded": "Downloaded" + "rate": "Ranger", + "remaining": "Gjenstรฅende", + "downloaded": "Nedlastede" }, "plex": { - "streams": "Active Streams", - "albums": "Albums", - "movies": "Movies", - "tv": "TV Shows" + "streams": "Aktive strรธmmninger", + "albums": "Album", + "movies": "Film", + "tv": "TV serier" }, "sabnzbd": { - "rate": "Rate", - "queue": "Queue", - "timeleft": "Time Left" + "rate": "Ranger", + "queue": "Kรธ", + "timeleft": "Gjenstรฅende tid" }, "rutorrent": { - "active": "Active", - "upload": "Upload", - "download": "Download" + "active": "Aktiv", + "upload": "Opplastning", + "download": "Last ned" }, "transmission": { - "download": "Download", - "upload": "Upload", + "download": "Last ned", + "upload": "Opplastning", "leech": "Leech", "seed": "Seed" }, "qbittorrent": { - "download": "Download", - "upload": "Upload", + "download": "Last ned", + "upload": "Opplastning", "leech": "Leech", "seed": "Seed" }, "qnap": { - "cpuUsage": "CPU Usage", - "memUsage": "MEM Usage", - "systemTempC": "System Temp", - "poolUsage": "Pool Usage", - "volumeUsage": "Volume Usage", - "invalid": "Invalid" + "cpuUsage": "CPU Bruk", + "memUsage": "Minnebruk", + "systemTempC": "System temp", + "poolUsage": "Pool Bruk", + "volumeUsage": "Volumbruk", + "invalid": "Ugyldig" }, "deluge": { - "download": "Download", - "upload": "Upload", + "download": "Last ned", + "upload": "Opplastning", "leech": "Leech", "seed": "Seed" }, "downloadstation": { - "download": "Download", - "upload": "Upload", + "download": "Last ned", + "upload": "Opplastning", "leech": "Leech", "seed": "Seed" }, "sonarr": { - "wanted": "Wanted", - "queued": "Queued", - "series": "Series", - "queue": "Queue", - "unknown": "Unknown" + "wanted": "ร˜nsket", + "queued": "Ventende", + "series": "Serie", + "queue": "Kรธ", + "unknown": "Ukjent" }, "radarr": { - "wanted": "Wanted", - "missing": "Missing", - "queued": "Queued", - "movies": "Movies", - "queue": "Queue", - "unknown": "Unknown" + "wanted": "ร˜nsket", + "missing": "Mangler", + "queued": "Ventende", + "movies": "Film", + "queue": "Kรธ", + "unknown": "Ukjent" }, "lidarr": { - "wanted": "Wanted", - "queued": "Queued", - "artists": "Artists" + "wanted": "ร˜nsket", + "queued": "Ventende", + "artists": "Artister" }, "readarr": { - "wanted": "Wanted", - "queued": "Queued", - "books": "Books" + "wanted": "ร˜nsket", + "queued": "Ventende", + "books": "Bรธker" }, "bazarr": { - "missingEpisodes": "Missing Episodes", - "missingMovies": "Missing Movies" + "missingEpisodes": "Manglende episoder", + "missingMovies": "Manglende filmer" }, "ombi": { - "pending": "Pending", - "approved": "Approved", - "available": "Available" + "pending": "Ventende", + "approved": "Godkjent", + "available": "Tilgjengelig" }, "jellyseerr": { - "pending": "Pending", - "approved": "Approved", - "available": "Available" + "pending": "Ventende", + "approved": "Godkjent", + "available": "Tilgjengelig" }, "overseerr": { - "pending": "Pending", - "processing": "Processing", - "approved": "Approved", - "available": "Available" + "pending": "Ventende", + "processing": "Behandler", + "approved": "Godkjent", + "available": "Tilgjengelig" }, - "pialert": { - "total": "Total", - "connected": "Connected", - "new_devices": "New Devices", + "netalertx": { + "total": "Totalt", + "connected": "Tilkoblet", + "new_devices": "Nye enheter", "down_alerts": "Down Alerts" }, "pihole": { - "queries": "Queries", - "blocked": "Blocked", - "blocked_percent": "Blocked %", - "gravity": "Gravity" + "queries": "Spรธrringer", + "blocked": "Blokkert", + "blocked_percent": "Blokkert %", + "gravity": "Gravitasjon" }, "adguard": { - "queries": "Queries", - "blocked": "Blocked", - "filtered": "Filtered", - "latency": "Latency" + "queries": "Spรธrringer", + "blocked": "Blokkert", + "filtered": "Filtrert", + "latency": "Responstid" }, "speedtest": { - "upload": "Upload", - "download": "Download", - "ping": "Ping" + "upload": "Opplastning", + "download": "Last ned", + "ping": "Responstid" }, "portainer": { - "running": "Running", - "stopped": "Stopped", - "total": "Total" + "running": "Kjรธrer", + "stopped": "Stoppet", + "total": "Totalt" }, "tailscale": { - "address": "Address", - "expires": "Expires", - "never": "Never", - "last_seen": "Last Seen", - "now": "Now", + "address": "Adresse", + "expires": "Utgรฅr", + "never": "Aldri", + "last_seen": "Sist sett", + "now": "Nรฅ", "years": "{{number}}y", "weeks": "{{number}}w", "days": "{{number}}d", @@ -313,79 +320,79 @@ "ago": "{{value}} Ago" }, "tdarr": { - "queue": "Queue", - "processed": "Processed", - "errored": "Errored", - "saved": "Saved" + "queue": "Kรธ", + "processed": "Behandlet", + "errored": "Feilet", + "saved": "Lagret" }, "traefik": { - "routers": "Routers", - "services": "Services", - "middleware": "Middleware" + "routers": "Rutere", + "services": "Tjenester", + "middleware": "Mellomvare" }, "navidrome": { - "nothing_streaming": "No Active Streams", - "please_wait": "Please Wait" + "nothing_streaming": "Ingen aktive strรธmminger", + "please_wait": "Vennligst vent" }, "npm": { - "enabled": "Enabled", - "disabled": "Disabled", - "total": "Total" + "enabled": "Aktivert", + "disabled": "Deaktivert", + "total": "Totalt" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track", - "1hour": "1 Hour", - "1day": "1 Day", - "7days": "7 Days", - "30days": "30 Days" + "configure": "Konfigurer รฉn eller flere krypteringsvalutaer som skal spores", + "1hour": "ร‰n time", + "1day": "ร‰n dag", + "7days": "7 dager", + "30days": "30 dager" }, "gotify": { - "apps": "Applications", - "clients": "Clients", - "messages": "Messages" + "apps": "Applikasjoner", + "clients": "Klienter", + "messages": "Meldinger" }, "prowlarr": { - "enableIndexers": "Indexers", - "numberOfGrabs": "Grabs", - "numberOfQueries": "Queries", - "numberOfFailGrabs": "Fail Grabs", - "numberOfFailQueries": "Fail Queries" + "enableIndexers": "Indeksere", + "numberOfGrabs": "Tatt", + "numberOfQueries": "Spรธrringer", + "numberOfFailGrabs": "Feil ved henting", + "numberOfFailQueries": "Spรธrring mislyktes" }, "jackett": { - "configured": "Configured", - "errored": "Errored" + "configured": "Konfigurert", + "errored": "Feilet" }, "strelaysrv": { - "numActiveSessions": "Sessions", - "numConnections": "Connections", - "dataRelayed": "Relayed", - "transferRate": "Rate" + "numActiveSessions": "Sesjoner", + "numConnections": "Tilkoblinger", + "dataRelayed": "Videresendt", + "transferRate": "Ranger" }, "mastodon": { - "user_count": "Users", - "status_count": "Posts", - "domain_count": "Domains" + "user_count": "Brukere", + "status_count": "Innlegg", + "domain_count": "Domener" }, "medusa": { - "wanted": "Wanted", - "queued": "Queued", - "series": "Series" + "wanted": "ร˜nsket", + "queued": "Ventende", + "series": "Serie" }, "minecraft": { - "players": "Players", - "version": "Version", + "players": "Spillere", + "version": "Versjon", "status": "Status", - "up": "Online", - "down": "Offline" + "up": "Pรฅ nett", + "down": "Frakoblet" }, "miniflux": { "read": "Read", - "unread": "Unread" + "unread": "Ulest" }, "authentik": { - "users": "Users", + "users": "Brukere", "loginsLast24H": "Logins (24h)", - "failedLoginsLast24H": "Failed Logins (24h)" + "failedLoginsLast24H": "Mislykket innlogginger (24t)" }, "proxmox": { "mem": "MEM", @@ -395,202 +402,211 @@ }, "glances": { "cpu": "CPU", - "load": "Load", - "wait": "Please wait", + "load": "Last", + "wait": "Vennligst vent", "temp": "TEMP", "_temp": "Temp", - "warn": "Warn", - "uptime": "UP", - "total": "Total", - "free": "Free", - "used": "Used", + "warn": "Advarsel", + "uptime": "OPP", + "total": "Totalt", + "free": "Ledig", + "used": "Brukt", "days": "d", - "hours": "h", + "hours": "t", "crit": "Crit", "read": "Read", - "write": "Write", + "write": "Skriv", "gpu": "GPU", "mem": "Mem", "swap": "Swap" }, "quicklaunch": { - "bookmark": "Bookmark", - "service": "Service", - "search": "Search", - "custom": "Custom", - "visit": "Visit", - "url": "URL" + "bookmark": "Bokmerke", + "service": "Tjeneste", + "search": "Sรธk", + "custom": "Egendefinert", + "visit": "Besรธk", + "url": "Nettadresse", + "searchsuggestion": "Forslag" }, "wmo": { - "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", - "95-night": "Thunderstorm", - "96-day": "Thunderstorm With Hail", - "96-night": "Thunderstorm With Hail", - "99-day": "Thunderstorm With Hail", - "99-night": "Thunderstorm With Hail" + "0-day": "Solfylt", + "0-night": "Klart", + "1-day": "Lettskyet", + "1-night": "Lettskyet", + "2-day": "Delvis skyet", + "2-night": "Delvis skyet", + "3-day": "Skyet", + "3-night": "Skyet", + "45-day": "Tรฅke", + "45-night": "Tรฅke", + "48-day": "Tรฅke", + "48-night": "Tรฅke", + "51-day": "Lett yr", + "51-night": "Lett yr", + "53-day": "Yr", + "53-night": "Yr", + "55-day": "Tungt Regn", + "55-night": "Tungt Regn", + "56-day": "Lett underkjรธlt regn", + "56-night": "Lett underkjรธlt regn", + "57-day": "Underkjรธlt Regn", + "57-night": "Underkjรธlt Regn", + "61-day": "Lett regn", + "61-night": "Lett regn", + "63-day": "Regn", + "63-night": "Regn", + "65-day": "Kraftig regn", + "65-night": "Kraftig regn", + "66-day": "Underkjรธlt regn", + "66-night": "Underkjรธlt regn", + "67-day": "Underkjรธlt regn", + "67-night": "Underkjรธlt regn", + "71-day": "Lett snรธvรฆr", + "71-night": "Lett snรธvรฆr", + "73-day": "Snรธ", + "73-night": "Snรธ", + "75-day": "Tett snรธ", + "75-night": "Tett snรธ", + "77-day": "Snรธkorn", + "77-night": "Snรธkorn", + "80-day": "Lette Regnbyger", + "80-night": "Lette Regnbyger", + "81-day": "Regnbyger", + "81-night": "Regnbyger", + "82-day": "Tunge regnbyger", + "82-night": "Tunge regnbyger", + "85-day": "Snรธbyger", + "85-night": "Snรธbyger", + "86-day": "Snรธbyger", + "86-night": "Snรธbyger", + "95-day": "Tordenbyger", + "95-night": "Tordenbyger", + "96-day": "Tordenvรฆr med hagl", + "96-night": "Tordenvรฆr med hagl", + "99-day": "Tordenvรฆr med hagl", + "99-night": "Tordenvรฆr med hagl" }, "homebridge": { "available_update": "System", - "updates": "Updates", - "update_available": "Update Available", - "up_to_date": "Up to Date", + "updates": "Oppdateringer", + "update_available": "Oppdatering tilgjengelig", + "up_to_date": "Oppdatert", "child_bridges": "Child Bridges", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Up", - "pending": "Pending", - "down": "Down" + "up": "Oppe", + "pending": "Ventende", + "down": "Nede" }, "healthchecks": { - "new": "New", - "up": "Up", - "grace": "In Grace Period", - "down": "Down", - "paused": "Paused", + "new": "Ny", + "up": "Oppe", + "grace": "I rammeperiode", + "down": "Nede", + "paused": "Pauset", "status": "Status", - "last_ping": "Last Ping", - "never": "No pings yet" + "last_ping": "Siste Ping", + "never": "Ingen ping ennรฅ" }, "watchtower": { - "containers_scanned": "Scanned", - "containers_updated": "Updated", - "containers_failed": "Failed" + "containers_scanned": "Skannet", + "containers_updated": "Oppdatert", + "containers_failed": "Mislyktes" }, "autobrr": { - "approvedPushes": "Approved", - "rejectedPushes": "Rejected", - "filters": "Filters", - "indexers": "Indexers" + "approvedPushes": "Godkjent", + "rejectedPushes": "Avvist", + "filters": "Filtre", + "indexers": "Indeksere" }, "tubearchivist": { - "downloads": "Queue", - "videos": "Videos", - "channels": "Channels", - "playlists": "Playlists" + "downloads": "Kรธ", + "videos": "Videoer", + "channels": "Kanal", + "playlists": "Spillelister" }, "truenas": { - "load": "System Load", - "uptime": "Uptime", - "alerts": "Alerts" + "load": "Last pรฅ systemet", + "uptime": "Oppetid", + "alerts": "Varsler" }, "pyload": { - "speed": "Speed", - "active": "Active", - "queue": "Queue", - "total": "Total" + "speed": "Hastighet", + "active": "Aktiv", + "queue": "Kรธ", + "total": "Totalt" }, "gluetun": { - "public_ip": "Public IP", + "public_ip": "Offentlig IP", "region": "Region", - "country": "Country" + "country": "Land" }, "hdhomerun": { - "channels": "Channels", - "hd": "HD" + "channels": "Kanal", + "hd": "HD", + "tunerCount": "Tunere", + "channelNumber": "Kanal", + "channelNetwork": "Nettverk", + "signalStrength": "Styrke", + "signalQuality": "Kvalitet", + "symbolQuality": "Kvalitet", + "networkRate": "Bitrate", + "clientIP": "Klient" }, "scrutiny": { - "passed": "Passed", - "failed": "Failed", - "unknown": "Unknown" + "passed": "Bestรฅtt", + "failed": "Mislyktes", + "unknown": "Ukjent" }, "paperlessngx": { - "inbox": "Inbox", - "total": "Total" + "inbox": "Innboks", + "total": "Totalt" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", - "online": "Online", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "battery_charge": "Batteriladning", + "ups_load": "UPS last", + "ups_status": "UPS status", + "online": "Pรฅ nett", + "on_battery": "Pรฅ batteri", + "low_battery": "Lavt batterinivรฅ" }, "nextdns": { - "wait": "Please Wait", - "no_devices": "No Device Data Received" + "wait": "Vennligst vent", + "no_devices": "Ingen enhetsdata mottatt" }, "mikrotik": { - "cpuLoad": "CPU Load", - "memoryUsed": "Memory Used", - "uptime": "Uptime", + "cpuLoad": "Prosessorbelastning", + "memoryUsed": "Minne brukt", + "uptime": "Oppetid", "numberOfLeases": "Leases" }, "xteve": { - "streams_all": "All Streams", - "streams_active": "Active Streams", - "streams_xepg": "XEPG Channels" + "streams_all": "Alle strรธmminger", + "streams_active": "Aktive strรธmmninger", + "streams_xepg": "XEPG Kanaler" }, "opendtu": { - "yieldDay": "Today", - "absolutePower": "Power", - "relativePower": "Power %", - "limit": "Limit" + "yieldDay": "Idag", + "absolutePower": "Effekt", + "relativePower": "Effekt %", + "limit": "Grense" }, "opnsense": { - "cpu": "CPU Load", - "memory": "Active Memory", - "wanUpload": "WAN Upload", - "wanDownload": "WAN Download" + "cpu": "Prosessorbelastning", + "memory": "Aktiv minne", + "wanUpload": "WAN Opplasting", + "wanDownload": "WAN Nedlasting" }, "moonraker": { - "printer_state": "Printer State", + "printer_state": "Skriver tilstand", "print_status": "Print Status", - "print_progress": "Progress", - "layers": "Layers" + "print_progress": "Progresjon", + "layers": "Lag" }, "octoprint": { "printer_state": "Status", - "temp_tool": "Tool temp", - "temp_bed": "Bed temp", + "temp_tool": "Verktรธy temperatur", + "temp_bed": "Seng temperatur", "job_completion": "Completion" }, "cloudflared": { @@ -601,8 +617,8 @@ "load": "Load Avg", "memory": "Mem Usage", "wanStatus": "WAN Status", - "up": "Up", - "down": "Down", + "up": "Oppe", + "down": "Nede", "temp": "Temp", "disk": "Disk Usage", "wanIP": "WAN IP" @@ -614,49 +630,49 @@ "memory_usage": "Memory" }, "immich": { - "users": "Users", + "users": "Brukere", "photos": "Photos", - "videos": "Videos", - "storage": "Storage" + "videos": "Videoer", + "storage": "Lagring" }, "uptimekuma": { - "up": "Sites Up", + "up": "Nettsteder opp", "down": "Sites Down", - "uptime": "Uptime", + "uptime": "Oppetid", "incident": "Incident", "m": "m" }, "atsumeru": { - "series": "Series", + "series": "Serie", "archives": "Archives", "chapters": "Chapters", "categories": "Categories" }, "komga": { "libraries": "Libraries", - "series": "Series", - "books": "Books" + "series": "Serie", + "books": "Bรธker" }, "diskstation": { - "days": "Days", - "uptime": "Uptime", - "volumeAvailable": "Available" + "days": "Dager", + "uptime": "Oppetid", + "volumeAvailable": "Tilgjengelig" }, "mylar": { - "series": "Series", + "series": "Serie", "issues": "Issues", - "wanted": "Wanted" + "wanted": "ร˜nsket" }, "photoprism": { - "albums": "Albums", + "albums": "Album", "photos": "Photos", - "videos": "Videos", + "videos": "Videoer", "people": "People" }, "fileflows": { - "queue": "Queue", - "processing": "Processing", - "processed": "Processed", + "queue": "Kรธ", + "processing": "Behandler", + "processed": "Behandlet", "time": "Time" }, "grafana": { @@ -678,130 +694,199 @@ "size": "Size", "lastrun": "Last Run", "nextrun": "Next Run", - "failed": "Failed" + "failed": "Mislyktes" }, "unmanic": { "active_workers": "Active Workers", - "total_workers": "Total Workers", - "records_total": "Queue Length" + "total_workers": "Totalt antall Arbeidere", + "records_total": "Kรธ lengde" }, "pterodactyl": { - "servers": "Servers", - "nodes": "Nodes" + "servers": "Servere", + "nodes": "Noder" }, "prometheus": { - "targets_up": "Targets Up", - "targets_down": "Targets Down", - "targets_total": "Total Targets" + "targets_up": "Mรฅl oppe", + "targets_down": "Mรฅl nede", + "targets_total": "Totalt antall mรฅl" + }, + "gatus": { + "up": "Nettsteder opp", + "down": "Sites Down", + "uptime": "Oppetid" }, "ghostfolio": { - "gross_percent_today": "Today", - "gross_percent_1y": "One year", - "gross_percent_max": "All time" + "gross_percent_today": "Idag", + "gross_percent_1y": "Ett รฅr", + "gross_percent_max": "Gjennom tidene" }, "audiobookshelf": { - "podcasts": "Podcasts", - "books": "Books", - "podcastsDuration": "Duration", - "booksDuration": "Duration" + "podcasts": "Podkaster", + "books": "Bรธker", + "podcastsDuration": "Varighet", + "booksDuration": "Varighet" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Personer hjemme", + "lights_on": "Lys pรฅ", + "switches_on": "Slรฅr Pรฅ" }, "whatsupdocker": { - "monitoring": "Monitoring", - "updates": "Updates" + "monitoring": "Overvรฅker", + "updates": "Oppdateringer" }, "calibreweb": { - "books": "Books", - "authors": "Authors", + "books": "Bรธker", + "authors": "Forfattere", "categories": "Categories", - "series": "Series" + "series": "Serie" }, "jdownloader": { - "downloadCount": "Queue", - "downloadBytesRemaining": "Remaining", + "downloadCount": "Kรธ", + "downloadBytesRemaining": "Gjenstรฅende", "downloadTotalBytes": "Size", - "downloadSpeed": "Speed" + "downloadSpeed": "Hastighet" }, "kavita": { - "seriesCount": "Series", + "seriesCount": "Serie", "totalFiles": "Files" }, "azuredevops": { - "result": "Result", + "result": "Resultat", "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" + "buildId": "Produksjons ID", + "succeeded": "Vellykket", + "notStarted": "Ikke startet", + "failed": "Mislyktes", + "canceled": "Avbrutt", + "inProgress": "Pรฅgรฅende", + "totalPrs": "Totalt PR-er", + "myPrs": "Mine PR'er", + "approved": "Godkjent" }, "gamedig": { "status": "Status", - "online": "Online", - "offline": "Offline", - "name": "Name", - "map": "Map", - "currentPlayers": "Current players", - "players": "Players", - "maxPlayers": "Max players", + "online": "Pรฅ nett", + "offline": "Frakoblet", + "name": "Navn", + "map": "Kart", + "currentPlayers": "Aktuelle spillere", + "players": "Spillere", + "maxPlayers": "Maks spillere", "bots": "Bots", - "ping": "Ping" + "ping": "Responstid" }, "urbackup": { "ok": "Ok", - "errored": "Errors", - "noRecent": "Out of Date", - "totalUsed": "Used Storage" + "errored": "Feil", + "noRecent": "Utdatert", + "totalUsed": "Brukt lagringsplass" }, "mealie": { - "recipes": "Recipes", - "users": "Users", + "recipes": "Oppskrifter", + "users": "Brukere", "categories": "Categories", - "tags": "Tags" + "tags": "Stikkord" }, "openmediavault": { - "downloading": "Downloading", - "total": "Total", - "running": "Running", - "stopped": "Stopped", - "passed": "Passed", - "failed": "Failed" + "downloading": "Nedlaster", + "total": "Totalt", + "running": "Kjรธrer", + "stopped": "Stoppet", + "passed": "Bestรฅtt", + "failed": "Mislyktes" + }, + "openwrt": { + "uptime": "Oppetid", + "cpuLoad": "CPU-belastning snitt (5m)", + "up": "Oppe", + "down": "Nede", + "bytesTx": "Sendt", + "bytesRx": "Mottatt" }, "uptimerobot": { "status": "Status", - "uptime": "Uptime", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", - "sitesUp": "Sites Up", + "uptime": "Oppetid", + "lastDown": "Siste nedetid", + "downDuration": "Varighet pรฅ nedetid", + "sitesUp": "Nettsteder opp", "sitesDown": "Sites Down", - "paused": "Paused", - "notyetchecked": "Not Yet Checked", - "up": "Up", - "seemsdown": "Seems Down", - "down": "Down", - "unknown": "Unknown" + "paused": "Pauset", + "notyetchecked": "Ikke sjekket enda", + "up": "Oppe", + "seemsdown": "Virker nede", + "down": "Nede", + "unknown": "Ukjent" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", - "digitalRelease": "Digital release", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "inCinemas": "Pรฅ Kino", + "physicalRelease": "Fysisk utslipp", + "digitalRelease": "Digital utgivelse", + "noEventsToday": "Ingen hendelser for i dag!", + "noEventsFound": "Ingen hendelser funnet" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Plattformer", + "totalRoms": "Totale ROM-er" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Advarsler", + "criticals": "Kritiske" + }, + "plantit": { + "events": "Begivenheter", + "plants": "Planter", + "photos": "Photos", + "species": "Arter" + }, + "gitea": { + "notifications": "Varslinger", + "issues": "Issues", + "pulls": "Forespรธrsel" + }, + "stash": { + "scenes": "Scener", + "scenesPlayed": "Scener avspilt", + "playCount": "Totalt Spillt", + "playDuration": "Tid Sett", + "sceneSize": "Scenesstรธrrelse", + "sceneDuration": "Scener Varighet", + "images": "Bilder", + "imageSize": "Bildestรธrrelse", + "galleries": "Gallerier", + "performers": "Utรธvere", + "studios": "Studios", + "movies": "Film", + "tags": "Stikkord", + "oCount": "O antall" + }, + "tandoor": { + "users": "Brukere", + "recipes": "Oppskrifter", + "keywords": "Nรธkkelord" + }, + "homebox": { + "items": "Enheter", + "totalWithWarranty": "Med garanti", + "locations": "Posisjon", + "labels": "Etiketter", + "users": "Brukere", + "totalValue": "Totalverdi" + }, + "crowdsec": { + "alerts": "Varsler", + "bans": "Utestengelse" + }, + "wgeasy": { + "connected": "Tilkoblet", + "enabled": "Aktivert", + "disabled": "Deaktivert", + "total": "Totalt" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/pl/common.json b/public/locales/pl/common.json index f6e6dca4..eddd0a5a 100644 --- a/public/locales/pl/common.json +++ b/public/locales/pl/common.json @@ -14,9 +14,9 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", + "months": "mc", "days": "d", - "hours": "h", + "hours": "g", "minutes": "m", "seconds": "s" }, @@ -40,7 +40,7 @@ }, "resources": { "cpu": "Procesor", - "mem": "PAM", + "mem": "RAM", "total": "Caล‚kowite", "free": "Wolne", "used": "Uลผyte", @@ -53,9 +53,9 @@ "users": "Uลผytkownicy", "uptime": "Czas dziaล‚ania", "days": "Dni", - "wan": "Sieฤ‡ WAN", - "lan": "Sieฤ‡ LAN", - "wlan": "Sieฤ‡ WLAN", + "wan": "WAN", + "lan": "LAN", + "wlan": "WLAN", "devices": "Urzฤ…dzenia", "lan_devices": "Urzฤ…dzenia LAN", "wlan_devices": "Urzฤ…dzenia WLAN", @@ -64,23 +64,23 @@ "up": "CZAS", "down": "Pobieranie", "wait": "Proszฤ™ czekaฤ‡", - "empty_data": "Nieznany stan" + "empty_data": "Status podsystemu nieznany" }, "docker": { "rx": "Rx", "tx": "Tx", - "mem": "PAM", + "mem": "RAM", "cpu": "Procesor", "running": "Dziaล‚a", "offline": "Nieosiฤ…galny", "error": "Bล‚ฤ…d", "unknown": "Nieznany", "healthy": "Zdrowy", - "starting": "Rozpoczynanie", - "unhealthy": "Niezdrowe", + "starting": "Uruchamianie", + "unhealthy": "Niezdrowy", "not_found": "Nie znaleziono", - "exited": "Zakoล„czone", - "partial": "Czฤ™ล›ciowe" + "exited": "Zakoล„czony", + "partial": "Czฤ™ล›ciowy" }, "ping": { "error": "Bล‚ฤ…d", @@ -107,6 +107,13 @@ "episodes": "Odcinki", "songs": "Piosenki" }, + "esphome": { + "offline": "Nieosiฤ…galny", + "offline_alt": "Nieosiฤ…galny", + "online": "Dostฤ™pny", + "total": "Caล‚kowite", + "unknown": "Nieznany" + }, "evcc": { "pv_power": "Produkcja", "battery_soc": "Bateria", @@ -130,18 +137,18 @@ "connectionStatusUnconfigured": "Nieskonfigurowane", "connectionStatusConnecting": "ลฤ…czenie", "connectionStatusAuthenticating": "Uwierzytelnianie", - "connectionStatusPendingDisconnect": "Pending Disconnect", + "connectionStatusPendingDisconnect": "Oczekujฤ…ce rozล‚ฤ…czenie", "connectionStatusDisconnecting": "Rozล‚ฤ…czanie", "connectionStatusDisconnected": "Rozล‚ฤ…czono", - "connectionStatusConnected": "Poล‚ฤ…czony", + "connectionStatusConnected": "Connected", "uptime": "Czas dziaล‚ania", - "maxDown": "Max. Down", - "maxUp": "Max. Up", + "maxDown": "Maks. Pobieranie", + "maxUp": "Maks. Wysyล‚anie", "down": "Niedostฤ™pny", "up": "Dostฤ™pny", "received": "Odebrane", "sent": "Wysล‚ane", - "externalIPAddress": "Ext. IP" + "externalIPAddress": "Pub. IP" }, "caddy": { "upstreams": "Upstreams", @@ -149,12 +156,12 @@ "requests_failed": "Nieudane zapytania" }, "changedetectionio": { - "totalObserved": "Obserwowanych ogรณล‚em", - "diffsDetected": "Wykryto rรณลผnic" + "totalObserved": "ลฤ…cznie obserwowanych", + "diffsDetected": "Wykrytych rรณลผnic" }, "channelsdvrserver": { "shows": "Seriale", - "recordings": "Nagrywanie", + "recordings": "Nagrania", "scheduled": "W kolejce", "passes": "Przebiegi" }, @@ -270,11 +277,11 @@ "approved": "Zaakceptowane", "available": "Dostฤ™pne" }, - "pialert": { + "netalertx": { "total": "Caล‚kowite", - "connected": "Poล‚ฤ…czony", - "new_devices": "Nowe urzฤ…dzenia", - "down_alerts": "Powiadomienia o niedostฤ™pnoล›ci" + "connected": "Connected", + "new_devices": "New Devices", + "down_alerts": "Down Alerts" }, "pihole": { "queries": "Zapytania", @@ -388,7 +395,7 @@ "failedLoginsLast24H": "Nieudane logowania (24h)" }, "proxmox": { - "mem": "PAM", + "mem": "RAM", "cpu": "Procesor", "lxc": "Kontenery LXC", "vms": "Maszyn wirtualnych" @@ -405,8 +412,8 @@ "free": "Wolne", "used": "Uลผyte", "days": "d", - "hours": "h", - "crit": "Crit", + "hours": "g", + "crit": "Krytyczyny", "read": "Przeczytane", "write": "Zapis", "gpu": "Karta graficzna", @@ -419,7 +426,8 @@ "search": "Wyszukaj", "custom": "Niestandardowe", "visit": "Odwiedลบ", - "url": "Adres URL" + "url": "Adres URL", + "searchsuggestion": "Sugestia" }, "wmo": { "0-day": "Sล‚oneczny", @@ -484,7 +492,7 @@ "updates": "Aktualizacje", "update_available": "Dostฤ™pna aktualizacja", "up_to_date": "Aktualny", - "child_bridges": "Child Bridges", + "child_bridges": "Mostki podrzฤ™dne", "child_bridges_status": "{{ok}}/{{total}}", "up": "Dostฤ™pny", "pending": "Oczekiwane", @@ -493,12 +501,12 @@ "healthchecks": { "new": "Nowy", "up": "Dostฤ™pny", - "grace": "In Grace Period", + "grace": "W okresie karencji", "down": "Niedostฤ™pny", "paused": "Zatrzymane", "status": "Stan", "last_ping": "Ostatni ping", - "never": "No pings yet" + "never": "Brak pingรณw" }, "watchtower": { "containers_scanned": "Zeskanowane", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanaล‚y", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tunery", + "channelNumber": "Kanaล‚", + "channelNetwork": "Sieฤ‡", + "signalStrength": "Siล‚a", + "signalQuality": "Jakoล›ฤ‡", + "symbolQuality": "Jakoล›ฤ‡", + "networkRate": "Bitrate", + "clientIP": "Klient" }, "scrutiny": { "passed": "Powodzenie", @@ -547,12 +563,12 @@ "total": "Caล‚kowite" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "battery_charge": "Stan baterii", + "ups_load": "Obciฤ…ลผenie UPS", + "ups_status": "Status UPS", "online": "Dostฤ™pny", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "Na baterii", + "low_battery": "Niski poziom baterii" }, "nextdns": { "wait": "Proszฤ™ czekaฤ‡", @@ -560,7 +576,7 @@ }, "mikrotik": { "cpuLoad": "Obciฤ…ลผenie procesora", - "memoryUsed": "Zuyลผyta pamiฤ™ฤ‡", + "memoryUsed": "Zuลผyta pamiฤ™ฤ‡", "uptime": "Czas dziaล‚ania", "numberOfLeases": "Dzierลผawy" }, @@ -571,8 +587,8 @@ }, "opendtu": { "yieldDay": "Dzisiaj", - "absolutePower": "Power", - "relativePower": "Power %", + "absolutePower": "Zasilanie", + "relativePower": "Moc %", "limit": "Limit" }, "opnsense": { @@ -589,16 +605,16 @@ }, "octoprint": { "printer_state": "Stan", - "temp_tool": "Tool temp", - "temp_bed": "Bed temp", + "temp_tool": "Temperatura narzฤ™dzia", + "temp_bed": "Temp. ล‚รณลผka", "job_completion": "Ukoล„czono" }, "cloudflared": { - "origin_ip": "Origin IP", + "origin_ip": "IP ลนrรณdล‚a", "status": "Stan" }, "pfsense": { - "load": "Load Avg", + "load": "ลšr. Obciฤ…ลผenie", "memory": "Uลผycie pamiฤ™ci", "wanStatus": "Status WAN", "up": "Dostฤ™pny", @@ -608,8 +624,8 @@ "wanIP": "WAN IP" }, "proxmoxbackupserver": { - "datastore_usage": "Datastore", - "failed_tasks_24h": "Failed Tasks 24h", + "datastore_usage": "Magazyn danych", + "failed_tasks_24h": "Nieudane zadania 24h", "cpu_usage": "Procesor", "memory_usage": "Pamiฤ™ฤ‡" }, @@ -662,8 +678,8 @@ "grafana": { "dashboards": "Panel gล‚รณwny", "datasources": "ลนrรณdล‚a danych", - "totalalerts": "Total Alerts", - "alertstriggered": "Alerts Triggered" + "totalalerts": "Wszystkie alerty", + "alertstriggered": "Wywoล‚ane alerty" }, "nextcloud": { "cpuload": "Obciฤ…ลผenie CPU", @@ -671,7 +687,7 @@ "freespace": "Wolna przestrzeล„", "activeusers": "Aktywni uลผytkownicy", "numfiles": "Pliki", - "numshares": "Shared Items" + "numshares": "Udostฤ™pnione elementy" }, "kopia": { "status": "Stan", @@ -682,7 +698,7 @@ }, "unmanic": { "active_workers": "Aktywni pracownicy", - "total_workers": "Total Workers", + "total_workers": "Wszyscy pracownicy", "records_total": "Dล‚ugoล›ฤ‡ kolejki" }, "pterodactyl": { @@ -690,9 +706,14 @@ "nodes": "Wฤ™zล‚y" }, "prometheus": { - "targets_up": "Targets Up", - "targets_down": "Targets Down", - "targets_total": "Total Targets" + "targets_up": "Cele wล‚ฤ…czone", + "targets_down": "Cele wyล‚ฤ…czone", + "targets_total": "Wszystkich Celi" + }, + "gatus": { + "up": "Dziaล‚ajฤ…ce", + "down": "Niedziaล‚ajฤ…ce", + "uptime": "Czas dziaล‚ania" }, "ghostfolio": { "gross_percent_today": "Dzisiaj", @@ -706,9 +727,9 @@ "booksDuration": "Czas trwania" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Dom ludzi", + "lights_on": "ลšwiatล‚a wล‚ฤ…czone", + "switches_on": "Przeล‚ฤ…czniki wล‚ฤ…czone" }, "whatsupdocker": { "monitoring": "Monitoring", @@ -735,12 +756,12 @@ "status": "Stan", "buildId": "ID kompilacji", "succeeded": "Ukoล„czono", - "notStarted": "Not Started", + "notStarted": "Nierozpoczฤ™te", "failed": "Niepowodzenie", "canceled": "Anulowano", "inProgress": "W trakcie", - "totalPrs": "Total PRs", - "myPrs": "My PRs", + "totalPrs": "ลฤ…cznie PRs", + "myPrs": "Moje PRs", "approved": "Zaakceptowane" }, "gamedig": { @@ -749,7 +770,7 @@ "offline": "Nieosiฤ…galny", "name": "Nazwa", "map": "Mapa", - "currentPlayers": "Current players", + "currentPlayers": "Gracze online", "players": "Gracze", "maxPlayers": "Maksymalna iloล›ฤ‡ graczy", "bots": "Boty", @@ -759,10 +780,10 @@ "ok": "Ok", "errored": "Bล‚ฤ™dy", "noRecent": "Nieaktualne", - "totalUsed": "Used Storage" + "totalUsed": "Uลผyta pamiฤ™ฤ‡" }, "mealie": { - "recipes": "Recipes", + "recipes": "Przepisy", "users": "Uลผytkownicy", "categories": "Kategorie", "tags": "Tagi" @@ -775,33 +796,97 @@ "passed": "Powodzenie", "failed": "Niepowodzenie" }, + "openwrt": { + "uptime": "Czas dziaล‚ania", + "cpuLoad": "ลšr. obciฤ…ลผenie CPU (5m)", + "up": "Dostฤ™pny", + "down": "Niedostฤ™pny", + "bytesTx": "Przesล‚ane", + "bytesRx": "Odebrane" + }, "uptimerobot": { "status": "Stan", "uptime": "Czas dziaล‚ania", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", + "lastDown": "Ostatni downtime", + "downDuration": "Dล‚ugoล›ฤ‡ downtime'u", "sitesUp": "Dziaล‚ajฤ…ce", "sitesDown": "Niedziaล‚ajฤ…ce", "paused": "Zatrzymane", - "notyetchecked": "Not Yet Checked", + "notyetchecked": "Nie sprawdzono", "up": "Dostฤ™pny", - "seemsdown": "Seems Down", + "seemsdown": "Moลผliwe, ลผe wyล‚ฤ…czony", "down": "Niedostฤ™pny", "unknown": "Nieznany" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", - "digitalRelease": "Digital release", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "inCinemas": "W kinach", + "physicalRelease": "Wydanie fizyczne", + "digitalRelease": "Wydanie cyfrowe", + "noEventsToday": "Brak wydarzeล„ na dziล›!", + "noEventsFound": "Nie znaleziono wydarzeล„" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platformy", + "totalRoms": "ลฤ…cznie ROM" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Ostrzeลผenia", + "criticals": "Krytyczny" + }, + "plantit": { + "events": "Wydarzenia", + "plants": "Roล›liny", + "photos": "Zdjฤ™cia", + "species": "Gatunki" + }, + "gitea": { + "notifications": "Powiadomienia", + "issues": "Zgล‚oszenia", + "pulls": "ลปฤ…dania Pull" + }, + "stash": { + "scenes": "Sceny", + "scenesPlayed": "Odgrane sceny", + "playCount": "ลฤ…cznie odtworzone", + "playDuration": "ลฤ…czny czas oglฤ…dania", + "sceneSize": "Rozmiar scen", + "sceneDuration": "Czas trwania scen", + "images": "Obrazy", + "imageSize": "Rozmiar obrazรณw", + "galleries": "Galerie", + "performers": "Artyล›ci", + "studios": "Studia", + "movies": "Filmy", + "tags": "Tagi", + "oCount": "O Licznik" + }, + "tandoor": { + "users": "Uลผytkownicy", + "recipes": "Przepisy", + "keywords": "Sล‚owa kluczowe" + }, + "homebox": { + "items": "Elementy", + "totalWithWarranty": "Z gwarancjฤ…", + "locations": "Lokalizacje", + "labels": "Etykiety", + "users": "Uลผytkownicy", + "totalValue": "Wartoล›ฤ‡ caล‚kowita" + }, + "crowdsec": { + "alerts": "Alarmy", + "bans": "Bany" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Wล‚ฤ…czone", + "disabled": "Wyล‚ฤ…czone", + "total": "Caล‚kowite" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/pt/common.json b/public/locales/pt/common.json index b471ccc2..558e9867 100644 --- a/public/locales/pt/common.json +++ b/public/locales/pt/common.json @@ -107,6 +107,13 @@ "episodes": "Episรณdios", "songs": "Canรงรตes" }, + "esphome": { + "offline": "Desligado", + "offline_alt": "Desligado", + "online": "Online", + "total": "Total", + "unknown": "Desconhecido" + }, "evcc": { "pv_power": "Produรงรฃo", "battery_soc": "Bateria", @@ -133,7 +140,7 @@ "connectionStatusPendingDisconnect": "Desconexรฃo pendente", "connectionStatusDisconnecting": "Desconectando", "connectionStatusDisconnected": "Desconectado", - "connectionStatusConnected": "Conectado", + "connectionStatusConnected": "Connected", "uptime": "Ligado", "maxDown": "Mรกx. de Descarga", "maxUp": "Max. de Envio", @@ -270,11 +277,11 @@ "approved": "Aprovada", "available": "Disponรญvel" }, - "pialert": { + "netalertx": { "total": "Total", - "connected": "Conectado", - "new_devices": "Novos dispositivos", - "down_alerts": "Alertas de Baixo" + "connected": "Connected", + "new_devices": "New Devices", + "down_alerts": "Down Alerts" }, "pihole": { "queries": "Consultas", @@ -419,7 +426,8 @@ "search": "Busca", "custom": "Personalizado", "visit": "Visitar", - "url": "Endereรงo URL" + "url": "Endereรงo URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Solarengo", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Canais", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Taxa de bits", + "clientIP": "Client" }, "scrutiny": { "passed": "Aprovado", @@ -694,6 +710,11 @@ "targets_down": "Alvo inativo", "targets_total": "Total de Alvos" }, + "gatus": { + "up": "Sites no Ar", + "down": "Sites Fora do Ar", + "uptime": "Ligado" + }, "ghostfolio": { "gross_percent_today": "Hoje", "gross_percent_1y": "Um ano", @@ -775,6 +796,14 @@ "passed": "Aprovado", "failed": "Falhou" }, + "openwrt": { + "uptime": "Ligado", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Recebido" + }, "uptimerobot": { "status": "Estado", "uptime": "Ligado", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Fotos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Problemas", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Filmes", + "tags": "Etiquetas", + "oCount": "O Count" + }, + "tandoor": { + "users": "Utilizadores", + "recipes": "Receitas", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Utilizadores", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alertas", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Ativo", + "disabled": "Desabilitado", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/pt_BR/common.json b/public/locales/pt_BR/common.json index 3fda97f8..e622ddeb 100644 --- a/public/locales/pt_BR/common.json +++ b/public/locales/pt_BR/common.json @@ -14,7 +14,7 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", + "months": "M", "days": "d", "hours": "h", "minutes": "m", @@ -22,11 +22,11 @@ }, "widget": { "missing_type": "Tipo de Widget ausente: {{type}}", - "api_error": "Erro da API", + "api_error": "Erros de API", "information": "Informaรงรฃo", "status": "Estado", "url": "Endereรงo URL", - "raw_error": "Erro", + "raw_error": "Erro Raw", "response_data": "Dados da Resposta" }, "weather": { @@ -85,28 +85,35 @@ "ping": { "error": "Erro", "ping": "Tempo de resposta", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "down": "Inativo", + "up": "Ativo", + "not_available": "Nรฃo Disponรญvel" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "Estado HTTP", "error": "Erro", - "response": "Response", - "down": "Down", - "up": "Up", - "not_available": "Not Available" + "response": "Resposta", + "down": "Inativo", + "up": "Ativo", + "not_available": "Nรฃo Disponรญvel" }, "emby": { "playing": "A reproduzir", "transcoding": "Transcodificaรงรฃo", "bitrate": "Taxa de bits", - "no_active": "Sem streams ativas", + "no_active": "Sem Streams Ativos", "movies": "Filmes", "series": "Sรฉries", "episodes": "Episรณdios", "songs": "Canรงรตes" }, + "esphome": { + "offline": "Desligado", + "offline_alt": "Desligado", + "online": "Disponรญvel", + "total": "Total", + "unknown": "Desconhecido" + }, "evcc": { "pv_power": "Produรงรฃo", "battery_soc": "Bateria", @@ -127,24 +134,24 @@ }, "fritzbox": { "connectionStatus": "Estado", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", - "connectionStatusConnected": "Connected", + "connectionStatusUnconfigured": "Nรฃo configurado", + "connectionStatusConnecting": "Conectando", + "connectionStatusAuthenticating": "Autenticando", + "connectionStatusPendingDisconnect": "Desconexรฃo Pendente", + "connectionStatusDisconnecting": "Desconectando", + "connectionStatusDisconnected": "Desconectado", + "connectionStatusConnected": "Conectado", "uptime": "Ligado", "maxDown": "Max. Down", - "maxUp": "Max. Up", - "down": "Down", - "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "maxUp": "Mรกx. Acima", + "down": "Inativo", + "up": "Ativo", + "received": "Recebido", + "sent": "Enviado", + "externalIPAddress": "IP Externo" }, "caddy": { - "upstreams": "Upstreams", + "upstreams": "Streams de Envio", "requests": "Solicitaรงรตes atuais", "requests_failed": "Solicitaรงรตes com falha" }, @@ -153,24 +160,24 @@ "diffsDetected": "Diferenรงas Detetadas" }, "channelsdvrserver": { - "shows": "Shows", + "shows": "Programas", "recordings": "Gravaรงรตes", - "scheduled": "Scheduled", + "scheduled": "Agendado", "passes": "Passes" }, "tautulli": { "playing": "A reproduzir", "transcoding": "Transcodificaรงรฃo", "bitrate": "Taxa de bits", - "no_active": "Sem streams ativas", - "plex_connection_error": "Check Plex Connection" + "no_active": "Sem Streams Ativos", + "plex_connection_error": "Verifique a conexรฃo do Plex" }, "omada": { "connectedAp": "APs Ligados", - "activeUser": "Dispositivos activos", + "activeUser": "Dispositivos ativos", "alerts": "Alertas", - "connectedGateway": "Gateways ligados", - "connectedSwitches": "Switches ligados" + "connectedGateway": "Gateways conectados", + "connectedSwitches": "Switches conectados" }, "nzbget": { "rate": "Taxa", @@ -179,7 +186,7 @@ }, "plex": { "streams": "Streams Ativas", - "albums": "Albums", + "albums": "รlbuns", "movies": "Filmes", "tv": "Series de TV" }, @@ -206,12 +213,12 @@ "seed": "Semente" }, "qnap": { - "cpuUsage": "CPU Usage", - "memUsage": "MEM Usage", - "systemTempC": "System Temp", + "cpuUsage": "Uso de CPU", + "memUsage": "Uso de Memรณria", + "systemTempC": "Temp. do Sistema", "poolUsage": "Pool Usage", - "volumeUsage": "Volume Usage", - "invalid": "Invalid" + "volumeUsage": "Uso do volume", + "invalid": "Invรกlido" }, "deluge": { "download": "Descarregar", @@ -243,7 +250,7 @@ "lidarr": { "wanted": "Desejada", "queued": "Em fila", - "artists": "Artists" + "artists": "Artistas" }, "readarr": { "wanted": "Desejada", @@ -270,16 +277,16 @@ "approved": "Aprovada", "available": "Disponรญvel" }, - "pialert": { + "netalertx": { "total": "Total", - "connected": "Connected", - "new_devices": "New Devices", - "down_alerts": "Down Alerts" + "connected": "Conectado", + "new_devices": "Novos dispositivos", + "down_alerts": "Alertas de Inatividade" }, "pihole": { "queries": "Consultas", "blocked": "Bloqueado", - "blocked_percent": "Blocked %", + "blocked_percent": "Bloqueado %", "gravity": "Gravidade" }, "adguard": { @@ -299,11 +306,11 @@ "total": "Total" }, "tailscale": { - "address": "Address", - "expires": "Expires", - "never": "Never", - "last_seen": "Last Seen", - "now": "Now", + "address": "Endereรงo", + "expires": "Expira em", + "never": "Nunca", + "last_seen": "Visto por รบltimo", + "now": "Agora", "years": "{{number}}y", "weeks": "{{number}}w", "days": "{{number}}d", @@ -324,8 +331,8 @@ "middleware": "Middleware" }, "navidrome": { - "nothing_streaming": "Sem streams ativas", - "please_wait": "Por favor aguarde" + "nothing_streaming": "Sem Streams Ativos", + "please_wait": "Por favor, aguarde" }, "npm": { "enabled": "Ativo", @@ -375,7 +382,7 @@ "players": "Reprodutores", "version": "Versรฃo", "status": "Estado", - "up": "Online", + "up": "Disponรญvel", "down": "Desligado" }, "miniflux": { @@ -398,20 +405,20 @@ "load": "Carga", "wait": "Por favor aguarde", "temp": "TEMP", - "_temp": "Temp", - "warn": "Warn", + "_temp": "Temperatura", + "warn": "Aviso", "uptime": "CIMA", "total": "Total", "free": "Livre", "used": "Utilizado", "days": "d", "hours": "h", - "crit": "Crit", + "crit": "Crรญtico", "read": "Lido", - "write": "Write", + "write": "Escrita", "gpu": "GPU", - "mem": "Mem", - "swap": "Swap" + "mem": "Memรณria", + "swap": "Temporรกrio" }, "quicklaunch": { "bookmark": "Marcador", @@ -419,7 +426,8 @@ "search": "Busca", "custom": "Personalizado", "visit": "Visitar", - "url": "Endereรงo URL" + "url": "Endereรงo URL", + "searchsuggestion": "Sugestรฃo" }, "wmo": { "0-day": "Solarengo", @@ -486,15 +494,15 @@ "up_to_date": "Atualizado", "child_bridges": "Pontes Filhas", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Up", + "up": "Ativo", "pending": "Pendente", - "down": "Down" + "down": "Inativo" }, "healthchecks": { "new": "Novo", - "up": "Up", + "up": "Ativo", "grace": "Em Perรญodo Gratuito", - "down": "Down", + "down": "Inativo", "paused": "Pausado", "status": "Estado", "last_ping": "Ultimo Ping", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Canais", - "hd": "HD" + "hd": "HD", + "tunerCount": "Sintonizadores", + "channelNumber": "Canal", + "channelNetwork": "Rede", + "signalStrength": "Potรชncia", + "signalQuality": "Qualidade", + "symbolQuality": "Qualidade", + "networkRate": "Taxa de bits", + "clientIP": "Cliente" }, "scrutiny": { "passed": "Aprovado", @@ -547,15 +563,15 @@ "total": "Total" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", - "online": "Online", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "battery_charge": "Carga da bateria", + "ups_load": "Carga do UPS", + "ups_status": "Estado UPS", + "online": "Disponรญvel", + "on_battery": "Na bateria", + "low_battery": "Bateria Fraca" }, "nextdns": { - "wait": "Por favor aguarde", + "wait": "Por favor, aguarde", "no_devices": "Nenhum dado do dispositivo recebido" }, "mikrotik": { @@ -570,10 +586,10 @@ "streams_xepg": "Canais XEPG" }, "opendtu": { - "yieldDay": "Today", - "absolutePower": "Power", - "relativePower": "Power %", - "limit": "Limit" + "yieldDay": "Hoje", + "absolutePower": "Energia", + "relativePower": "Energia %", + "limit": "Limite" }, "opnsense": { "cpu": "Carga do CPU", @@ -598,14 +614,14 @@ "status": "Estado" }, "pfsense": { - "load": "Load Avg", - "memory": "Mem Usage", - "wanStatus": "WAN Status", - "up": "Up", - "down": "Down", - "temp": "Temp", - "disk": "Disk Usage", - "wanIP": "WAN IP" + "load": "Carga Mรฉdia", + "memory": "Uso de memรณria", + "wanStatus": "Estado WAN", + "up": "Ativo", + "down": "Inativo", + "temp": "Temperatura", + "disk": "Uso do disco", + "wanIP": "IP WAN" }, "proxmoxbackupserver": { "datastore_usage": "Armaz. de Dados", @@ -628,9 +644,9 @@ }, "atsumeru": { "series": "Sรฉries", - "archives": "Archives", - "chapters": "Chapters", - "categories": "Categories" + "archives": "Arquivos", + "chapters": "Capรญtulos", + "categories": "Categorias" }, "komga": { "libraries": "Bibliotecas", @@ -648,7 +664,7 @@ "wanted": "Desejada" }, "photoprism": { - "albums": "Albums", + "albums": "รlbuns", "photos": "Fotos", "videos": "Vรญdeos", "people": "Pessoa" @@ -670,8 +686,8 @@ "memoryusage": "Memรณria Utilizada", "freespace": "Espaรงo Livre", "activeusers": "Utilizadores Ativos", - "numfiles": "Files", - "numshares": "Shared Items" + "numfiles": "Arquivos", + "numshares": "Itens compartilhados" }, "kopia": { "status": "Estado", @@ -682,7 +698,7 @@ }, "unmanic": { "active_workers": "Workers Ativos", - "total_workers": "Total Workers", + "total_workers": "Total de trabalhadores", "records_total": "Comprimento da Fila" }, "pterodactyl": { @@ -694,8 +710,13 @@ "targets_down": "Alvo inativo", "targets_total": "Total de Alvos" }, + "gatus": { + "up": "Sites no Ar", + "down": "Sites Fora do Ar", + "uptime": "Ligado" + }, "ghostfolio": { - "gross_percent_today": "Today", + "gross_percent_today": "Hoje", "gross_percent_1y": "Um ano", "gross_percent_max": "Todo o tempo" }, @@ -711,13 +732,13 @@ "switches_on": "Interruptores Ligados" }, "whatsupdocker": { - "monitoring": "Monitoring", + "monitoring": "Monitorando", "updates": "Atualizaรงรตes" }, "calibreweb": { "books": "Livros", - "authors": "Authors", - "categories": "Categories", + "authors": "Autores", + "categories": "Categorias", "series": "Sรฉries" }, "jdownloader": { @@ -728,80 +749,144 @@ }, "kavita": { "seriesCount": "Sรฉries", - "totalFiles": "Files" + "totalFiles": "Arquivos" }, "azuredevops": { - "result": "Result", + "result": "Resultado", "status": "Estado", - "buildId": "Build ID", - "succeeded": "Succeeded", - "notStarted": "Not Started", + "buildId": "ID Compilaรงรฃo", + "succeeded": "Bem-sucedido", + "notStarted": "Nรฃo iniciado", "failed": "Falhou", - "canceled": "Canceled", - "inProgress": "In Progress", - "totalPrs": "Total PRs", - "myPrs": "My PRs", + "canceled": "Cancelado", + "inProgress": "Em Progresso", + "totalPrs": "Total de PRs", + "myPrs": "Minhas PRs", "approved": "Aprovada" }, "gamedig": { "status": "Estado", - "online": "Online", + "online": "Disponรญvel", "offline": "Desligado", - "name": "Name", - "map": "Map", - "currentPlayers": "Current players", + "name": "Nome", + "map": "Mapa", + "currentPlayers": "Jogadores atuais", "players": "Reprodutores", - "maxPlayers": "Max players", - "bots": "Bots", + "maxPlayers": "Nรบmero Mรกximo de Jogadores", + "bots": "Robรดs", "ping": "Tempo de resposta" }, "urbackup": { "ok": "Ok", - "errored": "Errors", - "noRecent": "Out of Date", - "totalUsed": "Used Storage" + "errored": "Erros", + "noRecent": "Desatualizado", + "totalUsed": "Armazanamento Utilizado" }, "mealie": { - "recipes": "Recipes", + "recipes": "Receitas", "users": "Utilizadores", - "categories": "Categories", - "tags": "Tags" + "categories": "Categorias", + "tags": "Marcadores" }, "openmediavault": { - "downloading": "Downloading", + "downloading": "Baixando", "total": "Total", "running": "A correr", "stopped": "Parado", "passed": "Aprovado", "failed": "Falhou" }, + "openwrt": { + "uptime": "Ligado", + "cpuLoad": "Carga da CPU mรฉdia (5m)", + "up": "Ativo", + "down": "Inativo", + "bytesTx": "Transmitido", + "bytesRx": "Recebido" + }, "uptimerobot": { "status": "Estado", "uptime": "Ligado", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", + "lastDown": "รšltima inatividade", + "downDuration": "Duraรงรฃo de inatividade", "sitesUp": "Sites no Ar", "sitesDown": "Sites Fora do Ar", "paused": "Pausado", - "notyetchecked": "Not Yet Checked", - "up": "Up", - "seemsdown": "Seems Down", - "down": "Down", + "notyetchecked": "Nรฃo conferidos ainda", + "up": "Ativo", + "seemsdown": "Parece Desconectado", + "down": "Inativo", "unknown": "Desconhecido" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", - "digitalRelease": "Digital release", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "inCinemas": "Nos cinemas", + "physicalRelease": "Versรฃo fรญsica", + "digitalRelease": "Versรฃo digital", + "noEventsToday": "Nenhum evento para hoje!", + "noEventsFound": "Nenhum evento encontrado" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Plataformas", + "totalRoms": "Total de ROMs" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Alertas", + "criticals": "Crรญticos" + }, + "plantit": { + "events": "Eventos", + "plants": "Plantas", + "photos": "Fotos", + "species": "Espรฉcies" + }, + "gitea": { + "notifications": "Notificaรงรตes", + "issues": "Problemas", + "pulls": "Solicitaรงรตes de Envio" + }, + "stash": { + "scenes": "Cenas", + "scenesPlayed": "Cenas Reproduzidas", + "playCount": "Total de Reproduรงรตes", + "playDuration": "Tempo Assistido", + "sceneSize": "Tamanho das cenas", + "sceneDuration": "Duraรงรฃo das cenas", + "images": "Imagens", + "imageSize": "Tamanho da Imagem", + "galleries": "Galerias", + "performers": "Atores", + "studios": "Estรบdios", + "movies": "Filmes", + "tags": "Marcadores", + "oCount": "Contagem 0" + }, + "tandoor": { + "users": "Utilizadores", + "recipes": "Receitas", + "keywords": "Palavras-chave" + }, + "homebox": { + "items": "Itens", + "totalWithWarranty": "Com Garantia", + "locations": "Localizaรงรฃo", + "labels": "Rรณtulos", + "users": "Utilizadores", + "totalValue": "Valor Total" + }, + "crowdsec": { + "alerts": "Alertas", + "bans": "Banimentos" + }, + "wgeasy": { + "connected": "Conectado", + "enabled": "Ativo", + "disabled": "Desabilitado", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/ro/common.json b/public/locales/ro/common.json index 348989ae..5b5187d3 100644 --- a/public/locales/ro/common.json +++ b/public/locales/ro/common.json @@ -107,6 +107,13 @@ "episodes": "Episoade", "songs": "Melodii" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Total", + "unknown": "Necunoscut" + }, "evcc": { "pv_power": "Producศ›ie", "battery_soc": "Baterie", @@ -270,7 +277,7 @@ "approved": "Aprobate", "available": "Disponibile" }, - "pialert": { + "netalertx": { "total": "Total", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Cautฤƒ", "custom": "Personalizat", "visit": "Vizitฤƒ", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "รŽnsorit", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Rata de biศ›i", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Sus", + "down": "Jos", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Stare", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Filme", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Utilizatori", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Utilizatori", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Activat", + "disabled": "Dezactivat", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index f52d6007..5c7c771a 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -14,11 +14,11 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", - "days": "d", - "hours": "h", - "minutes": "m", - "seconds": "s" + "months": "ะผะตั", + "days": "ะดะฝะตะน", + "hours": "ั‡ะฐั", + "minutes": "ะผะธะฝ", + "seconds": "ัะตะบ" }, "widget": { "missing_type": "ะžั‚ััƒั‚ัั‚ะฒัƒะตั‚ ั‚ะธะฟ ะฒะธะดะถะตั‚ะฐ: {{type}}", @@ -107,6 +107,13 @@ "episodes": "ะญะฟะธะทะพะดั‹", "songs": "ะŸะตัะฝะธ" }, + "esphome": { + "offline": "ะะต ะฒ ัะตั‚ะธ", + "offline_alt": "ะะต ะฒ ัะตั‚ะธ", + "online": "ะ’ ัะตั‚ะธ", + "total": "ะ’ัะตะณะพ", + "unknown": "ะะตะธะทะฒะตัั‚ะตะฝ" + }, "evcc": { "pv_power": "ะŸั€ะพะด", "battery_soc": "ะŸะธั‚ะฐะฝะธะต", @@ -130,7 +137,7 @@ "connectionStatusUnconfigured": "ะะต ะฝะฐัั‚ั€ะพะตะฝะพ", "connectionStatusConnecting": "ะŸะพะดะบะปัŽั‡ะตะฝะธะต", "connectionStatusAuthenticating": "ะะฒั‚ะพั€ะธะทะฐั†ะธั", - "connectionStatusPendingDisconnect": "Pending Disconnect", + "connectionStatusPendingDisconnect": "ะžะถะธะดะฐะตั‚ ะพั‚ะบะปัŽั‡ะตะฝะธั", "connectionStatusDisconnecting": "ะžั‚ะบะปัŽั‡ะตะฝะธะต", "connectionStatusDisconnected": "ะžั‚ะบะปัŽั‡ะตะฝะพ", "connectionStatusConnected": "ะŸะพะดะบะปัŽั‡ะตะฝะพ", @@ -270,10 +277,10 @@ "approved": "ะžะดะพะฑั€ะตะฝะพ", "available": "ะ”ะพัั‚ัƒะฟะฝะพ" }, - "pialert": { + "netalertx": { "total": "ะ’ัะตะณะพ", "connected": "ะŸะพะดะบะปัŽั‡ะตะฝะพ", - "new_devices": "ะะพะฒั‹ะต ัƒัั‚ั€ะพะนัั‚ะฒะฐ", + "new_devices": "ะะพะฒะพะต ัƒัั‚ั€ะพะนัั‚ะฒะพ", "down_alerts": "ะžะฟะพะฒะตั‰ะตะฝะธะต ะพ ะฝะตะดะพัั‚ัƒะฟะฝะพัั‚ะธ" }, "pihole": { @@ -404,8 +411,8 @@ "total": "ะ’ัะตะณะพ", "free": "ะกะฒะพะฑะพะดะฝะพ", "used": "ะ˜ัะฟะพะปัŒะทะพะฒะฐะฝะพ", - "days": "d", - "hours": "h", + "days": "ะดะฝะตะน", + "hours": "ั‡ะฐั", "crit": "ะšั€ะธั‚", "read": "ะŸั€ะพั‡ะธั‚ะฐะฝะพ", "write": "ะ—ะฐะฟะธััŒ", @@ -419,7 +426,8 @@ "search": "ะŸะพะธัะบ", "custom": "ะŸะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบะธะน", "visit": "ะŸะพัะตั‚ะธั‚ะต", - "url": "ะกัั‹ะปะบะฐ" + "url": "ะกัั‹ะปะบะฐ", + "searchsuggestion": "ะŸั€ะตะดะปะพะถะตะฝะธะต" }, "wmo": { "0-day": "ะกะพะปะฝะตั‡ะฝะพ", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "ะšะฐะฝะฐะปั‹", - "hd": "HD" + "hd": "HD", + "tunerCount": "ะขัŽะฝะตั€ั‹", + "channelNumber": "ะšะฐะฝะฐะป", + "channelNetwork": "ะกะตั‚ัŒ", + "signalStrength": "ะกะธะปะฐ", + "signalQuality": "ะšะฐั‡ะตัั‚ะฒะพ", + "symbolQuality": "ะšะฐั‡ะตัั‚ะฒะพ", + "networkRate": "ะ‘ะธั‚ั€ะตะนั‚", + "clientIP": "ะšะปะธะตะฝั‚" }, "scrutiny": { "passed": "ะฃัะฟะตัˆะฝะพ", @@ -547,12 +563,12 @@ "total": "ะ’ัะตะณะพ" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "battery_charge": "ะ—ะฐั€ัะด ะฑะฐั‚ะฐั€ะตะธ", + "ups_load": "ะะฐะณั€ัƒะทะบะฐ ะฝะฐ UPS", + "ups_status": "ะกั‚ะฐั‚ัƒั UPS", "online": "ะ’ ัะตั‚ะธ", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "ะžั‚ ะฑะฐั‚ะฐั€ะตะธ", + "low_battery": "ะะธะทะบะธะน ะทะฐั€ัะด" }, "nextdns": { "wait": "ะŸะพะถะฐะปัƒะนัั‚ะฐ, ะฟะพะดะพะถะดะธั‚ะต", @@ -624,7 +640,7 @@ "down": "ะะตะฐะบั‚ะธะฒะฝั‹ะต ัะฐะนั‚ั‹", "uptime": "ะ’ั€ะตะผั ั€ะฐะฑะพั‚ั‹", "incident": "ะŸั€ะพะธััˆะตัั‚ะฒะธั", - "m": "m" + "m": "ะผะธะฝ" }, "atsumeru": { "series": "ะกะตั€ะธะธ", @@ -694,6 +710,11 @@ "targets_down": "ะะตะฐะบั‚ะธะฒะฝั‹ะต ั†ะตะปะธ", "targets_total": "ะ’ัะตะณะพ ั†ะตะปะตะน" }, + "gatus": { + "up": "ะะบั‚ะธะฒะฝั‹ะต ัะฐะนั‚ั‹", + "down": "ะะตะฐะบั‚ะธะฒะฝั‹ะต ัะฐะนั‚ั‹", + "uptime": "ะ’ั€ะตะผั ั€ะฐะฑะพั‚ั‹" + }, "ghostfolio": { "gross_percent_today": "ะกะตะณะพะดะฝั", "gross_percent_1y": "ะžะดะธะฝ ะณะพะด", @@ -775,6 +796,14 @@ "passed": "ะฃัะฟะตัˆะฝะพ", "failed": "ะŸั€ะพะฒะฐะปะตะฝะพ" }, + "openwrt": { + "uptime": "ะ’ั€ะตะผั ั€ะฐะฑะพั‚ั‹", + "cpuLoad": "ะกั€ะตะดะฝัั ะฝะฐะณั€ัƒะทะบะฐ ะฆะŸ (5ะผ)", + "up": "ะžะฝะปะฐะนะฝ", + "down": "ะžั„ะปะฐะนะฝ", + "bytesTx": "ะŸะตั€ะตะดะฐะฝะพ", + "bytesRx": "ะŸะพะปัƒั‡ะตะฝะพ" + }, "uptimerobot": { "status": "ะกั‚ะฐั‚ัƒั", "uptime": "ะ’ั€ะตะผั ั€ะฐะฑะพั‚ั‹", @@ -797,11 +826,67 @@ "noEventsFound": "ะกะพะฑั‹ั‚ะธะน ะฝะต ะฝะฐะนะดะตะฝะพ" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "ะŸะปะฐั‚ั„ะพั€ะผั‹", + "totalRoms": "ะ’ัะตะณะพ ะŸะ—ะฃ" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "ะŸั€ะตะดัƒะฟั€ะตะถะดะตะฝะธั", + "criticals": "ะšั€ะธั‚ะธั‡ะตัะบะธะต" + }, + "plantit": { + "events": "ะกะพะฑั‹ั‚ะธั", + "plants": "ะ ะฐัั‚ะตะฝะธั", + "photos": "ะคะพั‚ะพ", + "species": "ะ’ะธะดั‹" + }, + "gitea": { + "notifications": "ะฃะฒะตะดะพะผะปะตะฝะธั", + "issues": "ะ’ะพะฟั€ะพัั‹", + "pulls": "ะ—ะฐะฟั€ะพัั‹ ะฝะฐ ัะปะธัะฝะธะต (Pull Request)" + }, + "stash": { + "scenes": "ะกั†ะตะฝั‹", + "scenesPlayed": "ะŸั€ะพะธะณั€ะฐะฝะฝั‹ั… ัั†ะตะฝ", + "playCount": "ะ’ัะตะณะพ ะฟั€ะพะธะณั€ะฐะฝะพ", + "playDuration": "ะŸั€ะพัะผะพั‚ั€ะตะฝะพ ะฒั€ะตะผะตะฝะธ", + "sceneSize": "ะ ะฐะทะผะตั€ ัั†ะตะฝั‹", + "sceneDuration": "ะ”ะปะธั‚ะตะปัŒะฝะพัั‚ัŒ ัั†ะตะฝ", + "images": "ะ˜ะทะพะฑั€ะฐะถะตะฝะธั", + "imageSize": "ะ ะฐะทะผะตั€ ะธะทะพะฑั€ะฐะถะตะฝะธะน", + "galleries": "ะ“ะฐะปะตั€ะตะธ", + "performers": "ะ˜ัะฟะพะปะฝะธั‚ะตะปะธ", + "studios": "ะกั‚ัƒะดะธะธ", + "movies": "ะคะธะปัŒะผั‹", + "tags": "ะขะตะณะธ", + "oCount": "0" + }, + "tandoor": { + "users": "ะŸะพะปัŒะทะพะฒะฐั‚ะตะปะธ", + "recipes": "ะ ะตั†ะตะฟั‚ั‹", + "keywords": "ะšะปัŽั‡ะตะฒั‹ะต ัะปะพะฒะฐ" + }, + "homebox": { + "items": "ะญะปะตะผะตะฝั‚ั‹", + "totalWithWarranty": "ะก ะณะฐั€ะฐะฝั‚ะธะตะน", + "locations": "ะœะตัั‚ะพะฟะพะปะพะถะตะฝะธั", + "labels": "ะฏั€ะปั‹ะบะธ", + "users": "ะŸะพะปัŒะทะพะฒะฐั‚ะตะปะธ", + "totalValue": "ะžะฑั‰ะฐั ัั‚ะพะธะผะพัั‚ัŒ" + }, + "crowdsec": { + "alerts": "ะŸั€ะตะดัƒะฟั€ะตะถะดะตะฝะธั", + "bans": "ะ—ะฐะฟั€ะตั‚ั‹" + }, + "wgeasy": { + "connected": "ะŸะพะดะบะปัŽั‡ะตะฝะพ", + "enabled": "ะ’ะบะปัŽั‡ะตะฝะพ", + "disabled": "ะ’ั‹ะบะปัŽั‡ะตะฝะพ", + "total": "ะ’ัะตะณะพ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/sk/common.json b/public/locales/sk/common.json index 015187d2..42afe41a 100644 --- a/public/locales/sk/common.json +++ b/public/locales/sk/common.json @@ -11,7 +11,7 @@ "percent": "{{value, percent}}", "number": "{{value, number}}", "ms": "{{value, number}}", - "date": "{value, date}", + "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", "months": "mes", @@ -107,6 +107,13 @@ "episodes": "Epizรณdy", "songs": "Skladby" }, + "esphome": { + "offline": "Nedostupnรฝ", + "offline_alt": "Nedostupnรฝ", + "online": "Online", + "total": "Celkovo", + "unknown": "Neznรกme" + }, "evcc": { "pv_power": "Produkcia", "battery_soc": "Batรฉria", @@ -135,8 +142,8 @@ "connectionStatusDisconnected": "Odpojenรฉ", "connectionStatusConnected": "Pripojenรฉ", "uptime": "Prevรกdzka", - "maxDown": "Max. Down", - "maxUp": "Max. Up", + "maxDown": "Max. sลฅahovanie", + "maxUp": "Max. nahrรกvanie", "down": "Sลฅahovanie", "up": "Nahrรกvanie", "received": "Prijatรฉ", @@ -270,7 +277,7 @@ "approved": "Schvรกlenรฉ", "available": "Dostupnรฉ" }, - "pialert": { + "netalertx": { "total": "Celkovo", "connected": "Pripojenรฉ", "new_devices": "Novรฉ zariadenia", @@ -419,7 +426,8 @@ "search": "Hฤพadaลฅ", "custom": "Vlastnรฉ", "visit": "Navลกtรญviลฅ", - "url": "Odkaz" + "url": "Odkaz", + "searchsuggestion": "Nรกvrh" }, "wmo": { "0-day": "Slneฤno", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanรกly", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tunery", + "channelNumber": "Kanรกl", + "channelNetwork": "Sieลฅ", + "signalStrength": "Sila", + "signalQuality": "Kvalita", + "symbolQuality": "Kvalita", + "networkRate": "Prenosovรก rรฝchlosลฅ", + "clientIP": "Klient" }, "scrutiny": { "passed": "รšspeลกnรฝ", @@ -694,6 +710,11 @@ "targets_down": "Nedostupnรฉ ciele", "targets_total": "Cieฤพov spolu" }, + "gatus": { + "up": "Weby dostupnรฉ", + "down": "Weby nedostupnรฉ", + "uptime": "Prevรกdzka" + }, "ghostfolio": { "gross_percent_today": "Dnes", "gross_percent_1y": "Jeden rok", @@ -775,6 +796,14 @@ "passed": "รšspeลกnรฝ", "failed": "Zlyhanรฉ" }, + "openwrt": { + "uptime": "Prevรกdzka", + "cpuLoad": "Zรกลฅaลพ CPU priem. (5m)", + "up": "Nahrรกvanie", + "down": "Sลฅahovanie", + "bytesTx": "Prenesenรฝch", + "bytesRx": "Prijatรฉ" + }, "uptimerobot": { "status": "Stav", "uptime": "Prevรกdzka", @@ -797,11 +826,67 @@ "noEventsFound": "ลฝiadne udalosti" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platformy", + "totalRoms": "Celkovo ROM" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Upozornenia", + "criticals": "Kritickรฉ" + }, + "plantit": { + "events": "Udalosti", + "plants": "Rastliny", + "photos": "Fotografie", + "species": "Druhy" + }, + "gitea": { + "notifications": "Oznรกmenia", + "issues": "Problรฉmy", + "pulls": "Pull requesty" + }, + "stash": { + "scenes": "Scรฉny", + "scenesPlayed": "Prehranรฉ scรฉny", + "playCount": "Celkovo prehranรญ", + "playDuration": "Pozeranรฝ ฤas", + "sceneSize": "Veฤพkosลฅ obrazovky", + "sceneDuration": "Dฤบลพka scรฉny", + "images": "Obrรกzky", + "imageSize": "Veฤพkosลฅ obrรกzkov", + "galleries": "Galรฉrie", + "performers": "Herci", + "studios": "ล tรบdiรก", + "movies": "Filmy", + "tags": "ล tรญtky", + "oCount": "O Count" + }, + "tandoor": { + "users": "Pouลพรญvatelia", + "recipes": "Recepty", + "keywords": "Kฤพรบฤovรฉ slovรก" + }, + "homebox": { + "items": "Poloลพky", + "totalWithWarranty": "So zรกrukou", + "locations": "Umiestnenia", + "labels": "ล tรญtky", + "users": "Pouลพรญvatelia", + "totalValue": "Celkovรก hodnota" + }, + "crowdsec": { + "alerts": "Upozornenia", + "bans": "Bany" + }, + "wgeasy": { + "connected": "Pripojenรฉ", + "enabled": "Povolenรฉ", + "disabled": "Zakรกzanรฉ", + "total": "Celkovo" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Zastaranรฉ", + "banned": "Zabanovanรฝ" } } diff --git a/public/locales/sl/common.json b/public/locales/sl/common.json index ed79137d..6dcd5415 100644 --- a/public/locales/sl/common.json +++ b/public/locales/sl/common.json @@ -107,6 +107,13 @@ "episodes": "Epizode", "songs": "Pesmi" }, + "esphome": { + "offline": "Ni povezan", + "offline_alt": "Ni povezan", + "online": "Na spletu", + "total": "Skupaj", + "unknown": "Neznano" + }, "evcc": { "pv_power": "Proizvodnja", "battery_soc": "Baterija", @@ -133,7 +140,7 @@ "connectionStatusPendingDisconnect": "ฤŒakanje na prekinitev", "connectionStatusDisconnecting": "Prekinitev", "connectionStatusDisconnected": "Prekinjeno", - "connectionStatusConnected": "Povezanih", + "connectionStatusConnected": "Povezan", "uptime": "ฤŒas delovanja", "maxDown": "Maks. dol", "maxUp": "Maks. gor", @@ -146,7 +153,7 @@ "caddy": { "upstreams": "Pretok gor", "requests": "Trenutnih zahtev", - "requests_failed": "Neuspeลกnih zahtev" + "requests_failed": "Neuspeลก. zahtev" }, "changedetectionio": { "totalObserved": "Skupaj opazovano", @@ -270,11 +277,11 @@ "approved": "Odobreno", "available": "Na voljo" }, - "pialert": { + "netalertx": { "total": "Skupaj", - "connected": "Povezanih", - "new_devices": "Nove naprave", - "down_alerts": "Izkljuฤeno" + "connected": "Povezan", + "new_devices": "Nova naprave", + "down_alerts": "Alarmi nedelovanja" }, "pihole": { "queries": "Poizvedbe", @@ -348,8 +355,8 @@ "enableIndexers": "Indekserji", "numberOfGrabs": "Zajemi", "numberOfQueries": "Poizvedbe", - "numberOfFailGrabs": "Neuspeลกni zajemi", - "numberOfFailQueries": "Neuspeลกne poizvedbe" + "numberOfFailGrabs": "Neuspeลก. zajem", + "numberOfFailQueries": "Neuspeลก. poizvedb" }, "jackett": { "configured": "Nastavljeno", @@ -419,7 +426,8 @@ "search": "Iskanje", "custom": "Po meri", "visit": "Obiลกฤi", - "url": "URL" + "url": "URL", + "searchsuggestion": "Predlog" }, "wmo": { "0-day": "Sonฤno", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanali", - "hd": "HD" + "hd": "HD", + "tunerCount": "Sprejemniki", + "channelNumber": "Kanal", + "channelNetwork": "Omreลพje", + "signalStrength": "Moฤ", + "signalQuality": "Kakovost", + "symbolQuality": "Kakovost", + "networkRate": "Pasovna ลกirina", + "clientIP": "Odjemalec" }, "scrutiny": { "passed": "Opravljeno", @@ -694,6 +710,11 @@ "targets_down": "Tarฤe dol", "targets_total": "Skupaj tarฤ" }, + "gatus": { + "up": "Deluje", + "down": "Ne deluje", + "uptime": "ฤŒas delovanja" + }, "ghostfolio": { "gross_percent_today": "Danes", "gross_percent_1y": "Eno leto", @@ -775,6 +796,14 @@ "passed": "Opravljeno", "failed": "Neuspeลกno" }, + "openwrt": { + "uptime": "ฤŒas delovanja", + "cpuLoad": "CPU obremenitev povp. (5m)", + "up": "Povezan", + "down": "Nepovezan", + "bytesTx": "Preneลกeno", + "bytesRx": "Prejeto" + }, "uptimerobot": { "status": "Stanje", "uptime": "ฤŒas delovanja", @@ -797,11 +826,67 @@ "noEventsFound": "Ni dogodkov" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platforme", + "totalRoms": "Skupaj ROM-ov" }, "netdata": { "warnings": "Opozorila", "criticals": "Kritiฤno" + }, + "plantit": { + "events": "Dogodki", + "plants": "Rastline", + "photos": "Slike", + "species": "Vrste" + }, + "gitea": { + "notifications": "Obvestila", + "issues": "Teลพave", + "pulls": "Zahteve za prenos" + }, + "stash": { + "scenes": "Scene", + "scenesPlayed": "Predvajane scene", + "playCount": "Skupaj predvajano", + "playDuration": "ฤŒas gledanja", + "sceneSize": "Velikost scene", + "sceneDuration": "Dolลพina scene", + "images": "Slike", + "imageSize": "Velikosti slik", + "galleries": "Galerije", + "performers": "Izvajalci", + "studios": "Studiji", + "movies": "Filmi", + "tags": "Znaฤke", + "oCount": "O ลกtetje" + }, + "tandoor": { + "users": "Uporabniki", + "recipes": "Recepti", + "keywords": "Kljuฤne besede" + }, + "homebox": { + "items": "Predmeti", + "totalWithWarranty": "Z garancijo", + "locations": "Lokacije", + "labels": "Oznake", + "users": "Uporabniki", + "totalValue": "Skupna vrednost" + }, + "crowdsec": { + "alerts": "Opozorila", + "bans": "Prepovedi" + }, + "wgeasy": { + "connected": "Povezan", + "enabled": "Omogoฤen", + "disabled": "Onemogoฤen", + "total": "Skupaj" + }, + "swagdashboard": { + "proxied": "ฤŒez proxi", + "auth": "Z Auth", + "outdated": "Zastarelo", + "banned": "Prepovedan" } } diff --git a/public/locales/sr/common.json b/public/locales/sr/common.json index ca628d3b..62714000 100644 --- a/public/locales/sr/common.json +++ b/public/locales/sr/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Total", + "unknown": "Unknown" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Approved", "available": "Available" }, - "pialert": { + "netalertx": { "total": "Total", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Status", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Users", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Users", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Enabled", + "disabled": "Disabled", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/sv/common.json b/public/locales/sv/common.json index af27210e..53fe576c 100644 --- a/public/locales/sv/common.json +++ b/public/locales/sv/common.json @@ -14,7 +14,7 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", + "months": "mรฅn", "days": "d", "hours": "h", "minutes": "m", @@ -56,7 +56,7 @@ "wan": "WAN", "lan": "LAN", "wlan": "WLAN", - "devices": "Devices", + "devices": "Enheter", "lan_devices": "LAN Devices", "wlan_devices": "WLAN Devices", "lan_users": "LAN-anvรคndare", @@ -104,9 +104,16 @@ "no_active": "Inga aktiva strรถmmar", "movies": "Movies", "series": "Series", - "episodes": "Episodes", + "episodes": "Avsnitt", "songs": "Songs" }, + "esphome": { + "offline": "Offline", + "offline_alt": "Offline", + "online": "Online", + "total": "Total", + "unknown": "Unknown" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Godkรคnda", "available": "Tillgรคnglig" }, - "pialert": { + "netalertx": { "total": "Total", "connected": "Connected", "new_devices": "New Devices", @@ -416,10 +423,11 @@ "quicklaunch": { "bookmark": "Bookmark", "service": "Service", - "search": "Search", + "search": "Sรถk", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Status", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Anvรคndare", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Anvรคndare", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Aktiverad", + "disabled": "Inaktiverad", + "total": "Total" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/te/common.json b/public/locales/te/common.json index 81b6af79..1dd640f2 100644 --- a/public/locales/te/common.json +++ b/public/locales/te/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "เฐ†เฐซเฑโ€Œเฐฒเฑˆเฐจเฑ", + "offline_alt": "เฐ†เฐซเฑโ€Œเฐฒเฑˆเฐจเฑ", + "online": "Online", + "total": "เฐฎเฑŠเฐคเฑเฐคเฐ‚", + "unknown": "Unknown" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "เฐ†เฐฎเฑ‹เฐฆเฐฟเฐ‚เฐšเฐฌเฐกเฐฟเฐ‚เฐฆเฐฟ", "available": "เฐ…เฐ‚เฐฆเฑเฐฌเฐพเฐŸเฑเฐฒเฑ‹ เฐตเฑเฐจเฑเฐจเฐตเฐฟ" }, - "pialert": { + "netalertx": { "total": "เฐฎเฑŠเฐคเฑเฐคเฐ‚", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "เฐธเฐจเฑเฐจเฑ€", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "เฐฌเฐฟเฐŸเฑเฐฐเฑ‡เฐŸเฑ", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "เฐตเฐฟเฐซเฐฒเฐฎเฐฏเฑเฐฏเฐพเฐฐเฑ" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "เฐนเฑ‹เฐฆเฐพ", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "เฐตเฐฟเฐจเฐฟเฐฏเฑ‹เฐ—เฐฆเฐพเฐฐเฑเฐฒเฑ", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "เฐตเฐฟเฐจเฐฟเฐฏเฑ‹เฐ—เฐฆเฐพเฐฐเฑเฐฒเฑ", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "เฐชเฑเฐฐเฐพเฐฐเฐ‚เฐญเฐฟเฐ‚เฐšเฐฌเฐกเฐฟเฐ‚เฐฆเฐฟ", + "disabled": "เฐกเฐฟเฐธเฑ‡เฐฌเฑเฐฒเฑ†เฐกเฑ", + "total": "เฐฎเฑŠเฐคเฑเฐคเฐ‚" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/th/common.json b/public/locales/th/common.json index 86b7021a..682451b4 100644 --- a/public/locales/th/common.json +++ b/public/locales/th/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "เธญเธญเธŸเน„เธฅเธ™เนŒ", + "offline_alt": "เธญเธญเธŸเน„เธฅเธ™เนŒ", + "online": "Online", + "total": "เธ—เธฑเน‰เธ‡เธซเธกเธ”", + "unknown": "เน„เธกเนˆเธ—เธฃเธฒเธš" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "Approved", "available": "Available" }, - "pialert": { + "netalertx": { "total": "เธ—เธฑเน‰เธ‡เธซเธกเธ”", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "เธญเธฑเธ•เธฃเธฒเธšเธดเธ•", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "เน€เธงเน‡เธšเน„เธ‹เธ•เนŒ เธฅเนˆเธก", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "เธชเธ–เธฒเธ™เธฐ", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "เธœเธนเน‰เนƒเธŠเน‰", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "เธœเธนเน‰เนƒเธŠเน‰", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Enabled", + "disabled": "Disabled", + "total": "เธ—เธฑเน‰เธ‡เธซเธกเธ”" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/tr/common.json b/public/locales/tr/common.json index 7ac4a63a..a44ec8f0 100644 --- a/public/locales/tr/common.json +++ b/public/locales/tr/common.json @@ -21,7 +21,7 @@ "seconds": "s" }, "widget": { - "missing_type": "Kayฤฑp Araรง Tรผrรผ: {{type}}", + "missing_type": "Eksik Araรง Tรผrรผ: {{type}}", "api_error": "API Hatasฤฑ", "information": "Bilgi", "status": "Durum", @@ -42,12 +42,12 @@ "cpu": "CPU", "mem": "MEM", "total": "Toplam", - "free": "BoลŸta", + "free": "BoลŸ", "used": "Kullanฤฑmda", "load": "Yรผk", - "temp": "Geรงici", + "temp": "Sฤฑcaklฤฑk", "max": "En Yรผksek", - "uptime": "ร‡alฤฑลŸma Sรผresi" + "uptime": "ร‡alฤฑลŸฤฑyor" }, "unifi": { "users": "Kullanฤฑcฤฑlar", @@ -61,7 +61,7 @@ "wlan_devices": "WLAN Aygฤฑtlarฤฑ", "lan_users": "LAN Kullanฤฑcฤฑlarฤฑ", "wlan_users": "WLAN Kullanฤฑcฤฑlarฤฑ", - "up": "ร‡alฤฑลŸma Sรผresi", + "up": "ร‡alฤฑลŸฤฑyor", "down": "AลŸaฤŸฤฑ", "wait": "Lรผtfen bekleyin", "empty_data": "Alt sistem durumu bilinmiyor" @@ -71,15 +71,15 @@ "tx": "Giden Veri", "mem": "MEM", "cpu": "CPU", - "running": "ร‡alฤฑลŸan", + "running": "ร‡alฤฑลŸฤฑyor", "offline": "ร‡evrimdฤฑลŸฤฑ", "error": "Hata", "unknown": "Bilinmiyor", - "healthy": "SaฤŸlฤฑk", + "healthy": "SaฤŸlฤฑklฤฑ", "starting": "BaลŸlatฤฑlฤฑyor", "unhealthy": "SaฤŸlฤฑksฤฑz", "not_found": "Bulunamadฤฑ", - "exited": "Durduruldu", + "exited": "Kapandฤฑ", "partial": "Parรงalฤฑ" }, "ping": { @@ -107,6 +107,13 @@ "episodes": "Bรถlรผmler", "songs": "ลžarkฤฑlar" }, + "esphome": { + "offline": "ร‡evrimdฤฑลŸฤฑ", + "offline_alt": "ร‡evrimdฤฑลŸฤฑ", + "online": "ร‡evrimiรงi", + "total": "Toplam", + "unknown": "Bilinmiyor" + }, "evcc": { "pv_power": "รœretim", "battery_soc": "Batarya", @@ -116,8 +123,8 @@ "watt_hour": "Watt/Saat" }, "flood": { - "download": "ฤฐndir", - "upload": "Yรผkle", + "download": "ฤฐndirme", + "upload": "Yรผkleme", "leech": "Tรผketici", "seed": "SaฤŸlayฤฑcฤฑ" }, @@ -130,18 +137,18 @@ "connectionStatusUnconfigured": "YapฤฑlandฤฑrฤฑlmamฤฑลŸ", "connectionStatusConnecting": "BaฤŸlanฤฑyor", "connectionStatusAuthenticating": "Kimlik doฤŸrulanฤฑyor", - "connectionStatusPendingDisconnect": "Pending Disconnect", + "connectionStatusPendingDisconnect": "BaฤŸlantฤฑnฤฑn Kesilmesi Bekleniyor", "connectionStatusDisconnecting": "BaฤŸlantฤฑ kesiliyor...", "connectionStatusDisconnected": "BaฤŸlantฤฑ kesildi", "connectionStatusConnected": "BaฤŸlandฤฑ", "uptime": "ร‡alฤฑลŸma Sรผresi", - "maxDown": "Max. Down", - "maxUp": "Max. Up", + "maxDown": "Max. Indirme", + "maxUp": "Max. Gรถnderme", "down": "ฤฐndirme", "up": "Yรผkleme", "received": "Alฤฑnan", "sent": "Gรถnderilen", - "externalIPAddress": "Ext. IP" + "externalIPAddress": "Harici IP" }, "caddy": { "upstreams": "AkฤฑลŸ", @@ -163,7 +170,7 @@ "transcoding": "DรถnรผลŸtรผrรผlรผyor", "bitrate": "Bit Oranฤฑ", "no_active": "Aktif akฤฑลŸ yok", - "plex_connection_error": "Check Plex Connection" + "plex_connection_error": "Plex BaฤŸlantฤฑsฤฑ Kontrol Ediliyor" }, "omada": { "connectedAp": "BaฤŸlฤฑ AP'ler", @@ -190,18 +197,18 @@ }, "rutorrent": { "active": "Aktif", - "upload": "Yรผkle", - "download": "ฤฐndir" + "upload": "Yรผkleme", + "download": "ฤฐndirme" }, "transmission": { - "download": "ฤฐndir", - "upload": "Yรผkle", + "download": "ฤฐndirme", + "upload": "Yรผkleme", "leech": "Tรผketici", "seed": "SaฤŸlayฤฑcฤฑ" }, "qbittorrent": { - "download": "ฤฐndir", - "upload": "Yรผkle", + "download": "ฤฐndirme", + "upload": "Yรผkleme", "leech": "Tรผketici", "seed": "SaฤŸlayฤฑcฤฑ" }, @@ -214,87 +221,87 @@ "invalid": "Geรงersiz" }, "deluge": { - "download": "ฤฐndir", - "upload": "Yรผkle", + "download": "ฤฐndirme", + "upload": "Yรผkleme", "leech": "Tรผketici", "seed": "SaฤŸlayฤฑcฤฑ" }, "downloadstation": { - "download": "ฤฐndir", - "upload": "Yรผkle", + "download": "ฤฐndirme", + "upload": "Yรผkleme", "leech": "Tรผketici", "seed": "SaฤŸlayฤฑcฤฑ" }, "sonarr": { - "wanted": "Aranan", - "queued": "Kuyrukta", + "wanted": "ฤฐstendi", + "queued": "Sฤฑrada", "series": "Diziler", "queue": "Kuyruk", "unknown": "Bilinmiyor" }, "radarr": { - "wanted": "Aranan", - "missing": "Kayฤฑp", - "queued": "Kuyrukta", + "wanted": "ฤฐstendi", + "missing": "Eksik", + "queued": "Sฤฑrada", "movies": "Filmler", "queue": "Kuyruk", "unknown": "Bilinmiyor" }, "lidarr": { - "wanted": "Aranan", - "queued": "Kuyrukta", + "wanted": "ฤฐstendi", + "queued": "Sฤฑrada", "artists": "Sanatรงฤฑlar" }, "readarr": { - "wanted": "Aranan", - "queued": "Kuyrukta", + "wanted": "ฤฐstendi", + "queued": "Sฤฑrada", "books": "Kitaplar" }, "bazarr": { - "missingEpisodes": "Kayฤฑp Bรถlรผmler", - "missingMovies": "Kayฤฑp Filmler" + "missingEpisodes": "Eksik Bรถlรผmler", + "missingMovies": "Eksik Filmler" }, "ombi": { - "pending": "Bekliyor", + "pending": "Bekleyen", "approved": "Onaylฤฑ", "available": "Kullanฤฑlabilir" }, "jellyseerr": { - "pending": "Bekliyor", + "pending": "Bekleyen", "approved": "Onaylฤฑ", "available": "Kullanฤฑlabilir" }, "overseerr": { - "pending": "Bekliyor", + "pending": "Bekleyen", "processing": "ฤฐลŸleniyor", "approved": "Onaylฤฑ", "available": "Kullanฤฑlabilir" }, - "pialert": { + "netalertx": { "total": "Toplam", "connected": "BaฤŸlandฤฑ", "new_devices": "Yeni Cihazlar", - "down_alerts": "DรผลŸme Uyarฤฑlarฤฑ" + "down_alerts": "Hata Uyarฤฑlarฤฑ" }, "pihole": { "queries": "Sorgular", "blocked": "Engellenen", "blocked_percent": "Engellenen %", - "gravity": "Yer ร‡ekimi" + "gravity": "Gravity" }, "adguard": { "queries": "Sorgular", "blocked": "Engellenen", - "filtered": "Filtrelenen", + "filtered": "Filtrelendi", "latency": "Gecikme" }, "speedtest": { - "upload": "Yรผkle", - "download": "ฤฐndir", + "upload": "Yรผkleme", + "download": "ฤฐndirme", "ping": "Gecikme" }, "portainer": { - "running": "ร‡alฤฑลŸan", + "running": "ร‡alฤฑลŸฤฑyor", "stopped": "Durduruldu", "total": "Toplam" }, @@ -346,10 +353,10 @@ }, "prowlarr": { "enableIndexers": "Dizin OluลŸturucular", - "numberOfGrabs": "Yakalama Sayฤฑsฤฑ", + "numberOfGrabs": "Yakalamalar", "numberOfQueries": "Sorgular", - "numberOfFailGrabs": "BaลŸarฤฑsฤฑz Yakalama Sayฤฑsฤฑ", - "numberOfFailQueries": "BaลŸarฤฑsฤฑz Sorgu Sayฤฑsฤฑ" + "numberOfFailGrabs": "BaลŸarฤฑsฤฑz Yakalamalar", + "numberOfFailQueries": "BaลŸarฤฑsฤฑz Sorgular" }, "jackett": { "configured": "YapฤฑlandฤฑrฤฑlmฤฑลŸ", @@ -367,8 +374,8 @@ "domain_count": "Etki Alanlarฤฑ" }, "medusa": { - "wanted": "Aranan", - "queued": "Kuyrukta", + "wanted": "ฤฐstendi", + "queued": "Sฤฑrada", "series": "Diziler" }, "minecraft": { @@ -379,7 +386,7 @@ "down": "ร‡evrimdฤฑลŸฤฑ" }, "miniflux": { - "read": "Oku", + "read": "Okunan", "unread": "OkunmamฤฑลŸ" }, "authentik": { @@ -397,17 +404,17 @@ "cpu": "CPU", "load": "Yรผk", "wait": "Lรผtfen bekleyin", - "temp": "Geรงici", + "temp": "Sฤฑcaklฤฑk", "_temp": "Sฤฑcaklฤฑk", "warn": "Uyarฤฑ", - "uptime": "ร‡alฤฑลŸma Sรผresi", + "uptime": "ร‡alฤฑลŸฤฑyor", "total": "Toplam", - "free": "BoลŸta", + "free": "BoลŸ", "used": "Kullanฤฑmda", "days": "g", "hours": "sa", "crit": "Kritik", - "read": "Oku", + "read": "Okunan", "write": "Yazma", "gpu": "GPU", "mem": "Hafฤฑza", @@ -419,7 +426,8 @@ "search": "Ara", "custom": "ร–zel", "visit": "Ziyaret", - "url": "URL" + "url": "URL", + "searchsuggestion": "ร–neri" }, "wmo": { "0-day": "GรผneลŸli", @@ -487,18 +495,18 @@ "child_bridges": "Alt Kรถprรผler", "child_bridges_status": "{{ok}}/{{total}}", "up": "Yรผkleme", - "pending": "Bekliyor", + "pending": "Bekleyen", "down": "ฤฐndirme" }, "healthchecks": { - "new": "New", + "new": "Yeni", "up": "Yรผkleme", - "grace": "In Grace Period", + "grace": "Tolerans Dรถneminde", "down": "ฤฐndirme", - "paused": "Paused", + "paused": "Duraklatฤฑldฤฑ", "status": "Durum", "last_ping": "Son Ping", - "never": "No pings yet" + "never": "Henรผz ping yok" }, "watchtower": { "containers_scanned": "Tarandฤฑ", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Kanallar", - "hd": "HD" + "hd": "HD", + "tunerCount": "Ayarlayฤฑcฤฑlar", + "channelNumber": "Kanal", + "channelNetwork": "AฤŸ", + "signalStrength": "SaฤŸlamlฤฑk", + "signalQuality": "Kalite", + "symbolQuality": "Kalite", + "networkRate": "Bit Oranฤฑ", + "clientIP": "Alฤฑcฤฑ" }, "scrutiny": { "passed": "Geรงti", @@ -548,11 +564,11 @@ }, "peanut": { "battery_charge": "Pil Yรผzdesi", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "ups_load": "UPS Yรผkรผ", + "ups_status": "UPS Durumu", "online": "ร‡evrimiรงi", "on_battery": "Pilde", - "low_battery": "Low Battery" + "low_battery": "DรผลŸรผk Pil" }, "nextdns": { "wait": "Lรผtfen Bekleyin", @@ -562,7 +578,7 @@ "cpuLoad": "CPU Yรผkรผ", "memoryUsed": "Bellek Kullanฤฑmฤฑ", "uptime": "ร‡alฤฑลŸma Sรผresi", - "numberOfLeases": "Leases" + "numberOfLeases": "Kiralama" }, "xteve": { "streams_all": "Tรผm AkฤฑลŸlar", @@ -570,9 +586,9 @@ "streams_xepg": "XEPG Kanallarฤฑ" }, "opendtu": { - "yieldDay": "Today", - "absolutePower": "Power", - "relativePower": "Power %", + "yieldDay": "Bugรผn", + "absolutePower": "Gรผรง", + "relativePower": "Gรผรง %", "limit": "Limit" }, "opnsense": { @@ -591,25 +607,25 @@ "printer_state": "Durum", "temp_tool": "Araรง sฤฑcaklฤฑฤŸฤฑ", "temp_bed": "Yatak sฤฑcaklฤฑฤŸฤฑ", - "job_completion": "Completion" + "job_completion": "Tamamlanma" }, "cloudflared": { - "origin_ip": "Origin IP", + "origin_ip": "Gerรงek IP", "status": "Durum" }, "pfsense": { - "load": "Load Avg", - "memory": "Mem Usage", - "wanStatus": "WAN Status", + "load": "Ort. Yรผkleme", + "memory": "Bellek Kullanฤฑmฤฑ", + "wanStatus": "WAN Durumu", "up": "Yรผkleme", "down": "ฤฐndirme", "temp": "Sฤฑcaklฤฑk", - "disk": "Disk Usage", + "disk": "Disk Kullanฤฑmฤฑ", "wanIP": "WAN IP" }, "proxmoxbackupserver": { - "datastore_usage": "Datastore", - "failed_tasks_24h": "Failed Tasks 24h", + "datastore_usage": "Veri deposu", + "failed_tasks_24h": "BaลŸarฤฑsฤฑz Gรถrevler 24h", "cpu_usage": "CPU", "memory_usage": "Bellek" }, @@ -620,17 +636,17 @@ "storage": "Depo" }, "uptimekuma": { - "up": "Sites Up", - "down": "Sites Down", + "up": "Siteler ร‡alฤฑลŸฤฑyor", + "down": "Siteler ร‡alฤฑลŸmฤฑyor", "uptime": "ร‡alฤฑลŸma Sรผresi", - "incident": "Incident", + "incident": "Olay", "m": "dk" }, "atsumeru": { "series": "Diziler", - "archives": "Archives", - "chapters": "Chapters", - "categories": "Categories" + "archives": "ArลŸivler", + "chapters": "Bรถlรผmler", + "categories": "Kategoriler" }, "komga": { "libraries": "Kรผtรผphane", @@ -645,7 +661,7 @@ "mylar": { "series": "Diziler", "issues": "Sorunlar", - "wanted": "Aranan" + "wanted": "ฤฐstendi" }, "photoprism": { "albums": "Albรผmler", @@ -657,151 +673,220 @@ "queue": "Kuyruk", "processing": "ฤฐลŸleniyor", "processed": "ฤฐลŸlendi", - "time": "Time" + "time": "Zaman" }, "grafana": { - "dashboards": "Dashboards", - "datasources": "Data Sources", - "totalalerts": "Total Alerts", - "alertstriggered": "Alerts Triggered" + "dashboards": "Kontrol Paneli", + "datasources": "Veri Kaynaklarฤฑ", + "totalalerts": "Toplam Uyarฤฑlar", + "alertstriggered": "Uyarฤฑlar Tetiklendi" }, "nextcloud": { - "cpuload": "Cpu Load", - "memoryusage": "Memory Usage", - "freespace": "Free Space", - "activeusers": "Active Users", - "numfiles": "Files", - "numshares": "Shared Items" + "cpuload": "Cpu Yรผkรผ", + "memoryusage": "Bellek Kullanฤฑmฤฑ", + "freespace": "BoลŸ Alan", + "activeusers": "Aktif Kullanฤฑcฤฑlar", + "numfiles": "Dosyalar", + "numshares": "PaylaลŸฤฑlan ร–ฤŸeler" }, "kopia": { "status": "Durum", - "size": "Size", - "lastrun": "Last Run", - "nextrun": "Next Run", + "size": "Boyut", + "lastrun": "Son ร‡alฤฑลŸma", + "nextrun": "Sonraki ร‡alฤฑลŸma", "failed": "BaลŸarฤฑsฤฑz" }, "unmanic": { - "active_workers": "Active Workers", - "total_workers": "Total Workers", - "records_total": "Queue Length" + "active_workers": "Aktif Kullanฤฑcฤฑlar", + "total_workers": "Toplam Kullanฤฑcฤฑlar", + "records_total": "Sฤฑra UzunluฤŸu" }, "pterodactyl": { - "servers": "Servers", - "nodes": "Nodes" + "servers": "Sunucular", + "nodes": "DรผฤŸรผmler" }, "prometheus": { - "targets_up": "Targets Up", - "targets_down": "Targets Down", - "targets_total": "Total Targets" + "targets_up": "Hedef ร‡alฤฑลŸฤฑyor", + "targets_down": "Hedef ร‡alฤฑลŸmฤฑyor", + "targets_total": "Toplam Hedef" + }, + "gatus": { + "up": "Siteler ร‡alฤฑลŸฤฑyor", + "down": "Siteler ร‡alฤฑลŸmฤฑyor", + "uptime": "ร‡alฤฑลŸma Sรผresi" }, "ghostfolio": { - "gross_percent_today": "Today", - "gross_percent_1y": "One year", - "gross_percent_max": "All time" + "gross_percent_today": "Bugรผn", + "gross_percent_1y": "Bir yฤฑl", + "gross_percent_max": "Tรผm zaman" }, "audiobookshelf": { - "podcasts": "Podcasts", + "podcasts": "Podcast", "books": "Kitaplar", - "podcastsDuration": "Duration", - "booksDuration": "Duration" + "podcastsDuration": "Sรผre", + "booksDuration": "Sรผre" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Evdeki ฤฐnsanlar", + "lights_on": "IลŸฤฑklar Aรงฤฑk", + "switches_on": "Aรง" }, "whatsupdocker": { - "monitoring": "Monitoring", + "monitoring": "ฤฐzleme", "updates": "Gรผncellemeler" }, "calibreweb": { "books": "Kitaplar", - "authors": "Authors", - "categories": "Categories", + "authors": "Yazarlar", + "categories": "Kategoriler", "series": "Diziler" }, "jdownloader": { "downloadCount": "Kuyruk", "downloadBytesRemaining": "Kalan", - "downloadTotalBytes": "Size", + "downloadTotalBytes": "Boyut", "downloadSpeed": "Hฤฑz" }, "kavita": { "seriesCount": "Diziler", - "totalFiles": "Files" + "totalFiles": "Dosyalar" }, "azuredevops": { - "result": "Result", + "result": "Sonuรง", "status": "Durum", - "buildId": "Build ID", - "succeeded": "Succeeded", - "notStarted": "Not Started", + "buildId": "Yapฤฑ KimliฤŸi", + "succeeded": "BaลŸarฤฑlฤฑ", + "notStarted": "Henรผz BaลŸlamadฤฑ", "failed": "BaลŸarฤฑsฤฑz", - "canceled": "Canceled", - "inProgress": "In Progress", - "totalPrs": "Total PRs", - "myPrs": "My PRs", + "canceled": "ฤฐptal edildi", + "inProgress": "Sรผrรผyor", + "totalPrs": "Toplam ร‡ekme ฤฐstekleri", + "myPrs": "Benim ร‡ekme ฤฐsteklerim", "approved": "Onaylฤฑ" }, "gamedig": { "status": "Durum", "online": "ร‡evrimiรงi", "offline": "ร‡evrimdฤฑลŸฤฑ", - "name": "Name", - "map": "Map", - "currentPlayers": "Current players", + "name": "ฤฐsim", + "map": "Harita", + "currentPlayers": "Mevcut oyuncular", "players": "Oyuncular", - "maxPlayers": "Max players", - "bots": "Bots", + "maxPlayers": "Maks. oyuncu", + "bots": "Botlar", "ping": "Gecikme" }, "urbackup": { - "ok": "Ok", - "errored": "Errors", - "noRecent": "Out of Date", - "totalUsed": "Used Storage" + "ok": "Tamam", + "errored": "Hatalar", + "noRecent": "Tarihi geรงmiลŸ", + "totalUsed": "Kullanฤฑlan depolama alanฤฑ" }, "mealie": { - "recipes": "Recipes", + "recipes": "Tarifler", "users": "Kullanฤฑcฤฑlar", - "categories": "Categories", - "tags": "Tags" + "categories": "Kategoriler", + "tags": "Etiketler" }, "openmediavault": { - "downloading": "Downloading", + "downloading": "ฤฐndiriliyor", "total": "Toplam", - "running": "ร‡alฤฑลŸan", + "running": "ร‡alฤฑลŸฤฑyor", "stopped": "Durduruldu", "passed": "Geรงti", "failed": "BaลŸarฤฑsฤฑz" }, + "openwrt": { + "uptime": "ร‡alฤฑลŸma Sรผresi", + "cpuLoad": "CPU Yรผkรผ Ortalamasฤฑ (5dk)", + "up": "Yรผkleme", + "down": "ฤฐndirme", + "bytesTx": "ฤฐletilen", + "bytesRx": "Alฤฑnan" + }, "uptimerobot": { "status": "Durum", "uptime": "ร‡alฤฑลŸma Sรผresi", - "lastDown": "Last Downtime", - "downDuration": "Downtime Duration", - "sitesUp": "Sites Up", - "sitesDown": "Sites Down", - "paused": "Paused", - "notyetchecked": "Not Yet Checked", + "lastDown": "Son Kesinti", + "downDuration": "Kesinti Sรผresi", + "sitesUp": "Siteler ร‡alฤฑลŸฤฑyor", + "sitesDown": "Siteler ร‡alฤฑลŸmฤฑyor", + "paused": "Duraklatฤฑldฤฑ", + "notyetchecked": "Henรผz Kontrol Edilmedi", "up": "Yรผkleme", - "seemsdown": "Seems Down", + "seemsdown": "Kapalฤฑ gรถrรผnรผyor", "down": "ฤฐndirme", "unknown": "Bilinmiyor" }, "calendar": { - "inCinemas": "In cinemas", - "physicalRelease": "Physical release", - "digitalRelease": "Digital release", - "noEventsToday": "No events for today!", - "noEventsFound": "No events found" + "inCinemas": "Sinemalarda", + "physicalRelease": "Fiziksel Yayฤฑnlanan", + "digitalRelease": "Dijitalde Yayฤฑnlandฤฑ", + "noEventsToday": "Bugรผn iรงin etkinlik yok!", + "noEventsFound": "Etkinlik bulunamadฤฑ" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "Platformlar", + "totalRoms": "Toplam ROM'lar" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "Uyarฤฑlar", + "criticals": "Kritik" + }, + "plantit": { + "events": "Etkinlikler", + "plants": "Bitkiler", + "photos": "FotoฤŸraflar", + "species": "Tรผrler" + }, + "gitea": { + "notifications": "Bildirimler", + "issues": "Sorunlar", + "pulls": "DeฤŸiลŸiklik ฤฐstekleri" + }, + "stash": { + "scenes": "Sahneler", + "scenesPlayed": "Oynanan Sahneler", + "playCount": "Toplam Oynatma", + "playDuration": "ฤฐzlenen Sรผre", + "sceneSize": "Sahne Boyutu", + "sceneDuration": "Sahne Sรผresi", + "images": "Gรถrseller", + "imageSize": "Gรถrsel Boyutu", + "galleries": "Galeriler", + "performers": "Oyuncu", + "studios": "Stรผdyolar", + "movies": "Filmler", + "tags": "Etiketler", + "oCount": "O Sayฤฑsฤฑ" + }, + "tandoor": { + "users": "Kullanฤฑcฤฑlar", + "recipes": "Tarifler", + "keywords": "Anahtar Sรถzcรผkler" + }, + "homebox": { + "items": "ร–geler", + "totalWithWarranty": "Garantili", + "locations": "Konum", + "labels": "Etiketler", + "users": "Kullanฤฑcฤฑlar", + "totalValue": "Toplam DeฤŸer" + }, + "crowdsec": { + "alerts": "Alarmlar", + "bans": "Yasaklar" + }, + "wgeasy": { + "connected": "BaฤŸlandฤฑ", + "enabled": "Etkin", + "disabled": "Devre DฤฑลŸฤฑ", + "total": "Toplam" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/uk/common.json b/public/locales/uk/common.json index 5cee41a6..239de674 100644 --- a/public/locales/uk/common.json +++ b/public/locales/uk/common.json @@ -107,6 +107,13 @@ "episodes": "ะ•ะฟั–ะทะพะดะธ", "songs": "ะŸั–ัะฝั–" }, + "esphome": { + "offline": "ะžั„ะปะฐะนะฝ", + "offline_alt": "ะžั„ะปะฐะนะฝ", + "online": "ะžะฝะปะฐะนะฝ", + "total": "ะฃััŒะพะณะพ", + "unknown": "ะะตะฒั–ะดะพะผะธะน" + }, "evcc": { "pv_power": "ะ’ะธั€ะพะฑะฝะธั†ั‚ะฒะพ", "battery_soc": "ะ‘ะฐั‚ะฐั€ะตั", @@ -133,7 +140,7 @@ "connectionStatusPendingDisconnect": "Pending Disconnect", "connectionStatusDisconnecting": "Disconnecting", "connectionStatusDisconnected": "Disconnected", - "connectionStatusConnected": "ะŸั–ะดะบะปัŽั‡ะตะฝะพ", + "connectionStatusConnected": "Connected", "uptime": "ะงะฐั ั€ะพะฑะพั‚ะธ", "maxDown": "Max. Down", "maxUp": "Max. Up", @@ -270,11 +277,11 @@ "approved": "ะ—ะฐั‚ะฒะตั€ะดะถะตะฝะพ", "available": "ะ”ะพัั‚ัƒะฟะฝะพ" }, - "pialert": { + "netalertx": { "total": "ะฃััŒะพะณะพ", - "connected": "ะŸั–ะดะบะปัŽั‡ะตะฝะพ", - "new_devices": "ะะพะฒั– ะฟั€ะธัั‚ั€ะพั—", - "down_alerts": "ะกะฟะพะฒั–ั‰ะตะฝะฝั ะฟั€ะพ ะทะฑั–ะน" + "connected": "Connected", + "new_devices": "New Devices", + "down_alerts": "Down Alerts" }, "pihole": { "queries": "ะ—ะฐะฟะธั‚ะธ", @@ -419,7 +426,8 @@ "search": "ะŸะพัˆัƒะบ", "custom": "ะšะพั€ะธัั‚ัƒะฒะฐั†ัŒะบะธะน", "visit": "ะ’ั–ะดะฒั–ะดะฐะนั‚ะต", - "url": "URL-ะฐะดั€ะตัะฐ" + "url": "URL-ะฐะดั€ะตัะฐ", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "ะกะพะฝัั‡ะฝะพ", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "ะšะฐะฝะฐะปะธ", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "ะ‘ั–ั‚ั€ะตะนั‚", + "clientIP": "Client" }, "scrutiny": { "passed": "ะŸั€ะพะนัˆะพะฒ", @@ -694,6 +710,11 @@ "targets_down": "ะฆั–ะปั– ะฒะฝะธะท", "targets_total": "ะ’ััŒะพะณะพ ั†ั–ะปะตะน" }, + "gatus": { + "up": "ะะบั‚ะธะฒะฝั– ัะฐะนั‚ะธ", + "down": "ะะตะฐะบั‚ะธะฒะฝั– ัะฐะนั‚ะธ", + "uptime": "ะงะฐั ั€ะพะฑะพั‚ะธ" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "ะžะดะธะฝ ั€ั–ะบ", @@ -775,6 +796,14 @@ "passed": "ะŸั€ะพะนัˆะพะฒ", "failed": "ะะตะฒะดะฐั‡ะฐ" }, + "openwrt": { + "uptime": "ะงะฐั ั€ะพะฑะพั‚ะธ", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "ะกั‚ะฐะฝ", "uptime": "ะงะฐั ั€ะพะฑะพั‚ะธ", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "ะคะพั‚ะพะณั€ะฐั„ั–ั—", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "ะŸะธั‚ะฐะฝะฝั", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "ะคั–ะปัŒะผะธ", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "ะšะพั€ะธัั‚ัƒะฒะฐั‡ั–", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "ะšะพั€ะธัั‚ัƒะฒะฐั‡ั–", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "ะžะฟะพะฒั–ั‰ะตะฝะฝั", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "ะฃะฒั–ะผะบะฝะตะฝะพ", + "disabled": "ะ’ะธะผะบะฝะตะฝะพ", + "total": "ะฃััŒะพะณะพ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/vi/common.json b/public/locales/vi/common.json index 45b7cdef..7eeab113 100644 --- a/public/locales/vi/common.json +++ b/public/locales/vi/common.json @@ -107,6 +107,13 @@ "episodes": "Episodes", "songs": "Songs" }, + "esphome": { + "offline": "Ngoแบกi tuyแบฟn", + "offline_alt": "Ngoแบกi tuyแบฟn", + "online": "Online", + "total": "Tแป•ng", + "unknown": "Unknown" + }, "evcc": { "pv_power": "Production", "battery_soc": "Battery", @@ -270,7 +277,7 @@ "approved": "ฤรฃ duyแป‡t", "available": "Available" }, - "pialert": { + "netalertx": { "total": "Tแป•ng", "connected": "Connected", "new_devices": "New Devices", @@ -419,7 +426,8 @@ "search": "Search", "custom": "Custom", "visit": "Visit", - "url": "URL" + "url": "URL", + "searchsuggestion": "Suggestion" }, "wmo": { "0-day": "Sunny", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "Channels", - "hd": "HD" + "hd": "HD", + "tunerCount": "Tuners", + "channelNumber": "Channel", + "channelNetwork": "Network", + "signalStrength": "Strength", + "signalQuality": "Quality", + "symbolQuality": "Quality", + "networkRate": "Bitrate", + "clientIP": "Client" }, "scrutiny": { "passed": "Passed", @@ -694,6 +710,11 @@ "targets_down": "Targets Down", "targets_total": "Total Targets" }, + "gatus": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime" + }, "ghostfolio": { "gross_percent_today": "Today", "gross_percent_1y": "One year", @@ -775,6 +796,14 @@ "passed": "Passed", "failed": "Failed" }, + "openwrt": { + "uptime": "Uptime", + "cpuLoad": "CPU Load Avg (5m)", + "up": "Up", + "down": "Down", + "bytesTx": "Transmitted", + "bytesRx": "Received" + }, "uptimerobot": { "status": "Trแบกng thรกi", "uptime": "Uptime", @@ -803,5 +832,61 @@ "netdata": { "warnings": "Warnings", "criticals": "Criticals" + }, + "plantit": { + "events": "Events", + "plants": "Plants", + "photos": "Photos", + "species": "Species" + }, + "gitea": { + "notifications": "Notifications", + "issues": "Issues", + "pulls": "Pull Requests" + }, + "stash": { + "scenes": "Scenes", + "scenesPlayed": "Scenes Played", + "playCount": "Total Plays", + "playDuration": "Time Watched", + "sceneSize": "Scenes Size", + "sceneDuration": "Scenes Duration", + "images": "Images", + "imageSize": "Images Size", + "galleries": "Galleries", + "performers": "Performers", + "studios": "Studios", + "movies": "Movies", + "tags": "Tags", + "oCount": "O Count" + }, + "tandoor": { + "users": "Users", + "recipes": "Recipes", + "keywords": "Keywords" + }, + "homebox": { + "items": "Items", + "totalWithWarranty": "With Warranty", + "locations": "Locations", + "labels": "Labels", + "users": "Users", + "totalValue": "Total Value" + }, + "crowdsec": { + "alerts": "Alerts", + "bans": "Bans" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "Enabled", + "disabled": "Disabled", + "total": "Tแป•ng" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/yue/common.json b/public/locales/yue/common.json index baec31f0..4d425c45 100644 --- a/public/locales/yue/common.json +++ b/public/locales/yue/common.json @@ -107,6 +107,13 @@ "episodes": "้›†", "songs": "ๆ›ฒ็›ฎ" }, + "esphome": { + "offline": "้›ข็ทš", + "offline_alt": "้›ข็ทš", + "online": "ๅœจ็ทš", + "total": "ๅ…จ้ƒจ", + "unknown": "ๆœช็Ÿฅ" + }, "evcc": { "pv_power": "ๆญฃๅผ็’ฐๅขƒ", "battery_soc": "้›ปๆฑ ", @@ -133,7 +140,7 @@ "connectionStatusPendingDisconnect": "ๅพ…่พฆ็š„ๆ–ท้–‹", "connectionStatusDisconnecting": "ๆญฃๅœจไธญๆ–ท้€ฃ็ทš", "connectionStatusDisconnected": "้€ฃๆŽฅๅทฒไธญๆ–ท", - "connectionStatusConnected": "ๅทฒ้€ฃ็ทš", + "connectionStatusConnected": "Connected", "uptime": "้‹่กŒๆ™‚้–“", "maxDown": "ๆœ€ๅคงไธ‹่ผ‰้€Ÿ็އ", "maxUp": "ๆœ€ๅคงไธŠๅ‚ณ้€Ÿ็އ", @@ -270,11 +277,11 @@ "approved": "ๆ‰นๅ‡†", "available": "ๅฏ็”จ" }, - "pialert": { + "netalertx": { "total": "ๅ…จ้ƒจ", - "connected": "ๅทฒ้€ฃ็ทš", - "new_devices": "ๆ–ฐ่ฃ็ฝฎ", - "down_alerts": "้›ข็ทš่ญฆๅ‘Š" + "connected": "Connected", + "new_devices": "New Devices", + "down_alerts": "Down Alerts" }, "pihole": { "queries": "ๆŸฅ่ฉข", @@ -419,7 +426,8 @@ "search": "ๆœๅฐ‹", "custom": "่‡ช่จ‚", "visit": "้€ ่จช", - "url": "็ถฒๅ€" + "url": "็ถฒๅ€", + "searchsuggestion": "ๅปบ่ญฐ" }, "wmo": { "0-day": "ๆ™ดๅคฉ", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "้ ป้“", - "hd": "้ซ˜็•ซ่ณช" + "hd": "้ซ˜็•ซ่ณช", + "tunerCount": "่ชฟ่ซงๅ™จ", + "channelNumber": "้ ป้“", + "channelNetwork": "็ถฒ็ตก", + "signalStrength": "ๅผทๅบฆ", + "signalQuality": "ๅ“่ณช", + "symbolQuality": "ๅ“่ณช", + "networkRate": "ๆฏ”็‰น็އ", + "clientIP": "็”จๆˆถ็ซฏ" }, "scrutiny": { "passed": "้€š้Ž", @@ -548,8 +564,8 @@ }, "peanut": { "battery_charge": "ๅ……้›ป", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "ups_load": "ๅพŒๅ‚™้›ป่ฒ ่ผ‰", + "ups_status": "ๅพŒๅ‚™้›ป็‹€ๆณ", "online": "ๅœจ็ทš", "on_battery": "้›ปๆฑ ไพ›้›ป", "low_battery": "ไฝŽ้›ป้‡" @@ -694,6 +710,11 @@ "targets_down": "็›ฎๆจ™้›ข็ทš", "targets_total": "็›ฎๆจ™็ธฝๆ•ธ" }, + "gatus": { + "up": "ๅœจ็ทš็ถฒ็ซ™", + "down": "้›ข็ทš็ถฒ็ซ™", + "uptime": "้‹่กŒๆ™‚้–“" + }, "ghostfolio": { "gross_percent_today": "ไปŠๆ—ฅ", "gross_percent_1y": "ไธ€ๅนด", @@ -775,6 +796,14 @@ "passed": "้€š้Ž", "failed": "ๅคฑๆ•—" }, + "openwrt": { + "uptime": "้‹่กŒๆ™‚้–“", + "cpuLoad": "่™•็†ๅ™จๅนณๅ‡่ฒ ่ผ‰(5ๅˆ†้˜)", + "up": "ๅœจ็ทš", + "down": "้›ข็ทš", + "bytesTx": "ๅทฒๅ‚ณ้€", + "bytesRx": "ๅทฒๆŽฅๆ”ถ" + }, "uptimerobot": { "status": "็‹€ๆณ", "uptime": "้‹่กŒๆ™‚้–“", @@ -797,11 +826,67 @@ "noEventsFound": "ๆœชๆ‰พๅˆฐไบ‹ไปถ" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "ๅนณๅฐ", + "totalRoms": "็ธฝๅ”ฏ่ฎ€่จ˜ๆ†ถ้ซ”" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "่ญฆๅ‘Š", + "criticals": "ๅšด้‡" + }, + "plantit": { + "events": "ไบ‹ไปถ", + "plants": "ๆค็‰ฉ", + "photos": "็…ง็‰‡", + "species": "็‰ฉ็จฎ" + }, + "gitea": { + "notifications": "ไฟกๆฏ", + "issues": "ๅ‡บ็‰ˆ", + "pulls": "ๆๅ–่ซ‹ๆฑ‚" + }, + "stash": { + "scenes": "ๅ ดๆ™ฏ", + "scenesPlayed": "ๅทฒๆ’ญๆ”พๅ ดๆ™ฏ", + "playCount": "ๅˆๅ…ฑๆ’ญๆ”พ", + "playDuration": "่ง€็œ‹ๆ™‚ๆ•ธ", + "sceneSize": "ๅ ดๆ™ฏๅคงๅฐ", + "sceneDuration": "ๅ ดๆ™ฏ็‚บๆœŸ", + "images": "ๅœ–็‰‡", + "imageSize": "ๅœ–ๅƒๅคงๅฐ", + "galleries": "็•ซๅปŠ", + "performers": "่กจๆผ”่€…", + "studios": "ๅทฅไฝœๅฎค", + "movies": "้›ปๅฝฑ", + "tags": "ๆจ™็ฑค", + "oCount": "0 ๅ€‹" + }, + "tandoor": { + "users": "ไฝฟ็”จ่€…", + "recipes": "้ฃŸ่ญœ", + "keywords": "้—œ้ตๅญ—" + }, + "homebox": { + "items": "้ …็›ฎ", + "totalWithWarranty": "ๆœ‰ไฟ่จผ", + "locations": "ไฝ็ฝฎ", + "labels": "ๆจ™็ฑค", + "users": "ไฝฟ็”จ่€…", + "totalValue": "็ธฝๅ…ฑ" + }, + "crowdsec": { + "alerts": "่ญฆ็คบ", + "bans": "็ฆๆญข" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "ๅ•Ÿ็”จ", + "disabled": "ๅœ็”จๅ’—", + "total": "ๅ…จ้ƒจ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/public/locales/zh-Hans/common.json b/public/locales/zh-Hans/common.json index 68e17e85..f82495b9 100644 --- a/public/locales/zh-Hans/common.json +++ b/public/locales/zh-Hans/common.json @@ -14,11 +14,11 @@ "date": "{{value, date}}", "relativeDate": "{{value, relativeDate}}", "uptime": "{{value, uptime}}", - "months": "mo", - "days": "d", - "hours": "h", - "minutes": "m", - "seconds": "s" + "months": "ๆœˆ", + "days": "ๆ—ฅ", + "hours": "ๆ—ถ", + "minutes": "ๅˆ†", + "seconds": "็ง’" }, "widget": { "missing_type": "็ผบๅคฑ็š„็ป„ไปถ็ฑปๅž‹: {{type}}", @@ -57,10 +57,10 @@ "lan": "LAN", "wlan": "WLAN", "devices": "่ฎพๅค‡", - "lan_devices": "LAN่ฎพๅค‡", + "lan_devices": "LAN ่ฎพๅค‡", "wlan_devices": "WLAN ่ฎพๅค‡", - "lan_users": "LAN ็”จๆˆท", - "wlan_users": "WLAN ็”จๆˆท", + "lan_users": "ๆœ‰็บฟ็”จๆˆท", + "wlan_users": "ๆ— ็บฟ็”จๆˆท", "up": "่ฟ่กŒๆ—ถ้—ด", "down": "็ฆป็บฟ", "wait": "่ฏท็จๅ€™", @@ -90,7 +90,7 @@ "not_available": "ไธๅฏ็”จ" }, "siteMonitor": { - "http_status": "HTTP status", + "http_status": "HTTP ็Šถๆ€", "error": "้”™่ฏฏ", "response": "ๅ“ๅบ”", "down": "็ฆป็บฟ", @@ -107,6 +107,13 @@ "episodes": "้›†", "songs": "ๆ›ฒ็›ฎ" }, + "esphome": { + "offline": "็ฆป็บฟ", + "offline_alt": "็ฆป็บฟ", + "online": "ๅœจ็บฟ", + "total": "ๆ€ป่ฎก", + "unknown": "ๆœช็Ÿฅ" + }, "evcc": { "pv_power": "ๅ‘็”ต้‡", "battery_soc": "็”ต้‡", @@ -127,21 +134,21 @@ }, "fritzbox": { "connectionStatus": "็Šถๆ€", - "connectionStatusUnconfigured": "Unconfigured", - "connectionStatusConnecting": "Connecting", - "connectionStatusAuthenticating": "Authenticating", - "connectionStatusPendingDisconnect": "Pending Disconnect", - "connectionStatusDisconnecting": "Disconnecting", - "connectionStatusDisconnected": "Disconnected", + "connectionStatusUnconfigured": "ๆœช้…็ฝฎ", + "connectionStatusConnecting": "่ฟžๆŽฅไธญ", + "connectionStatusAuthenticating": "่ฎค่ฏไธญ", + "connectionStatusPendingDisconnect": "็ญ‰ๅพ…ๆ–ญๅผ€่ฟžๆŽฅ", + "connectionStatusDisconnecting": "ๆญฃๅœจๆ–ญๅผ€่ฟžๆŽฅ", + "connectionStatusDisconnected": "ๆœช่ฟžๆŽฅ", "connectionStatusConnected": "ๅทฒ่ฟžๆŽฅ", "uptime": "่ฟ่กŒๆ—ถ้—ด", - "maxDown": "Max. Down", - "maxUp": "Max. Up", + "maxDown": "ๆœ€ๅคงไธ‹่ฝฝ้€Ÿๅบฆ", + "maxUp": "", "down": "็ฆป็บฟ", "up": "ๅœจ็บฟ", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP" + "received": "ๅทฒๆŽฅๆ”ถ", + "sent": "ๅทฒๅ‘้€", + "externalIPAddress": "ๅค–้ƒจIP" }, "caddy": { "upstreams": "ไธŠ่กŒ", @@ -227,7 +234,7 @@ }, "sonarr": { "wanted": "ๅ…ณๆณจไธญ", - "queued": "ๅทฒๅŠ ๅ…ฅ้˜Ÿๅˆ—", + "queued": "้˜Ÿๅˆ—ไธญ", "series": "ๅ‰ง้›†", "queue": "้˜Ÿๅˆ—", "unknown": "ๆœช็Ÿฅ" @@ -235,19 +242,19 @@ "radarr": { "wanted": "ๅ…ณๆณจไธญ", "missing": "็ผบๅคฑ", - "queued": "ๅทฒๅŠ ๅ…ฅ้˜Ÿๅˆ—", + "queued": "้˜Ÿๅˆ—ไธญ", "movies": "็”ตๅฝฑ", "queue": "้˜Ÿๅˆ—", "unknown": "ๆœช็Ÿฅ" }, "lidarr": { "wanted": "ๅ…ณๆณจไธญ", - "queued": "ๅทฒๅŠ ๅ…ฅ้˜Ÿๅˆ—", + "queued": "้˜Ÿๅˆ—ไธญ", "artists": "่‰บๆœฏๅฎถ" }, "readarr": { "wanted": "ๅ…ณๆณจไธญ", - "queued": "ๅทฒๅŠ ๅ…ฅ้˜Ÿๅˆ—", + "queued": "้˜Ÿๅˆ—ไธญ", "books": "ไนฆ็ฑ" }, "bazarr": { @@ -270,7 +277,7 @@ "approved": "ๅทฒๆ‰นๅ‡†", "available": "ๅฏ็”จ" }, - "pialert": { + "netalertx": { "total": "ๆ€ป่ฎก", "connected": "ๅทฒ่ฟžๆŽฅ", "new_devices": "ๆ–ฐ่ฎพๅค‡", @@ -368,7 +375,7 @@ }, "medusa": { "wanted": "ๅ…ณๆณจไธญ", - "queued": "ๅทฒๅŠ ๅ…ฅ้˜Ÿๅˆ—", + "queued": "้˜Ÿๅˆ—ไธญ", "series": "ๅ‰ง้›†" }, "minecraft": { @@ -404,8 +411,8 @@ "total": "ๆ€ป่ฎก", "free": "็ฉบ้—ฒ", "used": "ๅทฒไฝฟ็”จ", - "days": "d", - "hours": "h", + "days": "ๆ—ฅ", + "hours": "ๆ—ถ", "crit": "ไธฅ้‡", "read": "ๅทฒ่ฏป", "write": "ๅ†™ๅ…ฅ", @@ -419,7 +426,8 @@ "search": "ๆœ็ดข", "custom": "่‡ชๅฎšไน‰", "visit": "่ฎฟ้—ฎ", - "url": "URL" + "url": "URL", + "searchsuggestion": "ๅปบ่ฎฎ" }, "wmo": { "0-day": "ๆ™ดๅคฉ", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "้ข‘้“", - "hd": "HD" + "hd": "HD", + "tunerCount": "็”ตๅฐๆ•ฐ", + "channelNumber": "้ข‘้“ๆ•ฐ", + "channelNetwork": "็ฝ‘็ปœ", + "signalStrength": "ๅผบๅบฆ", + "signalQuality": "่ดจ้‡", + "symbolQuality": "่ดจ้‡", + "networkRate": "็ ็އ", + "clientIP": "ๅฎขๆˆท็ซฏ" }, "scrutiny": { "passed": "้€š่ฟ‡", @@ -547,12 +563,12 @@ "total": "ๆ€ป่ฎก" }, "peanut": { - "battery_charge": "Battery Charge", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "battery_charge": "ๅ……็”ตไธญ", + "ups_load": "UPS ่ดŸ่ฝฝ", + "ups_status": "UPS ็Šถๆ€", "online": "ๅœจ็บฟ", - "on_battery": "On Battery", - "low_battery": "Low Battery" + "on_battery": "็”ตๆฑ ไพ›็”ต", + "low_battery": "็”ต้‡ไฝŽ" }, "nextdns": { "wait": "่ฏท็จๅ€™", @@ -624,7 +640,7 @@ "down": "็ฆป็บฟ็ฝ‘็ซ™", "uptime": "่ฟ่กŒๆ—ถ้—ด", "incident": "ไบ‹ไปถ", - "m": "m" + "m": "ๅˆ†" }, "atsumeru": { "series": "ๅ‰ง้›†", @@ -694,6 +710,11 @@ "targets_down": "็ฆป็บฟ็›ฎๆ ‡", "targets_total": "็›ฎๆ ‡ๆ€ปๆ•ฐ" }, + "gatus": { + "up": "ๅœจ็บฟ็ฝ‘็ซ™", + "down": "็ฆป็บฟ็ฝ‘็ซ™", + "uptime": "่ฟ่กŒๆ—ถ้—ด" + }, "ghostfolio": { "gross_percent_today": "ไปŠๆ—ฅ", "gross_percent_1y": "1ๅนด", @@ -775,6 +796,14 @@ "passed": "้€š่ฟ‡", "failed": "ๅคฑ่ดฅ" }, + "openwrt": { + "uptime": "่ฟ่กŒๆ—ถ้—ด", + "cpuLoad": "CPU ่ดŸ่ฝฝๅนณๅ‡ๅ€ผ(5m)", + "up": "ๅœจ็บฟ", + "down": "็ฆป็บฟ", + "bytesTx": "ๅทฒไผ ่พ“", + "bytesRx": "ๅทฒๆŽฅๆ”ถ" + }, "uptimerobot": { "status": "็Šถๆ€", "uptime": "่ฟ่กŒๆ—ถ้—ด", @@ -797,11 +826,67 @@ "noEventsFound": "ๆœชๆ‰พๅˆฐไบ‹ไปถ" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "ๅนณๅฐ", + "totalRoms": "ๆ€ปROM" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "่ญฆๅ‘Š", + "criticals": "ไธฅ้‡" + }, + "plantit": { + "events": "ไบ‹ไปถ", + "plants": "ๆค็‰ฉ", + "photos": "็…ง็‰‡", + "species": "็‰ฉ็ง" + }, + "gitea": { + "notifications": "้€š็Ÿฅ", + "issues": "ๅ‡บ็‰ˆ", + "pulls": "PR" + }, + "stash": { + "scenes": "ๅœบๆ™ฏ", + "scenesPlayed": "ๅทฒๆ’ญๆ”พๅœบๆ™ฏ", + "playCount": "ๆ’ญๆ”พๆ€ปๆ•ฐ", + "playDuration": "ๆ’ญๆ”พๆ—ถ้—ด", + "sceneSize": "ๅœบๆ™ฏๅคงๅฐ", + "sceneDuration": "ๅœบๆ™ฏๆ—ถ้•ฟ", + "images": "ๅ›พ็‰‡", + "imageSize": "ๅ›พๅƒๅคงๅฐ", + "galleries": "ๅ›พๅบ“", + "performers": "ๆผ”ๅ‘˜", + "studios": "ๅทฅไฝœๅฎค", + "movies": "็”ตๅฝฑ", + "tags": "ๆ ‡็ญพ", + "oCount": "O ไธช" + }, + "tandoor": { + "users": "็”จๆˆทๆ•ฐ", + "recipes": "้ฃŸ่ฐฑ", + "keywords": "ๅ…ณ้”ฎ่ฏ" + }, + "homebox": { + "items": "ๆก็›ฎ", + "totalWithWarranty": "ๆœ‰ไฟ่ฏ", + "locations": "ไฝ็ฝฎ", + "labels": "ๆ ‡็ญพ", + "users": "็”จๆˆทๆ•ฐ", + "totalValue": "ๆ€ป่ฎก" + }, + "crowdsec": { + "alerts": "่ญฆๅ‘Š", + "bans": "็ฆ็”จ" + }, + "wgeasy": { + "connected": "ๅทฒ่ฟžๆŽฅ", + "enabled": "ๅฏ็”จ", + "disabled": "็ฆ็”จ", + "total": "ๆ€ป่ฎก" + }, + "swagdashboard": { + "proxied": "ๅทฒไปฃ็†", + "auth": "ไฝฟ็”จ่ฎค่ฏ", + "outdated": "ๅทฒ่ฟ‡ๆœŸ", + "banned": "ๅทฒ็ฆๆญข" } } diff --git a/public/locales/zh-Hant/common.json b/public/locales/zh-Hant/common.json index 08ebe7d5..e88ac2bb 100644 --- a/public/locales/zh-Hant/common.json +++ b/public/locales/zh-Hant/common.json @@ -32,8 +32,8 @@ "weather": { "current": "็›ฎๅ‰ไฝ็ฝฎ", "allow": "้ปžๆ“Šไปฅๅ…่จฑ", - "updating": "ๆ›ดๆ–ฐไธญ", - "wait": "่ซ‹็จๅพŒ" + "updating": "ๆญฃๅœจๆ›ดๆ–ฐ", + "wait": "่ซ‹็จๅ€™" }, "search": { "placeholder": "ๆœๅฐ‹โ€ฆ" @@ -50,7 +50,7 @@ "uptime": "้‹ไฝœๆ™‚้–“" }, "unifi": { - "users": "ไฝฟ็”จ่€…", + "users": "็”จๆˆถ", "uptime": "้‹่กŒๆ™‚้–“", "days": "ๅคฉ", "wan": "WAN", @@ -63,7 +63,7 @@ "wlan_users": "็„ก็ทšไฝฟ็”จ่€…", "up": "้‹ไฝœๆ™‚้–“", "down": "้›ข็ทš", - "wait": "่ซ‹็จๅพŒ", + "wait": "่ซ‹็จๅ€™", "empty_data": "ๅญ็ณป็ตฑ็‹€ๆ…‹ๆœช็Ÿฅ" }, "docker": { @@ -107,6 +107,13 @@ "episodes": "้›†", "songs": "ๆ›ฒ็›ฎ" }, + "esphome": { + "offline": "้›ข็ทš", + "offline_alt": "้›ข็ทš", + "online": "ๅœจ็ทš", + "total": "ๅ…จ้ƒจ", + "unknown": "ๆœช็Ÿฅ" + }, "evcc": { "pv_power": "ๆญฃๅผ็’ฐๅขƒ", "battery_soc": "้›ปๆฑ ", @@ -133,7 +140,7 @@ "connectionStatusPendingDisconnect": "ๅพ…่พฆ็š„ๆ–ท้–‹", "connectionStatusDisconnecting": "ๆญฃๅœจไธญๆ–ท้€ฃ็ทš", "connectionStatusDisconnected": "้€ฃๆŽฅๅทฒไธญๆ–ท", - "connectionStatusConnected": "ๅทฒ้€ฃ็ทš", + "connectionStatusConnected": "Connected", "uptime": "้‹่กŒๆ™‚้–“", "maxDown": "ๆœ€ๅคงไธ‹่ผ‰้€Ÿ็އ", "maxUp": "ๆœ€ๅคงไธŠๅ‚ณ้€Ÿ็އ", @@ -270,11 +277,11 @@ "approved": "ๅทฒๆ ธๅ‡†", "available": "ๅฏ่ง€็œ‹" }, - "pialert": { + "netalertx": { "total": "ๅ…จ้ƒจ", - "connected": "ๅทฒ้€ฃ็ทš", - "new_devices": "ๆ–ฐ่ฃ็ฝฎ", - "down_alerts": "้›ข็ทš่ญฆๅ‘Š" + "connected": "Connected", + "new_devices": "New Devices", + "down_alerts": "Down Alerts" }, "pihole": { "queries": "ๆŸฅ่ฉข", @@ -362,7 +369,7 @@ "transferRate": "้€Ÿ็އ" }, "mastodon": { - "user_count": "ไฝฟ็”จ่€…", + "user_count": "็”จๆˆถ", "status_count": "ๆ–‡็ซ ", "domain_count": "็ถฒๅŸŸ" }, @@ -383,7 +390,7 @@ "unread": "ๆœช่ฎ€" }, "authentik": { - "users": "ไฝฟ็”จ่€…", + "users": "็”จๆˆถ", "loginsLast24H": "็™ปๅ…ฅ (้ŽๅŽป 24 ๅฐๆ™‚)", "failedLoginsLast24H": "็™ปๅ…ฅๅคฑๆ•— (้ŽๅŽป 24 ๅฐๆ™‚)" }, @@ -396,7 +403,7 @@ "glances": { "cpu": "CPU", "load": "่ฒ ่ผ‰", - "wait": "่ซ‹็จๅพŒ", + "wait": "่ซ‹็จๅ€™", "temp": "ๆบซๅบฆ", "_temp": "ๆบซๅบฆ", "warn": "่ญฆๅ‘Š", @@ -419,7 +426,8 @@ "search": "ๆœๅฐ‹", "custom": "่‡ช่จ‚", "visit": "้€ ่จช", - "url": "็ถฒๅ€" + "url": "็ถฒๅ€", + "searchsuggestion": "ๅปบ่ญฐ" }, "wmo": { "0-day": "ๆ™ดๅคฉ", @@ -535,7 +543,15 @@ }, "hdhomerun": { "channels": "้ ป้“", - "hd": "้ซ˜็•ซ่ณช" + "hd": "้ซ˜็•ซ่ณช", + "tunerCount": "่ชฟ่ซงๅ™จ", + "channelNumber": "้ ป้“", + "channelNetwork": "็ถฒ็ตก", + "signalStrength": "ๅผทๅบฆ", + "signalQuality": "ๅ“่ณช", + "symbolQuality": "ๅ“่ณช", + "networkRate": "ไฝๅ…ƒ็އ", + "clientIP": "็”จๆˆถ็ซฏ" }, "scrutiny": { "passed": "้€š้Ž", @@ -548,8 +564,8 @@ }, "peanut": { "battery_charge": "ๅ……้›ป", - "ups_load": "UPS Load", - "ups_status": "UPS Status", + "ups_load": "ๅพŒๅ‚™้›ป่ฒ ่ผ‰", + "ups_status": "ๅพŒๅ‚™้›ป็‹€ๆณ", "online": "ๅœจ็ทš", "on_battery": "้›ปๆฑ ไพ›้›ป", "low_battery": "ไฝŽ้›ป้‡" @@ -614,7 +630,7 @@ "memory_usage": "่จ˜ๆ†ถ้ซ”" }, "immich": { - "users": "ไฝฟ็”จ่€…", + "users": "็”จๆˆถ", "photos": "็…ง็‰‡", "videos": "ๅฝฑ็‰‡", "storage": "ๅ„ฒๅญ˜็ฉบ้–“" @@ -694,6 +710,11 @@ "targets_down": "็›ฎๆจ™้›ข็ทš", "targets_total": "็›ฎๆจ™็ธฝๆ•ธ" }, + "gatus": { + "up": "ๅœจ็ทš็ถฒ็ซ™", + "down": "้›ข็ทš็ถฒ็ซ™", + "uptime": "้‹่กŒๆ™‚้–“" + }, "ghostfolio": { "gross_percent_today": "ไปŠๆ—ฅ", "gross_percent_1y": "ไธ€ๅนด", @@ -707,8 +728,8 @@ }, "homeassistant": { "people_home": "ๅœจๅฎถไบบๆ•ธ", - "lights_on": "็‡ˆไบฎ่‘—", - "switches_on": "้–‹้—œ้–‹่‘—" + "lights_on": "็‡ˆๅ…‰้–‹ๅ•Ÿ", + "switches_on": "้–‹้—œ้–‹ๅ•Ÿ" }, "whatsupdocker": { "monitoring": "็›ฃๆธฌไธญ", @@ -763,7 +784,7 @@ }, "mealie": { "recipes": "้ฃŸ่ญœ", - "users": "ไฝฟ็”จ่€…", + "users": "็”จๆˆถ", "categories": "้กžๅˆฅ", "tags": "ๆจ™็ฑค" }, @@ -775,6 +796,14 @@ "passed": "้€š้Ž", "failed": "ๅคฑๆ•—" }, + "openwrt": { + "uptime": "้‹่กŒๆ™‚้–“", + "cpuLoad": "่™•็†ๅ™จๅนณๅ‡่ฒ ่ผ‰(5ๅˆ†้˜)", + "up": "ๅœจ็ทš", + "down": "้›ข็ทš", + "bytesTx": "ๅทฒๅ‚ณ้€", + "bytesRx": "ๅทฒๆŽฅๆ”ถ" + }, "uptimerobot": { "status": "็‹€ๆ…‹", "uptime": "้‹่กŒๆ™‚้–“", @@ -797,11 +826,67 @@ "noEventsFound": "ๆœชๆ‰พๅˆฐไบ‹ไปถ" }, "romm": { - "platforms": "Platforms", - "totalRoms": "Total ROMs" + "platforms": "ๅนณๅฐ", + "totalRoms": "็ธฝๅ”ฏ่ฎ€่จ˜ๆ†ถ้ซ”" }, "netdata": { - "warnings": "Warnings", - "criticals": "Criticals" + "warnings": "่ญฆๅ‘Š", + "criticals": "ๅšด้‡" + }, + "plantit": { + "events": "ไบ‹ไปถ", + "plants": "ๆค็‰ฉ", + "photos": "็…ง็‰‡", + "species": "็‰ฉ็จฎ" + }, + "gitea": { + "notifications": "ไฟกๆฏ", + "issues": "ๅ‡บ็‰ˆ", + "pulls": "ๆๅ–่ซ‹ๆฑ‚" + }, + "stash": { + "scenes": "ๅ ดๆ™ฏ", + "scenesPlayed": "ๅทฒๆ’ญๆ”พๅ ดๆ™ฏ", + "playCount": "ๅˆๅ…ฑๆ’ญๆ”พ", + "playDuration": "่ง€็œ‹ๆ™‚ๆ•ธ", + "sceneSize": "ๅ ดๆ™ฏๅคงๅฐ", + "sceneDuration": "ๅ ดๆ™ฏ็‚บๆœŸ", + "images": "ๅœ–็‰‡", + "imageSize": "ๅœ–ๅƒๅคงๅฐ", + "galleries": "็•ซๅปŠ", + "performers": "่กจๆผ”่€…", + "studios": "ๅทฅไฝœๅฎค", + "movies": "้›ปๅฝฑ", + "tags": "ๆจ™็ฑค", + "oCount": "0 ๅ€‹" + }, + "tandoor": { + "users": "็”จๆˆถ", + "recipes": "้ฃŸ่ญœ", + "keywords": "้—œ้ตๅญ—" + }, + "homebox": { + "items": "้ …็›ฎ", + "totalWithWarranty": "ๆœ‰ไฟ่จผ", + "locations": "ไฝ็ฝฎ", + "labels": "ๆจ™็ฑค", + "users": "็”จๆˆถ", + "totalValue": "็ธฝๅ…ฑ" + }, + "crowdsec": { + "alerts": "่ญฆ็คบ", + "bans": "็ฆๆญข" + }, + "wgeasy": { + "connected": "Connected", + "enabled": "ๅทฒๅ•Ÿ็”จ", + "disabled": "ๅทฒๅœ็”จ", + "total": "ๅ…จ้ƒจ" + }, + "swagdashboard": { + "proxied": "Proxied", + "auth": "With Auth", + "outdated": "Outdated", + "banned": "Banned" } } diff --git a/requirements.txt b/requirements.txt index e0365917..b4716522 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,9 +9,9 @@ Jinja2==3.1.2 Markdown==3.4.4 MarkupSafe==2.1.3 mergedeep==1.3.4 -mkdocs==1.5.3 -mkdocs-material==9.5.2 -mkdocs-material-extensions==1.3 +mkdocs==1.6 +mkdocs-material==9.5.26 +mkdocs-material-extensions==1.3.1 packaging==23.1 paginate==0.5.6 pathspec==0.11.2 @@ -27,3 +27,4 @@ six==1.16.0 urllib3==2.0.5 watchdog==3.0.0 pre-commit==3.5.0 +mkdocs-material[imaging]==9.5.26 diff --git a/src/components/quicklaunch.jsx b/src/components/quicklaunch.jsx index aaa40493..f2089065 100644 --- a/src/components/quicklaunch.jsx +++ b/src/components/quicklaunch.jsx @@ -1,26 +1,18 @@ import { useTranslation } from "react-i18next"; import { useEffect, useState, useRef, useCallback, useContext } from "react"; import classNames from "classnames"; +import useSWR from "swr"; import ResolvedIcon from "./resolvedicon"; +import { getStoredProvider, searchProviders } from "./widgets/search/search"; import { SettingsContext } from "utils/contexts/settings"; -export default function QuickLaunch({ - servicesAndBookmarks, - searchString, - setSearchString, - isOpen, - close, - searchProvider, -}) { +export default function QuickLaunch({ servicesAndBookmarks, searchString, setSearchString, isOpen, close }) { const { t } = useTranslation(); const { settings } = useContext(SettingsContext); const { searchDescriptions = false, hideVisitURL = false } = settings?.quicklaunch ?? {}; - const showSearchSuggestions = !!( - settings?.quicklaunch?.showSearchSuggestions ?? searchProvider?.showSearchSuggestions - ); const searchField = useRef(); @@ -29,9 +21,42 @@ export default function QuickLaunch({ const [url, setUrl] = useState(null); const [searchSuggestions, setSearchSuggestions] = useState([]); + const { data: widgets } = useSWR("/api/widgets"); + const searchWidget = Object.values(widgets).find((w) => w.type === "search"); + + let searchProvider; + + if (settings?.quicklaunch?.provider === "custom" && settings?.quicklaunch?.url?.length > 0) { + searchProvider = settings.quicklaunch; + } else if (settings?.quicklaunch?.provider && settings?.quicklaunch?.provider !== "custom") { + searchProvider = searchProviders[settings.quicklaunch.provider]; + } else if (searchWidget) { + // If there is no search provider in quick launch settings, try to get it from the search widget + if (Array.isArray(searchWidget.options?.provider)) { + // If search provider is a list, try to retrieve from localstorage, fall back to the first + searchProvider = getStoredProvider() ?? searchProviders[searchWidget.options.provider[0]]; + } else if (searchWidget.options?.provider === "custom") { + searchProvider = searchWidget.options; + } else { + searchProvider = searchProviders[searchWidget.options?.provider]; + } + } + + if (searchProvider) { + searchProvider.showSearchSuggestions = !!( + settings?.quicklaunch?.showSearchSuggestions ?? + searchWidget?.options?.showSearchSuggestions ?? + false + ); + } + function openCurrentItem(newWindow) { const result = results[currentItemIndex]; - window.open(result.href, newWindow ? "_blank" : result.target ?? settings.target ?? "_blank", "noreferrer"); + window.open( + result.href, + newWindow ? "_blank" : result.target ?? searchProvider?.target ?? settings.target ?? "_blank", + "noreferrer", + ); } const closeAndReset = useCallback(() => { @@ -44,16 +69,18 @@ export default function QuickLaunch({ }, [close, setSearchString, setCurrentItemIndex, setSearchSuggestions]); function handleSearchChange(event) { - const rawSearchString = event.target.value.toLowerCase(); + const rawSearchString = event.target.value; try { if (!/.+[.:].+/g.test(rawSearchString)) throw new Error(); // basic test for probably a url let urlString = rawSearchString; - if (urlString.indexOf("http") !== 0) urlString = `https://${rawSearchString}`; + if (urlString.toLowerCase().indexOf("http") !== 0) urlString = `https://${rawSearchString}`; setUrl(new URL(urlString)); // basic validation + setSearchString(rawSearchString); + return; } catch (e) { setUrl(null); } - setSearchString(rawSearchString); + setSearchString(rawSearchString.toLowerCase()); } function handleSearchKeyDown(event) { @@ -119,7 +146,7 @@ export default function QuickLaunch({ type: "search", }); - if (showSearchSuggestions && searchProvider.suggestionUrl) { + if (searchProvider.showSearchSuggestions && searchProvider.suggestionUrl) { if (searchString.trim() !== searchSuggestions[0]?.trim()) { fetch( `/api/search/searchSuggestion?query=${encodeURIComponent(searchString)}&providerName=${ @@ -172,17 +199,7 @@ export default function QuickLaunch({ return () => { abortController.abort(); }; - }, [ - searchString, - servicesAndBookmarks, - searchDescriptions, - hideVisitURL, - showSearchSuggestions, - searchSuggestions, - searchProvider, - url, - t, - ]); + }, [searchString, servicesAndBookmarks, searchDescriptions, hideVisitURL, searchSuggestions, searchProvider, url, t]); const [hidden, setHidden] = useState(true); useEffect(() => { diff --git a/src/components/services/item.jsx b/src/components/services/item.jsx index 480e58d5..a38dfaa3 100644 --- a/src/components/services/item.jsx +++ b/src/components/services/item.jsx @@ -36,7 +36,6 @@ export default function Item({ service, group, useEqualHeights }) {
{style !== "dot" ? (
{statusLabel}
diff --git a/src/components/tab.jsx b/src/components/tab.jsx index 699b1912..e0c2f46e 100644 --- a/src/components/tab.jsx +++ b/src/components/tab.jsx @@ -3,13 +3,19 @@ import classNames from "classnames"; import { TabContext } from "utils/contexts/tab"; -export function slugify(tabName) { - return tabName !== undefined ? encodeURIComponent(tabName.toString().replace(/\s+/g, "-").toLowerCase()) : ""; +function slugify(tabName) { + return tabName.toString().replace(/\s+/g, "-").toLowerCase(); +} + +export function slugifyAndEncode(tabName) { + return tabName !== undefined ? encodeURIComponent(slugify(tabName)) : ""; } export default function Tab({ tab }) { const { activeTab, setActiveTab } = useContext(TabContext); + const matchesTab = decodeURI(activeTab) === slugify(tab); + return (
  • { - setActiveTab(slugify(tab)); - window.location.hash = `#${slugify(tab)}`; + setActiveTab(slugifyAndEncode(tab)); + window.location.hash = `#${slugifyAndEncode(tab)}`; }} > {tab} diff --git a/src/components/widgets/longhorn/node.jsx b/src/components/widgets/longhorn/node.jsx index da2882ee..75bff72c 100644 --- a/src/components/widgets/longhorn/node.jsx +++ b/src/components/widgets/longhorn/node.jsx @@ -1,5 +1,5 @@ import { useTranslation } from "next-i18next"; -import { FaThermometerHalf } from "react-icons/fa"; +import { FiHardDrive } from "react-icons/fi"; import Resource from "../widget/resource"; import WidgetLabel from "../widget/widget_label"; @@ -10,7 +10,7 @@ export default function Node({ data, expanded, labels }) { return ( {t(`wmo.${data.current_weather.weathercode}-${timeOfDay}`)} @@ -83,8 +84,6 @@ export default function OpenMeteo({ options }) { } }; - // if (!requesting && !location) requestLocation(); - if (!location) { return ( {options.label && `${options.label}, `} - {t("common.number", { value: data.main.temp, style: "unit", unit })} + {t("common.number", { value: data.main.temp, style: "unit", unit, ...options.format })} {data.weather[0].description} diff --git a/src/components/widgets/resources/cputemp.jsx b/src/components/widgets/resources/cputemp.jsx index 96f98096..ef994c65 100644 --- a/src/components/widgets/resources/cputemp.jsx +++ b/src/components/widgets/resources/cputemp.jsx @@ -9,7 +9,7 @@ function convertToFahrenheit(t) { return (t * 9) / 5 + 32; } -export default function CpuTemp({ expanded, units, refresh = 1500 }) { +export default function CpuTemp({ expanded, units, refresh = 1500, tempmin = 0, tempmax = -1 }) { const { t } = useTranslation(); const { data, error } = useSWR(`/api/widgets/resources?type=cputemp`, { @@ -39,7 +39,12 @@ export default function CpuTemp({ expanded, units, refresh = 1500 }) { } const unit = units === "imperial" ? "fahrenheit" : "celsius"; mainTemp = unit === "celsius" ? mainTemp : convertToFahrenheit(mainTemp); - const maxTemp = unit === "celsius" ? data.cputemp.max : convertToFahrenheit(data.cputemp.max); + + const minTemp = tempmin < mainTemp ? tempmin : mainTemp; + let maxTemp = tempmax; + if (maxTemp < minTemp) { + maxTemp = unit === "celsius" ? data.cputemp.max : convertToFahrenheit(data.cputemp.max); + } return ( ); diff --git a/src/components/widgets/resources/resources.jsx b/src/components/widgets/resources/resources.jsx index e2f2bfb8..634e0ff5 100644 --- a/src/components/widgets/resources/resources.jsx +++ b/src/components/widgets/resources/resources.jsx @@ -8,7 +8,7 @@ import CpuTemp from "./cputemp"; import Uptime from "./uptime"; export default function Resources({ options }) { - const { expanded, units, diskUnits } = options; + const { expanded, units, diskUnits, tempmin, tempmax } = options; let { refresh } = options; if (!refresh) refresh = 1500; refresh = Math.max(refresh, 1000); @@ -23,7 +23,9 @@ export default function Resources({ options }) { )) : options.disk && } - {options.cputemp && } + {options.cputemp && ( + + )} {options.uptime && }
  • {options.label && ( diff --git a/src/components/widgets/unifi_console/unifi_console.jsx b/src/components/widgets/unifi_console/unifi_console.jsx index 0031b224..5295dbb7 100644 --- a/src/components/widgets/unifi_console/unifi_console.jsx +++ b/src/components/widgets/unifi_console/unifi_console.jsx @@ -14,8 +14,8 @@ import useWidgetAPI from "utils/proxy/use-widget-api"; export default function Widget({ options }) { const { t } = useTranslation(); - // eslint-disable-next-line no-param-reassign - options.type = "unifi_console"; + // eslint-disable-next-line no-param-reassign, no-multi-assign + options.service_group = options.service_name = "unifi_console"; const { data: statsData, error: statsError } = useWidgetAPI(options, "stat/sites", { index: options.index }); if (statsError) { diff --git a/src/components/widgets/weather/weather.jsx b/src/components/widgets/weather/weather.jsx index 08074ee5..4ebb08c5 100644 --- a/src/components/widgets/weather/weather.jsx +++ b/src/components/widgets/weather/weather.jsx @@ -45,6 +45,7 @@ function Widget({ options }) { value: options.units === "metric" ? data.current.temp_c : data.current.temp_f, style: "unit", unit, + ...options.format, })} {data.current.condition.text} diff --git a/src/components/widgets/widget/container.jsx b/src/components/widgets/widget/container.jsx index 442aa084..c9240dd3 100644 --- a/src/components/widgets/widget/container.jsx +++ b/src/components/widgets/widget/container.jsx @@ -16,7 +16,7 @@ export function getAllClasses(options, additionalClassNames = "") { } return classNames( - "flex flex-col justify-center ml-2 mr-2", + "flex flex-col justify-center", "mt-2 m:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-2 pl-3 pr-3", additionalClassNames, ); @@ -24,7 +24,7 @@ export function getAllClasses(options, additionalClassNames = "") { let widgetAlignedClasses = "flex flex-col max-w:full sm:basis-auto self-center grow-0 flex-wrap"; if (options?.style?.isRightAligned) { - widgetAlignedClasses = "flex flex-col justify-center first:ml-auto ml-2 mr-2 "; + widgetAlignedClasses = "flex flex-col justify-center"; } return classNames(widgetAlignedClasses, additionalClassNames); diff --git a/src/components/widgets/widget/container_form.jsx b/src/components/widgets/widget/container_form.jsx index 3b2c02e2..68cbd64b 100644 --- a/src/components/widgets/widget/container_form.jsx +++ b/src/components/widgets/widget/container_form.jsx @@ -2,11 +2,7 @@ import { getAllClasses, getInnerBlock, getBottomBlock } from "./container"; export default function ContainerForm({ children = [], options, additionalClassNames = "", callback }) { return ( -
    + {getInnerBlock(children)} {getBottomBlock(children)}
    diff --git a/src/components/widgets/widget/container_link.jsx b/src/components/widgets/widget/container_link.jsx index e6bc4cec..6f157875 100644 --- a/src/components/widgets/widget/container_link.jsx +++ b/src/components/widgets/widget/container_link.jsx @@ -3,7 +3,7 @@ import { getAllClasses, getInnerBlock, getBottomBlock } from "./container"; export default function ContainerLink({ children = [], options, additionalClassNames = "", target }) { return ( diff --git a/src/pages/api/config/[path].js b/src/pages/api/config/[path].js index 7f3b6a07..6cb04698 100644 --- a/src/pages/api/config/[path].js +++ b/src/pages/api/config/[path].js @@ -28,7 +28,7 @@ export default async function handler(req, res) { res.setHeader("Content-Type", mimeType); return res.status(200).send(fileContent); } catch (error) { - logger.error(error); + if (error) logger.error(error); return res.status(500).end("Internal Server Error"); } } diff --git a/src/pages/api/docker/stats/[...service].js b/src/pages/api/docker/stats/[...service].js index 715e5188..e92bad7c 100644 --- a/src/pages/api/docker/stats/[...service].js +++ b/src/pages/api/docker/stats/[...service].js @@ -80,7 +80,7 @@ export default async function handler(req, res) { error: "not found", }); } catch (e) { - logger.error(e); + if (e) logger.error(e); return res.status(500).send({ error: { message: e?.message ?? "Unknown error" }, }); diff --git a/src/pages/api/docker/status/[...service].js b/src/pages/api/docker/status/[...service].js index 96c6bea6..f9dc640b 100644 --- a/src/pages/api/docker/status/[...service].js +++ b/src/pages/api/docker/status/[...service].js @@ -108,7 +108,7 @@ export default async function handler(req, res) { status: "not found", }); } catch (e) { - logger.error(e); + if (e) logger.error(e); return res.status(500).send({ error: { message: e?.message ?? "Unknown error" }, }); diff --git a/src/pages/api/kubernetes/stats/[...service].js b/src/pages/api/kubernetes/stats/[...service].js index 90a67bec..b1bf8345 100644 --- a/src/pages/api/kubernetes/stats/[...service].js +++ b/src/pages/api/kubernetes/stats/[...service].js @@ -106,7 +106,7 @@ export default async function handler(req, res) { stats, }); } catch (e) { - logger.error(e); + if (e) logger.error(e); res.status(500).send({ error: "unknown error", }); diff --git a/src/pages/api/kubernetes/status/[...service].js b/src/pages/api/kubernetes/status/[...service].js index 1ca19126..7d950038 100644 --- a/src/pages/api/kubernetes/status/[...service].js +++ b/src/pages/api/kubernetes/status/[...service].js @@ -43,8 +43,9 @@ export default async function handler(req, res) { if (pods.length === 0) { res.status(404).send({ - error: `no pods found with namespace=${namespace} and labelSelector=${labelSelector}`, + status: "not found", }); + logger.error(`no pods found with namespace=${namespace} and labelSelector=${labelSelector}`); return; } const someReady = pods.find((pod) => pod.status.phase === "Running"); @@ -59,7 +60,7 @@ export default async function handler(req, res) { status, }); } catch (e) { - logger.error(e); + if (e) logger.error(e); res.status(500).send({ error: "unknown error", }); diff --git a/src/pages/api/search/searchSuggestion.js b/src/pages/api/search/searchSuggestion.js index c1c936c9..fa8eba0d 100644 --- a/src/pages/api/search/searchSuggestion.js +++ b/src/pages/api/search/searchSuggestion.js @@ -19,5 +19,5 @@ export default async function handler(req, res) { return res.json([query, []]); // Responde with the same array format but with no suggestions. } - return res.send(await cachedFetch(`${provider.suggestionUrl}${encodeURIComponent(query)}`, 5)); + return res.send(await cachedFetch(`${provider.suggestionUrl}${encodeURIComponent(query)}`, 5, "Mozilla/5.0")); } diff --git a/src/pages/api/services/proxy.js b/src/pages/api/services/proxy.js index 80856419..fd39ab96 100644 --- a/src/pages/api/services/proxy.js +++ b/src/pages/api/services/proxy.js @@ -2,12 +2,21 @@ import { formatApiCall } from "utils/proxy/api-helpers"; import createLogger from "utils/logger"; import genericProxyHandler from "utils/proxy/handlers/generic"; import widgets from "widgets/widgets"; +import calendarProxyHandler from "widgets/calendar/proxy"; +import getServiceWidget from "utils/config/service-helpers"; const logger = createLogger("servicesProxy"); export default async function handler(req, res) { try { - const { type } = req.query; + const { service, group } = req.query; + const serviceWidget = await getServiceWidget(group, service); + let type = serviceWidget?.type; + + // exceptions + if (type === "calendar") type = "ical"; + else if (service === "unifi_console" && group === "unifi_console") type = "unifi_console"; + const widget = widgets[type]; if (!widget) { @@ -18,6 +27,11 @@ export default async function handler(req, res) { const serviceProxyHandler = widget.proxyHandler || genericProxyHandler; if (serviceProxyHandler instanceof Function) { + // quick return for no endpoint services, calendar is an exception + if (!req.query.endpoint || serviceProxyHandler === calendarProxyHandler) { + return serviceProxyHandler(req, res); + } + // map opaque endpoints to their actual endpoint if (widget?.mappings) { const mapping = widget?.mappings?.[req.query.endpoint]; @@ -27,6 +41,11 @@ export default async function handler(req, res) { const endpoint = mapping?.endpoint; const endpointProxy = mapping?.proxyHandler || serviceProxyHandler; + if (mapping.method && mapping.method !== req.method) { + logger.debug("Unsupported method: %s", req.method); + return res.status(403).json({ error: "Unsupported method" }); + } + if (!endpoint) { logger.debug("Unsupported service endpoint: %s", type); return res.status(403).json({ error: "Unsupported service endpoint" }); @@ -38,6 +57,17 @@ export default async function handler(req, res) { if (req.query.segments) { const segments = JSON.parse(req.query.segments); + let validSegments = true; + Object.keys(segments).forEach((key) => { + if (!mapping.segments.includes(key)) { + logger.debug("Unsupported segment: %s", key); + validSegments = false; + } else if (segments[key].includes("/") || segments[key].includes("\\") || segments[key].includes("..")) { + logger.debug("Unsupported segment value: %s", segments[key]); + validSegments = false; + } + }); + if (!validSegments) return res.status(403).json({ error: "Unsupported segment" }); req.query.endpoint = formatApiCall(endpoint, segments); } @@ -66,13 +96,20 @@ export default async function handler(req, res) { return serviceProxyHandler(req, res, map); } - return serviceProxyHandler(req, res); + if (widget.allowedEndpoints instanceof RegExp) { + if (widget.allowedEndpoints.test(req.query.endpoint)) { + return serviceProxyHandler(req, res); + } + } + + logger.debug("Unmapped proxy request."); + return res.status(403).json({ error: "Unmapped proxy request." }); } logger.debug("Unknown proxy service type: %s", type); return res.status(403).json({ error: "Unkown proxy service type" }); - } catch (ex) { - logger.error(ex); + } catch (e) { + if (e) logger.error(e); return res.status(500).send({ error: "Unexpected error" }); } } diff --git a/src/pages/api/widgets/glances.js b/src/pages/api/widgets/glances.js index 0d87a9ae..199c133e 100644 --- a/src/pages/api/widgets/glances.js +++ b/src/pages/api/widgets/glances.js @@ -13,7 +13,7 @@ async function retrieveFromGlancesAPI(privateWidgetOptions, endpoint) { throw new Error(errorMessage); } - const apiUrl = `${url}/api/3/${endpoint}`; + const apiUrl = `${url}/api/${privateWidgetOptions.version}/${endpoint}`; const headers = { "Accept-Encoding": "application/json", }; @@ -42,9 +42,10 @@ async function retrieveFromGlancesAPI(privateWidgetOptions, endpoint) { } export default async function handler(req, res) { - const { index, cputemp: includeCpuTemp, uptime: includeUptime, disk: includeDisks } = req.query; + const { index, cputemp: includeCpuTemp, uptime: includeUptime, disk: includeDisks, version } = req.query; const privateWidgetOptions = await getPrivateWidgetOptions("glances", index); + privateWidgetOptions.version = version ?? 3; try { const cpuData = await retrieveFromGlancesAPI(privateWidgetOptions, "cpu"); diff --git a/src/pages/api/widgets/kubernetes.js b/src/pages/api/widgets/kubernetes.js index b55b02d7..0859212f 100644 --- a/src/pages/api/widgets/kubernetes.js +++ b/src/pages/api/widgets/kubernetes.js @@ -94,7 +94,7 @@ export default async function handler(req, res) { nodes: Object.entries(nodeMap).map(([name, node]) => ({ name, ...node })), }); } catch (e) { - logger.error("exception %s", e); + if (e) logger.error(e); return res.status(500).send({ error: "unknown error", }); diff --git a/src/pages/api/widgets/openweathermap.js b/src/pages/api/widgets/openweathermap.js index a2070997..089ee804 100644 --- a/src/pages/api/widgets/openweathermap.js +++ b/src/pages/api/widgets/openweathermap.js @@ -1,9 +1,11 @@ import cachedFetch from "utils/proxy/cached-fetch"; import { getSettings } from "utils/config/config"; +import { getPrivateWidgetOptions } from "utils/config/widget-helpers"; export default async function handler(req, res) { - const { latitude, longitude, units, provider, cache, lang } = req.query; - let { apiKey } = req.query; + const { latitude, longitude, units, provider, cache, lang, index } = req.query; + const privateWidgetOptions = await getPrivateWidgetOptions("openweathermap", index); + let { apiKey } = privateWidgetOptions; if (!apiKey && !provider) { return res.status(400).json({ error: "Missing API key or provider" }); diff --git a/src/pages/api/widgets/weather.js b/src/pages/api/widgets/weather.js index 5cba47ba..9d0451ce 100644 --- a/src/pages/api/widgets/weather.js +++ b/src/pages/api/widgets/weather.js @@ -1,9 +1,11 @@ import cachedFetch from "utils/proxy/cached-fetch"; import { getSettings } from "utils/config/config"; +import { getPrivateWidgetOptions } from "utils/config/widget-helpers"; export default async function handler(req, res) { - const { latitude, longitude, provider, cache, lang } = req.query; - let { apiKey } = req.query; + const { latitude, longitude, provider, cache, lang, index } = req.query; + const privateWidgetOptions = await getPrivateWidgetOptions("weatherapi", index); + let { apiKey } = privateWidgetOptions; if (!apiKey && !provider) { return res.status(400).json({ error: "Missing API key or provider" }); diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 39ac6cf2..75674c30 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -10,7 +10,7 @@ import { BiError } from "react-icons/bi"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; import { useRouter } from "next/router"; -import Tab, { slugify } from "components/tab"; +import Tab, { slugifyAndEncode } from "components/tab"; import ServicesGroup from "components/services/group"; import BookmarksGroup from "components/bookmarks/group"; import Widget from "components/widgets/widget"; @@ -26,7 +26,6 @@ import { bookmarksResponse, servicesResponse, widgetsResponse } from "utils/conf import ErrorBoundary from "components/errorboundry"; import themes from "utils/styles/themes"; import QuickLaunch from "components/quicklaunch"; -import { getStoredProvider, searchProviders } from "components/widgets/search/search"; const ThemeToggle = dynamic(() => import("components/toggles/theme"), { ssr: false, @@ -65,7 +64,7 @@ export async function getStaticProps() { }, }; } catch (e) { - if (logger) { + if (logger && e) { logger.error(e); } return { @@ -161,10 +160,10 @@ function Index({ initialSettings, fallback }) { const headerStyles = { boxed: - "m-6 mb-0 sm:m-9 sm:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-3", - underlined: "m-6 mb-0 sm:m-9 sm:mb-1 border-b-2 pb-4 border-theme-800 dark:border-theme-200/50", - clean: "m-6 mb-0 sm:m-9 sm:mb-0", - boxedWidgets: "m-6 mb-0 sm:m-9 sm:mb-0 sm:mt-1", + "m-5 mb-0 sm:m-9 sm:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-3", + underlined: "m-5 mb-0 sm:m-9 sm:mb-1 border-b-2 pb-4 border-theme-800 dark:border-theme-200/50", + clean: "m-5 mb-0 sm:m-9 sm:mb-0", + boxedWidgets: "m-5 mb-0 sm:m-9 sm:mb-0 sm:mt-1", }; function Home({ initialSettings }) { @@ -204,20 +203,6 @@ function Home({ initialSettings }) { const [searching, setSearching] = useState(false); const [searchString, setSearchString] = useState(""); - let searchProvider = null; - const searchWidget = Object.values(widgets).find((w) => w.type === "search"); - if (searchWidget) { - if (Array.isArray(searchWidget.options?.provider)) { - // if search provider is a list, try to retrieve from localstorage, fall back to the first - searchProvider = getStoredProvider() ?? searchProviders[searchWidget.options.provider[0]]; - } else if (searchWidget.options?.provider === "custom") { - searchProvider = searchWidget.options; - } else { - searchProvider = searchProviders[searchWidget.options?.provider]; - } - // to pass to quicklaunch - searchProvider.showSearchSuggestions = searchWidget.options?.showSearchSuggestions; - } const headerStyle = settings?.headerStyle || "underlined"; useEffect(() => { @@ -225,9 +210,10 @@ function Home({ initialSettings }) { if (e.target.tagName === "BODY" || e.target.id === "inner_wrapper") { if ( (e.key.length === 1 && - e.key.match(/(\w|\s|[ร -รผ]|[ร€-รœ])/g) && + e.key.match(/(\w|\s|[ร -รผ]|[ร€-รœ]|[\w\u0430-\u044f])/gi) && !(e.altKey || e.ctrlKey || e.metaKey || e.shiftKey)) || - e.key.match(/([ร -รผ]|[ร€-รœ])/g) || // accented characters may require modifier keys + // accented characters and the bang may require modifier keys + e.key.match(/([ร -รผ]|[ร€-รœ]|!)/g) || (e.key === "v" && (e.ctrlKey || e.metaKey)) ) { setSearching(true); @@ -258,13 +244,13 @@ function Home({ initialSettings }) { useEffect(() => { if (!activeTab) { - const initialTab = decodeURI(asPath.substring(asPath.indexOf("#") + 1)); - setActiveTab(initialTab === "/" ? slugify(tabs["0"]) : initialTab); + const initialTab = asPath.substring(asPath.indexOf("#") + 1); + setActiveTab(initialTab === "/" ? slugifyAndEncode(tabs["0"]) : initialTab); } }); const servicesAndBookmarksGroups = useMemo(() => { - const tabGroupFilter = (g) => g && [activeTab, ""].includes(slugify(settings.layout?.[g.name]?.tab)); + const tabGroupFilter = (g) => g && [activeTab, ""].includes(slugifyAndEncode(settings.layout?.[g.name]?.tab)); const undefinedGroupFilter = (g) => settings.layout?.[g.name] === undefined; const layoutGroups = Object.keys(settings.layout ?? {}) @@ -282,7 +268,7 @@ function Home({ initialSettings }) { return ( <> {tabs.length > 0 && ( -
    +
      -
      +
      {widgets && ( <> {widgets @@ -436,7 +417,7 @@ function Home({ initialSettings }) { id="information-widgets-right" className={classNames( "m-auto flex flex-wrap grow sm:basis-auto justify-between md:justify-end", - headerStyle === "boxedWidgets" ? "sm:ml-4" : "sm:ml-2", + "m-auto flex flex-wrap grow sm:basis-auto justify-between md:justify-end gap-x-2", )} > {widgets diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js index 9f997915..7de077bf 100644 --- a/src/utils/config/service-helpers.js +++ b/src/utils/config/service-helpers.js @@ -117,6 +117,8 @@ export async function servicesFromDocker() { return { server: serverName, services: discovered.filter((filteredService) => filteredService) }; } catch (e) { + logger.error("Error getting services from Docker server '%s': %s", serverName, e); + // a server failed, but others may succeed return { server: serverName, services: [] }; } @@ -252,7 +254,8 @@ export async function servicesFromKubernetes() { ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/enabled`] === "true" && (!ingress.metadata.annotations[`${ANNOTATION_BASE}/instance`] || - ingress.metadata.annotations[`${ANNOTATION_BASE}/instance`] === instanceName), + ingress.metadata.annotations[`${ANNOTATION_BASE}/instance`] === instanceName || + `${ANNOTATION_BASE}/instance.${instanceName}` in ingress.metadata.annotations), ) .map((ingress) => { let constructedService = { @@ -325,7 +328,7 @@ export async function servicesFromKubernetes() { return mappedServiceGroups; } catch (e) { - logger.error(e); + if (e) logger.error(e); throw e; } } @@ -391,6 +394,14 @@ export function cleanServiceGroups(groups) { enableBlocks, enableNowPlaying, + // emby, jellyfin, tautulli + enableUser, + expandOneStreamToTwoRows, + showEpisodeNumber, + + // glances, pihole + version, + // glances chart, metric, @@ -440,20 +451,27 @@ export function cleanServiceGroups(groups) { // proxmox node, + // speedtest + bitratePrecision, + // sonarr, radarr enableQueue, // truenas enablePools, + nasType, // unifi site, + + // wgeasy + threshold, } = cleanedService.widget; let fieldsList = fields; if (typeof fields === "string") { try { - JSON.parse(fields); + fieldsList = JSON.parse(fields); } catch (e) { logger.error("Invalid fields list detected in config for service '%s'", service.name); fieldsList = null; @@ -512,11 +530,19 @@ export function cleanServiceGroups(groups) { if (enableBlocks !== undefined) cleanedService.widget.enableBlocks = JSON.parse(enableBlocks); if (enableNowPlaying !== undefined) cleanedService.widget.enableNowPlaying = JSON.parse(enableNowPlaying); } + if (["emby", "jellyfin", "tautulli"].includes(type)) { + if (expandOneStreamToTwoRows !== undefined) + cleanedService.widget.expandOneStreamToTwoRows = !!JSON.parse(expandOneStreamToTwoRows); + if (showEpisodeNumber !== undefined) + cleanedService.widget.showEpisodeNumber = !!JSON.parse(showEpisodeNumber); + if (enableUser !== undefined) cleanedService.widget.enableUser = !!JSON.parse(enableUser); + } if (["sonarr", "radarr"].includes(type)) { if (enableQueue !== undefined) cleanedService.widget.enableQueue = JSON.parse(enableQueue); } if (type === "truenas") { if (enablePools !== undefined) cleanedService.widget.enablePools = JSON.parse(enablePools); + if (nasType !== undefined) cleanedService.widget.nasType = nasType; } if (["diskstation", "qnap"].includes(type)) { if (volume) cleanedService.widget.volume = volume; @@ -525,6 +551,9 @@ export function cleanServiceGroups(groups) { if (snapshotHost) cleanedService.widget.snapshotHost = snapshotHost; if (snapshotPath) cleanedService.widget.snapshotPath = snapshotPath; } + if (["glances", "pihole"].includes(type)) { + if (version) cleanedService.widget.version = version; + } if (type === "glances") { if (metric) cleanedService.widget.metric = metric; if (chart !== undefined) { @@ -566,6 +595,14 @@ export function cleanServiceGroups(groups) { if (type === "healthchecks") { if (uuid !== undefined) cleanedService.widget.uuid = uuid; } + if (type === "speedtest") { + if (bitratePrecision !== undefined) { + cleanedService.widget.bitratePrecision = parseInt(bitratePrecision, 10); + } + } + if (type === "wgeasy") { + if (threshold !== undefined) cleanedService.widget.threshold = parseInt(threshold, 10); + } } return cleanedService; diff --git a/src/utils/config/widget-helpers.js b/src/utils/config/widget-helpers.js index 6514fea2..7c5c78cd 100644 --- a/src/utils/config/widget-helpers.js +++ b/src/utils/config/widget-helpers.js @@ -32,7 +32,7 @@ export async function cleanWidgetGroups(widgets) { const optionKeys = Object.keys(sanitizedOptions); // delete private options from the sanitized options - ["username", "password", "key"].forEach((pO) => { + ["username", "password", "key", "apiKey"].forEach((pO) => { if (optionKeys.includes(pO)) { delete sanitizedOptions[pO]; } @@ -57,7 +57,7 @@ export async function getPrivateWidgetOptions(type, widgetIndex) { const widgets = await widgetsFromConfig(); const privateOptions = widgets.map((widget) => { - const { index, url, username, password, key } = widget.options; + const { index, url, username, password, key, apiKey } = widget.options; return { type: widget.type, @@ -67,6 +67,7 @@ export async function getPrivateWidgetOptions(type, widgetIndex) { username, password, key, + apiKey, }, }; }); diff --git a/src/utils/logger.js b/src/utils/logger.js index cbf84b3b..a3a6ee87 100644 --- a/src/utils/logger.js +++ b/src/utils/logger.js @@ -3,68 +3,89 @@ import { format as utilFormat } from "node:util"; import winston from "winston"; -import checkAndCopyConfig, { getSettings, CONF_DIR } from "utils/config/config"; +import checkAndCopyConfig, { CONF_DIR, getSettings } from "utils/config/config"; let winstonLogger; -function init() { - checkAndCopyConfig("settings.yaml"); +function combineMessageAndSplat() { + return { + // eslint-disable-next-line no-unused-vars + transform: (info, opts) => { + // combine message and args if any + // eslint-disable-next-line no-param-reassign + info.message = utilFormat(info.message, ...(info[Symbol.for("splat")] || [])); + return info; + }, + }; +} + +function messageFormatter(logInfo) { + if (logInfo.label) { + if (logInfo.stack) { + return `[${logInfo.timestamp}] ${logInfo.level}: <${logInfo.label}> ${logInfo.stack}`; + } + return `[${logInfo.timestamp}] ${logInfo.level}: <${logInfo.label}> ${logInfo.message}`; + } + + if (logInfo.stack) { + return `[${logInfo.timestamp}] ${logInfo.level}: ${logInfo.stack}`; + } + return `[${logInfo.timestamp}] ${logInfo.level}: ${logInfo.message}`; +} + +function getConsoleLogger() { + return new winston.transports.Console({ + format: winston.format.combine( + winston.format.errors({ stack: true }), + combineMessageAndSplat(), + winston.format.timestamp(), + winston.format.colorize(), + winston.format.printf(messageFormatter), + ), + handleExceptions: true, + handleRejections: true, + }); +} + +function getFileLogger() { const settings = getSettings(); const logpath = settings.logpath || CONF_DIR; - function combineMessageAndSplat() { - return { - // eslint-disable-next-line no-unused-vars - transform: (info, opts) => { - // combine message and args if any - // eslint-disable-next-line no-param-reassign - info.message = utilFormat(info.message, ...(info[Symbol.for("splat")] || [])); - return info; - }, - }; - } + return new winston.transports.File({ + format: winston.format.combine( + winston.format.errors({ stack: true }), + combineMessageAndSplat(), + winston.format.timestamp(), + winston.format.printf(messageFormatter), + ), + filename: `${logpath}/logs/homepage.log`, + handleExceptions: true, + handleRejections: true, + }); +} - function messageFormatter(logInfo) { - if (logInfo.label) { - if (logInfo.stack) { - return `[${logInfo.timestamp}] ${logInfo.level}: <${logInfo.label}> ${logInfo.stack}`; - } - return `[${logInfo.timestamp}] ${logInfo.level}: <${logInfo.label}> ${logInfo.message}`; - } +function init() { + checkAndCopyConfig("settings.yaml"); + const configuredTargets = process.env.LOG_TARGETS || "both"; + const loggingTransports = []; - if (logInfo.stack) { - return `[${logInfo.timestamp}] ${logInfo.level}: ${logInfo.stack}`; - } - return `[${logInfo.timestamp}] ${logInfo.level}: ${logInfo.message}`; + switch (configuredTargets) { + case "both": + loggingTransports.push(getConsoleLogger(), getFileLogger()); + break; + case "stdout": + loggingTransports.push(getConsoleLogger()); + break; + case "file": + loggingTransports.push(getFileLogger()); + break; + default: + loggingTransports.push(getConsoleLogger(), getFileLogger()); } winstonLogger = winston.createLogger({ level: process.env.LOG_LEVEL || "info", - transports: [ - new winston.transports.Console({ - format: winston.format.combine( - winston.format.errors({ stack: true }), - combineMessageAndSplat(), - winston.format.timestamp(), - winston.format.colorize(), - winston.format.printf(messageFormatter), - ), - handleExceptions: true, - handleRejections: true, - }), - - new winston.transports.File({ - format: winston.format.combine( - winston.format.errors({ stack: true }), - combineMessageAndSplat(), - winston.format.timestamp(), - winston.format.printf(messageFormatter), - ), - filename: `${logpath}/logs/homepage.log`, - handleExceptions: true, - handleRejections: true, - }), - ], + transports: loggingTransports, }); // patch the console log mechanism to use our logger diff --git a/src/utils/proxy/api-helpers.js b/src/utils/proxy/api-helpers.js index 5fc22e1e..8e0682db 100644 --- a/src/utils/proxy/api-helpers.js +++ b/src/utils/proxy/api-helpers.js @@ -8,22 +8,15 @@ export function formatApiCall(url, args) { return url.replace(/\/+$/, "").replace(find, replace).replace(find, replace); } -function getURLSearchParams(widget, endpoint) { +export function getURLSearchParams(widget, endpoint) { const params = new URLSearchParams({ - type: widget.type, group: widget.service_group, service: widget.service_name, - endpoint, }); - return params; -} - -export function formatProxyUrlWithSegments(widget, endpoint, segments) { - const params = getURLSearchParams(widget, endpoint); - if (segments) { - params.append("segments", JSON.stringify(segments)); + if (endpoint) { + params.append("endpoint", endpoint); } - return `/api/services/proxy?${params.toString()}`; + return params; } export function formatProxyUrl(widget, endpoint, queryParams) { @@ -57,8 +50,9 @@ export function jsonArrayFilter(data, filter) { export function sanitizeErrorURL(errorURL) { // Dont display sensitive params on frontend const url = new URL(errorURL); - ["apikey", "api_key", "token", "t", "access_token"].forEach((key) => { + ["apikey", "api_key", "token", "t", "access_token", "auth"].forEach((key) => { if (url.searchParams.has(key)) url.searchParams.set(key, "***"); + if (url.hash.includes(key)) url.hash = url.hash.replace(new RegExp(`${key}=[^&]+`), `${key}=***`); }); return url.toString(); } diff --git a/src/utils/proxy/cached-fetch.js b/src/utils/proxy/cached-fetch.js index 30b00f77..ae3c4610 100644 --- a/src/utils/proxy/cached-fetch.js +++ b/src/utils/proxy/cached-fetch.js @@ -2,7 +2,7 @@ import cache from "memory-cache"; const defaultDuration = 5; -export default async function cachedFetch(url, duration) { +export default async function cachedFetch(url, duration, ua) { const cached = cache.get(url); // eslint-disable-next-line no-param-reassign @@ -13,7 +13,13 @@ export default async function cachedFetch(url, duration) { } // wrapping text in JSON.parse to handle utf-8 issues - const data = JSON.parse(await fetch(url).then((res) => res.text())); + const options = {}; + if (ua) { + options.headers = { + "User-Agent": ua, + }; + } + const data = await fetch(url, options).then((res) => res.json()); cache.put(url, data, duration * 1000 * 60); return data; } diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js index 02338b82..de2111b1 100644 --- a/src/utils/proxy/handlers/credentialed.js +++ b/src/utils/proxy/handlers/credentialed.js @@ -29,7 +29,9 @@ export default async function credentialedProxyHandler(req, res, map) { } else if (widget.type === "gotify") { headers["X-gotify-Key"] = `${widget.key}`; } else if ( - ["authentik", "cloudflared", "ghostfolio", "mealie", "tailscale", "pterodactyl"].includes(widget.type) + ["authentik", "cloudflared", "ghostfolio", "mealie", "tailscale", "tandoor", "pterodactyl"].includes( + widget.type, + ) ) { headers.Authorization = `Bearer ${widget.key}`; } else if (widget.type === "truenas") { diff --git a/src/utils/proxy/handlers/jsonrpc.js b/src/utils/proxy/handlers/jsonrpc.js index 4e79b76b..b1b080fd 100644 --- a/src/utils/proxy/handlers/jsonrpc.js +++ b/src/utils/proxy/handlers/jsonrpc.js @@ -31,6 +31,10 @@ export async function sendJsonRpcRequest(url, method, params, username, password if (status === 200) { const json = JSON.parse(data.toString()); + if (json.id === null) { + json.id = 1; + } + // in order to get access to the underlying error object in the JSON response // you must set `result` equal to undefined if (json.error && json.result === null) { diff --git a/src/utils/proxy/http.js b/src/utils/proxy/http.js index 1755dd93..875bfb4c 100644 --- a/src/utils/proxy/http.js +++ b/src/utils/proxy/http.js @@ -5,6 +5,7 @@ import { createUnzip, constants as zlibConstants } from "node:zlib"; import { http, https } from "follow-redirects"; import { addCookieToJar, setCookieHeader } from "./cookie-jar"; +import { sanitizeErrorURL } from "./api-helpers"; import createLogger from "utils/logger"; @@ -44,7 +45,7 @@ function handleRequest(requestor, url, params) { // zlib errors responseContent.on("error", (e) => { - logger.error(e); + if (e) logger.error(e); responseContent = response; // fallback }); response.pipe(responseContent); @@ -103,7 +104,7 @@ export async function httpProxy(url, params = {}) { try { const [status, contentType, data, responseHeaders] = await request; - return [status, contentType, data, responseHeaders]; + return [status, contentType, data, responseHeaders, params]; } catch (err) { logger.error( "Error calling %s//%s%s%s...", @@ -112,7 +113,12 @@ export async function httpProxy(url, params = {}) { constructedUrl.port ? `:${constructedUrl.port}` : "", constructedUrl.pathname, ); - logger.error(err); - return [500, "application/json", { error: { message: err?.message ?? "Unknown error", url, rawError: err } }, null]; + if (err) logger.error(err); + return [ + 500, + "application/json", + { error: { message: err?.message ?? "Unknown error", url: sanitizeErrorURL(url), rawError: err } }, + null, + ]; } } diff --git a/src/widgets/audiobookshelf/proxy.js b/src/widgets/audiobookshelf/proxy.js index c4dba5cd..9701c1fe 100644 --- a/src/widgets/audiobookshelf/proxy.js +++ b/src/widgets/audiobookshelf/proxy.js @@ -63,7 +63,7 @@ export default async function audiobookshelfProxyHandler(req, res) { return res.status(200).send(libraryStats); } catch (e) { - logger.error(e.message); + if (e) logger.error(e); return res.status(500).send({ error: { message: e.message } }); } } diff --git a/src/widgets/caddy/component.jsx b/src/widgets/caddy/component.jsx index a6e6f28e..36e5f959 100644 --- a/src/widgets/caddy/component.jsx +++ b/src/widgets/caddy/component.jsx @@ -8,7 +8,7 @@ export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { data: resultData, error: resultError } = useWidgetAPI(widget, "result"); + const { data: resultData, error: resultError } = useWidgetAPI(widget, "upstreams"); if (resultError) { return ; @@ -17,7 +17,6 @@ export default function Component({ service }) { if (!resultData) { return ( - , diff --git a/src/widgets/caddy/widget.js b/src/widgets/caddy/widget.js index 2fb1978b..7e1dc6ba 100644 --- a/src/widgets/caddy/widget.js +++ b/src/widgets/caddy/widget.js @@ -1,8 +1,14 @@ import genericProxyHandler from "utils/proxy/handlers/generic"; const widget = { - api: "{url}/reverse_proxy/upstreams", + api: "{url}/{endpoint}", proxyHandler: genericProxyHandler, + + mappings: { + upstreams: { + endpoint: "reverse_proxy/upstreams", + }, + }, }; export default widget; diff --git a/src/widgets/coinmarketcap/component.jsx b/src/widgets/coinmarketcap/component.jsx index c351cd8d..7e717bef 100644 --- a/src/widgets/coinmarketcap/component.jsx +++ b/src/widgets/coinmarketcap/component.jsx @@ -65,7 +65,7 @@ export default function Component({ service }) { return ( -
      +
      diff --git a/src/widgets/components.js b/src/widgets/components.js index f589fb98..2a2dca72 100644 --- a/src/widgets/components.js +++ b/src/widgets/components.js @@ -16,6 +16,7 @@ const components = { channelsdvrserver: dynamic(() => import("./channelsdvrserver/component")), cloudflared: dynamic(() => import("./cloudflared/component")), coinmarketcap: dynamic(() => import("./coinmarketcap/component")), + crowdsec: dynamic(() => import("./crowdsec/component")), iframe: dynamic(() => import("./iframe/component")), customapi: dynamic(() => import("./customapi/component")), deluge: dynamic(() => import("./deluge/component")), @@ -24,6 +25,7 @@ const components = { docker: dynamic(() => import("./docker/component")), kubernetes: dynamic(() => import("./kubernetes/component")), emby: dynamic(() => import("./emby/component")), + esphome: dynamic(() => import("./esphome/component")), evcc: dynamic(() => import("./evcc/component")), fileflows: dynamic(() => import("./fileflows/component")), flood: dynamic(() => import("./flood/component")), @@ -40,6 +42,7 @@ const components = { hdhomerun: dynamic(() => import("./hdhomerun/component")), peanut: dynamic(() => import("./peanut/component")), homeassistant: dynamic(() => import("./homeassistant/component")), + homebox: dynamic(() => import("./homebox/component")), homebridge: dynamic(() => import("./homebridge/component")), healthchecks: dynamic(() => import("./healthchecks/component")), immich: dynamic(() => import("./immich/component")), @@ -62,6 +65,7 @@ const components = { moonraker: dynamic(() => import("./moonraker/component")), mylar: dynamic(() => import("./mylar/component")), navidrome: dynamic(() => import("./navidrome/component")), + netalertx: dynamic(() => import("./netalertx/component")), netdata: dynamic(() => import("./netdata/component")), nextcloud: dynamic(() => import("./nextcloud/component")), nextdns: dynamic(() => import("./nextdns/component")), @@ -80,7 +84,7 @@ const components = { pfsense: dynamic(() => import("./pfsense/component")), photoprism: dynamic(() => import("./photoprism/component")), proxmoxbackupserver: dynamic(() => import("./proxmoxbackupserver/component")), - pialert: dynamic(() => import("./pialert/component")), + pialert: dynamic(() => import("./netalertx/component")), pihole: dynamic(() => import("./pihole/component")), plantit: dynamic(() => import("./plantit/component")), plex: dynamic(() => import("./plex/component")), @@ -100,8 +104,11 @@ const components = { scrutiny: dynamic(() => import("./scrutiny/component")), sonarr: dynamic(() => import("./sonarr/component")), speedtest: dynamic(() => import("./speedtest/component")), + stash: dynamic(() => import("./stash/component")), strelaysrv: dynamic(() => import("./strelaysrv/component")), + swagdashboard: dynamic(() => import("./swagdashboard/component")), tailscale: dynamic(() => import("./tailscale/component")), + tandoor: dynamic(() => import("./tandoor/component")), tautulli: dynamic(() => import("./tautulli/component")), tdarr: dynamic(() => import("./tdarr/component")), titlecardmaker: dynamic(() => import("./titlecardmaker/component")), @@ -115,6 +122,7 @@ const components = { uptimerobot: dynamic(() => import("./uptimerobot/component")), urbackup: dynamic(() => import("./urbackup/component")), watchtower: dynamic(() => import("./watchtower/component")), + wgeasy: dynamic(() => import("./wgeasy/component")), whatsupdocker: dynamic(() => import("./whatsupdocker/component")), wgeasy: dynamic(() => import("./wgeasy/component")), wled: dynamic(() => import("./wled/component")), diff --git a/src/widgets/crowdsec/component.jsx b/src/widgets/crowdsec/component.jsx new file mode 100644 index 00000000..2e98cee9 --- /dev/null +++ b/src/widgets/crowdsec/component.jsx @@ -0,0 +1,34 @@ +import { useTranslation } from "next-i18next"; + +import Container from "components/services/widget/container"; +import Block from "components/services/widget/block"; +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { t } = useTranslation(); + + const { widget } = service; + + const { data: alerts, error: alertsError } = useWidgetAPI(widget, "alerts"); + const { data: bans, error: bansError } = useWidgetAPI(widget, "bans"); + + if (alertsError || bansError) { + return ; + } + + if (!alerts && !bans) { + return ( + + + + + ); + } + + return ( + + + + + ); +} diff --git a/src/widgets/crowdsec/proxy.js b/src/widgets/crowdsec/proxy.js new file mode 100644 index 00000000..e78fbc5e --- /dev/null +++ b/src/widgets/crowdsec/proxy.js @@ -0,0 +1,86 @@ +import cache from "memory-cache"; + +import { httpProxy } from "utils/proxy/http"; +import { formatApiCall } from "utils/proxy/api-helpers"; +import getServiceWidget from "utils/config/service-helpers"; +import createLogger from "utils/logger"; +import widgets from "widgets/widgets"; + +const proxyName = "crowdsecProxyHandler"; +const logger = createLogger(proxyName); +const sessionTokenCacheKey = `${proxyName}__sessionToken`; + +async function login(widget, service) { + const url = formatApiCall(widgets[widget.type].loginURL, widget); + const [status, , data] = await httpProxy(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "Mozilla/5.0", // Crowdsec requires a user-agent + }, + body: JSON.stringify({ + machine_id: widget.username, + password: widget.password, + scenarios: [], + }), + }); + + const dataParsed = JSON.parse(data); + + if (!(status === 200) || !dataParsed.token) { + logger.error("Failed to login to Crowdsec API, status: %d", status); + cache.del(`${sessionTokenCacheKey}.${service}`); + } + cache.put(`${sessionTokenCacheKey}.${service}`, dataParsed.token, new Date(dataParsed.expire) - new Date()); +} + +export default async function crowdsecProxyHandler(req, res) { + const { group, service, endpoint } = req.query; + + if (!group || !service) { + logger.error("Invalid or missing service '%s' or group '%s'", service, group); + return res.status(400).json({ error: "Invalid proxy service type" }); + } + + const widget = await getServiceWidget(group, service); + if (!widget || !widgets[widget.type].api) { + logger.error("Invalid or missing widget for service '%s' in group '%s'", service, group); + return res.status(400).json({ error: "Invalid widget configuration" }); + } + + if (!cache.get(`${sessionTokenCacheKey}.${service}`)) { + await login(widget, service); + } + + const token = cache.get(`${sessionTokenCacheKey}.${service}`); + if (!token) { + return res.status(500).json({ error: "Failed to authenticate with Crowdsec" }); + } + + const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget })); + + try { + const params = { + method: "GET", + headers: { + "User-Agent": "Mozilla/5.0", // Crowdsec requires a user-agent + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + }; + + logger.debug("Calling Crowdsec API endpoint: %s", endpoint); + + const [status, , data] = await httpProxy(url, params); + + if (status !== 200) { + logger.error("Error calling Crowdsec API: %d. Data: %s", status, data); + return res.status(status).json({ error: "Crowdsec API Error", data }); + } + + return res.status(status).send(data); + } catch (error) { + logger.error("Exception calling Crowdsec API: %s", error.message); + return res.status(500).json({ error: "Crowdsec API Error", message: error.message }); + } +} diff --git a/src/widgets/crowdsec/widget.js b/src/widgets/crowdsec/widget.js new file mode 100644 index 00000000..d29fa1f1 --- /dev/null +++ b/src/widgets/crowdsec/widget.js @@ -0,0 +1,18 @@ +import crowdsecProxyHandler from "./proxy"; + +const widget = { + api: "{url}/v1/{endpoint}", + loginURL: "{url}/v1/watchers/login", + proxyHandler: crowdsecProxyHandler, + + mappings: { + alerts: { + endpoint: "alerts", + }, + bans: { + endpoint: "alerts?decision_type=ban&origin=crowdsec&has_active_decision=1", + }, + }, +}; + +export default widget; diff --git a/src/widgets/emby/component.jsx b/src/widgets/emby/component.jsx index 89fd44c3..6f66d1dc 100644 --- a/src/widgets/emby/component.jsx +++ b/src/widgets/emby/component.jsx @@ -4,7 +4,7 @@ import { MdOutlineSmartDisplay } from "react-icons/md"; import Block from "components/services/widget/block"; import Container from "components/services/widget/container"; -import { formatProxyUrlWithSegments } from "utils/proxy/api-helpers"; +import { getURLSearchParams } from "utils/proxy/api-helpers"; import useWidgetAPI from "utils/proxy/use-widget-api"; function ticksToTime(ticks) { @@ -27,9 +27,26 @@ function ticksToString(ticks) { return parts.map((part) => part.toString().padStart(2, "0")).join(":"); } -function SingleSessionEntry({ playCommand, session }) { +function generateStreamTitle(session, enableUser, showEpisodeNumber) { + const { + NowPlayingItem: { Name, SeriesName, Type, ParentIndexNumber, IndexNumber }, + UserName, + } = session; + let streamTitle = ""; + + if (Type === "Episode" && showEpisodeNumber) { + const seasonStr = `S${ParentIndexNumber.toString().padStart(2, "0")}`; + const episodeStr = `E${IndexNumber.toString().padStart(2, "0")}`; + streamTitle = `${SeriesName}: ${seasonStr} ยท ${episodeStr} - ${Name}`; + } else { + streamTitle = `${Name}${SeriesName ? ` - ${SeriesName}` : ""}`; + } + + return enableUser ? `${streamTitle} (${UserName})` : streamTitle; +} + +function SingleSessionEntry({ playCommand, session, enableUser, showEpisodeNumber }) { const { - NowPlayingItem: { Name, SeriesName }, PlayState: { PositionTicks, IsPaused, IsMuted }, } = session; @@ -42,13 +59,13 @@ function SingleSessionEntry({ playCommand, session }) { const percent = Math.min(1, PositionTicks / RunTimeTicks) * 100; + const streamTitle = generateStreamTitle(session, enableUser, showEpisodeNumber); return ( <>
      -
      - {Name} - {SeriesName && ` - ${SeriesName}`} +
      + {streamTitle}
      @@ -97,9 +114,8 @@ function SingleSessionEntry({ playCommand, session }) { ); } -function SessionEntry({ playCommand, session }) { +function SessionEntry({ playCommand, session, enableUser, showEpisodeNumber }) { const { - NowPlayingItem: { Name, SeriesName }, PlayState: { PositionTicks, IsPaused, IsMuted }, } = session; @@ -110,6 +126,8 @@ function SessionEntry({ playCommand, session }) { IsVideoDirect: true, }; // if no transcodinginfo its videodirect + const streamTitle = generateStreamTitle(session, enableUser, showEpisodeNumber); + const percent = Math.min(1, PositionTicks / RunTimeTicks) * 100; return ( @@ -139,9 +157,8 @@ function SessionEntry({ playCommand, session }) { )}
      -
      - {Name} - {SeriesName && ` - ${SeriesName}`} +
      + {streamTitle}
      {IsMuted && }
      @@ -200,11 +217,17 @@ export default function Component({ service }) { }); async function handlePlayCommand(session, command) { - const url = formatProxyUrlWithSegments(widget, "PlayControl", { - sessionId: session.Id, - command, - }); - await fetch(url).then(() => { + const params = getURLSearchParams(widget, command); + params.append( + "segments", + JSON.stringify({ + sessionId: session.Id, + }), + ); + const url = `/api/services/proxy?${params.toString()}`; + await fetch(url, { + method: "POST", + }).then(() => { sessionMutate(); }); } @@ -215,6 +238,9 @@ export default function Component({ service }) { const enableBlocks = service.widget?.enableBlocks; const enableNowPlaying = service.widget?.enableNowPlaying ?? true; + const enableUser = !!service.widget?.enableUser; // default is false + const expandOneStreamToTwoRows = service.widget?.expandOneStreamToTwoRows !== false; // default is true + const showEpisodeNumber = !!service.widget?.showEpisodeNumber; // default is false if (!sessionsData || !countData) { return ( @@ -225,9 +251,11 @@ export default function Component({ service }) {
      -
      -
      - - -
      + {expandOneStreamToTwoRows && ( +
      + - +
      + )}
      )} @@ -255,15 +283,17 @@ export default function Component({ service }) {
      {t("emby.no_active")}
      -
      - - -
      + {expandOneStreamToTwoRows && ( +
      + - +
      + )}
      ); } - if (playing.length === 1) { + if (expandOneStreamToTwoRows && playing.length === 1) { const session = playing[0]; return ( <> @@ -272,27 +302,30 @@ export default function Component({ service }) { handlePlayCommand(currentSession, command)} session={session} + enableUser={enableUser} + showEpisodeNumber={showEpisodeNumber} />
      ); } - if (playing.length > 0) - return ( - <> - {enableBlocks && } -
      - {playing.map((session) => ( - handlePlayCommand(currentSession, command)} - session={session} - /> - ))} -
      - - ); + return ( + <> + {enableBlocks && } +
      + {playing.map((session) => ( + handlePlayCommand(currentSession, command)} + session={session} + enableUser={enableUser} + showEpisodeNumber={showEpisodeNumber} + /> + ))} +
      + + ); } if (enableBlocks) { diff --git a/src/widgets/emby/widget.js b/src/widgets/emby/widget.js index 1dc009b2..3b04f59f 100644 --- a/src/widgets/emby/widget.js +++ b/src/widgets/emby/widget.js @@ -10,12 +10,16 @@ const widget = { }, Count: { endpoint: "Items/Counts", - segments: ["MovieCount", "SeriesCount", "EpisodeCount", "SongCount"], }, - PlayControl: { + Unpause: { method: "POST", - endpoint: "Sessions/{sessionId}/Playing/{command}", - segments: ["sessionId", "command"], + endpoint: "Sessions/{sessionId}/Playing/Unpause", + segments: ["sessionId"], + }, + Pause: { + method: "POST", + endpoint: "Sessions/{sessionId}/Playing/Pause", + segments: ["sessionId"], }, }, }; diff --git a/src/widgets/esphome/component.jsx b/src/widgets/esphome/component.jsx new file mode 100644 index 00000000..ea2e5db3 --- /dev/null +++ b/src/widgets/esphome/component.jsx @@ -0,0 +1,44 @@ +import { useTranslation } from "next-i18next"; + +import Block from "components/services/widget/block"; +import Container from "components/services/widget/container"; +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { t } = useTranslation(); + + const { widget } = service; + const { data: resultData, error: resultError } = useWidgetAPI(widget); + + if (resultError) { + return ; + } + + if (!resultData) { + return ( + + + + + + + + ); + } + + const total = Object.keys(resultData).length; + const online = Object.entries(resultData).filter(([, v]) => v === true).length; + const notOnline = Object.entries(resultData).filter(([, v]) => v !== true).length; + const offline = Object.entries(resultData).filter(([, v]) => v === false).length; + const unknown = Object.entries(resultData).filter(([, v]) => v === null).length; + + return ( + + + + + + + + ); +} diff --git a/src/widgets/esphome/widget.js b/src/widgets/esphome/widget.js new file mode 100644 index 00000000..c5a87b68 --- /dev/null +++ b/src/widgets/esphome/widget.js @@ -0,0 +1,8 @@ +import genericProxyHandler from "utils/proxy/handlers/generic"; + +const widget = { + api: "{url}/ping", + proxyHandler: genericProxyHandler, +}; + +export default widget; diff --git a/src/widgets/evcc/component.jsx b/src/widgets/evcc/component.jsx index 649bb340..9f5d4c4d 100644 --- a/src/widgets/evcc/component.jsx +++ b/src/widgets/evcc/component.jsx @@ -17,7 +17,6 @@ export default function Component({ service }) { if (!stateData) { return ( - , diff --git a/src/widgets/flood/widget.js b/src/widgets/flood/widget.js index 027ff344..13413cf4 100644 --- a/src/widgets/flood/widget.js +++ b/src/widgets/flood/widget.js @@ -2,6 +2,12 @@ import floodProxyHandler from "./proxy"; const widget = { proxyHandler: floodProxyHandler, + + mappings: { + torrents: { + endpoint: "torrents", + }, + }, }; export default widget; diff --git a/src/widgets/fritzbox/widget.js b/src/widgets/fritzbox/widget.js index 13193821..32e8a5c2 100644 --- a/src/widgets/fritzbox/widget.js +++ b/src/widgets/fritzbox/widget.js @@ -2,6 +2,7 @@ import fritzboxProxyHandler from "./proxy"; const widget = { proxyHandler: fritzboxProxyHandler, + allowedEndpoints: /status/, }; export default widget; diff --git a/src/widgets/gamedig/proxy.js b/src/widgets/gamedig/proxy.js index 0029834c..8a7e55c5 100644 --- a/src/widgets/gamedig/proxy.js +++ b/src/widgets/gamedig/proxy.js @@ -28,7 +28,7 @@ export default async function gamedigProxyHandler(req, res) { ping: serverData.ping, }); } catch (e) { - logger.error(e); + if (e) logger.error(e); res.status(200).send({ online: false, diff --git a/src/widgets/gamedig/widget.js b/src/widgets/gamedig/widget.js index 6ccfa123..0f888b43 100644 --- a/src/widgets/gamedig/widget.js +++ b/src/widgets/gamedig/widget.js @@ -2,6 +2,7 @@ import gamedigProxyHandler from "./proxy"; const widget = { proxyHandler: gamedigProxyHandler, + allowedEndpoints: /status/, }; export default widget; diff --git a/src/widgets/ghostfolio/component.jsx b/src/widgets/ghostfolio/component.jsx index 3bd79325..747fdabf 100644 --- a/src/widgets/ghostfolio/component.jsx +++ b/src/widgets/ghostfolio/component.jsx @@ -5,8 +5,12 @@ import Block from "components/services/widget/block"; import useWidgetAPI from "utils/proxy/use-widget-api"; function getPerformancePercent(t, performanceRange) { - return `${performanceRange.performance.currentGrossPerformancePercent > 0 ? "+" : ""}${t("common.percent", { - value: performanceRange.performance.currentGrossPerformancePercent * 100, + // ghostfolio v2.79.0 changed to grossPerformancePercentage + const percent = + performanceRange.performance.grossPerformancePercentage ?? + performanceRange.performance.currentGrossPerformancePercent; + return `${percent > 0 ? "+" : ""}${t("common.percent", { + value: percent * 100, maximumFractionDigits: 2, })}`; } @@ -24,6 +28,10 @@ export default function Component({ service }) { return ; } + if (performanceToday?.statusCode === 401) { + return ; + } + if (!performanceToday || !performanceYear || !performanceMax) { return ( diff --git a/src/widgets/glances/metrics/cpu.jsx b/src/widgets/glances/metrics/cpu.jsx index c36aba9d..553517ba 100644 --- a/src/widgets/glances/metrics/cpu.jsx +++ b/src/widgets/glances/metrics/cpu.jsx @@ -16,15 +16,15 @@ const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit } = widget; + const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit, version = 3 } = widget; const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ value: 0 }, 0, pointsLimit)); - const { data, error } = useWidgetAPI(service.widget, "cpu", { + const { data, error } = useWidgetAPI(service.widget, `${version}/cpu`, { refreshInterval: Math.max(defaultInterval, refreshInterval), }); - const { data: systemData, error: systemError } = useWidgetAPI(service.widget, "system"); + const { data: quicklookData, error: quicklookError } = useWidgetAPI(service.widget, `${version}/quicklook`); useEffect(() => { if (data) { @@ -71,22 +71,15 @@ export default function Component({ service }) { /> )} - {!chart && systemData && !systemError && ( + {!chart && quicklookData && !quicklookError && ( -
      - {systemData.linux_distro && `${systemData.linux_distro} - `} - {systemData.os_version && systemData.os_version} -
      +
      {quicklookData.cpu_name && quicklookData.cpu_name}
      )} - {systemData && !systemError && ( + {quicklookData && !quicklookError && ( - {systemData.linux_distro && chart &&
      {systemData.linux_distro}
      } - - {systemData.os_version && chart &&
      {systemData.os_version}
      } - - {systemData.hostname &&
      {systemData.hostname}
      } + {quicklookData.cpu_name && chart &&
      {quicklookData.cpu_name}
      }
      )} diff --git a/src/widgets/glances/metrics/disk.jsx b/src/widgets/glances/metrics/disk.jsx index d5cac477..04a5071f 100644 --- a/src/widgets/glances/metrics/disk.jsx +++ b/src/widgets/glances/metrics/disk.jsx @@ -16,7 +16,7 @@ const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit } = widget; + const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit, version = 3 } = widget; const [, diskName] = widget.metric.split(":"); const [dataPoints, setDataPoints] = useState( @@ -24,7 +24,7 @@ export default function Component({ service }) { ); const [ratePoints, setRatePoints] = useState(new Array(pointsLimit).fill({ a: 0, b: 0 }, 0, pointsLimit)); - const { data, error } = useWidgetAPI(service.widget, "diskio", { + const { data, error } = useWidgetAPI(service.widget, `${version}/diskio`, { refreshInterval: Math.max(defaultInterval, refreshInterval), }); diff --git a/src/widgets/glances/metrics/fs.jsx b/src/widgets/glances/metrics/fs.jsx index 16d8d153..3ec7eb6c 100644 --- a/src/widgets/glances/metrics/fs.jsx +++ b/src/widgets/glances/metrics/fs.jsx @@ -11,11 +11,11 @@ const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart, refreshInterval = defaultInterval } = widget; + const { chart, refreshInterval = defaultInterval, version = 3 } = widget; const [, fsName] = widget.metric.split("fs:"); const diskUnits = widget.diskUnits === "bbytes" ? "common.bbytes" : "common.bytes"; - const { data, error } = useWidgetAPI(widget, "fs", { + const { data, error } = useWidgetAPI(widget, `${version}/fs`, { refreshInterval: Math.max(defaultInterval, refreshInterval), }); diff --git a/src/widgets/glances/metrics/gpu.jsx b/src/widgets/glances/metrics/gpu.jsx index c33c6396..174ae2e0 100644 --- a/src/widgets/glances/metrics/gpu.jsx +++ b/src/widgets/glances/metrics/gpu.jsx @@ -16,12 +16,12 @@ const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit } = widget; + const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit, version = 3 } = widget; const [, gpuName] = widget.metric.split(":"); const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ a: 0, b: 0 }, 0, pointsLimit)); - const { data, error } = useWidgetAPI(widget, "gpu", { + const { data, error } = useWidgetAPI(widget, `${version}/gpu`, { refreshInterval: Math.max(defaultInterval, refreshInterval), }); diff --git a/src/widgets/glances/metrics/info.jsx b/src/widgets/glances/metrics/info.jsx index e7555bce..1ee47b98 100644 --- a/src/widgets/glances/metrics/info.jsx +++ b/src/widgets/glances/metrics/info.jsx @@ -74,13 +74,13 @@ const defaultSystemInterval = 30000; // This data (OS, hostname, distribution) i export default function Component({ service }) { const { widget } = service; - const { chart, refreshInterval = defaultInterval } = widget; + const { chart, refreshInterval = defaultInterval, version = 3 } = widget; - const { data: quicklookData, errorL: quicklookError } = useWidgetAPI(service.widget, "quicklook", { + const { data: quicklookData, errorL: quicklookError } = useWidgetAPI(service.widget, `${version}/quicklook`, { refreshInterval, }); - const { data: systemData, errorL: systemError } = useWidgetAPI(service.widget, "system", { + const { data: systemData, errorL: systemError } = useWidgetAPI(service.widget, `${version}/system`, { refreshInterval: defaultSystemInterval, }); @@ -122,7 +122,10 @@ export default function Component({ service }) { )} {!chart && quicklookData?.swap === 0 && ( -
      {quicklookData.cpu_name}
      +
      + {systemData && systemData.linux_distro && `${systemData.linux_distro} - `} + {systemData && systemData.os_version} +
      )}
      {!chart && }
      @@ -137,7 +140,7 @@ export default function Component({ service }) { )} {!chart && ( - + )} diff --git a/src/widgets/glances/metrics/memory.jsx b/src/widgets/glances/metrics/memory.jsx index d6cc5e6c..49046a5f 100644 --- a/src/widgets/glances/metrics/memory.jsx +++ b/src/widgets/glances/metrics/memory.jsx @@ -17,11 +17,11 @@ export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; const { chart } = widget; - const { refreshInterval = defaultInterval(chart), pointsLimit = defaultPointsLimit } = widget; + const { refreshInterval = defaultInterval(chart), pointsLimit = defaultPointsLimit, version = 3 } = widget; const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ value: 0 }, 0, pointsLimit)); - const { data, error } = useWidgetAPI(service.widget, "mem", { + const { data, error } = useWidgetAPI(service.widget, `${version}/mem`, { refreshInterval: Math.max(defaultInterval(chart), refreshInterval), }); diff --git a/src/widgets/glances/metrics/net.jsx b/src/widgets/glances/metrics/net.jsx index 3bd92c22..c1ec937e 100644 --- a/src/widgets/glances/metrics/net.jsx +++ b/src/widgets/glances/metrics/net.jsx @@ -17,13 +17,16 @@ export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; const { chart, metric } = widget; - const { refreshInterval = defaultInterval(chart), pointsLimit = defaultPointsLimit } = widget; + const { refreshInterval = defaultInterval(chart), pointsLimit = defaultPointsLimit, version = 3 } = widget; + + const rxKey = version === 3 ? "rx" : "bytes_recv"; + const txKey = version === 3 ? "tx" : "bytes_sent"; const [, interfaceName] = metric.split(":"); const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ value: 0 }, 0, pointsLimit)); - const { data, error } = useWidgetAPI(widget, "network", { + const { data, error } = useWidgetAPI(widget, `${version}/network`, { refreshInterval: Math.max(defaultInterval(chart), refreshInterval), }); @@ -36,8 +39,8 @@ export default function Component({ service }) { const newDataPoints = [ ...prevDataPoints, { - a: (interfaceData.rx * 8) / interfaceData.time_since_update, - b: (interfaceData.tx * 8) / interfaceData.time_since_update, + a: (interfaceData[rxKey] * 8) / interfaceData.time_since_update, + b: (interfaceData[txKey] * 8) / interfaceData.time_since_update, }, ]; if (newDataPoints.length > pointsLimit) { @@ -47,7 +50,7 @@ export default function Component({ service }) { }); } } - }, [data, interfaceName, pointsLimit]); + }, [data, interfaceName, pointsLimit, rxKey, txKey]); if (error) { return ( @@ -97,7 +100,7 @@ export default function Component({ service }) {
      {t("common.bitrate", { - value: (interfaceData.rx * 8) / interfaceData.time_since_update, + value: (interfaceData[rxKey] * 8) / interfaceData.time_since_update, maximumFractionDigits: 0, })}{" "} {t("docker.rx")} @@ -115,7 +118,7 @@ export default function Component({ service }) {
      {t("common.bitrate", { - value: (interfaceData.tx * 8) / interfaceData.time_since_update, + value: (interfaceData[txKey] * 8) / interfaceData.time_since_update, maximumFractionDigits: 0, })}{" "} {t("docker.tx")} diff --git a/src/widgets/glances/metrics/process.jsx b/src/widgets/glances/metrics/process.jsx index cd21356d..b242535e 100644 --- a/src/widgets/glances/metrics/process.jsx +++ b/src/widgets/glances/metrics/process.jsx @@ -22,9 +22,11 @@ const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart, refreshInterval = defaultInterval } = widget; + const { chart, refreshInterval = defaultInterval, version = 3 } = widget; - const { data, error } = useWidgetAPI(service.widget, "processlist", { + const memoryInfoKey = version === 3 ? 0 : "data"; + + const { data, error } = useWidgetAPI(service.widget, `${version}/processlist`, { refreshInterval: Math.max(defaultInterval, refreshInterval), }); @@ -62,11 +64,11 @@ export default function Component({ service }) {
      {statusMap[item.status]}
      -
      {item.name}
      +
      {item.name}
      {item.cpu_percent.toFixed(1)}%
      {t("common.bytes", { - value: item.memory_info[0], + value: item.memory_info[memoryInfoKey], maximumFractionDigits: 0, })}
      diff --git a/src/widgets/glances/metrics/sensor.jsx b/src/widgets/glances/metrics/sensor.jsx index 60ea07c8..e0f679c1 100644 --- a/src/widgets/glances/metrics/sensor.jsx +++ b/src/widgets/glances/metrics/sensor.jsx @@ -16,12 +16,12 @@ const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit } = widget; + const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit, version = 3 } = widget; const [, sensorName] = widget.metric.split(":"); const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ value: 0 }, 0, pointsLimit)); - const { data, error } = useWidgetAPI(service.widget, "sensors", { + const { data, error } = useWidgetAPI(service.widget, `${version}/sensors`, { refreshInterval: Math.max(defaultInterval, refreshInterval), }); diff --git a/src/widgets/glances/widget.js b/src/widgets/glances/widget.js index 3da1c6d1..00d3ac5a 100644 --- a/src/widgets/glances/widget.js +++ b/src/widgets/glances/widget.js @@ -1,8 +1,9 @@ import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; const widget = { - api: "{url}/api/3/{endpoint}", + api: "{url}/api/{endpoint}", proxyHandler: credentialedProxyHandler, + allowedEndpoints: /\d\/quicklook|diskio|cpu|fs|gpu|system|mem|network|processlist|sensors/, }; export default widget; diff --git a/src/widgets/homebox/component.jsx b/src/widgets/homebox/component.jsx new file mode 100644 index 00000000..18ea520e --- /dev/null +++ b/src/widgets/homebox/component.jsx @@ -0,0 +1,58 @@ +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 const homeboxDefaultFields = ["items", "locations", "totalValue"]; + +export default function Component({ service }) { + const { t } = useTranslation(); + const { widget } = service; + const { data: homeboxData, error: homeboxError } = useWidgetAPI(widget); + + if (homeboxError) { + return ; + } + + // Default fields + if (!widget.fields?.length > 0) { + widget.fields = homeboxDefaultFields; + } + const MAX_ALLOWED_FIELDS = 4; + // Limits max number of displayed fields + if (widget.fields?.length > MAX_ALLOWED_FIELDS) { + widget.fields = widget.fields.slice(0, MAX_ALLOWED_FIELDS); + } + + if (!homeboxData) { + return ( + + + + + + + + + ); + } + + return ( + + + + + + + + + ); +} diff --git a/src/widgets/homebox/proxy.js b/src/widgets/homebox/proxy.js new file mode 100644 index 00000000..0d6fdf13 --- /dev/null +++ b/src/widgets/homebox/proxy.js @@ -0,0 +1,103 @@ +import cache from "memory-cache"; + +import { formatApiCall } from "utils/proxy/api-helpers"; +import { httpProxy } from "utils/proxy/http"; +import getServiceWidget from "utils/config/service-helpers"; +import createLogger from "utils/logger"; + +const proxyName = "homeboxProxyHandler"; +const sessionTokenCacheKey = `${proxyName}__sessionToken`; +const logger = createLogger(proxyName); + +async function login(widget, service) { + logger.debug("Homebox is rejecting the request, logging in."); + + const loginUrl = new URL(`${widget.url}/api/v1/users/login`).toString(); + const loginBody = `username=${encodeURIComponent(widget.username)}&password=${encodeURIComponent(widget.password)}`; + const loginParams = { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: loginBody, + }; + + const [, , data] = await httpProxy(loginUrl, loginParams); + + try { + const { token, expiresAt } = JSON.parse(data.toString()); + const expiresAtDate = new Date(expiresAt).getTime(); + cache.put(`${sessionTokenCacheKey}.${service}`, token, expiresAtDate - Date.now()); + return { token }; + } catch (e) { + logger.error("Unable to login to Homebox API: %s", e); + } + + return { token: false }; +} + +async function apiCall(widget, endpoint, service) { + const key = `${sessionTokenCacheKey}.${service}`; + const url = new URL(formatApiCall("{url}/api/v1/{endpoint}", { endpoint, ...widget })); + const headers = { + "Content-Type": "application/json", + Authorization: `${cache.get(key)}`, + }; + const params = { method: "GET", headers }; + + let [status, contentType, data, responseHeaders] = await httpProxy(url, params); + + if (status === 401 || status === 403) { + logger.debug("Homebox API rejected the request, attempting to obtain new access token"); + const { token } = await login(widget, service); + headers.Authorization = `${token}`; + + // retry request with new token + [status, contentType, data, responseHeaders] = await httpProxy(url, params); + + if (status !== 200) { + logger.error("HTTP %d logging in to Homebox, data: %s", status, data); + return { status, contentType, data: null, responseHeaders }; + } + } + + if (status !== 200) { + logger.error("HTTP %d getting data from Homebox, data: %s", status, data); + return { status, contentType, data: null, responseHeaders }; + } + + return { status, contentType, data: JSON.parse(data.toString()), responseHeaders }; +} + +export default async function homeboxProxyHandler(req, res) { + const { group, service } = req.query; + + if (!group || !service) { + logger.debug("Invalid or missing service '%s' or group '%s'", service, group); + return res.status(400).json({ error: "Invalid proxy service type" }); + } + + const widget = await getServiceWidget(group, service); + if (!widget) { + logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group); + return res.status(400).json({ error: "Invalid proxy service type" }); + } + + if (!cache.get(`${sessionTokenCacheKey}.${service}`)) { + await login(widget, service); + } + + // Get stats for the main blocks + const { data: groupStats } = await apiCall(widget, "groups/statistics", service); + + // Get group info for currency + const { data: groupData } = await apiCall(widget, "groups", service); + + return res.status(200).send({ + items: groupStats?.totalItems, + locations: groupStats?.totalLocations, + labels: groupStats?.totalLabels, + totalWithWarranty: groupStats?.totalWithWarranty, + totalValue: groupStats?.totalItemPrice, + users: groupStats?.totalUsers, + currencyCode: groupData?.currency, + }); +} diff --git a/src/widgets/homebox/widget.js b/src/widgets/homebox/widget.js new file mode 100644 index 00000000..37b06a4f --- /dev/null +++ b/src/widgets/homebox/widget.js @@ -0,0 +1,7 @@ +import homeboxProxyHandler from "./proxy"; + +const widget = { + proxyHandler: homeboxProxyHandler, +}; + +export default widget; diff --git a/src/widgets/homebridge/proxy.js b/src/widgets/homebridge/proxy.js index 2803415a..17dc8635 100644 --- a/src/widgets/homebridge/proxy.js +++ b/src/widgets/homebridge/proxy.js @@ -14,7 +14,7 @@ async function login(widget, service) { const endpoint = "auth/login"; const api = widgets?.[widget.type]?.api; const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget })); - const loginBody = { username: widget.username, password: widget.password }; + const loginBody = { username: widget.username.toString(), password: widget.password.toString() }; const headers = { "Content-Type": "application/json" }; // eslint-disable-next-line no-unused-vars const [status, contentType, data, responseHeaders] = await httpProxy(loginUrl, { diff --git a/src/widgets/jackett/proxy.js b/src/widgets/jackett/proxy.js new file mode 100644 index 00000000..5292695f --- /dev/null +++ b/src/widgets/jackett/proxy.js @@ -0,0 +1,68 @@ +import { httpProxy } from "utils/proxy/http"; +import { formatApiCall } from "utils/proxy/api-helpers"; +import getServiceWidget from "utils/config/service-helpers"; +import createLogger from "utils/logger"; +import widgets from "widgets/widgets"; + +const logger = createLogger("jackettProxyHandler"); + +async function fetchJackettCookie(widget, loginURL) { + const url = new URL(formatApiCall(loginURL, widget)); + const loginData = `password=${encodeURIComponent(widget.password)}`; + const [status, , , , params] = await httpProxy(url, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: loginData, + }); + + if (!(status === 200) || !params?.headers?.Cookie) { + logger.error("Failed to fetch Jackett cookie, status: %d", status); + return null; + } + return params.headers.Cookie; +} + +export default async function jackettProxyHandler(req, res) { + const { group, service, endpoint } = req.query; + + if (!group || !service) { + logger.error("Invalid or missing service '%s' or group '%s'", service, group); + return res.status(400).json({ error: "Invalid proxy service type" }); + } + + const widget = await getServiceWidget(group, service); + if (!widget || !widgets[widget.type].api) { + logger.error("Invalid or missing widget for service '%s' in group '%s'", service, group); + return res.status(400).json({ error: "Invalid widget configuration" }); + } + + if (widget.password) { + const jackettCookie = await fetchJackettCookie(widget, widgets[widget.type].loginURL); + if (!jackettCookie) { + return res.status(500).json({ error: "Failed to authenticate with Jackett" }); + } + // Add the cookie to the widget for use in subsequent requests + widget.headers = { ...widget.headers, Cookie: jackettCookie }; + } + + const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget })); + + try { + const [status, , data] = await httpProxy(url, { + method: "GET", + headers: widget.headers, + }); + + if (status !== 200) { + logger.error("Error calling Jackett API: %d. Data: %s", status, data); + return res.status(status).json({ error: "Failed to call Jackett API", data }); + } + + return res.status(status).send(data); + } catch (error) { + logger.error("Exception calling Jackett API: %s", error.message); + return res.status(500).json({ error: "Server error", message: error.message }); + } +} diff --git a/src/widgets/jackett/widget.js b/src/widgets/jackett/widget.js index 9d2a9b5c..0af816e5 100644 --- a/src/widgets/jackett/widget.js +++ b/src/widgets/jackett/widget.js @@ -1,8 +1,9 @@ -import genericProxyHandler from "utils/proxy/handlers/generic"; +import jackettProxyHandler from "./proxy"; const widget = { api: "{url}/api/v2.0/{endpoint}?apikey={key}&configured=true", - proxyHandler: genericProxyHandler, + proxyHandler: jackettProxyHandler, + loginURL: "{url}/UI/Dashboard", mappings: { indexers: { diff --git a/src/widgets/kubernetes/component.jsx b/src/widgets/kubernetes/component.jsx index 2454f2aa..68d0da29 100644 --- a/src/widgets/kubernetes/component.jsx +++ b/src/widgets/kubernetes/component.jsx @@ -18,10 +18,13 @@ export default function Component({ service }) { ); if (statsError || statusError) { - return ; + return ; } - if (statusData && !(statusData.status.includes("running") || statusData.status.includes("partial"))) { + if ( + statusData && + (!statusData.status || !(statusData.status.includes("running") || statusData.status.includes("partial"))) + ) { return ( diff --git a/src/widgets/minecraft/proxy.js b/src/widgets/minecraft/proxy.js index 7aeedfb9..f7bac9d4 100644 --- a/src/widgets/minecraft/proxy.js +++ b/src/widgets/minecraft/proxy.js @@ -18,7 +18,7 @@ export default async function minecraftProxyHandler(req, res) { players: pingResponse.players, }); } catch (e) { - logger.error(e); + if (e) logger.error(e); res.status(200).send({ version: undefined, online: false, diff --git a/src/widgets/minecraft/widget.js b/src/widgets/minecraft/widget.js index f8a81bfb..fbe413b7 100644 --- a/src/widgets/minecraft/widget.js +++ b/src/widgets/minecraft/widget.js @@ -2,6 +2,7 @@ import minecraftProxyHandler from "./proxy"; const widget = { proxyHandler: minecraftProxyHandler, + allowedEndpoints: /status/, }; export default widget; diff --git a/src/widgets/netalertx/component.jsx b/src/widgets/netalertx/component.jsx new file mode 100644 index 00000000..5172121e --- /dev/null +++ b/src/widgets/netalertx/component.jsx @@ -0,0 +1,37 @@ +import { useTranslation } from "next-i18next"; + +import Container from "components/services/widget/container"; +import Block from "components/services/widget/block"; +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { t } = useTranslation(); + + const { widget } = service; + + const { data: netalertxData, error: netalertxError } = useWidgetAPI(widget, "data"); + + if (netalertxError) { + return ; + } + + if (!netalertxData) { + return ( + + + + + + + ); + } + + return ( + + + + + + + ); +} diff --git a/src/widgets/pialert/widget.js b/src/widgets/netalertx/widget.js similarity index 100% rename from src/widgets/pialert/widget.js rename to src/widgets/netalertx/widget.js diff --git a/src/widgets/npm/component.jsx b/src/widgets/npm/component.jsx index 37712266..06ac91eb 100644 --- a/src/widgets/npm/component.jsx +++ b/src/widgets/npm/component.jsx @@ -5,7 +5,7 @@ import useWidgetAPI from "utils/proxy/use-widget-api"; export default function Component({ service }) { const { widget } = service; - const { data: infoData, error: infoError } = useWidgetAPI(widget, "nginx/proxy-hosts"); + const { data: infoData, error: infoError } = useWidgetAPI(widget, "hosts"); if (infoError) { return ; diff --git a/src/widgets/npm/widget.js b/src/widgets/npm/widget.js index 652cb4a2..24b3ce02 100644 --- a/src/widgets/npm/widget.js +++ b/src/widgets/npm/widget.js @@ -3,6 +3,12 @@ import npmProxyHandler from "./proxy"; const widget = { api: "{url}/api/{endpoint}", proxyHandler: npmProxyHandler, + + mappings: { + hosts: { + endpoint: "nginx/proxy-hosts", + }, + }, }; export default widget; diff --git a/src/widgets/nzbget/widget.js b/src/widgets/nzbget/widget.js index 841fb66c..79ca1807 100644 --- a/src/widgets/nzbget/widget.js +++ b/src/widgets/nzbget/widget.js @@ -3,6 +3,7 @@ import jsonrpcProxyHandler from "utils/proxy/handlers/jsonrpc"; const widget = { api: "{url}/jsonrpc", proxyHandler: jsonrpcProxyHandler, + allowedEndpoints: /status/, }; export default widget; diff --git a/src/widgets/omada/component.jsx b/src/widgets/omada/component.jsx index d0565e43..e63f93d3 100644 --- a/src/widgets/omada/component.jsx +++ b/src/widgets/omada/component.jsx @@ -9,7 +9,7 @@ export default function Component({ service }) { const { widget } = service; - const { data: omadaData, error: omadaAPIError } = useWidgetAPI(widget, { + const { data: omadaData, error: omadaAPIError } = useWidgetAPI(widget, "info", { refreshInterval: 5000, }); @@ -17,12 +17,20 @@ export default function Component({ service }) { return ; } + if (!widget.fields) { + widget.fields = ["connectedAp", "activeUser", "alerts", "connectedGateway"]; + } else if (widget.fields?.length > 4) { + widget.fields = widget.fields.slice(0, 4); + } + if (!omadaData) { return ( + + ); } @@ -32,9 +40,8 @@ export default function Component({ service }) { - {omadaData.connectedGateways > 0 && ( - - )} + + ); } diff --git a/src/widgets/omada/widget.js b/src/widgets/omada/widget.js index 5e32edad..3f5a70a1 100644 --- a/src/widgets/omada/widget.js +++ b/src/widgets/omada/widget.js @@ -2,6 +2,12 @@ import omadaProxyHandler from "./proxy"; const widget = { proxyHandler: omadaProxyHandler, + + mappings: { + info: { + endpoint: "api/info", + }, + }, }; export default widget; diff --git a/src/widgets/openwrt/proxy.js b/src/widgets/openwrt/proxy.js index 04c7a503..977db8ca 100644 --- a/src/widgets/openwrt/proxy.js +++ b/src/widgets/openwrt/proxy.js @@ -77,7 +77,7 @@ async function fetchSystem(url) { const systemResponse = JSON.parse(data.toString())[1]; const response = { uptime: systemResponse.uptime, - cpuLoad: systemResponse.load[1], + cpuLoad: (systemResponse.load[1] / 65536.0).toFixed(2), }; return [200, contentType, response]; } diff --git a/src/widgets/pialert/component.jsx b/src/widgets/pialert/component.jsx deleted file mode 100644 index 49bef897..00000000 --- a/src/widgets/pialert/component.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import { useTranslation } from "next-i18next"; - -import Container from "components/services/widget/container"; -import Block from "components/services/widget/block"; -import useWidgetAPI from "utils/proxy/use-widget-api"; - -export default function Component({ service }) { - const { t } = useTranslation(); - - const { widget } = service; - - const { data: pialertData, error: pialertError } = useWidgetAPI(widget, "data"); - - if (pialertError) { - return ; - } - - if (!pialertData) { - return ( - - - - - - - ); - } - - return ( - - - - - - - ); -} diff --git a/src/widgets/pihole/component.jsx b/src/widgets/pihole/component.jsx index c9b03610..7aa706e4 100644 --- a/src/widgets/pihole/component.jsx +++ b/src/widgets/pihole/component.jsx @@ -9,12 +9,16 @@ export default function Component({ service }) { const { widget } = service; - const { data: piholeData, error: piholeError } = useWidgetAPI(widget, "summaryRaw"); + const { data: piholeData, error: piholeError } = useWidgetAPI(widget); if (piholeError) { return ; } + if (!widget.fields) { + widget.fields = ["queries", "blocked", "gravity"]; + } + if (!piholeData) { return ( @@ -26,13 +30,18 @@ export default function Component({ service }) { ); } + let blockedValue = `${t("common.number", { value: parseInt(piholeData.ads_blocked_today, 10) })}`; + if (!widget.fields.includes("blocked_percent")) { + blockedValue += ` (${t("common.percent", { value: parseFloat(piholeData.ads_percentage_today).toPrecision(3) })})`; + } + return ( - + ; diff --git a/src/widgets/qbittorrent/widget.js b/src/widgets/qbittorrent/widget.js index 1e8348b3..182ac9d1 100644 --- a/src/widgets/qbittorrent/widget.js +++ b/src/widgets/qbittorrent/widget.js @@ -2,6 +2,12 @@ import qbittorrentProxyHandler from "./proxy"; const widget = { proxyHandler: qbittorrentProxyHandler, + + mappings: { + torrents: { + endpoint: "torrents/info", + }, + }, }; export default widget; diff --git a/src/widgets/qnap/widget.js b/src/widgets/qnap/widget.js index ebaf93c9..1069fa9a 100644 --- a/src/widgets/qnap/widget.js +++ b/src/widgets/qnap/widget.js @@ -3,6 +3,7 @@ import qnapProxyHandler from "./proxy"; const widget = { api: "{url}", proxyHandler: qnapProxyHandler, + allowedEndpoints: /status/, }; export default widget; diff --git a/src/widgets/romm/component.jsx b/src/widgets/romm/component.jsx index 37c00c2d..ea8ec4ef 100644 --- a/src/widgets/romm/component.jsx +++ b/src/widgets/romm/component.jsx @@ -1,9 +1,12 @@ +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 { widget } = service; + const { t } = useTranslation(); const { data: response, error: responseError } = useWidgetAPI(widget, "statistics"); @@ -19,14 +22,14 @@ export default function Component({ service }) { return ; } - if (response) { - const platforms = response.filter((x) => x.rom_count !== 0).length; - const totalRoms = response.reduce((total, stat) => total + stat.rom_count, 0); - return ( - - - - - ); - } + if (response) { + const platforms = response.filter((x) => x.rom_count !== 0).length; + const totalRoms = response.reduce((total, stat) => total + stat.rom_count, 0); + return ( + + + + + ); + } } diff --git a/src/widgets/sabnzbd/component.jsx b/src/widgets/sabnzbd/component.jsx index d7fde734..260375a4 100644 --- a/src/widgets/sabnzbd/component.jsx +++ b/src/widgets/sabnzbd/component.jsx @@ -37,7 +37,7 @@ export default function Component({ service }) { return ( - + diff --git a/src/widgets/speedtest/component.jsx b/src/widgets/speedtest/component.jsx index 0102025b..9826f776 100644 --- a/src/widgets/speedtest/component.jsx +++ b/src/widgets/speedtest/component.jsx @@ -11,6 +11,11 @@ export default function Component({ service }) { const { data: speedtestData, error: speedtestError } = useWidgetAPI(widget, "speedtest/latest"); + const bitratePrecision = + !widget?.bitratePrecision || Number.isNaN(widget?.bitratePrecision) || widget?.bitratePrecision < 0 + ? 0 + : widget.bitratePrecision; + if (speedtestError) { return ; } @@ -29,9 +34,18 @@ export default function Component({ service }) { + - { + async function fetchStats() { + const url = formatProxyUrl(widget, "stats"); + const res = await fetch(url, { method: "POST" }); + setStats(await res.json()); + } + if (!stats) { + fetchStats(); + } + }, [widget, stats]); + + if (!stats) { + return ( + + + + + ); + } + + // Provide a default if not set in the config + if (!widget.fields) { + widget.fields = ["scenes", "images"]; + } + + // Limit to a maximum of 4 at a time + if (widget.fields.length > 4) { + widget.fields = widget.fields.slice(0, 4); + } + + return ( + + + + + + + + + + + + + + + + + + + ); +} diff --git a/src/widgets/stash/widget.js b/src/widgets/stash/widget.js new file mode 100644 index 00000000..82803c72 --- /dev/null +++ b/src/widgets/stash/widget.js @@ -0,0 +1,40 @@ +import { asJson } from "utils/proxy/api-helpers"; +import genericProxyHandler from "utils/proxy/handlers/generic"; + +const widget = { + api: "{url}/{endpoint}?apikey={key}", + proxyHandler: genericProxyHandler, + + mappings: { + stats: { + method: "POST", + endpoint: "graphql", + headers: { + "content-type": "application/json", + }, + body: JSON.stringify({ + query: `{ + stats { + scene_count + scenes_size + scenes_duration + image_count + images_size + gallery_count + performer_count + studio_count + movie_count + tag_count + total_o_count + total_play_duration + total_play_count + scenes_played + } + }`, + }), + map: (data) => asJson(data).data.stats, + }, + }, +}; + +export default widget; diff --git a/src/widgets/swagdashboard/component.jsx b/src/widgets/swagdashboard/component.jsx new file mode 100644 index 00000000..d4dbd494 --- /dev/null +++ b/src/widgets/swagdashboard/component.jsx @@ -0,0 +1,33 @@ +import Container from "components/services/widget/container"; +import Block from "components/services/widget/block"; +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { widget } = service; + + const { data: swagData, error: swagError } = useWidgetAPI(widget, "overview"); + + if (swagError) { + return ; + } + + if (!swagData) { + return ( + + + + + + + ); + } + + return ( + + + + + + + ); +} diff --git a/src/widgets/swagdashboard/widget.js b/src/widgets/swagdashboard/widget.js new file mode 100644 index 00000000..7067e55d --- /dev/null +++ b/src/widgets/swagdashboard/widget.js @@ -0,0 +1,9 @@ +import genericProxyHandler from "utils/proxy/handlers/generic"; + +const widget = { + api: "{url}/?stats=true", + proxyHandler: genericProxyHandler, + allowedEndpoints: /overview/, +}; + +export default widget; diff --git a/src/widgets/tandoor/component.jsx b/src/widgets/tandoor/component.jsx new file mode 100644 index 00000000..40d2b88e --- /dev/null +++ b/src/widgets/tandoor/component.jsx @@ -0,0 +1,32 @@ +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: spaceData, error: spaceError } = useWidgetAPI(widget, "space"); + const { data: keywordData, error: keywordError } = useWidgetAPI(widget, "keyword"); + + if (spaceError || keywordError) { + const finalError = spaceError ?? keywordError; + return ; + } + + if (!spaceData || !keywordData) { + return ( + + + + + + ); + } + return ( + + + + + + ); +} diff --git a/src/widgets/tandoor/widget.js b/src/widgets/tandoor/widget.js new file mode 100644 index 00000000..90eaa6d3 --- /dev/null +++ b/src/widgets/tandoor/widget.js @@ -0,0 +1,17 @@ +import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; + +const widget = { + api: "{url}/api/{endpoint}/", + proxyHandler: credentialedProxyHandler, + + mappings: { + space: { + endpoint: "space", + }, + keyword: { + endpoint: "keyword", + }, + }, +}; + +export default widget; diff --git a/src/widgets/tautulli/component.jsx b/src/widgets/tautulli/component.jsx index e1a4df00..b540c6d7 100644 --- a/src/widgets/tautulli/component.jsx +++ b/src/widgets/tautulli/component.jsx @@ -25,14 +25,32 @@ function millisecondsToString(milliseconds) { return parts.map((part) => part.toString().padStart(2, "0")).join(":"); } -function SingleSessionEntry({ session }) { - const { full_title, duration, view_offset, progress_percent, state, video_decision, audio_decision } = session; +function generateStreamTitle(session, enableUser, showEpisodeNumber) { + let stream_title = ""; + const { media_type, parent_media_index, media_index, title, grandparent_title, full_title, friendly_name } = session; + if (media_type === "episode" && showEpisodeNumber) { + const season_str = `S${parent_media_index.toString().padStart(2, "0")}`; + const episode_str = `E${media_index.toString().padStart(2, "0")}`; + stream_title = `${grandparent_title}: ${season_str} ยท ${episode_str} - ${title}`; + } else { + stream_title = full_title; + } + + return enableUser ? `${stream_title} (${friendly_name})` : stream_title; +} + +function SingleSessionEntry({ session, enableUser, showEpisodeNumber }) { + const { duration, view_offset, progress_percent, state, video_decision, audio_decision } = session; + + const stream_title = generateStreamTitle(session, enableUser, showEpisodeNumber); return ( <>
      -
      {full_title}
      +
      + {stream_title} +
      {video_decision === "direct play" && audio_decision === "direct play" && ( @@ -74,8 +92,10 @@ function SingleSessionEntry({ session }) { ); } -function SessionEntry({ session }) { - const { full_title, view_offset, progress_percent, state, video_decision, audio_decision } = session; +function SessionEntry({ session, enableUser, showEpisodeNumber }) { + const { view_offset, progress_percent, state, video_decision, audio_decision } = session; + + const stream_title = generateStreamTitle(session, enableUser, showEpisodeNumber); return (
      @@ -94,7 +114,9 @@ function SessionEntry({ session }) { )}
      -
      {full_title}
      +
      + {stream_title} +
      {video_decision === "direct play" && audio_decision === "direct play" && ( @@ -122,6 +144,10 @@ export default function Component({ service }) { refreshInterval: 5000, }); + const enableUser = !!service.widget?.enableUser; // default is false + const expandOneStreamToTwoRows = service.widget?.expandOneStreamToTwoRows !== false; // default is true + const showEpisodeNumber = !!service.widget?.showEpisodeNumber; // default is false + if (activityError || (activityData && Object.keys(activityData.response.data).length === 0)) { return ; } @@ -132,9 +158,11 @@ export default function Component({ service }) {
      -
      -
      - - -
      + {expandOneStreamToTwoRows && ( +
      + - +
      + )}
      ); } @@ -155,18 +183,20 @@ export default function Component({ service }) {
      {t("tautulli.no_active")}
      -
      - - -
      + {expandOneStreamToTwoRows && ( +
      + - +
      + )}
      ); } - if (playing.length === 1) { + if (expandOneStreamToTwoRows && playing.length === 1) { const session = playing[0]; return (
      - +
      ); } @@ -174,7 +204,12 @@ export default function Component({ service }) { return (
      {playing.map((session) => ( - + ))}
      ); diff --git a/src/widgets/tdarr/proxy.js b/src/widgets/tdarr/proxy.js index a1ebc149..898082f4 100644 --- a/src/widgets/tdarr/proxy.js +++ b/src/widgets/tdarr/proxy.js @@ -8,7 +8,7 @@ const proxyName = "tdarrProxyHandler"; const logger = createLogger(proxyName); export default async function tdarrProxyHandler(req, res) { - const { group, service, endpoint } = req.query; + const { group, service } = req.query; if (!group || !service) { logger.debug("Invalid or missing service '%s' or group '%s'", service, group); @@ -22,7 +22,7 @@ export default async function tdarrProxyHandler(req, res) { return res.status(400).json({ error: "Invalid proxy service type" }); } - const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget })); + const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint: undefined, ...widget })); const [status, contentType, data] = await httpProxy(url, { method: "POST", diff --git a/src/widgets/transmission/proxy.js b/src/widgets/transmission/proxy.js index f12d2a0c..823def05 100644 --- a/src/widgets/transmission/proxy.js +++ b/src/widgets/transmission/proxy.js @@ -11,7 +11,7 @@ const headerCacheKey = `${proxyName}__headers`; const logger = createLogger(proxyName); export default async function transmissionProxyHandler(req, res) { - const { group, service, endpoint } = req.query; + const { group, service } = req.query; if (!group || !service) { logger.debug("Invalid or missing service '%s' or group '%s'", service, group); @@ -35,7 +35,7 @@ export default async function transmissionProxyHandler(req, res) { const api = `${widget.url}${widget.rpcUrl || widgets[widget.type].rpcUrl}rpc`; - const url = new URL(formatApiCall(api, { endpoint, ...widget })); + const url = new URL(formatApiCall(api, { endpoint: undefined, ...widget })); const csrfHeaderName = "x-transmission-session-id"; const method = "POST"; diff --git a/src/widgets/truenas/component.jsx b/src/widgets/truenas/component.jsx index 872d8c64..10d45bf6 100644 --- a/src/widgets/truenas/component.jsx +++ b/src/widgets/truenas/component.jsx @@ -40,7 +40,15 @@ export default function Component({ service }) { {enablePools && poolsData.map((pool) => ( - + ))} ); diff --git a/src/widgets/truenas/pool.jsx b/src/widgets/truenas/pool.jsx index 8e9d0465..b92ecb68 100644 --- a/src/widgets/truenas/pool.jsx +++ b/src/widgets/truenas/pool.jsx @@ -1,8 +1,18 @@ import classNames from "classnames"; import prettyBytes from "pretty-bytes"; -export default function Pool({ name, free, allocated, healthy }) { - const total = free + allocated; +export default function Pool({ name, free, allocated, healthy, data, nasType }) { + let total = 0; + if (nasType === "scale") { + total = free + allocated; + } else { + allocated = 0; // eslint-disable-line no-param-reassign + for (let i = 0; i < data.length; i += 1) { + total += data[i].stats.size; + allocated += data[i].stats.allocated; // eslint-disable-line no-param-reassign + } + } + const usedPercent = Math.round((allocated / total) * 100); const statusColor = healthy ? "bg-green-500" : "bg-yellow-500"; diff --git a/src/widgets/truenas/widget.js b/src/widgets/truenas/widget.js index 7435b6e1..5f8a38df 100644 --- a/src/widgets/truenas/widget.js +++ b/src/widgets/truenas/widget.js @@ -25,6 +25,7 @@ const widget = { healthy: entry.healthy, allocated: entry.allocated, free: entry.free, + data: entry.topology.data, })), }, }, diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js index c8356c1b..98c98f37 100644 --- a/src/widgets/unifi/proxy.js +++ b/src/widgets/unifi/proxy.js @@ -14,13 +14,13 @@ const prefixCacheKey = `${proxyName}__prefix`; const logger = createLogger(proxyName); async function getWidget(req) { - const { group, service, type } = req.query; + const { group, service } = req.query; let widget = null; - if (type === "unifi_console") { + if (group === "unifi_console" && service === "unifi_console") { // info widget const index = req.query?.query ? JSON.parse(req.query.query).index : undefined; - widget = await getPrivateWidgetOptions(type, index); + widget = await getPrivateWidgetOptions("unifi_console", index); if (!widget) { logger.debug("Error retrieving settings for this Unifi widget"); return null; diff --git a/src/widgets/unmanic/component.jsx b/src/widgets/unmanic/component.jsx index 03447068..98688463 100644 --- a/src/widgets/unmanic/component.jsx +++ b/src/widgets/unmanic/component.jsx @@ -1,16 +1,30 @@ +import { useEffect, useState } from "react"; + import Container from "components/services/widget/container"; import Block from "components/services/widget/block"; import useWidgetAPI from "utils/proxy/use-widget-api"; +import { formatProxyUrl } from "utils/proxy/api-helpers"; export default function Component({ service }) { const { widget } = service; const { data: workersData, error: workersError } = useWidgetAPI(widget, "workers"); - const { data: pendingData, error: pendingError } = useWidgetAPI(widget, "pending"); - if (workersError || pendingError) { - const finalError = workersError ?? pendingError; - return ; + const [pendingData, setPendingData] = useState(null); + + useEffect(() => { + async function fetchPending() { + const url = formatProxyUrl(widget, "pending"); + const res = await fetch(url, { method: "POST" }); + setPendingData(await res.json()); + } + if (!pendingData) { + fetchPending(); + } + }, [widget, pendingData]); + + if (workersError) { + return ; } if (!workersData || !pendingData) { diff --git a/src/widgets/uptimerobot/component.jsx b/src/widgets/uptimerobot/component.jsx index c0cb670f..27485401 100644 --- a/src/widgets/uptimerobot/component.jsx +++ b/src/widgets/uptimerobot/component.jsx @@ -1,18 +1,26 @@ import { useTranslation } from "next-i18next"; +import { useEffect, useState } from "react"; import Container from "components/services/widget/container"; import Block from "components/services/widget/block"; -import useWidgetAPI from "utils/proxy/use-widget-api"; +import { formatProxyUrl } from "utils/proxy/api-helpers"; export default function Component({ service }) { const { widget } = service; const { t } = useTranslation(); - const { data: uptimerobotData, error: uptimerobotError } = useWidgetAPI(widget, "getmonitors"); + const [uptimerobotData, setUptimerobotData] = useState(null); - if (uptimerobotError) { - return ; - } + useEffect(() => { + async function fetchData() { + const url = formatProxyUrl(widget, "getmonitors"); + const res = await fetch(url, { method: "POST" }); + setUptimerobotData(await res.json()); + } + if (!uptimerobotData) { + fetchData(); + } + }, [widget, uptimerobotData]); if (!uptimerobotData) { return ( diff --git a/src/widgets/urbackup/widget.js b/src/widgets/urbackup/widget.js index 5eac66d0..96c52296 100644 --- a/src/widgets/urbackup/widget.js +++ b/src/widgets/urbackup/widget.js @@ -2,6 +2,7 @@ import urbackupProxyHandler from "./proxy"; const widget = { proxyHandler: urbackupProxyHandler, + allowedEndpoints: /status/, }; export default widget; diff --git a/src/widgets/wgeasy/component.jsx b/src/widgets/wgeasy/component.jsx index e2434f51..624002c4 100644 --- a/src/widgets/wgeasy/component.jsx +++ b/src/widgets/wgeasy/component.jsx @@ -1,33 +1,45 @@ -import { useTranslation } from "next-i18next"; - -import Block from "components/services/widget/block"; import Container from "components/services/widget/container"; +import Block from "components/services/widget/block"; import useWidgetAPI from "utils/proxy/use-widget-api"; export default function Component({ service }) { - const { t } = useTranslation(); - const { widget } = service; - const { data: wgeasyData, error: wgeasyAPIError } = useWidgetAPI(widget, "unified", { - refreshInterval: 5000, - }); + const { data: infoData, error: infoError } = useWidgetAPI(widget); - if (wgeasyAPIError) { - return ; + if (!widget.fields) { + widget.fields = ["connected", "enabled", "total"]; } - if (!wgeasyData) { + if (infoError) { + return ; + } + + if (!infoData) { return ( - + + + + ); } + const enabled = infoData.filter((item) => item.enabled).length; + const disabled = infoData.length - enabled; + const connectionThreshold = (widget.threshold ?? 2) * 60 * 1000; + const currentTime = new Date(); + const connected = infoData.filter( + (item) => currentTime - new Date(item.latestHandshakeAt) < connectionThreshold, + ).length; + return ( - + + + + ); } diff --git a/src/widgets/wgeasy/proxy.js b/src/widgets/wgeasy/proxy.js index 76f61151..d4289dc6 100644 --- a/src/widgets/wgeasy/proxy.js +++ b/src/widgets/wgeasy/proxy.js @@ -1,117 +1,77 @@ -/* eslint-disable no-underscore-dangle */ +import cache from "memory-cache"; + +import getServiceWidget from "utils/config/service-helpers"; import { formatApiCall } from "utils/proxy/api-helpers"; import { httpProxy } from "utils/proxy/http"; -import getServiceWidget from "utils/config/service-helpers"; -import createLogger from "utils/logger"; import widgets from "widgets/widgets"; - +import createLogger from "utils/logger"; const proxyName = "wgeasyProxyHandler"; - const logger = createLogger(proxyName); -let globalSid = null; +const sessionSIDCacheKey = `${proxyName}__sessionSID`; -async function getWidget(req) { - const { group, service } = req.query; - if (!group || !service) { - logger.debug("Invalid or missing service '%s' or group '%s'", service, group); - return null; +async function login(widget, service) { + const url = formatApiCall(widgets[widget.type].api, { ...widget, endpoint: "session" }); + const [, , , responseHeaders] = await httpProxy(url, { + method: "POST", + body: JSON.stringify({ password: widget.password }), + headers: { + "Content-Type": "application/json", + }, + }); + + try { + let connectSidCookie = responseHeaders["set-cookie"]; + if (!connectSidCookie) { + const sid = cache.get(`${sessionSIDCacheKey}.${service}`); + if (sid) { + return sid; + } } + connectSidCookie = connectSidCookie + .find((cookie) => cookie.startsWith("connect.sid=")) + .split(";")[0] + .replace("connect.sid=", ""); + cache.put(`${sessionSIDCacheKey}.${service}`, connectSidCookie); + return connectSidCookie; + } catch (e) { + logger.error(`Error logging into wg-easy, error: ${e}`); + cache.del(`${sessionSIDCacheKey}.${service}`); + return null; + } +} + +export default async function wgeasyProxyHandler(req, res) { + const { group, service } = req.query; + + if (group && service) { const widget = await getServiceWidget(group, service); - if (!widget) { - logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group); - return null; + + if (!widgets?.[widget.type]?.api) { + return res.status(403).json({ error: "Service does not support API calls" }); } - return widget; -} - - -async function loginToWGEasy(endpoint, widget) { - const api = widgets?.[widget.type]?.api; - if (!api) { - return [403, null]; - } - // Create new session on WgEasy - const url = new URL(formatApiCall(api, { endpoint, ...widget })); - - const [status, data, , responseHeaders] = await httpProxy(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', + if (widget) { + let sid = cache.get(`${sessionSIDCacheKey}.${service}`); + if (!sid) { + sid = await login(widget, service); + if (!sid) { + return res.status(500).json({ error: "Failed to authenticate with Wg-Easy" }); + } + } + const [, , data] = await httpProxy( + formatApiCall(widgets[widget.type].api, { ...widget, endpoint: "wireguard/client" }), + { + headers: { + "Content-Type": "application/json", + Cookie: `connect.sid=${sid}`, + }, }, - body: JSON.stringify({ - password: widget.password, - }) - }); + ); - if (status !== 204) { - logger.error("HTTP %d communicating with NextPVR. Data: %s", status, data.toString()); - return [status, data, responseHeaders]; + return res.json(JSON.parse(data)); } - try { - [ globalSid ] = responseHeaders["set-cookie"] - } catch (e) { - logger.error("Error decoding NextPVR API data. Data: %s", data.toString()); - return [status, null]; - } - logger.info('gettingSID') - return [status, true]; + } + + return res.status(400).json({ error: "Invalid proxy service type" }); } - - -async function fetchDataFromWGeasy(endpoint, widget, sid) { - const api = widgets?.[widget.type]?.api; - if (!api) { - return [403, null]; - } - const url = `${new URL(formatApiCall(api, { endpoint, ...widget }))}` - const [status, contentType, data] = await httpProxy(url, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - 'Cookie': sid - }, - }); - - if (status !== 200) { - logger.error("HTTP %d communicating with WGeasy. Data: %s", status, data.toString()); - return [status, data]; - } - - try { - return [status, JSON.parse(data), contentType]; - } catch (e) { - logger.error("Error decoding WGeasy API data. Data: %s", data.toString()); - return [status, null]; - } -} - -export default async function WGeasyProxyHandler(req, res) { - const widget = await getWidget(req); - - if (!globalSid) { - await loginToWGEasy('session', widget); - } - if (!widget) { - return res.status(400).json({ error: "Invalid proxy service type" }); - } - - logger.debug("Getting data from WGeasy API"); - // Calculate the number of clients - const [status, apiData] = await fetchDataFromWGeasy('wireguard/client', widget, globalSid); - - if (status !== 200) { - return res.status(status).json({ error: { message: "HTTP error communicating with WGeasy API", data: Buffer.from(apiData).toString() } }); - } - let clientCount = 0; - clientCount = apiData.length; - - const data = { - clientCount - }; - - return res.status(status).send(data); - -} - diff --git a/src/widgets/wgeasy/widget.js b/src/widgets/wgeasy/widget.js index fcb5bef6..7f7d69d7 100644 --- a/src/widgets/wgeasy/widget.js +++ b/src/widgets/wgeasy/widget.js @@ -1,14 +1,8 @@ -import nextpvrProxyHandler from "./proxy"; +import wgeasyProxyHandler from "./proxy"; const widget = { api: "{url}/api/{endpoint}", - proxyHandler: nextpvrProxyHandler, - - mappings: { - unified: { - endpoint: "/", - }, - }, + proxyHandler: wgeasyProxyHandler, }; export default widget; diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js index 285a0a49..dc3c2352 100644 --- a/src/widgets/widgets.js +++ b/src/widgets/widgets.js @@ -12,11 +12,13 @@ import changedetectionio from "./changedetectionio/widget"; import channelsdvrserver from "./channelsdvrserver/widget"; import cloudflared from "./cloudflared/widget"; import coinmarketcap from "./coinmarketcap/widget"; +import crowdsec from "./crowdsec/widget"; import customapi from "./customapi/widget"; import deluge from "./deluge/widget"; import diskstation from "./diskstation/widget"; import downloadstation from "./downloadstation/widget"; import emby from "./emby/widget"; +import esphome from "./esphome/widget"; import evcc from "./evcc/widget"; import fileflows from "./fileflows/widget"; import flood from "./flood/widget"; @@ -32,6 +34,7 @@ import gotify from "./gotify/widget"; import grafana from "./grafana/widget"; import hdhomerun from "./hdhomerun/widget"; import homeassistant from "./homeassistant/widget"; +import homebox from "./homebox/widget"; import homebridge from "./homebridge/widget"; import healthchecks from "./healthchecks/widget"; import immich from "./immich/widget"; @@ -52,6 +55,7 @@ import mjpeg from "./mjpeg/widget"; import moonraker from "./moonraker/widget"; import mylar from "./mylar/widget"; import navidrome from "./navidrome/widget"; +import netalertx from "./netalertx/widget"; import netdata from "./netdata/widget"; import nextcloud from "./nextcloud/widget"; import nextdns from "./nextdns/widget"; @@ -71,7 +75,6 @@ import peanut from "./peanut/widget"; import pfsense from "./pfsense/widget"; import photoprism from "./photoprism/widget"; import proxmoxbackupserver from "./proxmoxbackupserver/widget"; -import pialert from "./pialert/widget"; import pihole from "./pihole/widget"; import plantit from "./plantit/widget"; import plex from "./plex/widget"; @@ -91,8 +94,11 @@ import sabnzbd from "./sabnzbd/widget"; import scrutiny from "./scrutiny/widget"; import sonarr from "./sonarr/widget"; import speedtest from "./speedtest/widget"; +import stash from "./stash/widget"; import strelaysrv from "./strelaysrv/widget"; +import swagdashboard from "./swagdashboard/widget"; import tailscale from "./tailscale/widget"; +import tandoor from "./tandoor/widget"; import tautulli from "./tautulli/widget"; import tdarr from "./tdarr/widget"; import titlecardmaker from "./titlecardmaker/widget"; @@ -105,6 +111,7 @@ import unmanic from "./unmanic/widget"; import uptimekuma from "./uptimekuma/widget"; import uptimerobot from "./uptimerobot/widget"; import watchtower from "./watchtower/widget"; +import wgeasy from "./wgeasy/widget"; import whatsupdocker from "./whatsupdocker/widget"; import wgeasy from "./wgeasy/widget"; import xteve from "./xteve/widget"; @@ -128,11 +135,13 @@ const widgets = { channelsdvrserver, cloudflared, coinmarketcap, + crowdsec, customapi, deluge, diskstation, downloadstation, emby, + esphome, evcc, fileflows, flood, @@ -148,6 +157,7 @@ const widgets = { grafana, hdhomerun, homeassistant, + homebox, homebridge, healthchecks, ical: calendar, @@ -171,6 +181,7 @@ const widgets = { moonraker, mylar, navidrome, + netalertx, netdata, nextcloud, nextdns, @@ -190,7 +201,7 @@ const widgets = { pfsense, photoprism, proxmoxbackupserver, - pialert, + pialert: netalertx, pihole, plantit, plex, @@ -210,8 +221,11 @@ const widgets = { scrutiny, sonarr, speedtest, + stash, strelaysrv, + swagdashboard, tailscale, + tandoor, tautulli, tdarr, titlecardmaker, @@ -226,6 +240,7 @@ const widgets = { uptimerobot, urbackup, watchtower, + wgeasy, whatsupdocker, wgeasy, xteve, diff --git a/src/widgets/xteve/component.jsx b/src/widgets/xteve/component.jsx index 75629909..84a617c2 100644 --- a/src/widgets/xteve/component.jsx +++ b/src/widgets/xteve/component.jsx @@ -9,7 +9,7 @@ export default function Component({ service }) { const { widget } = service; - const { data: xteveData, error: xteveError } = useWidgetAPI(widget, "api"); + const { data: xteveData, error: xteveError } = useWidgetAPI(widget); if (xteveError) { return ; diff --git a/src/widgets/xteve/proxy.js b/src/widgets/xteve/proxy.js index a8b1c80f..421f2b49 100644 --- a/src/widgets/xteve/proxy.js +++ b/src/widgets/xteve/proxy.js @@ -7,7 +7,7 @@ import getServiceWidget from "utils/config/service-helpers"; const logger = createLogger("xteveProxyHandler"); export default async function xteveProxyHandler(req, res) { - const { group, service, endpoint } = req.query; + const { group, service } = req.query; if (!group || !service) { return res.status(400).json({ error: "Invalid proxy service type" }); @@ -19,7 +19,7 @@ export default async function xteveProxyHandler(req, res) { return res.status(403).json({ error: "Service does not support API calls" }); } - const url = formatApiCall(api, { endpoint, ...widget }); + const url = formatApiCall(api, { endpoint: "api/", ...widget }); const method = "POST"; const payload = { cmd: "status" }; diff --git a/src/widgets/xteve/widget.js b/src/widgets/xteve/widget.js index e7998e2e..72c62b25 100644 --- a/src/widgets/xteve/widget.js +++ b/src/widgets/xteve/widget.js @@ -3,12 +3,6 @@ import xteveProxyHandler from "./proxy"; const widget = { api: "{url}/{endpoint}", proxyHandler: xteveProxyHandler, - - mappings: { - api: { - endpoint: "api/", - }, - }, }; export default widget;