diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..bb73799 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git +node_modules +build +.env.local +.github +.vscode diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6c2eeb8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +indent_size = 2 +indent_style = space diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..e9b5459 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,108 @@ +const a11yOff = Object.keys(require("eslint-plugin-jsx-a11y").rules).reduce( + (acc, rule) => { + acc[`jsx-a11y/${rule}`] = "off"; + return acc; + }, + {} +); + +module.exports = { + env: { + browser: true + }, + extends: [ + "airbnb", + "airbnb/hooks", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended" + ], + ignorePatterns: [ + "public/*", + "dist/*", + "/*.js", + "/*.ts", + "/*.mts", + "/plugins/*.ts", + "/plugins/*.mjs", + "/themes/**/*.ts" + ], + parser: "@typescript-eslint/parser", + parserOptions: { + project: "./tsconfig.json", + tsconfigRootDir: "./" + }, + settings: { + "import/resolver": { + typescript: { + project: "./tsconfig.json" + } + } + }, + plugins: ["@typescript-eslint", "import", "prettier"], + rules: { + "react/jsx-uses-react": "off", + "react/react-in-jsx-scope": "off", + "react/require-default-props": "off", + "react/destructuring-assignment": "off", + "no-underscore-dangle": "off", + "@typescript-eslint/no-explicit-any": "off", + "no-console": ["warn", { allow: ["warn", "error", "debug", "info"] }], + "@typescript-eslint/no-this-alias": "off", + "import/prefer-default-export": "off", + "@typescript-eslint/no-empty-function": "off", + "no-shadow": "off", + "@typescript-eslint/no-shadow": ["error"], + "no-restricted-syntax": "off", + "import/no-unresolved": ["error", { ignore: ["^virtual:"] }], + "react/jsx-props-no-spreading": "off", + "consistent-return": "off", + "no-continue": "off", + "no-eval": "off", + "no-await-in-loop": "off", + "no-nested-ternary": "off", + "prefer-destructuring": "off", + "no-param-reassign": "off", + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }], + "react/jsx-filename-extension": [ + "error", + { extensions: [".js", ".tsx", ".jsx"] } + ], + "import/extensions": [ + "error", + "ignorePackages", + { + ts: "never", + tsx: "never" + } + ], + "import/order": [ + "error", + { + groups: [ + "builtin", + "external", + "internal", + ["sibling", "parent"], + "index", + "unknown" + ], + "newlines-between": "always", + alphabetize: { + order: "asc", + caseInsensitive: true + } + } + ], + "sort-imports": [ + "error", + { + ignoreCase: false, + ignoreDeclarationSort: true, + ignoreMemberSort: false, + memberSyntaxSortOrder: ["none", "all", "multiple", "single"], + allowSeparatedGroups: true + } + ], + ...a11yOff + } +}; diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..55dc5f0 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +* Maintainers: [MW-Exodus Team](https://github.com/MW-Legacy) +* Founder: (sussy-code)[https://github.com/sussy-code] diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..22bd398 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +our [Discord](https://docs.undi.rest/links/discord). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..c62687e --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,91 @@ +# Contributing Guidelines for SkoolTV + +Thank you for investing your time in contributing to our project! Your contribution will be reflected on all of the community hosted instances that are on the latest version. + +Please read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable. + +## Contents +- [Contributing Guidelines for SkoolTV](#contributing-guidelines-for-SkoolTV) + - [Contents](#contents) + - [New contributor guide](#new-contributor-guide) + - [Requesting a feature or reporting a bug](#requesting-a-feature-or-reporting-a-bug) + - [Discord Server](#discord-server) + - [GitHub Issues](#github-issues) + - [Before you start!](#before-you-start) + - [Contributing](#contributing) + - [Recommended Development Environment](#recommended-development-environment) + - [Tips](#tips) + - [Language Contributions](#language-contributions) + +## New contributor guide + +To get an overview of the project, read the [README](README.md). Here are some resources to help you get started with open-source contributions: + +- [Finding ways to contribute to open-source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github) +- [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git) +- [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow) +- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests) + + +## Requesting a feature or reporting a bug +There are two places where to request features or report bugs: + - GitHub Issues + - The SkoolTV Discord server + +### Discord Server +If you do not have a GitHub account or want to discuss a feature or bug with us before making an issue, you can join our Discord server. +[Join bruh](https://docs.undi.rest/links/discord) + +### GitHub Issues +To make a GitHub issue for SkoolTV, please visit the [new issue page](https://github.com/sussy-code/smov/issues/new/choose) where you can pick either the "Bug Report" or "Feature Request" template. + +When filling out an issue template, please include as much detail as possible and any screenshots or console logs as appropriate. + +After an issue is created, it will be assigned either the https://github.com/sussy-code/smov/labels/bug or https://github.com/sussy-code/smov/labels/feature label, along with https://github.com/sussy-code/smov/labels/awaiting-approval. One of our maintainers will review your issue and, if it's accepted, will set the https://github.com/sussy-code/smov/labels/approved label. + +## Before you start! +Before starting a contribution, please check your contribution is part of an open issue on [our issues page](https://github.com/sussy-code/smov/issues?q=is%3Aopen+is%3Aissue+label%3Aapproved). + +GitHub issues are how we track our bugs and feature requests that will be implemented into SkoolTV - all contributions **must** have an issue and be approved by a maintainer before a pull request can be worked on. + +If a pull request is opened before an issue is created and accepted, you may risk having your pull request rejected! Always check with us before starting work on a feature - we don't want to waste your time! + +> **Note** +> The exception to this are language contributions, which are discussed in [this section](#language-contributions) + +Also, make sure that the issue you would like to work on has been given the https://github.com/sussy-code/smov/labels/approved label by a maintainer. Otherwise, if we reject the issue, it means your work will have gone to waste! + +## Contributing +If you're here because you'd like to work on an issue, amazing! Thank you for even considering contributing to SkoolTV; it means a lot :heart: + +Firstly, make sure you've read the [Before you start!](#before-you-start) section! + +When you have found a GitHub issue you would like to work on, you can request to be assigned to the issue by commenting on the GitHub issue. + +If you are assigned to an issue but can't complete it for whatever reason, no problem! Just let us know, and we will open up the issue to have someone else assigned. + +### Recommended Development Environment +Our recommended development environment to work on SkoolTV is: +- [Visual Studio Code](https://code.visualstudio.com/) +- [ESLint Extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) +- [EditorConfig Extension](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) + +When opening Visual Studio Code, you will be prompted to install our recommended extensions if they are not installed for you. + +Our project is set up to enforce formatting and code style standards using ESLint. + +### Tips +Here are some tips to make sure that your pull requests are :pinched_fingers: first time: + +- KISS - Keep It Simple Soldier! - Simple code makes readable and efficient code! +- Follow standard best practices for TypeScript and React. +- Keep as much as possible to the style of SkoolTV. Look around our codebase to familiarise yourself with how we do things! +- Ensure to take note of the ESLint errors and warnings! **Do not ignore them!** They are there for a reason. +- Test, test, test! Make sure you thoroughly test the features you are contributing. + +### Language Contributions +Language contributions help SkoolTV massively, allowing people worldwide to use our app! + +1. Create a new langague json file +2. Implement the langague file into settings +3. Thats it make a PR diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 0000000..3bf7111 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,50 @@ +name: Bug Report +description: File a bug report +title: "[Bug]: " +labels: ["bug", "awaiting-approval"] +assignees: [] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + + Please fill out with as much detail as possible + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Also tell us, what did you expect to happen? + placeholder: Tell us what you see! + validations: + required: true + - type: dropdown + id: browsers + attributes: + label: What browsers are you seeing the problem on? + multiple: true + options: + - Firefox + - Chrome + - Safari + - Microsoft Edge + - Other (tell us in input box below) + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce? + description: What steps have you taken to see the bug? (OPTIONAL) + placeholder: 1. ... + validations: + required: false + - type: textarea + id: other-info + attributes: + label: Other relevant information + description: | + Feel free to give us any more information that doesn't fit the above text boxes. + + Tip: You can attach files by clicking this textbox and dragging in files + validations: + required: false + diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 0000000..9d5bb8b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,26 @@ +name: Feature Request +description: Suggest a new feature +title: "[Feature]: " +labels: ["feature", "awaiting-approval"] +assignees: [] +body: + - type: textarea + id: what-feature + attributes: + label: What feature do you want to add? + placeholder: A new button! + validations: + required: true + - type: textarea + id: why-feature + attributes: + label: Why do you want to have this feature? + placeholder: A new button! + validations: + required: true + - type: textarea + id: other-details + attributes: + label: Any other details to share? + validations: + required: false diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..d02072a --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,10 @@ +# Security Policy + +## Supported Versions + +The latest version of SkoolTV is the only version that is supported, as it is the only version that is being actively developed. + +## Reporting a Vulnerability + +You can contact the SkoolTV maintainers to report a vulnerability: + - Report the vulnerability in the [Discord](https://docs.undi.rest/links/discord). diff --git a/.github/Sudo-Flix.png b/.github/Sudo-Flix.png new file mode 100644 index 0000000..4bf156f Binary files /dev/null and b/.github/Sudo-Flix.png differ diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..3b6d63d --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,6 @@ +This pull request resolves #XXX + + - [ ] I have read and agreed to the [code of conduct](https://github.com/sussy-code/smov/blob/dev/.github/CODE_OF_CONDUCT.md). + - [ ] I have read and complied with the [contributing guidelines](https://github.com/sussy-code/smov/blob/dev/.github/CONTRIBUTING.md). + - [ ] I have tested all of my changes. + - Enter discord user: `` (we require this for the contributor role) diff --git a/.github/workflows/deploying.yml b/.github/workflows/deploying.yml new file mode 100644 index 0000000..a19c0ca --- /dev/null +++ b/.github/workflows/deploying.yml @@ -0,0 +1,181 @@ +name: Deploying + +on: + push: + branches: + - main + +jobs: + build_pwa: + name: Build PWA + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install pnpm packages + run: pnpm install + + - name: Build project + run: pnpm run build:pwa + + - name: Upload production-ready build files + uses: actions/upload-artifact@v4 + with: + name: pwa + path: ./dist + + build: + name: Build + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install pnpm packages + run: pnpm install + + - name: Build project + run: pnpm run build + + - name: Upload production-ready build files + uses: actions/upload-artifact@v4 + with: + name: normal + path: ./dist + + release: + name: Release + needs: [build, build_pwa] + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download PWA artifact + uses: actions/download-artifact@v4 + with: + name: pwa + path: ./dist_pwa + + - name: Zip PWA files + run: cd dist_pwa && zip -r ../movie-web.pwa.zip . + + - name: Download normal artifact + uses: actions/download-artifact@v4 + with: + name: normal + path: ./dist_normal + + - name: Zip normal files + run: cd dist_normal && zip -r ../movie-web.zip . + + - name: Get version + id: package-version + uses: martinbeentjes/npm-get-version-action@main + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} + with: + tag_name: ${{ steps.package-version.outputs.current-version }} + release_name: Movie web v${{ steps.package-version.outputs.current-version }} + draft: false + prerelease: false + + - name: Upload release (PWA) + uses: actions/upload-release-asset@v1 + env: + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./movie-web.pwa.zip + asset_name: movie-web.pwa.zip + asset_content_type: application/zip + + - name: Upload Release (Normal) + uses: actions/upload-release-asset@v1 + env: + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./movie-web.zip + asset_name: movie-web.zip + asset_content_type: application/zip + + registry: + name: Push to registry + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + + env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Get version + id: package-version + uses: martinbeentjes/npm-get-version-action@main + + - name: Log into registry ${{ env.REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.PAT_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + flavor: | + latest=auto + tags: | + type=semver,pattern={{version}},value=v${{ steps.package-version.outputs.current-version }} + + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v5 + with: + push: true + platforms: linux/amd64,linux/arm64 + context: . + labels: ${{ steps.meta.outputs.labels }} + tags: ${{ steps.meta.outputs.tags }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/linting_testing.yml b/.github/workflows/linting_testing.yml new file mode 100644 index 0000000..993ea89 --- /dev/null +++ b/.github/workflows/linting_testing.yml @@ -0,0 +1,73 @@ +name: Linting and Testing + +on: + push: + branches: + - main + pull_request: + +jobs: + linting: + name: Run Linters + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install pnpm packages + run: pnpm install + + - name: Run ESLint + run: pnpm run lint + + building: + name: Build project + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install pnpm packages + run: pnpm install + + - name: Build Project + run: pnpm run build + + docker: + name: Build Docker + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + push: false + context: . diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9259432 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/dist +dev-dist +/stats.html + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* + +# other package managers +yarn.lock +package-lock.json + +# config +.env diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..bf2e764 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +shamefully-hoist=true diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..118c0ef --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..741f0c0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "eslint.format.enable": true, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + } +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..90587a9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,52 @@ +FROM node:20-alpine as build +WORKDIR /app +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable + +COPY package.json ./ +COPY pnpm-lock.yaml ./ +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile + +ARG PWA_ENABLED="true" +ARG GA_ID +ARG APP_DOMAIN +ARG OPENSEARCH_ENABLED="false" +ARG TMDB_READ_API_KEY +ARG CORS_PROXY_URL +ARG DMCA_EMAIL +ARG NORMAL_ROUTER="false" +ARG BACKEND_URL +ARG HAS_ONBOARDING="false" +ARG ONBOARDING_CHROME_EXTENSION_INSTALL_LINK +ARG ONBOARDING_PROXY_INSTALL_LINK +ARG DISALLOWED_IDS +ARG CDN_REPLACEMENTS +ARG TURNSTILE_KEY +ARG ALLOW_AUTOPLAY="false" + +ENV VITE_PWA_ENABLED=${PWA_ENABLED} +ENV VITE_GA_ID=${GA_ID} +ENV VITE_APP_DOMAIN=${APP_DOMAIN} +ENV VITE_OPENSEARCH_ENABLED=${OPENSEARCH_ENABLED} +ENV VITE_TMDB_READ_API_KEY=${TMDB_READ_API_KEY} +ENV VITE_CORS_PROXY_URL=${CORS_PROXY_URL} +ENV VITE_DMCA_EMAIL=${DMCA_EMAIL} +ENV VITE_NORMAL_ROUTER=${NORMAL_ROUTER} +ENV VITE_BACKEND_URL=${BACKEND_URL} +ENV VITE_HAS_ONBOARDING=${HAS_ONBOARDING} +ENV VITE_ONBOARDING_CHROME_EXTENSION_INSTALL_LINK=${ONBOARDING_CHROME_EXTENSION_INSTALL_LINK} +ENV VITE_ONBOARDING_PROXY_INSTALL_LINK=${ONBOARDING_PROXY_INSTALL_LINK} +ENV VITE_DISALLOWED_IDS=${DISALLOWED_IDS} +ENV VITE_CDN_REPLACEMENTS=${CDN_REPLACEMENTS} +ENV VITE_TURNSTILE_KEY=${TURNSTILE_KEY} +ENV VITE_ALLOW_AUTOPLAY=${ALLOW_AUTOPLAY} + +COPY . ./ +RUN pnpm run build + +# production environment +FROM nginx:stable-alpine +COPY --from=build /app/dist /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..d71bce9 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 James Hawkins + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..96df2c9 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# SkoolTV +[![SkoolTV Image](.github/SkoolTV.png)](https://docs.undi.rest) + +**I *do not* endorse piracy of any kind I simply enjoy programming and large user counts.** + +## Links And Resources +| Service | Link | Source Code | +|----------------|------------------------------------------------------------------|----------------------------------------------------------| +| SkoolTV Docs | [sudo-docs](https://docs.undi.rest) | [source code](https://github.com/sussy-code/docs) | +| Extension | [extension](https://docs.undi.rest/extension) | [source code](https://github.com/sussy-code/browser-ext) | +| Proxy | [sudo-proxy](https://sudo-proxy.up.railway.app) | [source code](https://github.com/sussy-code/sudo-proxy) | +| Backend | [sudo-backend](https://backend.undi.rest) | [source code](https://github.com/sussy-code/backend) | +| Frontend | [SkoolTV](https://docs.undi.rest/instances) | [source code](https://github.com/sussy-code/smov) | +| Weblate | [sudo-weblate](https://docs.undi.rest/links/weblate) | [source code](https://github.com/sussy-code/docs) | + +***I provide these if you are not able to host yourself, though I do encourage hosting the frontend.*** + + +## Referrers +- [FMHY (Voted as #1 multi-server streaming site of 2024)](https://fmhy.net) +- [Piracy Subreddit Megathread](https://www.reddit.com/r/Piracy/s/iymSloEpXn) +- [Toon's Instances](https://erynith.github.io/movie-web-instances) +- [Entertainment Empire](https://discord.gg/8NSDNEMfja) +- Search Engines: DuckDuckGo, Bing, Google +- Rentry.co + + +## Running Locally +Type the following commands into your terminal / command line to run SkoolTV locally +```bash +git clone https://github.com/sussy-code/smov.git +cd smov +git pull +pnpm install +pnpm run dev +``` +Then you can visit the local instance [here](http://localhost:5173) or, at local host on port 5173. + + +## Updating a SkoolTV Instance +To update a SkoolTV instance you can type the below commands into a terminal at the root of your project. +```bash +git remote add upstream https://github.com/sussy-code/smov.git +git fetch upstream # Grab the contents of the new remote source +git checkout # Most likely this would be `origin/main` +git merge upstream/main +# * Fix any conflicts present during merge * +git add . # Add all changes made during merge and conflict fixing +git commit -m "Update SkoolTV instance (merge upstream/main)" +git push # Push to YOUR repository +``` + + +## Contact Me +**Email:** *[dev@SkoolTV.lol](mailto:dev@SkoolTV.lol)* diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..c3745fd --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,26 @@ +version: "3.8" + +services: + + movieweb: + build: + context: . + # args: + # PWA_ENABLED: "false" + # GA_ID: "" + # APP_DOMAIN: "" + # OPENSEARCH_ENABLED: "false" + # TMDB_READ_API_KEY: "" + # CORS_PROXY_URL: "" + # DMCA_EMAIL: "" + # NORMAL_ROUTER: "false" + # BACKEND_URL: "" + # HAS_ONBOARDING: "false" + # ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: "" + # ONBOARDING_PROXY_INSTALL_LINK: "" + # DISALLOWED_IDS: "" + # CDN_REPLACEMENTS: "" + # TURNSTILE_KEY: "" + ports: + - "80:80" + restart: unless-stopped diff --git a/example.env b/example.env new file mode 100644 index 0000000..38c690a --- /dev/null +++ b/example.env @@ -0,0 +1,8 @@ +VITE_TMDB_READ_API_KEY=... +VITE_OPENSEARCH_ENABLED=false + +# make sure the cors proxy url does NOT have a slash at the end +VITE_CORS_PROXY_URL=... + +# make sure the domain does NOT have a slash at the end +VITE_APP_DOMAIN=http://localhost:5173 diff --git a/index.html b/index.html new file mode 100644 index 0000000..df15251 --- /dev/null +++ b/index.html @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SkoolTV + + {{#if opensearchEnabled }} + + + + + + {{/if}} + + + + +
+ + + + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..36267d2 --- /dev/null +++ b/manifest.json @@ -0,0 +1,37 @@ +{ + "name": "SkoolTV", + "short_name": "SkoolTV", + "start_url": "/", + "display": "standalone", + "background_color": "#120f1d", + "lang": "en", + "scope": "/", + "description": "Watch your favorite shows and movies for free with no ads ever! (っ'ヮ'c)", + "theme_color": "#120f1d", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "public/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "public/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..25d65a1 --- /dev/null +++ b/package.json @@ -0,0 +1,145 @@ +{ + "name": "SkoolTV", + "version": "4.7.0", + "private": true, + "homepage": "https://github.com/sussy-code/smov", + "scripts": { + "dev": "vite", + "build": "vite build", + "build:pwa": "cross-env VITE_PWA_ENABLED=true vite build", + "test": "vitest run", + "preview": "vite preview", + "lint": "eslint --ext .tsx,.ts src", + "lint:fix": "eslint --fix --ext .tsx,.ts src", + "lint:report": "eslint --ext .tsx,.ts --output-file eslint_report.json --format json src", + "preinstall": "npx -y only-allow pnpm" + }, + "browserslist": { + "production": [ + "defaults", + "chrome > 90" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "dependencies": { + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/modifiers": "^7.0.0", + "@dnd-kit/sortable": "^8.0.0", + "@dnd-kit/utilities": "^3.2.2", + "@formkit/auto-animate": "^0.8.2", + "@headlessui/react": "^1.7.19", + "@ladjs/country-language": "^1.0.3", + "@marsidev/react-turnstile": "^0.7.2", + "@movie-web/providers": "github:sussy-code/providers", + "@noble/hashes": "^1.4.0", + "@plasmohq/messaging": "^0.6.2", + "@react-spring/web": "^9.7.4", + "@scure/bip39": "^1.3.0", + "@sozialhelden/ietf-language-tags": "^5.4.2", + "@types/node-forge": "^1.3.11", + "classnames": "^2.5.1", + "core-js": "^3.37.1", + "detect-browser": "^5.3.0", + "dompurify": "^3.1.6", + "flag-icons": "^7.2.3", + "focus-trap-react": "^10.2.3", + "fscreen": "^1.2.0", + "fuse.js": "^7.0.0", + "hls.js": "^1.5.13", + "i18next": "^23.12.2", + "immer": "^10.1.1", + "jwt-decode": "^4.0.0", + "lodash.isequal": "^4.5.0", + "lodash.merge": "^4.6.2", + "million": "^2.6.4", + "nanoid": "^5.0.7", + "node-forge": "^1.3.1", + "ofetch": "^1.3.4", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-ga4": "^2.1.0", + "react-google-recaptcha-v3": "^1.10.1", + "react-helmet-async": "^2.0.5", + "react-i18next": "^14.1.3", + "react-lazy-with-preload": "^2.2.1", + "react-router-dom": "^6.25.1", + "react-sticky-el": "^2.1.0", + "react-use": "^17.5.1", + "semver": "^7.6.3", + "slugify": "^1.6.6", + "subsrt-ts": "^2.1.2", + "zustand": "^4.5.4" + }, + "devDependencies": { + "@babel/core": "^7.25.2", + "@babel/preset-env": "^7.25.3", + "@babel/preset-typescript": "^7.24.7", + "@rollup/wasm-node": "^4.19.1", + "@types/chromecast-caf-sender": "^1.0.10", + "@types/crypto-js": "^4.2.2", + "@types/dompurify": "^3.0.5", + "@types/fscreen": "^1.0.4", + "@types/lodash.isequal": "^4.5.8", + "@types/lodash.merge": "^4.6.9", + "@types/lodash.throttle": "^4.1.9", + "@types/node": "^20.14.13", + "@types/pako": "^2.0.3", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@types/react-helmet": "^6.1.11", + "@types/react-lazy-load-image-component": "^1.6.4", + "@types/react-router": "^5.1.20", + "@types/react-router-dom": "^5.3.3", + "@types/react-stickynode": "^4.0.3", + "@types/react-transition-group": "^4.4.10", + "@types/semver": "^7.5.8", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.19", + "cross-env": "^7.0.3", + "eslint": "^8.57.0", + "eslint-config-airbnb": "19.0.4", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsx-a11y": "^6.9.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react": "7.33.2", + "eslint-plugin-react-hooks": "4.6.0", + "glob": "^10.4.5", + "handlebars": "^4.7.8", + "jsdom": "^23.2.0", + "postcss": "^8.4.40", + "postcss-rtl": "^2.0.0", + "postcss-rtlcss": "^4.0.9", + "prettier": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.5.14", + "rollup-plugin-visualizer": "^5.12.0", + "tailwind-scrollbar": "^3.1.0", + "tailwindcss": "^3.4.7", + "tailwindcss-themer": "^4.0.0", + "type-fest": "^4.23.0", + "typescript": "^5.5.4", + "vite": "^5.3.5", + "vite-plugin-checker": "^0.6.4", + "vite-plugin-package-version": "^1.1.0", + "vite-plugin-pwa": "^0.17.5", + "vite-plugin-static-copy": "^1.0.6", + "vitest": "^1.6.0", + "workbox-window": "^7.1.0" + }, + "pnpm": { + "overrides": { + "get-func-name@<2.0.1": ">=2.0.1", + "postcss@<8.4.31": ">=8.4.31", + "@babel/traverse@<7.23.2": ">=7.23.2", + "crypto-js@<4.2.0": ">=4.2.0", + "rollup": "npm:@rollup/wasm-node" + } + } +} diff --git a/plugins/.gitignore b/plugins/.gitignore new file mode 100644 index 0000000..e9ee2f2 --- /dev/null +++ b/plugins/.gitignore @@ -0,0 +1 @@ +figmaTokens.json diff --git a/plugins/figmaTokensToThemeTokens.mjs b/plugins/figmaTokensToThemeTokens.mjs new file mode 100644 index 0000000..5be386d --- /dev/null +++ b/plugins/figmaTokensToThemeTokens.mjs @@ -0,0 +1,43 @@ +/** + * This script turns output from the figma plugin "style to JSON" into a usuable theme. + * It expects a format of "themes/{NAME}/anythinghere" + */ + +import fs from "fs"; + +const fileLocation = "./figmaTokens.json"; +const theme = "blue"; + +const fileContents = fs.readFileSync(fileLocation, { + encoding: "utf-8" +}); +const tokens = JSON.parse(fileContents); + +const themeTokens = tokens.themes[theme]; +const output = {}; + +function setKey(obj, key, defaultVal) { + const realKey = key.match(/^\d+$/g) ? "c" + key : key; + if (obj[key]) return obj[key]; + obj[realKey] = defaultVal; + return obj[realKey]; +} + +function handleToken(token, path) { + if (typeof token.name === "string" && typeof token.description === "string") { + let ref = output; + const lastKey = path.pop(); + path.forEach((v) => { + ref = setKey(ref, v, {}); + }); + setKey(ref, lastKey, token.hex); + return; + } + + for (let key in token) { + handleToken(token[key], [...path, key]); + } +} + +handleToken(themeTokens, []); +console.log(JSON.stringify(output, null, 2)); diff --git a/plugins/handlebars.ts b/plugins/handlebars.ts new file mode 100644 index 0000000..a8ab017 --- /dev/null +++ b/plugins/handlebars.ts @@ -0,0 +1,41 @@ +import { globSync } from "glob"; +import { viteStaticCopy } from 'vite-plugin-static-copy' +import { PluginOption } from "vite"; +import Handlebars from "handlebars"; +import path from "path"; + +export const handlebars = (options: { vars?: Record } = {}): PluginOption[] => { + const files = globSync("src/assets/**/**.hbs"); + + function render(content: string): string { + const template = Handlebars.compile(content); + return template(options?.vars ?? {}); + } + + return [ + { + name: 'hbs-templating', + enforce: "pre", + transformIndexHtml: { + order: 'pre', + handler(html) { + return render(html); + } + }, + }, + viteStaticCopy({ + silent: true, + targets: files.map(file => ({ + src: file, + dest: '', + rename: path.basename(file).slice(0, -4), // remove .hbs file extension + transform: { + encoding: 'utf8', + handler(content: string) { + return render(content); + } + } + })) + }) + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..5742ff4 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,8613 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + get-func-name@<2.0.1: '>=2.0.1' + postcss@<8.4.31: '>=8.4.31' + '@babel/traverse@<7.23.2': '>=7.23.2' + crypto-js@<4.2.0: '>=4.2.0' + rollup: npm:@rollup/wasm-node + +importers: + + .: + dependencies: + '@dnd-kit/core': + specifier: ^6.1.0 + version: 6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@dnd-kit/modifiers': + specifier: ^7.0.0 + version: 7.0.0(@dnd-kit/core@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@dnd-kit/sortable': + specifier: ^8.0.0 + version: 8.0.0(@dnd-kit/core@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@dnd-kit/utilities': + specifier: ^3.2.2 + version: 3.2.2(react@18.3.1) + '@formkit/auto-animate': + specifier: ^0.8.2 + version: 0.8.2 + '@headlessui/react': + specifier: ^1.7.19 + version: 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ladjs/country-language': + specifier: ^1.0.3 + version: 1.0.3 + '@marsidev/react-turnstile': + specifier: ^0.7.2 + version: 0.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@movie-web/providers': + specifier: github:sussy-code/providers + version: https://codeload.github.com/sussy-code/providers/tar.gz/0d43eceaf2edec2e22042e987b369357170da01f + '@noble/hashes': + specifier: ^1.4.0 + version: 1.4.0 + '@plasmohq/messaging': + specifier: ^0.6.2 + version: 0.6.2(react@18.3.1) + '@react-spring/web': + specifier: ^9.7.4 + version: 9.7.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@scure/bip39': + specifier: ^1.3.0 + version: 1.3.0 + '@sozialhelden/ietf-language-tags': + specifier: ^5.4.2 + version: 5.4.2 + '@types/node-forge': + specifier: ^1.3.11 + version: 1.3.11 + classnames: + specifier: ^2.5.1 + version: 2.5.1 + core-js: + specifier: ^3.37.1 + version: 3.37.1 + detect-browser: + specifier: ^5.3.0 + version: 5.3.0 + dompurify: + specifier: ^3.1.6 + version: 3.1.6 + flag-icons: + specifier: ^7.2.3 + version: 7.2.3 + focus-trap-react: + specifier: ^10.2.3 + version: 10.2.3(prop-types@15.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fscreen: + specifier: ^1.2.0 + version: 1.2.0 + fuse.js: + specifier: ^7.0.0 + version: 7.0.0 + hls.js: + specifier: ^1.5.13 + version: 1.5.13 + i18next: + specifier: ^23.12.2 + version: 23.12.2 + immer: + specifier: ^10.1.1 + version: 10.1.1 + jwt-decode: + specifier: ^4.0.0 + version: 4.0.0 + lodash.isequal: + specifier: ^4.5.0 + version: 4.5.0 + lodash.merge: + specifier: ^4.6.2 + version: 4.6.2 + million: + specifier: ^2.6.4 + version: 2.6.4 + nanoid: + specifier: ^5.0.7 + version: 5.0.7 + node-forge: + specifier: ^1.3.1 + version: 1.3.1 + ofetch: + specifier: ^1.3.4 + version: 1.3.4 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-ga4: + specifier: ^2.1.0 + version: 2.1.0 + react-google-recaptcha-v3: + specifier: ^1.10.1 + version: 1.10.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-helmet-async: + specifier: ^2.0.5 + version: 2.0.5(react@18.3.1) + react-i18next: + specifier: ^14.1.3 + version: 14.1.3(i18next@23.12.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-lazy-with-preload: + specifier: ^2.2.1 + version: 2.2.1 + react-router-dom: + specifier: ^6.25.1 + version: 6.25.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-sticky-el: + specifier: ^2.1.0 + version: 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-use: + specifier: ^17.5.1 + version: 17.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + semver: + specifier: ^7.6.3 + version: 7.6.3 + slugify: + specifier: ^1.6.6 + version: 1.6.6 + subsrt-ts: + specifier: ^2.1.2 + version: 2.1.2 + zustand: + specifier: ^4.5.4 + version: 4.5.4(@types/react@18.3.3)(immer@10.1.1)(react@18.3.1) + devDependencies: + '@babel/core': + specifier: ^7.25.2 + version: 7.25.2 + '@babel/preset-env': + specifier: ^7.25.3 + version: 7.25.3(@babel/core@7.25.2) + '@babel/preset-typescript': + specifier: ^7.24.7 + version: 7.24.7(@babel/core@7.25.2) + '@rollup/wasm-node': + specifier: ^4.19.1 + version: 4.19.1 + '@types/chromecast-caf-sender': + specifier: ^1.0.10 + version: 1.0.10 + '@types/crypto-js': + specifier: ^4.2.2 + version: 4.2.2 + '@types/dompurify': + specifier: ^3.0.5 + version: 3.0.5 + '@types/fscreen': + specifier: ^1.0.4 + version: 1.0.4 + '@types/lodash.isequal': + specifier: ^4.5.8 + version: 4.5.8 + '@types/lodash.merge': + specifier: ^4.6.9 + version: 4.6.9 + '@types/lodash.throttle': + specifier: ^4.1.9 + version: 4.1.9 + '@types/node': + specifier: ^20.14.13 + version: 20.14.13 + '@types/pako': + specifier: ^2.0.3 + version: 2.0.3 + '@types/react': + specifier: ^18.3.3 + version: 18.3.3 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.0 + '@types/react-helmet': + specifier: ^6.1.11 + version: 6.1.11 + '@types/react-lazy-load-image-component': + specifier: ^1.6.4 + version: 1.6.4 + '@types/react-router': + specifier: ^5.1.20 + version: 5.1.20 + '@types/react-router-dom': + specifier: ^5.3.3 + version: 5.3.3 + '@types/react-stickynode': + specifier: ^4.0.3 + version: 4.0.3 + '@types/react-transition-group': + specifier: ^4.4.10 + version: 4.4.10 + '@types/semver': + specifier: ^7.5.8 + version: 7.5.8 + '@typescript-eslint/eslint-plugin': + specifier: ^6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/parser': + specifier: ^6.21.0 + version: 6.21.0(eslint@8.57.0)(typescript@5.5.4) + '@vitejs/plugin-react': + specifier: ^4.3.1 + version: 4.3.1(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3)) + autoprefixer: + specifier: ^10.4.19 + version: 10.4.19(postcss@8.4.40) + cross-env: + specifier: ^7.0.3 + version: 7.0.3 + eslint: + 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(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.0(eslint@8.57.0))(eslint-plugin-react@7.33.2(eslint@8.57.0))(eslint@8.57.0) + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@8.57.0) + eslint-import-resolver-typescript: + specifier: ^3.6.1 + version: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: + specifier: ^2.29.1 + version: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-jsx-a11y: + specifier: ^6.9.0 + version: 6.9.0(eslint@8.57.0) + eslint-plugin-prettier: + specifier: ^5.2.1 + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3) + eslint-plugin-react: + specifier: 7.33.2 + version: 7.33.2(eslint@8.57.0) + eslint-plugin-react-hooks: + specifier: 4.6.0 + version: 4.6.0(eslint@8.57.0) + glob: + specifier: ^10.4.5 + version: 10.4.5 + handlebars: + specifier: ^4.7.8 + version: 4.7.8 + jsdom: + specifier: ^23.2.0 + version: 23.2.0 + postcss: + specifier: ^8.4.40 + version: 8.4.40 + postcss-rtl: + specifier: ^2.0.0 + version: 2.0.0(postcss@8.4.40) + postcss-rtlcss: + specifier: ^4.0.9 + version: 4.0.9(postcss@8.4.40) + prettier: + specifier: ^3.3.3 + version: 3.3.3 + prettier-plugin-tailwindcss: + specifier: ^0.5.14 + version: 0.5.14(prettier@3.3.3) + rollup-plugin-visualizer: + specifier: ^5.12.0 + version: 5.12.0(@rollup/wasm-node@4.20.0) + tailwind-scrollbar: + specifier: ^3.1.0 + version: 3.1.0(tailwindcss@3.4.7) + tailwindcss: + specifier: ^3.4.7 + version: 3.4.7 + tailwindcss-themer: + specifier: ^4.0.0 + version: 4.0.0(tailwindcss@3.4.7) + type-fest: + specifier: ^4.23.0 + version: 4.23.0 + typescript: + specifier: ^5.5.4 + version: 5.5.4 + vite: + specifier: ^5.3.5 + version: 5.3.5(@types/node@20.14.13)(terser@5.31.3) + vite-plugin-checker: + specifier: ^0.6.4 + version: 0.6.4(eslint@8.57.0)(optionator@0.9.4)(typescript@5.5.4)(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3)) + vite-plugin-package-version: + specifier: ^1.1.0 + version: 1.1.0(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3)) + vite-plugin-pwa: + specifier: ^0.17.5 + version: 0.17.5(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) + vite-plugin-static-copy: + specifier: ^1.0.6 + version: 1.0.6(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3)) + vitest: + specifier: ^1.6.0 + version: 1.6.0(@types/node@20.14.13)(jsdom@23.2.0)(terser@5.31.3) + workbox-window: + specifier: ^7.1.0 + version: 7.1.0 + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@apideck/better-ajv-errors@0.3.6': + resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} + engines: {node: '>=10'} + peerDependencies: + ajv: '>=8' + + '@asamuzakjp/dom-selector@2.0.2': + resolution: {integrity: sha512-x1KXOatwofR6ZAYzXRBL5wrdV0vwNxlTCK9NCuLqAzQYARqGcvFwiJA6A1ERuh+dgeA4Dxm3JBYictIes+SqUQ==} + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.25.2': + resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.2': + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.0': + resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.24.7': + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': + resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.2': + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.25.0': + resolution: {integrity: sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.25.2': + resolution: {integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.2': + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-member-expression-to-functions@7.24.8': + resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.2': + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.24.7': + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.24.8': + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.25.0': + resolution: {integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.25.0': + resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.24.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.25.0': + resolution: {integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.0': + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.3': + resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3': + resolution: {integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0': + resolution: {integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0': + resolution: {integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7': + resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0': + resolution: {integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-export-namespace-from@7.8.3': + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.24.7': + resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.24.7': + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.24.7': + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.24.7': + resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.24.7': + resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.25.0': + resolution: {integrity: sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.24.7': + resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.24.7': + resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.25.0': + resolution: {integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.24.7': + resolution: {integrity: sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.24.7': + resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.25.0': + resolution: {integrity: sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.24.7': + resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.24.8': + resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.24.7': + resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.24.7': + resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0': + resolution: {integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.24.7': + resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.24.7': + resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.24.7': + resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.24.7': + resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.25.1': + resolution: {integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.24.7': + resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.25.2': + resolution: {integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.24.7': + resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.24.7': + resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.24.7': + resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.24.8': + resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.25.0': + resolution: {integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.24.7': + resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7': + resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.24.7': + resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7': + resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.24.7': + resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.24.7': + resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.24.7': + resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.24.7': + resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.24.8': + resolution: {integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.24.7': + resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.24.7': + resolution: {integrity: sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.24.7': + resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.24.7': + resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-self@7.24.7': + resolution: {integrity: sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.24.7': + resolution: {integrity: sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.24.7': + resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-reserved-words@7.24.7': + resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.24.7': + resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.24.7': + resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.24.7': + resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.24.7': + resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.24.8': + resolution: {integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.25.2': + resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.24.7': + resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.24.7': + resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.24.7': + resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.24.7': + resolution: {integrity: sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.25.3': + resolution: {integrity: sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-typescript@7.24.7': + resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/regjsgen@0.8.0': + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + + '@babel/runtime@7.25.0': + resolution: {integrity: sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.3': + resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.2': + resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + engines: {node: '>=6.9.0'} + + '@dnd-kit/accessibility@3.1.0': + resolution: {integrity: sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==} + peerDependencies: + react: '>=16.8.0' + + '@dnd-kit/core@6.1.0': + resolution: {integrity: sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@dnd-kit/modifiers@7.0.0': + resolution: {integrity: sha512-BG/ETy3eBjFap7+zIti53f0PCLGDzNXyTmn6fSdrudORf+OH04MxrW4p5+mPu4mgMk9kM41iYONjc3DOUWTcfg==} + peerDependencies: + '@dnd-kit/core': ^6.1.0 + react: '>=16.8.0' + + '@dnd-kit/sortable@8.0.0': + resolution: {integrity: sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==} + peerDependencies: + '@dnd-kit/core': ^6.1.0 + react: '>=16.8.0' + + '@dnd-kit/utilities@3.2.2': + resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==} + peerDependencies: + react: '>=16.8.0' + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.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 + + '@eslint-community/regexpp@4.11.0': + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@formkit/auto-animate@0.8.2': + resolution: {integrity: sha512-SwPWfeRa5veb1hOIBMdzI+73te5puUBHmqqaF1Bu7FjvxlYSz/kJcZKSa9Cg60zL0uRNeJL2SbRxV6Jp6Q1nFQ==} + + '@headlessui/react@1.7.19': + resolution: {integrity: sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==} + engines: {node: '>=10'} + peerDependencies: + react: ^16 || ^17 || ^18 + react-dom: ^16 || ^17 || ^18 + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@ladjs/country-language@1.0.3': + resolution: {integrity: sha512-FJROu9/hh4eqVAGDyfL8vpv6Vb0qKHX1ozYLRZ+beUzD5xFf+3r0J+SVIWKviEa7W524Qvqou+ta1WrsRgzxGw==} + engines: {node: '>= 14'} + + '@marsidev/react-turnstile@0.7.2': + resolution: {integrity: sha512-0jwLvAUkcLkaYaS6jBOZB3zzUiKi5dU3kZtlaeBX6yV7Y4CbFEtfHCY352ovphNz1v0ZjpOj6+3QUczJvD56VA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@movie-web/providers@https://codeload.github.com/sussy-code/providers/tar.gz/0d43eceaf2edec2e22042e987b369357170da01f': + resolution: {tarball: https://codeload.github.com/sussy-code/providers/tar.gz/0d43eceaf2edec2e22042e987b369357170da01f} + version: 2.3.0 + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@plasmohq/messaging@0.6.2': + resolution: {integrity: sha512-CGfcvfVE0wsN/Y/i/jV0nwjkwh2gBCEujZFhLoxJ12N0ScoP3JVEIvUxJSFsAD4ylBQ8IjD2FyjQozwiSxWc4Q==} + peerDependencies: + react: ^16.8.6 || ^17 || ^18 + peerDependenciesMeta: + react: + optional: true + + '@react-spring/animated@9.7.4': + resolution: {integrity: sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/core@9.7.4': + resolution: {integrity: sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/rafz@9.7.4': + resolution: {integrity: sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==} + + '@react-spring/shared@9.7.4': + resolution: {integrity: sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/types@9.7.4': + resolution: {integrity: sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==} + + '@react-spring/web@9.7.4': + resolution: {integrity: sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@remix-run/router@1.18.0': + resolution: {integrity: sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==} + engines: {node: '>=14.0.0'} + + '@rollup/plugin-babel@5.3.1': + resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} + engines: {node: '>= 10.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: npm:@rollup/wasm-node + peerDependenciesMeta: + '@types/babel__core': + optional: true + + '@rollup/plugin-node-resolve@15.2.3': + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: npm:@rollup/wasm-node + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@2.4.2': + resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} + peerDependencies: + rollup: npm:@rollup/wasm-node + + '@rollup/plugin-terser@0.4.4': + resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: npm:@rollup/wasm-node + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@3.1.0': + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: npm:@rollup/wasm-node + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: npm:@rollup/wasm-node + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/wasm-node@4.19.1': + resolution: {integrity: sha512-G90QnusWbCqaHB0BRgGb5f1FIs7W+0bh/kaoBMZNS30VzCcGBEzbpL0UIDQZYPkbKnP5GHZ9s+HrWuny3IAGIw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + '@rollup/wasm-node@4.20.0': + resolution: {integrity: sha512-NxIRJDju9ZzXwpCZ+TMYEflT/KJPgcamVrkInPwB/jSzEIEhckHGgbC9C8Fkzt77nEZZpfF/H2BedwKfjxO9qQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + '@scure/base@1.1.7': + resolution: {integrity: sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sozialhelden/ietf-language-tags@5.4.2': + resolution: {integrity: sha512-aCN7bVOfX9sBN0EHyWJT14H8bx+VYBo8tdcynai35wgoxKMfVtgEECkQ1gs8nEL6GHGes8lPIfo6AjIch44N3w==} + + '@surma/rollup-plugin-off-main-thread@2.2.3': + resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} + + '@tanstack/react-virtual@3.8.4': + resolution: {integrity: sha512-Dq0VQr3QlTS2qL35g360QaJWBt7tCn/0xw4uZ0dHXPLO1Ak4Z4nVX4vuj1Npg1b/jqNMDToRtR5OIxM2NXRBWg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@tanstack/virtual-core@3.8.4': + resolution: {integrity: sha512-iO5Ujgw3O1yIxWDe9FgUPNkGjyT657b1WNX52u+Wv1DyBFEpdCdGkuVaky0M3hHFqNWjAmHWTn4wgj9rTr7ZQg==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/chrome@0.0.269': + resolution: {integrity: sha512-vF7x8YywnhXX2F06njQ/OE7a3Qeful43C5GUOsUksXWk89WoSFUU3iLeZW8lDpVO9atm8iZIEiLQTRC3H7NOXQ==} + + '@types/chromecast-caf-sender@1.0.10': + resolution: {integrity: sha512-B4iO+T4kMonmvIV+9xyWeIjxNWYVh6RyIQlFUeLk9fgQuXzHtFLnbnVwY7no5qshdUk9szKy0qbCWEMAjMkj4w==} + + '@types/crypto-js@4.2.2': + resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} + + '@types/dompurify@3.0.5': + resolution: {integrity: sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==} + + '@types/estree@0.0.39': + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/filesystem@0.0.36': + resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==} + + '@types/filewriter@0.0.33': + resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} + + '@types/fscreen@1.0.4': + resolution: {integrity: sha512-TsjxyAUvlvuQyao9vNk0yES4nY07K9xoAbkhgXU948JG39EqlLxniWuW9OiZde9Q8ACSpu3fmbXXRAfb/l/HqQ==} + + '@types/har-format@1.2.15': + resolution: {integrity: sha512-RpQH4rXLuvTXKR0zqHq3go0RVXYv/YVqv4TnPH95VbwUxZdQlK1EtcMvQvMpDngHbt13Csh9Z4qT9AbkiQH5BA==} + + '@types/history@4.7.11': + resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} + + '@types/js-cookie@2.2.7': + resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/lodash.isequal@4.5.8': + resolution: {integrity: sha512-uput6pg4E/tj2LGxCZo9+y27JNyB2OZuuI/T5F+ylVDYuqICLG2/ktjxx0v6GvVntAf8TvEzeQLcV0ffRirXuA==} + + '@types/lodash.merge@4.6.9': + resolution: {integrity: sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==} + + '@types/lodash.throttle@4.1.9': + resolution: {integrity: sha512-PCPVfpfueguWZQB7pJQK890F2scYKoDUL3iM522AptHWn7d5NQmeS/LTEHIcLr5PaTzl3dK2Z0xSUHHTHwaL5g==} + + '@types/lodash@4.17.7': + resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} + + '@types/node-forge@1.3.11': + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + + '@types/node@20.14.13': + resolution: {integrity: sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==} + + '@types/pako@2.0.3': + resolution: {integrity: sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q==} + + '@types/prop-types@15.7.12': + resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + + '@types/react-dom@18.3.0': + resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} + + '@types/react-helmet@6.1.11': + resolution: {integrity: sha512-0QcdGLddTERotCXo3VFlUSWO3ztraw8nZ6e3zJSgG7apwV5xt+pJUS8ewPBqT4NYB1optGLprNQzFleIY84u/g==} + + '@types/react-lazy-load-image-component@1.6.4': + resolution: {integrity: sha512-8pFPeDPF4yVG4lU1/ixZidJEEDZmEOYOTYDvmIu2IAabyuv97Q7n/93nMCocHvQ7vD1czKGiW+op55D9m3MkdA==} + + '@types/react-router-dom@5.3.3': + resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} + + '@types/react-router@5.1.20': + resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} + + '@types/react-stickynode@4.0.3': + resolution: {integrity: sha512-K7YkwdhXQE4YVxIVweix4nkpdG4onm/dcnKK+qCj0vgUrNiKng+09zOfjF5AlOcC1HQkg5yxVLwp/0AzT84R0w==} + + '@types/react-transition-group@4.4.10': + resolution: {integrity: sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==} + + '@types/react@18.3.3': + resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@typescript-eslint/eslint-plugin@6.21.0': + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@6.21.0': + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@6.21.0': + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/type-utils@6.21.0': + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@6.21.0': + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/typescript-estree@6.21.0': + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@6.21.0': + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + + '@typescript-eslint/visitor-keys@6.21.0': + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vitejs/plugin-react@4.3.1': + resolution: {integrity: sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 + + '@vitest/expect@1.6.0': + resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + + '@vitest/runner@1.6.0': + resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + + '@vitest/snapshot@1.6.0': + resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + + '@vitest/spy@1.6.0': + resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + + '@vitest/utils@1.6.0': + resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + + '@xobotyi/scrollbar-width@1.9.5': + resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + autoprefixer@10.4.19: + resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: '>=8.4.31' + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.10.0: + resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==} + engines: {node: '>=4'} + + axobject-query@3.1.1: + resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} + + babel-plugin-polyfill-corejs2@0.4.11: + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.10.4: + resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.2: + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.23.2: + resolution: {integrity: sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + caniuse-lite@1.0.30001645: + resolution: {integrity: sha512-GFtY2+qt91kzyMk6j48dJcwJVq5uTkk71XxE3RtScx7XWRLsO7bU44LOFkOZYR8w9YMS0UhPSYpN/6rAMImmLw==} + + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + common-tags@1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + confusing-browser-globals@1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + + core-js-compat@3.37.1: + resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} + + core-js@3.37.1: + resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==} + + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + + css-in-js-utils@3.1.0: + resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssstyle@4.0.1: + resolution: {integrity: sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==} + engines: {node: '>=18'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + dompurify@3.1.6: + resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.5.4: + resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + + es-iterator-helpers@1.0.19: + resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-airbnb-base@15.0.0: + resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.2 + + eslint-config-airbnb@19.0.4: + resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} + engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.3 + eslint-plugin-jsx-a11y: ^6.5.1 + eslint-plugin-react: ^7.28.0 + eslint-plugin-react-hooks: ^4.3.0 + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.6.1: + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + + eslint-module-utils@2.8.1: + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.29.1: + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.9.0: + resolution: {integrity: sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + + eslint-plugin-prettier@5.2.1: + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@4.6.0: + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react@7.33.2: + resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-shallow-equal@1.0.0: + resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} + + fast-uri@3.0.1: + resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==} + + fastest-stable-stringify@2.0.2: + resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flag-icons@7.2.3: + resolution: {integrity: sha512-X2gUdteNuqdNqob2KKTJTS+ZCvyWeLCtDz9Ty8uJP17Y4o82Y+U/Vd4JNrdwTAjagYsRznOn9DZ+E/Q52qbmqg==} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + focus-trap-react@10.2.3: + resolution: {integrity: sha512-YXBpFu/hIeSu6NnmV2xlXzOYxuWkoOtar9jzgp3lOmjWLWY59C/b8DtDHEAV4SPU07Nd/t+nS/SBNGkhUBFmEw==} + peerDependencies: + prop-types: ^15.8.1 + react: '>=16.3.0' + react-dom: '>=16.3.0' + + focus-trap@7.5.4: + resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + engines: {node: '>=14'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fscreen@1.2.0: + resolution: {integrity: sha512-hlq4+BU0hlPmwsFjwGGzZ+OZ9N/wq9Ljg/sq3pX+2CD7hrJsX9tJgWWK/wiNTFM212CLHWhicOoqwXyZGGetJg==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + fuse.js@7.0.0: + resolution: {integrity: sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==} + engines: {node: '>=10'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.7.6: + resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hls-parser@0.13.3: + resolution: {integrity: sha512-DXqW7bwx9j2qFcAXS/LBJTDJWitxknb6oUnsnTvECHrecPvPbhRgIu45OgNDUU6gpwKxMJx40SHRRUUhdIM2gA==} + + hls.js@1.5.13: + resolution: {integrity: sha512-xRgKo84nsC7clEvSfIdgn/Tc0NOT+d7vdiL/wvkLO+0k0juc26NRBPPG1SfB8pd5bHXIjMW/F5VM8VYYkOYYdw==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + + html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + engines: {node: '>= 14'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + hyphenate-style-name@1.1.0: + resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} + + i18next@23.12.2: + resolution: {integrity: sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + idb@7.1.1: + resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + immer@10.1.1: + resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + inline-style-prefixer@7.0.1: + resolution: {integrity: sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.15.0: + resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iso-639-1@3.1.2: + resolution: {integrity: sha512-Le7BRl3Jt9URvaiEHJCDEdvPZCfhiQoXnFgLAWNRhzFMwRFdWO7/5tLRQbiPzE394I9xd7KdRCM7S6qdOhwG5A==} + engines: {node: '>=6.0'} + + iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + js-cookie@2.2.1: + resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.0: + resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsdom@23.2.0: + resolution: {integrity: sha512-L88oL7D/8ufIES+Zjz7v0aes+oBMh2Xnh3ygWvL0OaICOomKEPKuPnIfBJekiXr+BHbbMjrWn/xqrDQuxFTeyA==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^2.11.2 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + just-unique@4.2.0: + resolution: {integrity: sha512-cxQGGUiit6CGUpuuiezY8N4m1wgF4o7127rXEXDFcxeDUFfdV7gSkwA26Fe2wWBiNQq2SZOgN4gSmMxB/StA8Q==} + + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.compact@3.0.1: + resolution: {integrity: sha512-2ozeiPi+5eBXW1CLtzjk8XQFhQOEMwwfxblqeq6EGyTxZJ1bPATqilY0e6g2SLQpP4KuMeuioBhEnWz5Pr7ICQ==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + million@2.6.4: + resolution: {integrity: sha512-voUkdd/jHWrG+7NS+mX49Pat+POKdgGW78V7pYMSrTaOjUitR6ySEcAci8hn17Rsx1IMI3+5w41dkADM1J1ZEg==} + hasBin: true + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nano-css@5.6.2: + resolution: {integrity: sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==} + peerDependencies: + react: '*' + react-dom: '*' + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.0.3: + resolution: {integrity: sha512-I7X2b22cxA4LIHXPSqbBCEQSL+1wv8TuoefejsX4HFWyC6jc5JG7CEaxOltiKjc1M+YCS2YkrZZcj4+dytw9GA==} + engines: {node: ^18 || >=20} + hasBin: true + + nanoid@5.0.7: + resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} + engines: {node: ^18 || >=20} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.hasown@1.1.4: + resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + ofetch@1.3.4: + resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse5-htmlparser2-tree-adapter@7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + pkg-types@1.1.3: + resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: '>=8.4.31' + + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: '>=8.4.31' + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.4.31' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: '>=8.4.31' + + postcss-rtl@2.0.0: + resolution: {integrity: sha512-vFu78CvaGY9BafWRHNgDm6OjUxzRCWWCrp+KtnyXdgwibLwb/j5ls8Z/ubvOsk9B/Q2NLwSPrXRARKMaa9RBmA==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: '>=8.4.31' + + postcss-rtlcss@4.0.9: + resolution: {integrity: sha512-dCNKEf+FgTv+EA3XI8ysg2RnpS5s3/iZmU+9qpCNFxHU/BhK+4hz7jyCsCAfo0CLnDrMPtaQENhwb+EGm1wh7Q==} + engines: {node: '>=18.0.0'} + peerDependencies: + postcss: '>=8.4.31' + + postcss-selector-parser@6.1.1: + resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.40: + resolution: {integrity: sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier-plugin-tailwindcss@0.5.14: + resolution: {integrity: sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig-melody': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig-melody': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-ga4@2.1.0: + resolution: {integrity: sha512-ZKS7PGNFqqMd3PJ6+C2Jtz/o1iU9ggiy8Y8nUeksgVuvNISbmrQtJiZNvC/TjDsqD0QlU5Wkgs7i+w9+OjHhhQ==} + + react-google-recaptcha-v3@1.10.1: + resolution: {integrity: sha512-K3AYzSE0SasTn+XvV2tq+6YaxM+zQypk9rbCgG4OVUt7Rh4ze9basIKefoBz9sC0CNslJj9N1uwTTgRMJQbQJQ==} + peerDependencies: + react: ^16.3 || ^17.0 || ^18.0 + react-dom: ^17.0 || ^18.0 + + react-helmet-async@2.0.5: + resolution: {integrity: sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg==} + peerDependencies: + react: ^16.6.0 || ^17.0.0 || ^18.0.0 + + react-i18next@14.1.3: + resolution: {integrity: sha512-wZnpfunU6UIAiJ+bxwOiTmBOAaB14ha97MjOEnLGac2RJ+h/maIYXZuTHlmyqQVX1UVHmU1YDTQ5vxLmwfXTjw==} + peerDependencies: + i18next: '>= 23.2.3' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-lazy-with-preload@2.2.1: + resolution: {integrity: sha512-ONSb8gizLE5jFpdHAclZ6EAAKuFX2JydnFXPPPjoUImZlLjGtKzyBS8SJgJq7CpLgsGKh9QCZdugJyEEOVC16Q==} + + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react-router-dom@6.25.1: + resolution: {integrity: sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + react-router@6.25.1: + resolution: {integrity: sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + + react-sticky-el@2.1.0: + resolution: {integrity: sha512-oo+a2GedF4QMfCfm20e9gD+RuuQp/ngvwGMUXAXpST+h4WnmKhuv7x6MQ4X/e3AHiLYgE0zDyJo1Pzo8m51KpA==} + peerDependencies: + react: '>=16.3.0' + react-dom: '>=16.3.0' + + react-universal-interface@0.6.2: + resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} + peerDependencies: + react: '*' + tslib: '*' + + react-use@17.5.1: + resolution: {integrity: sha512-LG/uPEVRflLWMwi3j/sZqR00nF6JGqTTDblkXK2nzXsIvij06hXl1V/MZIlwj1OKIQUtlh1l9jK8gLsRyCQxMg==} + peerDependencies: + react: '*' + react-dom: '*' + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + + regenerate-unicode-properties@10.1.1: + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + + regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup-plugin-visualizer@5.12.0: + resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + rollup: npm:@rollup/wasm-node + peerDependenciesMeta: + rollup: + optional: true + + rrweb-cssom@0.6.0: + resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} + + rtl-css-js@1.16.1: + resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} + + rtlcss@4.0.0: + resolution: {integrity: sha512-j6oypPP+mgFwDXL1JkLCtm6U/DQntMUqlv5SOhpgHhdIE+PmBcjrtAHIpXfbIup47kD5Sgja9JDsDF1NNOsBwQ==} + engines: {node: '>=12.0.0'} + hasBin: true + + rtlcss@4.1.1: + resolution: {integrity: sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==} + engines: {node: '>=12.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + screenfull@5.2.0: + resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} + engines: {node: '>=0.10.0'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + set-cookie-parser@2.7.0: + resolution: {integrity: sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-harmonic-interval@1.0.1: + resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==} + engines: {node: '>=6.9'} + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slugify@1.6.6: + resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} + engines: {node: '>=8.0.0'} + + smob@1.5.0: + resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.5.6: + resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + stack-generator@2.0.10: + resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + stacktrace-gps@3.1.2: + resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==} + + stacktrace-js@2.0.2: + resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + stop-iteration-iterator@1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.includes@2.0.0: + resolution: {integrity: sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==} + + string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-comments@2.0.1: + resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} + engines: {node: '>=10'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + + stylis@4.3.2: + resolution: {integrity: sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==} + + subsrt-ts@2.1.2: + resolution: {integrity: sha512-45yNlK42Z0pz4lAaNYbR5P60M2jmHl+gfAaiJxDIXsXXqoE7TkDCzl/00HgWyZXKkdIU6s8FiNtRvrlOZb+5Qg==} + hasBin: true + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + synckit@0.9.1: + resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==} + engines: {node: ^14.18.0 || >=16.0.0} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + + tailwind-scrollbar@3.1.0: + resolution: {integrity: sha512-pmrtDIZeHyu2idTejfV59SbaJyvp1VRjYxAjZBH0jnyrPRo6HL1kD5Glz8VPagasqr6oAx6M05+Tuw429Z8jxg==} + engines: {node: '>=12.13.0'} + peerDependencies: + tailwindcss: 3.x + + tailwindcss-themer@4.0.0: + resolution: {integrity: sha512-kngKDW+z36JtjvaNziX0aesO95r8f5+3FFdANVFDt1uzNHZsL6XLla1YDK6EBAYFqPichoPDbO4lrrTyB+UAbA==} + peerDependencies: + tailwindcss: ^3.1.0 + + tailwindcss@3.4.7: + resolution: {integrity: sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + temp-dir@2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + + tempy@0.6.0: + resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} + engines: {node: '>=10'} + + terser@5.31.3: + resolution: {integrity: sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==} + engines: {node: '>=10'} + hasBin: true + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + throttle-debounce@3.0.1: + resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} + engines: {node: '>=10'} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.8.0: + resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} + + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} + engines: {node: '>=14.0.0'} + + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + engines: {node: '>=18'} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-easing@0.2.0: + resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + + type-fest@0.16.0: + resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} + engines: {node: '>=10'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@4.23.0: + resolution: {integrity: sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==} + engines: {node: '>=16'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + uglify-js@3.19.1: + resolution: {integrity: sha512-y/2wiW+ceTYR2TSSptAhfnEtpLaQ4Ups5zrjB2d3kuVxHj16j/QJwPl5PvuGy9uARb39J0+iKxcRPvtpsx4A4A==} + engines: {node: '>=0.8.0'} + hasBin: true + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + + unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpacker@1.0.1: + resolution: {integrity: sha512-0HTljwp8+JBdITpoHcK1LWi7X9U2BspUmWv78UWZh7NshYhbh1nec8baY/iSbe2OQTZ2bhAtVdnr6/BTD0DKVg==} + + unplugin@1.12.0: + resolution: {integrity: sha512-KeczzHl2sATPQUx1gzo+EnUkmN4VmGBYRRVOZSGvGITE9rGHRDGqft6ONceP3vgXcyJ2XjX5axG5jMWUwNCYLw==} + engines: {node: '>=14.0.0'} + + upath@1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + + update-browserslist-db@1.1.0: + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite-node@1.6.0: + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite-plugin-checker@0.6.4: + resolution: {integrity: sha512-2zKHH5oxr+ye43nReRbC2fny1nyARwhxdm0uNYp/ERy4YvU9iZpNOsueoi/luXw5gnpqRSvjcEPxXbS153O2wA==} + engines: {node: '>=14.16'} + peerDependencies: + eslint: '>=7' + meow: ^9.0.0 + optionator: ^0.9.1 + stylelint: '>=13' + typescript: '*' + vite: '>=2.0.0' + vls: '*' + vti: '*' + vue-tsc: '>=1.3.9' + peerDependenciesMeta: + eslint: + optional: true + meow: + optional: true + optionator: + optional: true + stylelint: + optional: true + typescript: + optional: true + vls: + optional: true + vti: + optional: true + vue-tsc: + optional: true + + vite-plugin-package-version@1.1.0: + resolution: {integrity: sha512-TPoFZXNanzcaKCIrC3e2L/TVRkkRLB6l4RPN/S7KbG7rWfyLcCEGsnXvxn6qR7fyZwXalnnSN/I9d6pSFjHpEA==} + peerDependencies: + vite: '>=2.0.0-beta.69' + + vite-plugin-pwa@0.17.5: + resolution: {integrity: sha512-UxRNPiJBzh4tqU/vc8G2TxmrUTzT6BqvSzhszLk62uKsf+npXdvLxGDz9C675f4BJi6MbD2tPnJhi5txlMzxbQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + vite: ^3.1.0 || ^4.0.0 || ^5.0.0 + workbox-build: ^7.0.0 + workbox-window: ^7.0.0 + + vite-plugin-static-copy@1.0.6: + resolution: {integrity: sha512-3uSvsMwDVFZRitqoWHj0t4137Kz7UynnJeq1EZlRW7e25h2068fyIZX4ORCCOAkfp1FklGxJNVJBkBOD+PZIew==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + + vite@5.3.5: + resolution: {integrity: sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@1.6.0: + resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.0 + '@vitest/ui': 1.6.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + + vscode-jsonrpc@6.0.0: + resolution: {integrity: sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==} + engines: {node: '>=8.0.0 || >=10.0.0'} + + vscode-languageclient@7.0.0: + resolution: {integrity: sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==} + engines: {vscode: ^1.52.0} + + vscode-languageserver-protocol@3.16.0: + resolution: {integrity: sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.16.0: + resolution: {integrity: sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==} + + vscode-languageserver@7.0.0: + resolution: {integrity: sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==} + hasBin: true + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@14.0.0: + resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==} + engines: {node: '>=18'} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-builtin-type@1.1.4: + resolution: {integrity: sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + workbox-background-sync@7.1.0: + resolution: {integrity: sha512-rMbgrzueVWDFcEq1610YyDW71z0oAXLfdRHRQcKw4SGihkfOK0JUEvqWHFwA6rJ+6TClnMIn7KQI5PNN1XQXwQ==} + + workbox-broadcast-update@7.1.0: + resolution: {integrity: sha512-O36hIfhjej/c5ar95pO67k1GQw0/bw5tKP7CERNgK+JdxBANQhDmIuOXZTNvwb2IHBx9hj2kxvcDyRIh5nzOgQ==} + + workbox-build@7.1.1: + resolution: {integrity: sha512-WdkVdC70VMpf5NBCtNbiwdSZeKVuhTEd5PV3mAwpTQCGAB5XbOny1P9egEgNdetv4srAMmMKjvBk4RD58LpooA==} + engines: {node: '>=16.0.0'} + + workbox-cacheable-response@7.1.0: + resolution: {integrity: sha512-iwsLBll8Hvua3xCuBB9h92+/e0wdsmSVgR2ZlvcfjepZWwhd3osumQB3x9o7flj+FehtWM2VHbZn8UJeBXXo6Q==} + + workbox-core@7.1.0: + resolution: {integrity: sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==} + + workbox-expiration@7.1.0: + resolution: {integrity: sha512-m5DcMY+A63rJlPTbbBNtpJ20i3enkyOtSgYfv/l8h+D6YbbNiA0zKEkCUaMsdDlxggla1oOfRkyqTvl5Ni5KQQ==} + + workbox-google-analytics@7.1.0: + resolution: {integrity: sha512-FvE53kBQHfVTcZyczeBVRexhh7JTkyQ8HAvbVY6mXd2n2A7Oyz/9fIwnY406ZcDhvE4NFfKGjW56N4gBiqkrew==} + + workbox-navigation-preload@7.1.0: + resolution: {integrity: sha512-4wyAbo0vNI/X0uWNJhCMKxnPanNyhybsReMGN9QUpaePLTiDpKxPqFxl4oUmBNddPwIXug01eTSLVIFXimRG/A==} + + workbox-precaching@7.1.0: + resolution: {integrity: sha512-LyxzQts+UEpgtmfnolo0hHdNjoB7EoRWcF7EDslt+lQGd0lW4iTvvSe3v5JiIckQSB5KTW5xiCqjFviRKPj1zA==} + + workbox-range-requests@7.1.0: + resolution: {integrity: sha512-m7+O4EHolNs5yb/79CrnwPR/g/PRzMFYEdo01LqwixVnc/sbzNSvKz0d04OE3aMRel1CwAAZQheRsqGDwATgPQ==} + + workbox-recipes@7.1.0: + resolution: {integrity: sha512-NRrk4ycFN9BHXJB6WrKiRX3W3w75YNrNrzSX9cEZgFB5ubeGoO8s/SDmOYVrFYp9HMw6sh1Pm3eAY/1gVS8YLg==} + + workbox-routing@7.1.0: + resolution: {integrity: sha512-oOYk+kLriUY2QyHkIilxUlVcFqwduLJB7oRZIENbqPGeBP/3TWHYNNdmGNhz1dvKuw7aqvJ7CQxn27/jprlTdg==} + + workbox-strategies@7.1.0: + resolution: {integrity: sha512-/UracPiGhUNehGjRm/tLUQ+9PtWmCbRufWtV0tNrALuf+HZ4F7cmObSEK+E4/Bx1p8Syx2tM+pkIrvtyetdlew==} + + workbox-streams@7.1.0: + resolution: {integrity: sha512-WyHAVxRXBMfysM8ORwiZnI98wvGWTVAq/lOyBjf00pXFvG0mNaVz4Ji+u+fKa/mf1i2SnTfikoYKto4ihHeS6w==} + + workbox-sw@7.1.0: + resolution: {integrity: sha512-Hml/9+/njUXBglv3dtZ9WBKHI235AQJyLBV1G7EFmh4/mUdSQuXui80RtjDeVRrXnm/6QWgRUEHG3/YBVbxtsA==} + + workbox-window@7.1.0: + resolution: {integrity: sha512-ZHeROyqR+AS5UPzholQRDttLFqGMwP0Np8MKWAdyxsDETxq3qOAyXvqessc3GniohG6e0mAqSQyKOHmT8zPF7g==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml@2.5.0: + resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.1.1: + resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} + engines: {node: '>=12.20'} + + zustand@4.5.4: + resolution: {integrity: sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@apideck/better-ajv-errors@0.3.6(ajv@8.17.1)': + dependencies: + ajv: 8.17.1 + json-schema: 0.4.0 + jsonpointer: 5.0.1 + leven: 3.1.0 + + '@asamuzakjp/dom-selector@2.0.2': + dependencies: + bidi-js: 1.0.3 + css-tree: 2.3.1 + is-potential-custom-element-name: 1.0.1 + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + + '@babel/compat-data@7.25.2': {} + + '@babel/core@7.25.2': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + convert-source-map: 2.0.0 + debug: 4.3.6 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.25.0': + dependencies: + '@babel/types': 7.25.2 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-annotate-as-pure@7.24.7': + dependencies: + '@babel/types': 7.25.2 + + '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-compilation-targets@7.25.2': + dependencies: + '@babel/compat-data': 7.25.2 + '@babel/helper-validator-option': 7.24.8 + browserslist: 4.23.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/traverse': 7.25.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + regexpu-core: 5.3.2 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + debug: 4.3.6 + lodash.debounce: 4.0.8 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.24.8': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.24.7': + dependencies: + '@babel/types': 7.25.2 + + '@babel/helper-plugin-utils@7.24.8': {} + + '@babel/helper-remap-async-to-generator@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-wrap-function': 7.25.0 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.24.8': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/helper-validator-option@7.24.8': {} + + '@babel/helper-wrap-function@7.25.0': + dependencies: + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.25.0': + dependencies: + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + + '@babel/parser@7.25.3': + dependencies: + '@babel/types': 7.25.2 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-async-generator-functions@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-block-scoping@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + '@babel/traverse': 7.25.3 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/template': 7.25.0 + + '@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.25.1(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-literals@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + + '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-simple-access': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-new-target@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + + '@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + + '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-optional-chaining@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-react-jsx-source@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + regenerator-transform: 0.15.2 + + '@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-spread@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-typeof-symbol@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-typescript@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/preset-env@7.25.3(@babel/core@7.25.2)': + dependencies: + '@babel/compat-data': 7.25.2 + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-option': 7.24.8 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.3(@babel/core@7.25.2) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.2) + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-async-generator-functions': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-block-scoping': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-classes': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-function-name': 7.25.1(@babel/core@7.25.2) + '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-literals': 7.25.2(@babel/core@7.25.2) + '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-modules-systemjs': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-typeof-symbol': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.25.2) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.2) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) + babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.25.2) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) + core-js-compat: 3.37.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/types': 7.25.2 + esutils: 2.0.3 + + '@babel/preset-typescript@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-option': 7.24.8 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/regjsgen@0.8.0': {} + + '@babel/runtime@7.25.0': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.25.0': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 + + '@babel/traverse@7.25.3': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 + debug: 4.3.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.25.2': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@dnd-kit/accessibility@3.1.0(react@18.3.1)': + dependencies: + react: 18.3.1 + tslib: 2.6.3 + + '@dnd-kit/core@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@dnd-kit/accessibility': 3.1.0(react@18.3.1) + '@dnd-kit/utilities': 3.2.2(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.6.3 + + '@dnd-kit/modifiers@7.0.0(@dnd-kit/core@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + dependencies: + '@dnd-kit/core': 6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@dnd-kit/utilities': 3.2.2(react@18.3.1) + react: 18.3.1 + tslib: 2.6.3 + + '@dnd-kit/sortable@8.0.0(@dnd-kit/core@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + dependencies: + '@dnd-kit/core': 6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@dnd-kit/utilities': 3.2.2(react@18.3.1) + react: 18.3.1 + tslib: 2.6.3 + + '@dnd-kit/utilities@3.2.2(react@18.3.1)': + dependencies: + react: 18.3.1 + tslib: 2.6.3 + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.0': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.6 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.0': {} + + '@formkit/auto-animate@0.8.2': {} + + '@headlessui/react@1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/react-virtual': 3.8.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + client-only: 0.0.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.6 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@ladjs/country-language@1.0.3': {} + + '@marsidev/react-turnstile@0.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@movie-web/providers@https://codeload.github.com/sussy-code/providers/tar.gz/0d43eceaf2edec2e22042e987b369357170da01f': + dependencies: + cheerio: 1.0.0-rc.12 + cookie: 0.6.0 + crypto-js: 4.2.0 + form-data: 4.0.0 + hls-parser: 0.13.3 + iso-639-1: 3.1.2 + nanoid: 3.3.7 + node-fetch: 3.3.2 + set-cookie-parser: 2.7.0 + unpacker: 1.0.1 + + '@noble/hashes@1.4.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.1.1': {} + + '@plasmohq/messaging@0.6.2(react@18.3.1)': + dependencies: + nanoid: 5.0.3 + optionalDependencies: + react: 18.3.1 + + '@react-spring/animated@9.7.4(react@18.3.1)': + dependencies: + '@react-spring/shared': 9.7.4(react@18.3.1) + '@react-spring/types': 9.7.4 + react: 18.3.1 + + '@react-spring/core@9.7.4(react@18.3.1)': + dependencies: + '@react-spring/animated': 9.7.4(react@18.3.1) + '@react-spring/shared': 9.7.4(react@18.3.1) + '@react-spring/types': 9.7.4 + react: 18.3.1 + + '@react-spring/rafz@9.7.4': {} + + '@react-spring/shared@9.7.4(react@18.3.1)': + dependencies: + '@react-spring/rafz': 9.7.4 + '@react-spring/types': 9.7.4 + react: 18.3.1 + + '@react-spring/types@9.7.4': {} + + '@react-spring/web@9.7.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@react-spring/animated': 9.7.4(react@18.3.1) + '@react-spring/core': 9.7.4(react@18.3.1) + '@react-spring/shared': 9.7.4(react@18.3.1) + '@react-spring/types': 9.7.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@remix-run/router@1.18.0': {} + + '@rollup/plugin-babel@5.3.1(@babel/core@7.25.2)(@rollup/wasm-node@4.20.0)(@types/babel__core@7.20.5)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.20.0) + rollup: '@rollup/wasm-node@4.20.0' + optionalDependencies: + '@types/babel__core': 7.20.5 + transitivePeerDependencies: + - supports-color + + '@rollup/plugin-node-resolve@15.2.3(@rollup/wasm-node@4.20.0)': + dependencies: + '@rollup/pluginutils': 5.1.0(@rollup/wasm-node@4.20.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + optionalDependencies: + rollup: '@rollup/wasm-node@4.20.0' + + '@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.20.0)': + dependencies: + '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.20.0) + magic-string: 0.25.9 + rollup: '@rollup/wasm-node@4.20.0' + + '@rollup/plugin-terser@0.4.4(@rollup/wasm-node@4.20.0)': + dependencies: + serialize-javascript: 6.0.2 + smob: 1.5.0 + terser: 5.31.3 + optionalDependencies: + rollup: '@rollup/wasm-node@4.20.0' + + '@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.20.0)': + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: '@rollup/wasm-node@4.20.0' + + '@rollup/pluginutils@5.1.0(@rollup/wasm-node@4.20.0)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: '@rollup/wasm-node@4.20.0' + + '@rollup/wasm-node@4.19.1': + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + fsevents: 2.3.3 + + '@rollup/wasm-node@4.20.0': + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + fsevents: 2.3.3 + + '@scure/base@1.1.7': {} + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.7 + + '@sinclair/typebox@0.27.8': {} + + '@sozialhelden/ietf-language-tags@5.4.2': + dependencies: + lodash.compact: 3.0.1 + typescript: 4.9.5 + + '@surma/rollup-plugin-off-main-thread@2.2.3': + dependencies: + ejs: 3.1.10 + json5: 2.2.3 + magic-string: 0.25.9 + string.prototype.matchall: 4.0.11 + + '@tanstack/react-virtual@3.8.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/virtual-core': 3.8.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/virtual-core@3.8.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.25.2 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.25.2 + + '@types/chrome@0.0.269': + dependencies: + '@types/filesystem': 0.0.36 + '@types/har-format': 1.2.15 + + '@types/chromecast-caf-sender@1.0.10': + dependencies: + '@types/chrome': 0.0.269 + + '@types/crypto-js@4.2.2': {} + + '@types/dompurify@3.0.5': + dependencies: + '@types/trusted-types': 2.0.7 + + '@types/estree@0.0.39': {} + + '@types/estree@1.0.5': {} + + '@types/filesystem@0.0.36': + dependencies: + '@types/filewriter': 0.0.33 + + '@types/filewriter@0.0.33': {} + + '@types/fscreen@1.0.4': {} + + '@types/har-format@1.2.15': {} + + '@types/history@4.7.11': {} + + '@types/js-cookie@2.2.7': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/lodash.isequal@4.5.8': + dependencies: + '@types/lodash': 4.17.7 + + '@types/lodash.merge@4.6.9': + dependencies: + '@types/lodash': 4.17.7 + + '@types/lodash.throttle@4.1.9': + dependencies: + '@types/lodash': 4.17.7 + + '@types/lodash@4.17.7': {} + + '@types/node-forge@1.3.11': + dependencies: + '@types/node': 20.14.13 + + '@types/node@20.14.13': + dependencies: + undici-types: 5.26.5 + + '@types/pako@2.0.3': {} + + '@types/prop-types@15.7.12': {} + + '@types/react-dom@18.3.0': + dependencies: + '@types/react': 18.3.3 + + '@types/react-helmet@6.1.11': + dependencies: + '@types/react': 18.3.3 + + '@types/react-lazy-load-image-component@1.6.4': + dependencies: + '@types/react': 18.3.3 + csstype: 3.1.3 + + '@types/react-router-dom@5.3.3': + dependencies: + '@types/history': 4.7.11 + '@types/react': 18.3.3 + '@types/react-router': 5.1.20 + + '@types/react-router@5.1.20': + dependencies: + '@types/history': 4.7.11 + '@types/react': 18.3.3 + + '@types/react-stickynode@4.0.3': + dependencies: + '@types/react': 18.3.3 + + '@types/react-transition-group@4.4.10': + dependencies: + '@types/react': 18.3.3 + + '@types/react@18.3.3': + dependencies: + '@types/prop-types': 15.7.12 + csstype: 3.1.3 + + '@types/resolve@1.20.2': {} + + '@types/semver@7.5.8': {} + + '@types/trusted-types@2.0.7': {} + + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.6 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.6 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@6.21.0': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.5.4) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + debug: 4.3.6 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@6.21.0': {} + + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.5.4)': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.6 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.5.4) + eslint: 8.57.0 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@6.21.0': + dependencies: + '@typescript-eslint/types': 6.21.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@vitejs/plugin-react@4.3.1(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3))': + dependencies: + '@babel/core': 7.25.2 + '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.3.5(@types/node@20.14.13)(terser@5.31.3) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@1.6.0': + dependencies: + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + chai: 4.5.0 + + '@vitest/runner@1.6.0': + dependencies: + '@vitest/utils': 1.6.0 + p-limit: 5.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@1.6.0': + dependencies: + magic-string: 0.30.11 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@1.6.0': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@1.6.0': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + + '@xobotyi/scrollbar-width@1.9.5': {} + + acorn-jsx@5.3.2(acorn@8.12.1): + dependencies: + acorn: 8.12.1 + + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + + agent-base@7.1.1: + dependencies: + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.1 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + aria-query@5.1.3: + dependencies: + deep-equal: 2.2.3 + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-includes@3.1.8: + 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 + + array-union@2.1.0: {} + + array.prototype.findlastindex@1.2.5: + 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 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.tosorted@1.1.4: + 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 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + 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 + + assertion-error@1.1.0: {} + + ast-types-flow@0.0.8: {} + + async@3.2.5: {} + + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + + autoprefixer@10.4.19(postcss@8.4.40): + dependencies: + browserslist: 4.23.2 + caniuse-lite: 1.0.30001645 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.1 + postcss: 8.4.40 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axe-core@4.10.0: {} + + axobject-query@3.1.1: + dependencies: + deep-equal: 2.2.3 + + babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.2): + dependencies: + '@babel/compat-data': 7.25.2 + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + core-js-compat: 3.37.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + balanced-match@1.0.2: {} + + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + + binary-extensions@2.3.0: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.23.2: + dependencies: + caniuse-lite: 1.0.30001645 + electron-to-chromium: 1.5.4 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.2) + + buffer-from@1.1.2: {} + + builtin-modules@3.3.0: {} + + cac@6.7.14: {} + + call-bind@1.0.7: + 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 + + callsites@3.1.0: {} + + camelcase-css@2.0.1: {} + + caniuse-lite@1.0.30001645: {} + + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + htmlparser2: 8.0.2 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + classnames@2.5.1: {} + + client-only@0.0.1: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@2.20.3: {} + + commander@4.1.1: {} + + commander@8.3.0: {} + + common-tags@1.8.2: {} + + concat-map@0.0.1: {} + + confbox@0.1.7: {} + + confusing-browser-globals@1.0.11: {} + + convert-source-map@2.0.0: {} + + cookie@0.6.0: {} + + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + + core-js-compat@3.37.1: + dependencies: + browserslist: 4.23.2 + + core-js@3.37.1: {} + + cross-env@7.0.3: + dependencies: + cross-spawn: 7.0.3 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-js@4.2.0: {} + + crypto-random-string@2.0.0: {} + + css-in-js-utils@3.1.0: + dependencies: + hyphenate-style-name: 1.1.0 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.0 + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + cssstyle@4.0.1: + dependencies: + rrweb-cssom: 0.6.0 + + csstype@3.1.3: {} + + damerau-levenshtein@1.0.8: {} + + data-uri-to-buffer@4.0.1: {} + + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.0.0 + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.6: + dependencies: + ms: 2.1.2 + + decimal.js@10.4.3: {} + + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + + deep-equal@2.2.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + es-get-iterator: 1.1.3 + get-intrinsic: 1.2.4 + is-arguments: 1.1.1 + is-array-buffer: 3.0.4 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + isarray: 2.0.5 + object-is: 1.1.6 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + side-channel: 1.0.6 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-lazy-prop@2.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + destr@2.0.3: {} + + detect-browser@5.3.0: {} + + didyoumean@1.2.2: {} + + diff-sequences@29.6.3: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dlv@1.1.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + dompurify@3.1.6: {} + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + eastasianwidth@0.2.0: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.2 + + electron-to-chromium@1.5.4: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + entities@4.5.0: {} + + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + es-abstract@1.23.3: + 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.4 + 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.2 + 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 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + + es-iterator-helpers@1.0.19: + 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.4 + 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 + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint@8.57.0): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 8.57.0 + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + object.assign: 4.1.5 + object.entries: 1.1.8 + semver: 6.3.1 + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.0(eslint@8.57.0))(eslint-plugin-react@7.33.2(eslint@8.57.0))(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) + eslint-plugin-react: 7.33.2(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) + object.assign: 4.1.5 + object.entries: 1.1.8 + + eslint-config-prettier@9.1.0(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.15.0 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0): + dependencies: + debug: 4.3.6 + enhanced-resolve: 5.17.1 + eslint: 8.57.0 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.6 + is-core-module: 2.15.0 + is-glob: 4.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.15.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0): + dependencies: + aria-query: 5.1.3 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.2 + ast-types-flow: 0.0.8 + axe-core: 4.10.0 + axobject-query: 3.1.1 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + es-iterator-helpers: 1.0.19 + eslint: 8.57.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.0.3 + string.prototype.includes: 2.0.0 + + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3): + dependencies: + eslint: 8.57.0 + prettier: 3.3.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.9.1 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@8.57.0) + + eslint-plugin-react-hooks@4.6.0(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-plugin-react@7.33.2(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.2 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.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.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.11 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.11.0 + '@eslint/eslintrc': 2.1.4 + '@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 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.6 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 3.4.3 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@1.0.1: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + esutils@2.0.3: {} + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-shallow-equal@1.0.0: {} + + fast-uri@3.0.1: {} + + fastest-stable-stringify@2.0.2: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flag-icons@7.2.3: {} + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.3.1: {} + + focus-trap-react@10.2.3(prop-types@15.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + focus-trap: 7.5.4 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tabbable: 6.2.0 + + focus-trap@7.5.4: + dependencies: + tabbable: 6.2.0 + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.2.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fraction.js@4.3.7: {} + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fscreen@1.2.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + fuse.js@7.0.0: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-func-name@2.0.2: {} + + get-intrinsic@1.2.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 + + get-own-enumerable-property-symbols@3.0.2: {} + + get-stream@8.0.1: {} + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.7.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.2.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + glob@7.2.3: + 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 + + globals@11.12.0: {} + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.1 + + has-bigints@1.0.2: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hls-parser@0.13.3: {} + + hls.js@1.5.13: {} + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + + html-parse-stringify@3.0.1: + dependencies: + void-elements: 3.1.0 + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.1 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.5: + dependencies: + agent-base: 7.1.1 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + + human-signals@5.0.0: {} + + hyphenate-style-name@1.1.0: {} + + i18next@23.12.2: + dependencies: + '@babel/runtime': 7.25.0 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + idb@7.1.1: {} + + ignore@5.3.1: {} + + immer@10.1.1: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + inline-style-prefixer@7.0.1: + dependencies: + css-in-js-utils: 3.1.0 + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.3.2: {} + + is-async-function@2.0.0: + dependencies: + has-tostringtag: 1.0.2 + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-callable@1.2.7: {} + + is-core-module@2.15.0: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-docker@2.2.1: {} + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-module@1.0.0: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-obj@1.0.1: {} + + is-path-inside@3.0.3: {} + + is-potential-custom-element-name@1.0.1: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-regexp@1.0.0: {} + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-weakmap@2.0.2: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-weakset@2.0.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + iso-639-1@3.1.2: {} + + iterator.prototype@1.1.2: + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.9.2: + dependencies: + async: 3.2.5 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + + jiti@1.21.6: {} + + js-cookie@2.2.1: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsdom@23.2.0: + dependencies: + '@asamuzakjp/dom-selector': 2.0.2 + cssstyle: 4.0.1 + data-urls: 5.0.0 + decimal.js: 10.4.3 + form-data: 4.0.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 + is-potential-custom-element-name: 1.0.1 + parse5: 7.1.2 + rrweb-cssom: 0.6.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.1.4 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.0.0 + ws: 8.18.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsesc@0.5.0: {} + + jsesc@2.5.2: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema@0.4.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonpointer@5.0.1: {} + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.2.0 + + just-unique@4.2.0: {} + + jwt-decode@4.0.0: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@4.1.5: {} + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@2.1.0: {} + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.1 + pkg-types: 1.1.3 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.compact@3.0.1: {} + + lodash.debounce@4.0.8: {} + + lodash.isequal@4.5.0: {} + + lodash.merge@4.6.2: {} + + lodash.mergewith@4.6.2: {} + + lodash.sortby@4.7.0: {} + + lodash@4.17.21: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + mdn-data@2.0.14: {} + + mdn-data@2.0.30: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + million@2.6.4: + dependencies: + '@babel/core': 7.25.2 + '@babel/generator': 7.25.0 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) + '@babel/types': 7.25.2 + kleur: 4.1.5 + rollup: '@rollup/wasm-node@4.20.0' + unplugin: 1.12.0 + transitivePeerDependencies: + - supports-color + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@4.0.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mlly@1.7.1: + dependencies: + acorn: 8.12.1 + pathe: 1.1.2 + pkg-types: 1.1.3 + ufo: 1.5.4 + + ms@2.1.2: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nano-css@5.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + css-tree: 1.1.3 + csstype: 3.1.3 + fastest-stable-stringify: 2.0.2 + inline-style-prefixer: 7.0.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + rtl-css-js: 1.16.1 + stacktrace-js: 2.0.2 + stylis: 4.3.2 + + nanoid@3.3.7: {} + + nanoid@5.0.3: {} + + nanoid@5.0.7: {} + + natural-compare@1.4.0: {} + + neo-async@2.6.2: {} + + node-domexception@1.0.0: {} + + node-fetch-native@1.6.4: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-forge@1.3.1: {} + + node-releases@2.0.18: {} + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + object-inspect@1.13.2: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.entries@1.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.hasown@1.1.4: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + ofetch@1.3.4: + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.4 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@5.0.0: + dependencies: + yocto-queue: 1.1.1 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + package-json-from-dist@1.0.0: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse5-htmlparser2-tree-adapter@7.0.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-type@4.0.0: {} + + pathe@1.1.2: {} + + pathval@1.1.1: {} + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + pify@2.3.0: {} + + pirates@4.0.6: {} + + pkg-types@1.1.3: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + + possible-typed-array-names@1.0.0: {} + + postcss-import@15.1.0(postcss@8.4.40): + dependencies: + postcss: 8.4.40 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + + postcss-js@4.0.1(postcss@8.4.40): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.40 + + postcss-load-config@4.0.2(postcss@8.4.40): + dependencies: + lilconfig: 3.1.2 + yaml: 2.5.0 + optionalDependencies: + postcss: 8.4.40 + + postcss-nested@6.2.0(postcss@8.4.40): + dependencies: + postcss: 8.4.40 + postcss-selector-parser: 6.1.1 + + postcss-rtl@2.0.0(postcss@8.4.40): + dependencies: + postcss: 8.4.40 + rtlcss: 4.0.0 + + postcss-rtlcss@4.0.9(postcss@8.4.40): + dependencies: + postcss: 8.4.40 + rtlcss: 4.1.1 + + postcss-selector-parser@6.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.4.40: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier-plugin-tailwindcss@0.5.14(prettier@3.3.3): + dependencies: + prettier: 3.3.3 + + prettier@3.3.3: {} + + pretty-bytes@5.6.0: {} + + pretty-bytes@6.1.1: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + psl@1.9.0: {} + + punycode@2.3.1: {} + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-fast-compare@3.2.2: {} + + react-ga4@2.1.0: {} + + react-google-recaptcha-v3@1.10.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-helmet-async@2.0.5(react@18.3.1): + dependencies: + invariant: 2.2.4 + react: 18.3.1 + react-fast-compare: 3.2.2 + shallowequal: 1.1.0 + + react-i18next@14.1.3(i18next@23.12.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.25.0 + html-parse-stringify: 3.0.1 + i18next: 23.12.2 + react: 18.3.1 + optionalDependencies: + react-dom: 18.3.1(react@18.3.1) + + react-is@16.13.1: {} + + react-is@18.3.1: {} + + react-lazy-with-preload@2.2.1: {} + + react-refresh@0.14.2: {} + + react-router-dom@6.25.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@remix-run/router': 1.18.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 6.25.1(react@18.3.1) + + react-router@6.25.1(react@18.3.1): + dependencies: + '@remix-run/router': 1.18.0 + react: 18.3.1 + + react-sticky-el@2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-universal-interface@0.6.2(react@18.3.1)(tslib@2.6.3): + dependencies: + react: 18.3.1 + tslib: 2.6.3 + + react-use@17.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@types/js-cookie': 2.2.7 + '@xobotyi/scrollbar-width': 1.9.5 + copy-to-clipboard: 3.3.3 + fast-deep-equal: 3.1.3 + fast-shallow-equal: 1.0.0 + js-cookie: 2.2.1 + nano-css: 5.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-universal-interface: 0.6.2(react@18.3.1)(tslib@2.6.3) + resize-observer-polyfill: 1.5.1 + screenfull: 5.2.0 + set-harmonic-interval: 1.0.1 + throttle-debounce: 3.0.1 + ts-easing: 0.2.0 + tslib: 2.6.3 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + reflect.getprototypeof@1.0.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + which-builtin-type: 1.1.4 + + regenerate-unicode-properties@10.1.1: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.14.1: {} + + regenerator-transform@0.15.2: + dependencies: + '@babel/runtime': 7.25.0 + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + regexpu-core@5.3.2: + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + + regjsparser@0.9.1: + dependencies: + jsesc: 0.5.0 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + requires-port@1.0.0: {} + + resize-observer-polyfill@1.5.1: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.15.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup-plugin-visualizer@5.12.0(@rollup/wasm-node@4.20.0): + dependencies: + open: 8.4.2 + picomatch: 2.3.1 + source-map: 0.7.4 + yargs: 17.7.2 + optionalDependencies: + rollup: '@rollup/wasm-node@4.20.0' + + rrweb-cssom@0.6.0: {} + + rtl-css-js@1.16.1: + dependencies: + '@babel/runtime': 7.25.0 + + rtlcss@4.0.0: + dependencies: + escalade: 3.1.2 + picocolors: 1.0.1 + postcss: 8.4.40 + strip-json-comments: 3.1.1 + + rtlcss@4.1.1: + dependencies: + escalade: 3.1.2 + picocolors: 1.0.1 + postcss: 8.4.40 + strip-json-comments: 3.1.1 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.2.1: {} + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + safer-buffer@2.1.2: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + screenfull@5.2.0: {} + + semver@6.3.1: {} + + semver@7.6.3: {} + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + set-cookie-parser@2.7.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-harmonic-interval@1.0.1: {} + + shallowequal@1.1.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + slash@3.0.0: {} + + slugify@1.6.6: {} + + smob@1.5.0: {} + + source-map-js@1.2.0: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.5.6: {} + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + sourcemap-codec@1.4.8: {} + + stack-generator@2.0.10: + dependencies: + stackframe: 1.3.4 + + stackback@0.0.2: {} + + stackframe@1.3.4: {} + + stacktrace-gps@3.1.2: + dependencies: + source-map: 0.5.6 + stackframe: 1.3.4 + + stacktrace-js@2.0.2: + dependencies: + error-stack-parser: 2.1.4 + stack-generator: 2.0.10 + stacktrace-gps: 3.1.2 + + std-env@3.7.0: {} + + stop-iteration-iterator@1.0.0: + dependencies: + internal-slot: 1.0.7 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string.prototype.includes@2.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + + string.prototype.matchall@4.0.11: + 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 + 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 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + stringify-object@3.3.0: + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-bom@3.0.0: {} + + strip-comments@2.0.1: {} + + strip-final-newline@3.0.0: {} + + strip-json-comments@3.1.1: {} + + strip-literal@2.1.0: + dependencies: + js-tokens: 9.0.0 + + stylis@4.3.2: {} + + subsrt-ts@2.1.2: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + symbol-tree@3.2.4: {} + + synckit@0.9.1: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.3 + + tabbable@6.2.0: {} + + tailwind-scrollbar@3.1.0(tailwindcss@3.4.7): + dependencies: + tailwindcss: 3.4.7 + + tailwindcss-themer@4.0.0(tailwindcss@3.4.7): + dependencies: + color: 4.2.3 + just-unique: 4.2.0 + lodash.merge: 4.6.2 + lodash.mergewith: 4.6.2 + tailwindcss: 3.4.7 + + tailwindcss@3.4.7: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.7 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.1 + postcss: 8.4.40 + postcss-import: 15.1.0(postcss@8.4.40) + postcss-js: 4.0.1(postcss@8.4.40) + postcss-load-config: 4.0.2(postcss@8.4.40) + postcss-nested: 6.2.0(postcss@8.4.40) + postcss-selector-parser: 6.1.1 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + tapable@2.2.1: {} + + temp-dir@2.0.0: {} + + tempy@0.6.0: + dependencies: + is-stream: 2.0.1 + temp-dir: 2.0.0 + type-fest: 0.16.0 + unique-string: 2.0.0 + + terser@5.31.3: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.12.1 + commander: 2.20.3 + source-map-support: 0.5.21 + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + throttle-debounce@3.0.1: {} + + tiny-invariant@1.3.3: {} + + tinybench@2.8.0: {} + + tinypool@0.8.4: {} + + tinyspy@2.2.1: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toggle-selection@1.0.6: {} + + tough-cookie@4.1.4: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tr46@5.0.0: + dependencies: + punycode: 2.3.1 + + ts-api-utils@1.3.0(typescript@5.5.4): + dependencies: + typescript: 5.5.4 + + ts-easing@0.2.0: {} + + ts-interface-checker@0.1.13: {} + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.6.3: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.1.0: {} + + type-fest@0.16.0: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@4.23.0: {} + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typescript@4.9.5: {} + + typescript@5.5.4: {} + + ufo@1.5.4: {} + + uglify-js@3.19.1: + optional: true + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + undici-types@5.26.5: {} + + unicode-canonical-property-names-ecmascript@2.0.0: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + + unicode-match-property-value-ecmascript@2.1.0: {} + + unicode-property-aliases-ecmascript@2.1.0: {} + + unique-string@2.0.0: + dependencies: + crypto-random-string: 2.0.0 + + universalify@0.2.0: {} + + universalify@2.0.1: {} + + unpacker@1.0.1: {} + + unplugin@1.12.0: + dependencies: + acorn: 8.12.1 + chokidar: 3.6.0 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.6.2 + + upath@1.2.0: {} + + update-browserslist-db@1.1.0(browserslist@4.23.2): + dependencies: + browserslist: 4.23.2 + escalade: 3.1.2 + picocolors: 1.0.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + use-sync-external-store@1.2.0(react@18.3.1): + dependencies: + react: 18.3.1 + + util-deprecate@1.0.2: {} + + vite-node@1.6.0(@types/node@20.14.13)(terser@5.31.3): + dependencies: + cac: 6.7.14 + debug: 4.3.6 + pathe: 1.1.2 + picocolors: 1.0.1 + vite: 5.3.5(@types/node@20.14.13)(terser@5.31.3) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite-plugin-checker@0.6.4(eslint@8.57.0)(optionator@0.9.4)(typescript@5.5.4)(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3)): + dependencies: + '@babel/code-frame': 7.24.7 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + chokidar: 3.6.0 + commander: 8.3.0 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + npm-run-path: 4.0.1 + semver: 7.6.3 + strip-ansi: 6.0.1 + tiny-invariant: 1.3.3 + vite: 5.3.5(@types/node@20.14.13)(terser@5.31.3) + vscode-languageclient: 7.0.0 + vscode-languageserver: 7.0.0 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + optionalDependencies: + eslint: 8.57.0 + optionator: 0.9.4 + typescript: 5.5.4 + + vite-plugin-package-version@1.1.0(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3)): + dependencies: + vite: 5.3.5(@types/node@20.14.13)(terser@5.31.3) + + vite-plugin-pwa@0.17.5(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0): + dependencies: + debug: 4.3.6 + fast-glob: 3.3.2 + pretty-bytes: 6.1.1 + vite: 5.3.5(@types/node@20.14.13)(terser@5.31.3) + workbox-build: 7.1.1(@types/babel__core@7.20.5) + workbox-window: 7.1.0 + transitivePeerDependencies: + - supports-color + + vite-plugin-static-copy@1.0.6(vite@5.3.5(@types/node@20.14.13)(terser@5.31.3)): + dependencies: + chokidar: 3.6.0 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + picocolors: 1.0.1 + vite: 5.3.5(@types/node@20.14.13)(terser@5.31.3) + + vite@5.3.5(@types/node@20.14.13)(terser@5.31.3): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.40 + rollup: '@rollup/wasm-node@4.20.0' + optionalDependencies: + '@types/node': 20.14.13 + fsevents: 2.3.3 + terser: 5.31.3 + + vitest@1.6.0(@types/node@20.14.13)(jsdom@23.2.0)(terser@5.31.3): + dependencies: + '@vitest/expect': 1.6.0 + '@vitest/runner': 1.6.0 + '@vitest/snapshot': 1.6.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + acorn-walk: 8.3.3 + chai: 4.5.0 + debug: 4.3.6 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.11 + pathe: 1.1.2 + picocolors: 1.0.1 + std-env: 3.7.0 + strip-literal: 2.1.0 + tinybench: 2.8.0 + tinypool: 0.8.4 + vite: 5.3.5(@types/node@20.14.13)(terser@5.31.3) + vite-node: 1.6.0(@types/node@20.14.13)(terser@5.31.3) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.14.13 + jsdom: 23.2.0 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + void-elements@3.1.0: {} + + vscode-jsonrpc@6.0.0: {} + + vscode-languageclient@7.0.0: + dependencies: + minimatch: 3.1.2 + semver: 7.6.3 + vscode-languageserver-protocol: 3.16.0 + + vscode-languageserver-protocol@3.16.0: + dependencies: + vscode-jsonrpc: 6.0.0 + vscode-languageserver-types: 3.16.0 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.16.0: {} + + vscode-languageserver@7.0.0: + dependencies: + vscode-languageserver-protocol: 3.16.0 + + vscode-uri@3.0.8: {} + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@4.0.2: {} + + webidl-conversions@7.0.0: {} + + webpack-sources@3.2.3: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@14.0.0: + dependencies: + tr46: 5.0.0 + webidl-conversions: 7.0.0 + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-builtin-type@1.1.4: + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + workbox-background-sync@7.1.0: + dependencies: + idb: 7.1.1 + workbox-core: 7.1.0 + + workbox-broadcast-update@7.1.0: + dependencies: + workbox-core: 7.1.0 + + workbox-build@7.1.1(@types/babel__core@7.20.5): + dependencies: + '@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1) + '@babel/core': 7.25.2 + '@babel/preset-env': 7.25.3(@babel/core@7.25.2) + '@babel/runtime': 7.25.0 + '@rollup/plugin-babel': 5.3.1(@babel/core@7.25.2)(@rollup/wasm-node@4.20.0)(@types/babel__core@7.20.5) + '@rollup/plugin-node-resolve': 15.2.3(@rollup/wasm-node@4.20.0) + '@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.20.0) + '@rollup/plugin-terser': 0.4.4(@rollup/wasm-node@4.20.0) + '@surma/rollup-plugin-off-main-thread': 2.2.3 + ajv: 8.17.1 + common-tags: 1.8.2 + fast-json-stable-stringify: 2.1.0 + fs-extra: 9.1.0 + glob: 7.2.3 + lodash: 4.17.21 + pretty-bytes: 5.6.0 + rollup: '@rollup/wasm-node@4.20.0' + source-map: 0.8.0-beta.0 + stringify-object: 3.3.0 + strip-comments: 2.0.1 + tempy: 0.6.0 + upath: 1.2.0 + workbox-background-sync: 7.1.0 + workbox-broadcast-update: 7.1.0 + workbox-cacheable-response: 7.1.0 + workbox-core: 7.1.0 + workbox-expiration: 7.1.0 + workbox-google-analytics: 7.1.0 + workbox-navigation-preload: 7.1.0 + workbox-precaching: 7.1.0 + workbox-range-requests: 7.1.0 + workbox-recipes: 7.1.0 + workbox-routing: 7.1.0 + workbox-strategies: 7.1.0 + workbox-streams: 7.1.0 + workbox-sw: 7.1.0 + workbox-window: 7.1.0 + transitivePeerDependencies: + - '@types/babel__core' + - supports-color + + workbox-cacheable-response@7.1.0: + dependencies: + workbox-core: 7.1.0 + + workbox-core@7.1.0: {} + + workbox-expiration@7.1.0: + dependencies: + idb: 7.1.1 + workbox-core: 7.1.0 + + workbox-google-analytics@7.1.0: + dependencies: + workbox-background-sync: 7.1.0 + workbox-core: 7.1.0 + workbox-routing: 7.1.0 + workbox-strategies: 7.1.0 + + workbox-navigation-preload@7.1.0: + dependencies: + workbox-core: 7.1.0 + + workbox-precaching@7.1.0: + dependencies: + workbox-core: 7.1.0 + workbox-routing: 7.1.0 + workbox-strategies: 7.1.0 + + workbox-range-requests@7.1.0: + dependencies: + workbox-core: 7.1.0 + + workbox-recipes@7.1.0: + dependencies: + workbox-cacheable-response: 7.1.0 + workbox-core: 7.1.0 + workbox-expiration: 7.1.0 + workbox-precaching: 7.1.0 + workbox-routing: 7.1.0 + workbox-strategies: 7.1.0 + + workbox-routing@7.1.0: + dependencies: + workbox-core: 7.1.0 + + workbox-strategies@7.1.0: + dependencies: + workbox-core: 7.1.0 + + workbox-streams@7.1.0: + dependencies: + workbox-core: 7.1.0 + workbox-routing: 7.1.0 + + workbox-sw@7.1.0: {} + + workbox-window@7.1.0: + dependencies: + '@types/trusted-types': 2.0.7 + workbox-core: 7.1.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + ws@8.18.0: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yaml@2.5.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + yocto-queue@1.1.1: {} + + zustand@4.5.4(@types/react@18.3.3)(immer@10.1.1)(react@18.3.1): + dependencies: + use-sync-external-store: 1.2.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + immer: 10.1.1 + react: 18.3.1 diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/prettierrc.js b/prettierrc.js new file mode 100644 index 0000000..0af34d8 --- /dev/null +++ b/prettierrc.js @@ -0,0 +1,4 @@ +module.exports = { + trailingComma: "all", + singleQuote: true +}; diff --git a/public/_headers b/public/_headers new file mode 100644 index 0000000..0f4e3f2 --- /dev/null +++ b/public/_headers @@ -0,0 +1,13 @@ +/* + X-Frame-Options: DENY + X-XSS-Protection: 1; mode=block + X-Content-Type-Options: nosniff + Referrer-Policy: origin-when-cross-origin + Cache-Control: public, max-age=0, s-maxage=0, must-revalidate + +/manifest.webmanifest + Content-Type: application/manifest+json + +# assets get a long cache instead of no cache +/assets/* + Cache-Control: public, max-age=31536000, s-maxage=31536000, immutable diff --git a/public/_redirects b/public/_redirects new file mode 100644 index 0000000..ee9870c --- /dev/null +++ b/public/_redirects @@ -0,0 +1,2 @@ +/assets/* /assets/:splat 200 +/* /index.html 200 diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..fbf5448 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..c8c1abb Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..cb59056 Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/browserconfig.xml b/public/browserconfig.xml new file mode 100644 index 0000000..1252a42 --- /dev/null +++ b/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #120f1d + + + diff --git a/public/cat.svg b/public/cat.svg new file mode 100644 index 0000000..797cd75 --- /dev/null +++ b/public/cat.svg @@ -0,0 +1,94 @@ + + + + + + \ No newline at end of file diff --git a/public/config.js b/public/config.js new file mode 100644 index 0000000..793f63c --- /dev/null +++ b/public/config.js @@ -0,0 +1,20 @@ +window.__CONFIG__ = { + // The URL for the CORS proxy, the URL must NOT end with a slash! + // If not specified, the onboarding will not allow a "default setup". The user will have to use the extension or set up a proxy themselves + VITE_CORS_PROXY_URL: "", + + // The READ API key to access TMDB + VITE_TMDB_READ_API_KEY: "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI1NzlkZWYyZDY5ZWFlNDk4ZjJiOTI4MTgyNDdjM2ViMCIsInN1YiI6IjY2MjdmMGJlNjJmMzM1MDE0YmQ4NTFmMiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.h3KpPvkiaz8uNz1bntAKqsPrxG_4UUWaY3kYME6N6m8", + + // The DMCA email displayed in the footer, null to hide the DMCA link + VITE_DMCA_EMAIL: null, + + // Whether to disable hash-based routing, leave this as false if you don't know what this is + VITE_NORMAL_ROUTER: true, + + // The backend URL to communicate with + VITE_BACKEND_URL: null, + + // A comma separated list of disallowed IDs in the case of a DMCA claim - in the format "series-" and "movie-" + VITE_DISALLOWED_IDS: "" +}; diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..56d0a43 Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..ef644cb Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..b48e070 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/flags/965055-middle-removebg-preview.png b/public/flags/965055-middle-removebg-preview.png new file mode 100644 index 0000000..270eae1 Binary files /dev/null and b/public/flags/965055-middle-removebg-preview.png differ diff --git a/public/flags/cat.png b/public/flags/cat.png new file mode 100644 index 0000000..2177ab3 Binary files /dev/null and b/public/flags/cat.png differ diff --git a/public/flags/galicia.svg b/public/flags/galicia.svg new file mode 100644 index 0000000..2eb2795 --- /dev/null +++ b/public/flags/galicia.svg @@ -0,0 +1,199 @@ + + + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/flags/skull.svg b/public/flags/skull.svg new file mode 100644 index 0000000..b71d596 --- /dev/null +++ b/public/flags/skull.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/flags/tokiPona.svg b/public/flags/tokiPona.svg new file mode 100644 index 0000000..89d9584 --- /dev/null +++ b/public/flags/tokiPona.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/flags/uwu.png b/public/flags/uwu.png new file mode 100644 index 0000000..a782ab9 Binary files /dev/null and b/public/flags/uwu.png differ diff --git a/public/lightbar-images/auto-gun.png b/public/lightbar-images/auto-gun.png new file mode 100644 index 0000000..e48d5d3 Binary files /dev/null and b/public/lightbar-images/auto-gun.png differ diff --git a/public/lightbar-images/barn.png b/public/lightbar-images/barn.png new file mode 100644 index 0000000..e196c77 Binary files /dev/null and b/public/lightbar-images/barn.png differ diff --git a/public/lightbar-images/beer-bottle.png b/public/lightbar-images/beer-bottle.png new file mode 100644 index 0000000..99e30ac Binary files /dev/null and b/public/lightbar-images/beer-bottle.png differ diff --git a/public/lightbar-images/beer.png b/public/lightbar-images/beer.png new file mode 100644 index 0000000..265a7f3 Binary files /dev/null and b/public/lightbar-images/beer.png differ diff --git a/public/lightbar-images/camera.png b/public/lightbar-images/camera.png new file mode 100644 index 0000000..8576232 Binary files /dev/null and b/public/lightbar-images/camera.png differ diff --git a/public/lightbar-images/cat.png b/public/lightbar-images/cat.png new file mode 100644 index 0000000..b34c317 Binary files /dev/null and b/public/lightbar-images/cat.png differ diff --git a/public/lightbar-images/cigarette.png b/public/lightbar-images/cigarette.png new file mode 100644 index 0000000..cf68b37 Binary files /dev/null and b/public/lightbar-images/cigarette.png differ diff --git a/public/lightbar-images/cigarette2.png b/public/lightbar-images/cigarette2.png new file mode 100644 index 0000000..7985698 Binary files /dev/null and b/public/lightbar-images/cigarette2.png differ diff --git a/public/lightbar-images/cock.png b/public/lightbar-images/cock.png new file mode 100644 index 0000000..b83e0e7 Binary files /dev/null and b/public/lightbar-images/cock.png differ diff --git a/public/lightbar-images/coin.png b/public/lightbar-images/coin.png new file mode 100644 index 0000000..4d8af27 Binary files /dev/null and b/public/lightbar-images/coin.png differ diff --git a/public/lightbar-images/dice.svg b/public/lightbar-images/dice.svg new file mode 100644 index 0000000..5cc0b90 --- /dev/null +++ b/public/lightbar-images/dice.svg @@ -0,0 +1 @@ + diff --git a/public/lightbar-images/egg.png b/public/lightbar-images/egg.png new file mode 100644 index 0000000..cc83376 Binary files /dev/null and b/public/lightbar-images/egg.png differ diff --git a/public/lightbar-images/fishie.png b/public/lightbar-images/fishie.png new file mode 100644 index 0000000..8c528ba Binary files /dev/null and b/public/lightbar-images/fishie.png differ diff --git a/public/lightbar-images/ghost.png b/public/lightbar-images/ghost.png new file mode 100644 index 0000000..6881e89 Binary files /dev/null and b/public/lightbar-images/ghost.png differ diff --git a/public/lightbar-images/git.png b/public/lightbar-images/git.png new file mode 100644 index 0000000..c02a064 Binary files /dev/null and b/public/lightbar-images/git.png differ diff --git a/public/lightbar-images/gun.png b/public/lightbar-images/gun.png new file mode 100644 index 0000000..b1f078a Binary files /dev/null and b/public/lightbar-images/gun.png differ diff --git a/public/lightbar-images/heart.svg b/public/lightbar-images/heart.svg new file mode 100644 index 0000000..92e55b4 --- /dev/null +++ b/public/lightbar-images/heart.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/lightbar-images/money-sack.png b/public/lightbar-images/money-sack.png new file mode 100644 index 0000000..56c0337 Binary files /dev/null and b/public/lightbar-images/money-sack.png differ diff --git a/public/lightbar-images/money.png b/public/lightbar-images/money.png new file mode 100644 index 0000000..889fc34 Binary files /dev/null and b/public/lightbar-images/money.png differ diff --git a/public/lightbar-images/popcorn.png b/public/lightbar-images/popcorn.png new file mode 100644 index 0000000..a2f918e Binary files /dev/null and b/public/lightbar-images/popcorn.png differ diff --git a/public/lightbar-images/pumpkin.png b/public/lightbar-images/pumpkin.png new file mode 100644 index 0000000..94efa63 Binary files /dev/null and b/public/lightbar-images/pumpkin.png differ diff --git a/public/lightbar-images/santa.png b/public/lightbar-images/santa.png new file mode 100644 index 0000000..91525e2 Binary files /dev/null and b/public/lightbar-images/santa.png differ diff --git a/public/lightbar-images/shark.png b/public/lightbar-images/shark.png new file mode 100644 index 0000000..4840f57 Binary files /dev/null and b/public/lightbar-images/shark.png differ diff --git a/public/lightbar-images/ship.png b/public/lightbar-images/ship.png new file mode 100644 index 0000000..cf5d4dd Binary files /dev/null and b/public/lightbar-images/ship.png differ diff --git a/public/lightbar-images/skull.png b/public/lightbar-images/skull.png new file mode 100644 index 0000000..bfbdd23 Binary files /dev/null and b/public/lightbar-images/skull.png differ diff --git a/public/lightbar-images/snowflake.svg b/public/lightbar-images/snowflake.svg new file mode 100644 index 0000000..8b928e1 --- /dev/null +++ b/public/lightbar-images/snowflake.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/lightbar-images/star.png b/public/lightbar-images/star.png new file mode 100644 index 0000000..58da335 Binary files /dev/null and b/public/lightbar-images/star.png differ diff --git a/public/lightbar-images/ts.png b/public/lightbar-images/ts.png new file mode 100644 index 0000000..b27b1c7 Binary files /dev/null and b/public/lightbar-images/ts.png differ diff --git a/public/lightbar-images/turkey.png b/public/lightbar-images/turkey.png new file mode 100644 index 0000000..a8e1cc7 Binary files /dev/null and b/public/lightbar-images/turkey.png differ diff --git a/public/lightbar-images/weed.png b/public/lightbar-images/weed.png new file mode 100644 index 0000000..c85fbe1 Binary files /dev/null and b/public/lightbar-images/weed.png differ diff --git a/public/lightbar-images/wine.png b/public/lightbar-images/wine.png new file mode 100644 index 0000000..921f8ed Binary files /dev/null and b/public/lightbar-images/wine.png differ diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png new file mode 100644 index 0000000..e90933d Binary files /dev/null and b/public/mstile-150x150.png differ diff --git a/public/ping.txt b/public/ping.txt new file mode 100644 index 0000000..8e55469 --- /dev/null +++ b/public/ping.txt @@ -0,0 +1 @@ +pong diff --git a/public/placeholder.png b/public/placeholder.png new file mode 100644 index 0000000..8d00379 Binary files /dev/null and b/public/placeholder.png differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg new file mode 100644 index 0000000..c49ba8e --- /dev/null +++ b/public/safari-pinned-tab.svg @@ -0,0 +1 @@ +Created by potrace 1.14, written by Peter Selinger 2001-2017 \ No newline at end of file diff --git a/public/splash_screens/10.2__iPad_landscape.png b/public/splash_screens/10.2__iPad_landscape.png new file mode 100644 index 0000000..e5bd744 Binary files /dev/null and b/public/splash_screens/10.2__iPad_landscape.png differ diff --git a/public/splash_screens/10.2__iPad_portrait.png b/public/splash_screens/10.2__iPad_portrait.png new file mode 100644 index 0000000..b2a6e24 Binary files /dev/null and b/public/splash_screens/10.2__iPad_portrait.png differ diff --git a/public/splash_screens/10.5__iPad_Air_landscape.png b/public/splash_screens/10.5__iPad_Air_landscape.png new file mode 100644 index 0000000..929cef7 Binary files /dev/null and b/public/splash_screens/10.5__iPad_Air_landscape.png differ diff --git a/public/splash_screens/10.5__iPad_Air_portrait.png b/public/splash_screens/10.5__iPad_Air_portrait.png new file mode 100644 index 0000000..5812a33 Binary files /dev/null and b/public/splash_screens/10.5__iPad_Air_portrait.png differ diff --git a/public/splash_screens/10.9__iPad_Air_landscape.png b/public/splash_screens/10.9__iPad_Air_landscape.png new file mode 100644 index 0000000..b63e8ef Binary files /dev/null and b/public/splash_screens/10.9__iPad_Air_landscape.png differ diff --git a/public/splash_screens/10.9__iPad_Air_portrait.png b/public/splash_screens/10.9__iPad_Air_portrait.png new file mode 100644 index 0000000..2603d66 Binary files /dev/null and b/public/splash_screens/10.9__iPad_Air_portrait.png differ diff --git a/public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_landscape.png b/public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_landscape.png new file mode 100644 index 0000000..a4bee69 Binary files /dev/null and b/public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_landscape.png differ diff --git a/public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_portrait.png b/public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_portrait.png new file mode 100644 index 0000000..431c4e5 Binary files /dev/null and b/public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_portrait.png differ diff --git a/public/splash_screens/12.9__iPad_Pro_landscape.png b/public/splash_screens/12.9__iPad_Pro_landscape.png new file mode 100644 index 0000000..5f4e1fc Binary files /dev/null and b/public/splash_screens/12.9__iPad_Pro_landscape.png differ diff --git a/public/splash_screens/12.9__iPad_Pro_portrait.png b/public/splash_screens/12.9__iPad_Pro_portrait.png new file mode 100644 index 0000000..d850c75 Binary files /dev/null and b/public/splash_screens/12.9__iPad_Pro_portrait.png differ diff --git a/public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_landscape.png b/public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_landscape.png new file mode 100644 index 0000000..c7f80d1 Binary files /dev/null and b/public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_landscape.png differ diff --git a/public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_portrait.png b/public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_portrait.png new file mode 100644 index 0000000..a462a30 Binary files /dev/null and b/public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_portrait.png differ diff --git a/public/splash_screens/8.3__iPad_Mini_landscape.png b/public/splash_screens/8.3__iPad_Mini_landscape.png new file mode 100644 index 0000000..5a9a9b5 Binary files /dev/null and b/public/splash_screens/8.3__iPad_Mini_landscape.png differ diff --git a/public/splash_screens/8.3__iPad_Mini_portrait.png b/public/splash_screens/8.3__iPad_Mini_portrait.png new file mode 100644 index 0000000..18e1d65 Binary files /dev/null and b/public/splash_screens/8.3__iPad_Mini_portrait.png differ diff --git a/public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_landscape.png b/public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_landscape.png new file mode 100644 index 0000000..74a1b83 Binary files /dev/null and b/public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_landscape.png differ diff --git a/public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png b/public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png new file mode 100644 index 0000000..dfaa211 Binary files /dev/null and b/public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png differ diff --git a/public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_landscape.png b/public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_landscape.png new file mode 100644 index 0000000..2306b97 Binary files /dev/null and b/public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_landscape.png differ diff --git a/public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_portrait.png b/public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_portrait.png new file mode 100644 index 0000000..c409b3a Binary files /dev/null and b/public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_portrait.png differ diff --git a/public/splash_screens/iPhone_11__iPhone_XR_landscape.png b/public/splash_screens/iPhone_11__iPhone_XR_landscape.png new file mode 100644 index 0000000..11a5087 Binary files /dev/null and b/public/splash_screens/iPhone_11__iPhone_XR_landscape.png differ diff --git a/public/splash_screens/iPhone_11__iPhone_XR_portrait.png b/public/splash_screens/iPhone_11__iPhone_XR_portrait.png new file mode 100644 index 0000000..1922ce3 Binary files /dev/null and b/public/splash_screens/iPhone_11__iPhone_XR_portrait.png differ diff --git a/public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_landscape.png b/public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_landscape.png new file mode 100644 index 0000000..c5bcab4 Binary files /dev/null and b/public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_landscape.png differ diff --git a/public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_portrait.png b/public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_portrait.png new file mode 100644 index 0000000..64cbbee Binary files /dev/null and b/public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_portrait.png differ diff --git a/public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_landscape.png b/public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_landscape.png new file mode 100644 index 0000000..fe273cb Binary files /dev/null and b/public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_landscape.png differ diff --git a/public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_portrait.png b/public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_portrait.png new file mode 100644 index 0000000..d37f3f8 Binary files /dev/null and b/public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_portrait.png differ diff --git a/public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_landscape.png b/public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_landscape.png new file mode 100644 index 0000000..f1b91ac Binary files /dev/null and b/public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_landscape.png differ diff --git a/public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_portrait.png b/public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_portrait.png new file mode 100644 index 0000000..c05ea1b Binary files /dev/null and b/public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_portrait.png differ diff --git a/public/splash_screens/iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_landscape.png b/public/splash_screens/iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_landscape.png new file mode 100644 index 0000000..f92c7c7 Binary files /dev/null and b/public/splash_screens/iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_landscape.png differ diff --git a/public/splash_screens/iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_portrait.png b/public/splash_screens/iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_portrait.png new file mode 100644 index 0000000..2ef4a32 Binary files /dev/null and b/public/splash_screens/iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_portrait.png differ diff --git a/public/splash_screens/iPhone_15_Pro__iPhone_15__iPhone_14_Pro_landscape.png b/public/splash_screens/iPhone_15_Pro__iPhone_15__iPhone_14_Pro_landscape.png new file mode 100644 index 0000000..1414d77 Binary files /dev/null and b/public/splash_screens/iPhone_15_Pro__iPhone_15__iPhone_14_Pro_landscape.png differ diff --git a/public/splash_screens/iPhone_15_Pro__iPhone_15__iPhone_14_Pro_portrait.png b/public/splash_screens/iPhone_15_Pro__iPhone_15__iPhone_14_Pro_portrait.png new file mode 100644 index 0000000..b6d5f12 Binary files /dev/null and b/public/splash_screens/iPhone_15_Pro__iPhone_15__iPhone_14_Pro_portrait.png differ diff --git a/public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_landscape.png b/public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_landscape.png new file mode 100644 index 0000000..a3d3574 Binary files /dev/null and b/public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_landscape.png differ diff --git a/public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_portrait.png b/public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_portrait.png new file mode 100644 index 0000000..44d9d9a Binary files /dev/null and b/public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_portrait.png differ diff --git a/public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_landscape.png b/public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_landscape.png new file mode 100644 index 0000000..fba250c Binary files /dev/null and b/public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_landscape.png differ diff --git a/public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_portrait.png b/public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_portrait.png new file mode 100644 index 0000000..06b99ac Binary files /dev/null and b/public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_portrait.png differ diff --git a/public/splash_screens/icon.png b/public/splash_screens/icon.png new file mode 100644 index 0000000..7ff85ce Binary files /dev/null and b/public/splash_screens/icon.png differ diff --git a/public/splash_screens/icon144x144.png b/public/splash_screens/icon144x144.png new file mode 100644 index 0000000..fae66d7 Binary files /dev/null and b/public/splash_screens/icon144x144.png differ diff --git a/src/@types/country-language.d.ts b/src/@types/country-language.d.ts new file mode 100644 index 0000000..c0badd7 --- /dev/null +++ b/src/@types/country-language.d.ts @@ -0,0 +1,21 @@ +declare module "@ladjs/country-language" { + export interface LanguageObj { + countries: Array<{ + code_2: string; + code_3: string; + numCode: string; + }>; + direction: "RTL" | "LTR"; + name: string[]; + nativeName: string[]; + iso639_1: string; + } + + type Callback = (err: null | string, result: null | T) => void; + + declare namespace lib { + function getLanguage(locale: string, cb: Callback): void; + } + + export = lib; +} diff --git a/src/assets/README.md b/src/assets/README.md new file mode 100644 index 0000000..bfb7d17 --- /dev/null +++ b/src/assets/README.md @@ -0,0 +1,9 @@ +# About the languages + +Locales are difficult, here is some guidance. + +## Process on adding new languages +1. Use [Weblate](https://docs.undi.rest/links/weblate) to add translations, see contributing guidelines. +2. Add your language to `@/assets/languages.ts`. Must be in ISO format (ISO-639 for language and ISO-3166 for country/region). For joke languages, use any format. +3. If the language code doesn't have a region specified (Such as in `pt-BR`, `BR` being the region), add a default region in `@/utils/language.ts` at `defaultLanguageCodes` +4. If the language code doesn't contain a region (Such as in `zh-Hant`), add a default country in `@/utils/language.ts` at `countryPriority`. diff --git a/src/assets/css/index.css b/src/assets/css/index.css new file mode 100644 index 0000000..092499b --- /dev/null +++ b/src/assets/css/index.css @@ -0,0 +1,234 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +html, +body { + @apply bg-background-main font-main text-type-text; + min-height: 100vh; + min-height: 100dvh; + font-size: 1.0248em; +} + +html[data-full], +html[data-full] body { + overscroll-behavior-y: none; +} + +body[data-no-scroll] { + overflow-y: hidden; + height: 100vh; +} + +#root { + padding: 0.05px; + min-height: 100vh; + min-height: 100dvh; + width: 100%; +} + +body[data-no-select] { + user-select: none; +} + +html[data-no-scroll], html[data-no-scroll] body { + overflow: hidden; +} + +.roll { + animation: roll 1s; +} + +.roll-infinite { + animation: roll 2s infinite; +} + +@keyframes roll { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +.line-clamp { + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.google-cast-button:not(.casting) google-cast-launcher { + @apply brightness-[500]; +} + +.is-mobile-view .overflow-y-auto { + height: 60vh; +} + +.h-screen { + height: 100vh; + height: 100dvh; +} + +.min-h-screen { + min-height: 100vh; + min-height: 100dvh; +} + +/*generated with Input range slider CSS style generator (version 20211225) +https://toughengineer.github.io/demo/slider-styler*/ +:root { + --slider-height: 0.25rem; + --slider-border-radius: 1em; + --slider-progress-background: #8652bb; +} + +input[type=range].styled-slider { + height: var(--slider-height); + -webkit-appearance: none; + appearance: none; + border-radius: var(--slider-border-radius); + background: #1C161B; +} + +/*progress support*/ +input[type=range].styled-slider.slider-progress { + --range: calc(var(--max) - var(--min)); + --ratio: calc((var(--value) - var(--min)) / var(--range)); + --sx: calc(0.5 * 1rem + var(--ratio) * (100% - 1rem)); +} + +/*webkit*/ +input[type=range].styled-slider::-webkit-slider-thumb { + -webkit-appearance: none; + width: 1rem; + height: 1rem; + border-radius: var(--slider-border-radius); + background: #FFFFFF; + border: none; + box-shadow: 0 0 2px #000000; + margin-top: calc(0.25em * 0.5 - 1rem * 0.5); +} + +input[type=range].styled-slider::-webkit-slider-runnable-track { + height: var(--slider-height); + border: none; + box-shadow: none; + border-radius: var(--slider-border-radius); +} + +input[type=range].styled-slider::-webkit-slider-thumb:hover { + background: #DCDCDC; +} + +input[type=range].styled-slider.slider-progress::-webkit-slider-runnable-track { + background: linear-gradient(var(--slider-progress-background), var(--slider-progress-background)) 0/var(--sx) 100% no-repeat, #1C161B; +} + +/*mozilla*/ +input[type=range].styled-slider::-moz-range-thumb { + width: 1rem; + height: 1rem; + border-radius: var(--slider-border-radius); + background: #FFFFFF; + border: none; + box-shadow: 0 0 2px #000000; +} + +input[type=range].styled-slider::-moz-range-track { + height: var(--slider-height); + border: none; + border-radius: var(--slider-border-radius); + background: #1C161B; + box-shadow: none; +} + +input[type=range].styled-slider::-moz-range-thumb:hover { + background: #DCDCDC; +} + +input[type=range].styled-slider.slider-progress::-moz-range-track { + background: linear-gradient(var(--slider-progress-background), var(--slider-progress-background)) 0/var(--sx) 100% no-repeat, #1C161B; +} + +/*ms*/ +input[type=range].styled-slider::-ms-fill-upper { + background: transparent; + border-color: transparent; +} + +input[type=range].styled-slider::-ms-fill-lower { + background: transparent; + border-color: transparent; +} + +input[type=range].styled-slider::-ms-thumb { + width: 1rem; + height: 1rem; + border-radius: var(--slider-border-radius); + background: #FFFFFF; + border: none; + box-shadow: 0 0 2px #000000; + margin-top: 0; + box-sizing: border-box; +} + +input[type=range].styled-slider::-ms-track { + height: var(--slider-height); + border-radius: var(--slider-border-radius); + background: #1C161B; + border: none; + box-shadow: none; + box-sizing: border-box; +} + +input[type=range].styled-slider::-ms-thumb:hover { + background: #DCDCDC; +} + +input[type=range].styled-slider.slider-progress::-ms-fill-lower { + height: var(--slider-height); + border-radius: var(--slider-border-radius) 0 0 5px; + margin: -undefined 0 -undefined -undefined; + background: var(--slider-progress-background); + border: none; + border-right-width: 0; +} + +::-webkit-scrollbar-track { + background-color: transparent; +} + +::-webkit-scrollbar-thumb { + background-color: theme("colors.video.context.border"); + border: 5px solid transparent; + border-left: 0; + background-clip: content-box; +} + +::-webkit-scrollbar { + /* For some reason the styles don't get applied without the width */ + width: 13px; +} + +.grecaptcha-badge { + display: none !important; +} + +.tabbable:focus-visible { + outline: 2px solid theme('colors.themePreview.primary'); + box-shadow: 0 0 10px theme('colors.themePreview.secondary'); +} + +[dir="rtl"] .transform { + /* Invert horizontal X offset on transform (Tailwind RTL plugin does the rest) */ + transform: translate(calc(var(--tw-translate-x) * -1), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important; +} +[dir="ltr"] .transform { + /* default - otherwise it overwrites*/ + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important; +} diff --git a/src/assets/languages.ts b/src/assets/languages.ts new file mode 100644 index 0000000..e212bc2 --- /dev/null +++ b/src/assets/languages.ts @@ -0,0 +1,101 @@ +import ar from "@/assets/locales/ar.json"; +import bg from "@/assets/locales/bg.json"; +import bn from "@/assets/locales/bn.json"; +import ca from "@/assets/locales/ca.json"; +import caVl from "@/assets/locales/ca@valencia.json"; +import cs from "@/assets/locales/cs.json"; +import da from "@/assets/locales/da.json"; +import de from "@/assets/locales/de.json"; +import el from "@/assets/locales/el.json"; +import en from "@/assets/locales/en.json"; +import es from "@/assets/locales/es.json"; +import et from "@/assets/locales/et.json"; +import fa from "@/assets/locales/fa.json"; +import fi from "@/assets/locales/fi-FI.json"; +import fr from "@/assets/locales/fr.json"; +import gl from "@/assets/locales/gl.json"; +import gu from "@/assets/locales/gu.json"; +import he from "@/assets/locales/he.json"; +import hi from "@/assets/locales/hi.json"; +import id from "@/assets/locales/id.json"; +import is from "@/assets/locales/is-IS.json"; +import it from "@/assets/locales/it.json"; +import ja from "@/assets/locales/ja.json"; +import kitty from "@/assets/locales/kitty.json"; +import ko from "@/assets/locales/ko.json"; +import lv from "@/assets/locales/lv.json"; +import minion from "@/assets/locales/minion.json"; +import ne from "@/assets/locales/ne.json"; +import nl from "@/assets/locales/nl.json"; +import nv from "@/assets/locales/nv.json"; +import pa from "@/assets/locales/pa.json"; +import pirate from "@/assets/locales/pirate.json"; +import pl from "@/assets/locales/pl.json"; +import ptbr from "@/assets/locales/pt-BR.json"; +import ptpt from "@/assets/locales/pt-PT.json"; +import ro from "@/assets/locales/ro.json"; +import ru from "@/assets/locales/ru.json"; +import sl from "@/assets/locales/sl.json"; +import sv from "@/assets/locales/sv.json"; +import ta from "@/assets/locales/ta.json"; +import th from "@/assets/locales/th.json"; +import tok from "@/assets/locales/tok.json"; +import tr from "@/assets/locales/tr.json"; +import uk from "@/assets/locales/uk.json"; +import uwu from "@/assets/locales/uwu.json"; +import vi from "@/assets/locales/vi.json"; +import zhhant from "@/assets/locales/zh-Hant.json"; +import zh from "@/assets/locales/zh.json"; + +export const locales = { + en, + ca, + "ca-ES": caVl, + cs, + da, + de, + fr, + it, + nl, + pl, + tr, + vi, + zh, + he, + sv, + pirate, + kitty, + uwu, + minion, + lv, + th, + ne, + ar, + es, + et, + tok, + hi, + "pt-BR": ptbr, + "pt-PT": ptpt, + uk, + bg, + bn, + el, + fa, + gu, + id, + ja, + ko, + sl, + ta, + "zh-Hant": zhhant, + is, + ru, + gl, + pa, + ro, + fi, + nv, +}; + +export type Locales = keyof typeof locales; diff --git a/src/assets/locales/7358455941559356193.mp3 b/src/assets/locales/7358455941559356193.mp3 new file mode 100644 index 0000000..6a13869 Binary files /dev/null and b/src/assets/locales/7358455941559356193.mp3 differ diff --git a/src/assets/locales/ar.json b/src/assets/locales/ar.json new file mode 100644 index 0000000..9fe5737 --- /dev/null +++ b/src/assets/locales/ar.json @@ -0,0 +1,537 @@ +{ + "about": { + "description": "SkoolTV هو تطبيق ويب يبحث في الإنترنت عن بثوث. يهدف الفريق إلى تبني نهج معظمه بسيط في استهلاك المحتوى.", + "faqTitle": "الأسئلة الشائعة", + "q1": { + "body": "لا يستضيف SkoolTV أي محتوى. عندما تنقر فوق شيء للمشاهدة، يتم البحث على الإنترنت عن الوسائط المحددة (يمكنك رؤية المصدر الذي تستخدمه على شاشة التحميل وفي علامة تبويب \"مصادر الفيديو\"). لا يتم رفع الوسائط أبدًا عن طريق SkoolTV، كل شيء يتم من خلال آلية البحث هذه.", + "title": "من أين يأتي المحتوى؟" + }, + "q2": { + "body": "لا يمكن طلب عرض أو فيلم، لأن SkoolTV لا يدير أي محتوى. يتم مشاهدة جميع المحتويات من خلال مصادر على الإنترنت.", + "title": "أين يمكنني طلب مسلسل أو فلم؟" + }, + "q3": { + "body": "نتائج البحث لدينا مدعومة بقاعدة بيانات الأفلام (TMDB) وتظهر بغض النظر عما إذا كانت مصادرنا تتضمن فعليًا المحتوى أم لا.", + "title": "تعرِضُ نتائجُ البحثِ الخاصِّ بالعرض أو الفيلم اللذي أريد، لكن لماذا لا يمكنني تشغيله؟" + }, + "title": "حول SkoolTV" + }, + "actions": { + "copied": "تم النسخ", + "copy": "نسخ" + }, + "auth": { + "createAccount": "ليس لديك حساب بعد؟ <0>أنشئ حسابًا.", + "deviceNameLabel": "اسم الجهاز", + "deviceNamePlaceholder": "الهاتف الشخصي", + "generate": { + "description": "جملة مروركَ هي بمثابة اسم مستخدمٍ وكلمة مرورٍ. تأكد من حفظها بشكل آمن، ستحتاجها لتسجيل الدخول إلى حسابك", + "next": "لقد قمتُ بحفظ جملة مروري", + "passphraseFrameLabel": "جملة المرور", + "title": "جملة مرورك" + }, + "hasAccount": "لديك حساب بالفعل؟ <0>قم بتسجيل الدخول هنا.", + "login": { + "description": "رجاءً جملة المرور لتسجيل الدخول إلى حسابك", + "deviceLengthError": "رجاءً أدخل اسم جهاز", + "passphraseLabel": "جملة مرور من 12 كلمة", + "passphrasePlaceholder": "جملة مرور", + "submit": "تسجيل الدخول", + "title": "تسجيل الدخول إلى حسابك", + "validationError": "جملة المرور خاطئة أو ناقصة" + }, + "register": { + "information": { + "color1": "لون الملف الشخصي الأول", + "color2": "لون الملف الشخصي الثاني", + "header": "أدخل اسمًا لجهازك واختر ألوانًا وأيقونة مستخدم حسب اختيارك", + "icon": "أيقونة المستخدم", + "next": "التالي", + "title": "معلومات الحساب" + } + }, + "trust": { + "failed": { + "text": "هل قمت بضبطه بشكل صحيح؟", + "title": "تعَذَّر الوصول إلى الخادم" + }, + "host": "أنت على وشك الاتصال بـ <0>{{hostname}} - يرجى تأكيد أنك تثق فيه قبل إنشاء حساب", + "no": "عودة", + "title": "هل تثِقُ في هذا الخادم؟", + "yes": "أثِقُ في هذا الخادم" + }, + "verify": { + "description": "رجاءً أدخل جملة المرور السابقة لتأكيد أنك قد قمت بحفظها ولإنشاء حسابك", + "invalidData": "البيانات غير صالحة", + "noMatch": "جملة المرور غير متطابقة", + "passphraseLabel": "جملة مرورك المكونة من 12 كلمة", + "recaptchaFailed": "فشل التحقق من ReCaptcha", + "register": "إنشاء حساب", + "title": "قم بتأكيد جملة مرورك" + } + }, + "errors": { + "badge": "تم كسره", + "details": "تفاصيل الخطأ", + "reloadPage": "أعد تحميل الصفحة", + "showError": "عرض تفاصيل الخطأ", + "title": "واجهنا خطأ!" + }, + "footer": { + "legal": { + "disclaimer": "تنويه", + "disclaimerText": "لا يستضيف SkoolTV أي ملفات، بل يقوم بالربط مع خدمات طرف ثالث. يجب معالجة المشاكل القانونية مع مضيفي الملفات والمزودين. لا يتحمل SkoolTV مسؤولية أي ملفات يعرضها مزودو الفيديو." + }, + "links": { + "discord": "ديسكورد", + "dmca": "DMCA", + "github": "غيت هاب" + }, + "tagline": "شاهد عروضك وأفلامك المفضلة باستخدام تطبيق البث مفتوح المصدر هذا." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "حَول", + "dmca": "DMCA", + "login": "تسجيل الدخول", + "onboarding": "إعداد", + "pagetitle": "\"{{title}} - SkoolTV\"", + "register": "إنشاء حساب", + "settings": "الإعدادات" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "علامات مرجعية" + }, + "continueWatching": { + "sectionTitle": "متابعة المشاهدة" + }, + "mediaList": { + "stopEditing": "إنهاء التعديل" + }, + "search": { + "allResults": "هذا كل ما لدينا!", + "failed": "تعذر العثور على الوسائط، حاول مجددا!", + "loading": "جار التحميل...", + "noResults": "لم نتمكن من العثور على أي شيء!", + "placeholder": { + "default": "ماذا تريد أن تشاهد؟" + }, + "sectionTitle": "نتائج البحث" + }, + "titles": { + "day": { + "default": "ماذا تريد أن تشاهد في هذه الظهيرة؟", + "extra": [ + "متشوق للمغامرة؟ قد يكون Jurassic Park خيارًا مثاليًا لك." + ] + }, + "morning": { + "default": "ماذا تريد أن تشاهد في هذا الصباح؟", + "extra": [ + "سمعت أن فلم \"Before Sunrise\" جيد" + ] + }, + "night": { + "default": "ماذا تريد أن تشاهد في هذه الليلة؟", + "extra": [ + "مُرهَق؟ سمعت أن فيلم \"The Exorcist\" جيد." + ] + } + } + }, + "media": { + "episodeDisplay": "\"S{{season}} E{{episode}}\"", + "types": { + "movie": "فِلم", + "show": "مُسلسل" + } + }, + "navigation": { + "banner": { + "offline": "تحقق من اتصالك بالأنترنت" + }, + "menu": { + "about": "عنا", + "logout": "تسجيل الخروج", + "register": "مزامنة إلى االتخزين لسحابي", + "settings": "الإعدادات", + "support": "الدعم" + } + }, + "notFound": { + "badge": "صفحة غير موجودة", + "goHome": "عودة", + "message": "بحثنا في كل مكان: في الخزانة وحتى تحت الصناديق، ومع ذلك لم نعثر عن الصفحة التي طلبتَها.", + "title": "تعذر العثور على هذه الصفحة" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "إلغاء", + "confirm": "استخدم الإعداد الإفتراضي", + "description": "لا يحتوي الإعداد الافتراضي على أفضل التدفقات ويمكن أن يكون بطيئًا بشكل لا يحتمل.", + "title": "هل انت متأكد؟" + }, + "extension": { + "back": "ارجع", + "explainer": "باستخدام إضافةالمتصفح، يمكنك الحصول على أفضل البثوث التي نقدمها. فقط ثبت الإضافة.", + "explainerIos": "لسوء الحظ، لا يتم دعم الإضافة على iOS، اضغطارجع لاختيار خيار آخر.", + "extensionHelp": "إذا قمت بتثبيت الإضافة ولكن لم يتم اكتشافه، افتح الإضافةمن خلال قائمة إضافات المتصفح واتبع الخطوات على الشاشة.", + "linkChrome": "تثبيت إضافة Chrome", + "linkFirefox": "تثبيت إضافة Firefox", + "notDetecting": "تم تثبيته على Chrome، لكن الموقع لا يكتشفه ؟ حاول إعادة تحميل الصفحة!", + "notDetectingAction": "إعادة تحميل الصفحة", + "status": { + "disallowed": "الإضافة غير مفعلة لهذه الصفحة", + "disallowedAction": "فعل الإضافة", + "failed": "فشل ارسل الحالة", + "loading": "في انتظارك لتثبيت الإضافة", + "outdated": "إصدار الإضافة قديم", + "success": "الإضافة تعمل كما هو متوقع!" + }, + "submit": "أكمال", + "title": "لنبدا بإضافة" + }, + "proxy": { + "back": "ارجع", + "explainer": "باستخدام طريقة الوكيل، يمكنك الحصول على بثوث عالية الجودة من خلال عمل وكيل خدمة ذاتية.", + "input": { + "errorConnection": "لايمكن الاتصال بالوكيل", + "errorInvalidUrl": "رابط غير صالح", + "errorNotProxy": "توقعنا وكيل ولكن حصلنا على موقع", + "label": "رابط الوكيل", + "placeholder": "https://" + }, + "link": "تعلم كيف تصنع وكيل", + "submit": "تأكيد الوكيل", + "title": "دعنا نصنع وكيل جديد" + }, + "start": { + "explainer": "للحصول على أفضل بثوث ممكنة، ستحتاج إلى اختيار طريقة البث التي تريد استخدامها.", + "options": { + "default": { + "text": "لا أريد بثوث ذات جودة جيدة، < 0/> < 1 > استخدم الإعداد الافتراضي " + }, + "extension": { + "action": "ثبت الإضافة", + "description": "قم بتثبيت إضافة المتصفح والوصول إلى أفضل المصادر.", + "quality": "افضل جودة", + "title": "إضافة المتصفح" + }, + "proxy": { + "action": "إعداد وكيل", + "description": "قم بإعداد وكيل في 5 دقائق فقط والوصول إلى مصادر رائعة.", + "quality": "جودة جيدة", + "title": "وكيل مخصص" + } + }, + "title": "دعونا نحصل على إعداد مع SkoolTV" + } + }, + "overlays": { + "close": "إغلاق" + }, + "player": { + "back": { + "default": "عودة", + "short": "عُدْ" + }, + "casting": { + "enabled": "جارٍ العرض على الجهاز..." + }, + "menus": { + "downloads": { + "disclaimer": "يتم أخذ التنزيلات مباشرةً من قبل مقدم الخدمة. SkoolTV لاسيطرة له على كيفية توفير تلك التنزيلات.", + "downloadSubtitle": "تنزيل مقاطع الترجمة الحالية", + "downloadVideo": "تنزيل الفيديو", + "hlsDisclaimer": "يتم أخذ التنزيلات مباشرة من المزود. لا تتحكم SkoolTV في كيفية توفير التنزيلات.

يرجى ملاحظة أنك تقوم بتنزيل قائمة تشغيل HLS، لا ينصح بالتنزيل إذا لم تكن على دراية بتنسيقات البث المتقدمة. جرب مصادر مختلفة لتنسيقات مختلفة.", + "onAndroid": { + "1": "للتنزيل على أندرويد، أنقر زر التنزيل وفي الصفحة الموالية إضغط باستمرار على الفيديو، وبعدها اختر حفظ.", + "shortTitle": "تنزيل / Android", + "title": "تنزيل على Android" + }, + "onIos": { + "1": "للتنزيل على نظام iOS، انقر على زر التنزيل ثم، على الصفحة الجديدة، انقر على ، ثم حفظ إلى الملفات .", + "shortTitle": "تنزيل / iOS", + "title": "تنزيل على iOS" + }, + "onPc": { + "1": "على الحاسوب، انقر على زر التنزيل، ثم على الصفحة الجديدة، انقر بزر الفأرة الأيمن على الفيديو وحدد حفظ الفيديو باسم", + "shortTitle": "تنزيل / حاسوب", + "title": "تنزيل على الحاسوب" + }, + "title": "تنزيل" + }, + "episodes": { + "button": "الحلقات", + "emptyState": "لا توجد حلقات في هذا الموسم، يرجى التحقق لاحقًا!", + "episodeBadge": "E{{episode}}", + "loadingError": "خطأ في تحميل الموسم", + "loadingList": "تحميل...", + "loadingTitle": "تحميل...", + "unairedEpisodes": "تم تعطيل حلقة واحدة أو أكثر من هذا الموسم لأنه لم يتم بثها بعد." + }, + "playback": { + "speedLabel": "سرعة التشغيل", + "title": "إعدادات التشغيل" + }, + "quality": { + "automaticLabel": "جودة تلقائية", + "hint": "يمكنك محاولة <0>تغيير المصدر للحصول على خيارات جودة مختلفة.", + "iosNoQuality": "نظرًا للقيود المحددة من قبل Apple، خيارات الجودة غير متوفرة على iOS لهذا المصدر. يمكنك محاولة <0>التبديل إلى مصدر آخر للحصول على خيارات جودة مختلفة.", + "title": "جودة" + }, + "settings": { + "downloadItem": "تنزيل", + "enableSubtitles": "تفعيل مقاطع الترجمة", + "experienceSection": "تجربة المشاهدة", + "playbackItem": "إعدادات التشغيل", + "qualityItem": "جودة", + "sourceItem": "مصادر الفيديو", + "subtitleItem": "إعدادات الترجمة", + "videoSection": "إعدادات الفيديو" + }, + "sources": { + "failed": { + "text": "حدثت خطأ أثناء محاولة إيجاد عن أي فيديو، يرجى تجربة مصدر آخر.", + "title": "فشلت عملية الاستخراج" + }, + "noEmbeds": { + "text": "تعذر العثور على أي تضمينات، يرجى تجربة مصدر آخر.", + "title": "لم يتم العثور على تضمينات" + }, + "noStream": { + "text": "هذا المصدر ليس فيه بث لهذا الفلم أو المسلسل.", + "title": "لا بث" + }, + "title": "مصادر", + "unknownOption": "مجهول" + }, + "subtitles": { + "customChoice": "استيراد ترجمة من ملف", + "customizeLabel": "تخصيص", + "offChoice": "تعطيل", + "settings": { + "backlink": "مقاطع ترجمة مخصصة", + "delay": "تأخير مقاطع الترجمة", + "fixCapitals": "تصحيح تهجئة الحروف" + }, + "title": "مقاطع الترجمة", + "unknownLanguage": "مجهول" + } + }, + "metadata": { + "api": { + "text": "لا يمكن تحميل البيانات الوصفية لواجهة برمجة التطبيقات، يرجى التحقق من اتصال الإنترنت الخاص بك.", + "title": "فشل في تحميل البيانات الوصفية لواجهة برمجة التطبيقات" + }, + "dmca": { + "badge": "حذف", + "text": "لم تعد هذه الوسائط متاحة بسبب إشعار الإزالة أو مطالبة حقوق النشر.", + "title": "الوسائط محذوفه" + }, + "extensionPermission": { + "badge": "التصريح مفقود", + "button": "استخدم الإضافة", + "text": "الإضافة مثبتة, ولكن تحتاج الى تصريح للبدء إستخدام الإضافة.", + "title": "تعديل الإضافة" + }, + "failed": { + "badge": "فشل", + "homeButton": "عُدْ للصفحة الرئيسية", + "text": "تعذر تحميل البيانات الوصفية للوسائط من قاعدة البيانات TMDB. يرجى التحقق مما إذا كانت TMDB غير متاحة أو محظورة على اتصال الإنترنت الخاص بك.", + "title": "فشل في تحميل البيانات الوصفية" + }, + "notFound": { + "badge": "غير موجود", + "homeButton": "عُدْ للصفحة الرئيسية", + "text": "لم نتمكن من العثور على الوسيط الذي طلبته.", + "title": "تعذر إيجاد هذا الوسيط." + } + }, + "nextEpisode": { + "cancel": "إلغاء", + "next": "الحلقة الموالية" + }, + "playbackError": { + "badge": "خطأ في التشغيل", + "errors": { + "errorAborted": "تم إلغاء جلب الوسائط بناءً على طلب المستخدم.", + "errorDecode": "رغم كونها قابلة للتشغيل سابقا، أحد الأخطاء على مستوى فك ترميز الوسائط، أدى إلى فشل عملية التشغيل.", + "errorGenericMedia": "حدث خطأ مجهول متصل بالوسائط.", + "errorNetwork": "أحد الأخطاء المتصلة بالشبكة، تسبب في تعذرِ جلبِ الوسائط، على الرغم من توفرها سابقا.", + "errorNotSupported": "هذا الوسيط أو مصدره غير مدعوم." + }, + "homeButton": "عُدْ للصفحة الرئيسية", + "text": "حدث خطأٌ أثناء محاولة تشغيل الوسائط. رجاءً حاول مرة أخرى.", + "title": "فشِلَ تشغيلُ الفيديو!" + }, + "scraping": { + "items": { + "failure": "حدث خطأ", + "notFound": "لا يحتوي على اي فيديو", + "pending": "جارٍ التحققُ من وجود فيديوهات..." + }, + "notFound": { + "badge": "غير موجود", + "detailsButton": "عرض التفاصيل", + "homeButton": "عُدْ للصفحة الرئيسية", + "text": "بحثنا عن طريقِ مُزودينا ولم نعثر على ما كنتَ تبحثُ عنه! نحن لانستضيف الوسائط ولسنا المتحكمين فيما هو متاح. رجاءً انقر على 'عرض التفاصيل' أسفله لمزيد من المعلومات.", + "title": "لم نتمكن من العثور على ذلك" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "باقٍ {{timeLeft}} • سينتهي مع {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "الرجاء التحقق اذا كنت إنسان بإكمال الكابتشا على يمين. هذا لاستمرارية SkoolTV آمن!", + "error": "فشل التحقق. الرجاء إعادة المحاولة.", + "title": "نريد التحقق انك لست روبوت.", + "verifyingHumanity": "التحقق انك لست روبوت.." + } + }, + "screens": { + "dmca": { + "text": "مرحبًا بكم في صفحة SkoolTV الخاصة بالتواصل حول قانون الألفية للملكية الرقمية (DMCA) ! نحن نحترم حقوق الملكية الفكرية ونرغب في التعامل بسرعة مع أي مسألة تخص حقوق الطبع والنشر. إن كنت تعتقد أن أيا من أعمالك المحميو بحقوق الطبع والنشر قد تم استخدامها بشكل غير لائق على منصتنا، رجاءً أرسل إشعارا مفصلا إلى البريد الإلكتروني أدناه. يرجى تضمين وصف للمواد المحمية بحقوق الطبع والنشر، وكذا طريقةً للتواصل معك، إضافة إلى تصريح بمصداقية طلبك. نحن ملتزمون بحل هذه القضايا بسرعة ونقدر تعاونكم في الحفاظ على SkoolTV كمكان يحترم الإبداع وحقوق الطبع والنشر.", + "title": "DMCA" + }, + "loadingApp": "جار تحميل التطبيق", + "loadingUser": "جارٍ تحميل ملفك الشخصي", + "loadingUserError": { + "logout": "تسجيل الخروج", + "reset": "إعادة تعيين الخادم المخصص", + "text": "فشل تحميل ملفك الشخصي", + "textWithReset": "فشل تحميل ملفك الشخصي من خادمك المخصص، هل ترغب في العودة إلى الخادم الافتراضي؟" + }, + "migration": { + "failed": "فشلت عملية ترحيل بياناتك.", + "inProgress": "يرجى الانتظار، نقوم بترحيل بياناتك. لن يستغرق ذلك وقتًا طويلاً." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "اسم الجهاز", + "deviceNamePlaceholder": "الهاتف الشخصي", + "editProfile": "تعديل", + "logoutButton": "تسجيل الخروج" + }, + "actions": { + "delete": { + "button": "حذف الحساب", + "confirmButton": "حذف الحساب", + "confirmDescription": "هل أنت متأكد أنك تريد حذف حسابك؟ ستفقد جميع بياناتك!", + "confirmTitle": "هل أنت متأكد؟", + "text": "هذا الإجراء لا يمكن التراجع عنه. سيتم حذف جميع البيانات ولا يمكن استعادتها.", + "title": "حذف الحساب" + }, + "title": "الإجراءات" + }, + "devices": { + "deviceNameLabel": "اسم الجهاز", + "failed": "فشل تحميل الجلسات", + "removeDevice": "إزالة", + "title": "الأجهزة" + }, + "profile": { + "finish": "إنهاء التعديل", + "firstColor": "لون الملف الشخصي الأول", + "secondColor": "لون الملف الشخصي الثاني", + "title": "تعديل صورة الملف الشخصي", + "userIcon": "أيقونة المستخدم" + }, + "register": { + "cta": "ابدأ", + "text": "شارك تقدم مشاهدتك بين الأجهزة وحافظ على تزامنها.", + "title": "مزامنة إلى االتخزين لسحابي" + }, + "title": "حساب" + }, + "appearance": { + "activeTheme": "نَشِط", + "themes": { + "blue": "أزرق", + "default": "افتراضي", + "gray": "رمادي", + "red": "أحمر", + "teal": "تركواز" + }, + "title": "المظهر" + }, + "connections": { + "server": { + "description": "إذا كنت ترغب في الاتصال بخادم خلفي مخصص لتخزين بياناتك، قم بتفعيل هذا ووفر الرابط.<0>Instructions.", + "label": "خادم مُخصص", + "urlLabel": "رابط الخادم المخصص" + }, + "setup": { + "doSetup": "إعداد", + "errorStatus": { + "description": "يبدو أن عنصرًا أو أكثر في هذا الإعداد يحتاج إلى انتباهك.", + "title": "شيء ما يحتاج إلى انتباهك" + }, + "itemError": "هناك شيء خاطئ في هذا الإعداد. اذهب من خلال إعداد مرة أخرى لإصلاحه.", + "items": { + "default": "الإعداد الافتراضي", + "extension": "اضافة", + "proxy": "وكيل مخصص" + }, + "redoSetup": "إرجاع الإعداد", + "successStatus": { + "description": "كل شيء موجود لبدء مشاهدة أفلامك ومسلسلاتك المفضلة.", + "title": "تم إعداد كل شيء!" + }, + "unsetStatus": { + "description": "يرجى النقر على الزر إلى اليمين لبدء عملية الإعداد.", + "title": "أنت لم تمر من خلال الإعداد" + } + }, + "title": "الاتصالات", + "workers": { + "addButton": "إضافة وكيل جديد", + "description": "لتشغيل التطبيق، يتم توجيه كل الاتصالات عبر وكلاء البروكسي. قم بتمكين هذا إذا كنت ترغب في استخدام خوادم العمل الخاصة بك.<0>Instructions.", + "emptyState": "لا يوجد وكلاء حتى الآن، أضف واحدًا أدناه", + "label": "استخدام وكلاء مُخصصين", + "urlLabel": "روابط الوكلاء", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "لغة الموقع", + "languageDescription": "تم تطبيق اللغة على الموقع.", + "thumbnail": "إنشاء صور مصغرة", + "thumbnailDescription": "في معظم الأوقات، لا تحتوي مقاطع الفيديو على صور مصغرة. يمكنك تمكين هذا الإعداد من توليدها بسرعة ولكن يمكنها جعل الفيديو الخاص بك أبطأ.", + "thumbnailLabel": "إنشاء صور مصغرة", + "title": "تفضيلات" + }, + "reset": "إعادة تعيين", + "save": "حفظ", + "sidebar": { + "info": { + "appVersion": "إصدار التطبيق", + "backendUrl": "رابط النهاية الخلفية", + "backendVersion": "إصدار النهاية الخلفية", + "hostname": "اسم المضيف", + "insecure": "غير آمن", + "notLoggedIn": "أنت لم تسجل دخولك بعد", + "secure": "آمن", + "title": "معلومات التطبيق", + "unknownVersion": "غير معروف", + "userId": "معرِّف المستخدم" + } + }, + "subtitles": { + "backgroundLabel": "تعتيم الخلفية", + "colorLabel": "لون", + "previewQuote": "يجب أن لا أخأف. الخوف هو قاتل العقل.", + "textSizeLabel": "حجم النص", + "title": "مقاطع الترجمة" + }, + "unsaved": "لديك تغييرات غير محفوظة" + } +} diff --git a/src/assets/locales/bg.json b/src/assets/locales/bg.json new file mode 100644 index 0000000..8022d3b --- /dev/null +++ b/src/assets/locales/bg.json @@ -0,0 +1,359 @@ +{ + "about": { + "description": "SkoolTV е уеб приложение, което търси в интернет за стриймове. Екипът се стреми към предимно минималистичен подход при консумирането на съдържание.", + "faqTitle": "Общи въпроси", + "q1": { + "body": "SkoolTV не хоства никакво съдържание. Когато кликнете върху нещо, за да го гледате, се търси в интернет избраното медийно съдържание (На екрана за зареждане и в раздела \"Източници на видео\" можете да видите кой източник използвате). Медийното съдържание никога не се качва от SkoolTV, всичко става чрез този механизъм за търсене.", + "title": "От къде идва съдържанието?" + }, + "q2": { + "body": "Невъзможно е да поискате сериал или филм, SkoolTV не управлява никакво съдържание. Всичко се гледа чрез източници в интернет.", + "title": "Къде мога да поискам определен сериал или филм?" + }, + "q3": { + "body": "Резултатите от търсенето ни се поддържат от базата данни за филми (The Movie Database - TMDB) и се показват, независимо дали източниците ни реално разполагат със съдържанието.", + "title": "Резултатите от търсенето показват сериала или филма, защо не мога да го пусна?" + }, + "title": "Относно SkoolTV", + "q5": { + "title": "Как мога да разбера повече?", + "body": "Е, SkoolTV има акаунт в Twitter, който може да бъде намерен в долния колонтитул на тази страница, както и връзка към изходния код в Github." + }, + "q4": { + "title": "Какво ще кажете за моите данни и други неща?", + "body": "Всички данни се синхронизират със sudo-бекенда, който е различен от бекенда на общността и се хоства независимо от мен, всеки може да използва и това." + } + }, + "actions": { + "copied": "Копиране", + "copy": "Копирай" + }, + "auth": { + "createAccount": "Все още нямате акаунт? <0>Създайте акаунт.", + "deviceNameLabel": "Име на устройството", + "deviceNamePlaceholder": "Личен телефон", + "generate": { + "description": "Вашата паролна фраза служи като потребителско име и парола. Уверете се, че я пазите в безопасност, тъй като ще трябва да я въведете, за да влезете в своя акаунт.", + "next": "Запазих паролната си фраза", + "passphraseFrameLabel": "Паролна фраза", + "title": "Вашата паролна фраза" + }, + "hasAccount": "Вече имате акаунт? <0>Влезте тук.", + "login": { + "description": "Моля, въведете своята паролна фраза, за да влезете в своя акаунт", + "deviceLengthError": "Моля, въведете името на устройството", + "passphraseLabel": "12-думена паролна фраза", + "passphrasePlaceholder": "Паролна фраза", + "submit": "Вход", + "title": "Влезте в своя акаунт", + "validationError": "Некоректна или непълна паролна фраза" + }, + "register": { + "information": { + "color1": "Профилен цвят едно", + "color2": "Профилен цвят две", + "header": "Въведете име за устройството си и изберете цветове и потребителска икона по ваш избор", + "icon": "Потребителска икона", + "next": "Напред", + "title": "Информация за акаунта" + } + }, + "trust": { + "failed": { + "text": "Конфигурирахте ли го правилно?", + "title": "Неуспешно свързване със сървъра" + }, + "host": "Вие се свързвате към <0>{{hostname}} - моля, потвърдете, че му вярвате, преди да създадете акаунт", + "no": "Върнете се назад", + "title": "Вярвате ли на този сървър?", + "yes": "Вярвам на този сървър", + "noHostTitle": "Сървърът не е конфигуриран!", + "noHost": "Сървърът не е конфигуриран, следователно не можете да създадете акаунт" + }, + "verify": { + "description": "Моля, въведете паролната фраза от по-рано, за да потвърдите, че сте я запазили, и за да създадете своя акаунт", + "invalidData": "Данните не са валидни", + "noMatch": "Паролната фраза не съвпада", + "passphraseLabel": "Вашата 12-думена паролна фраза", + "recaptchaFailed": "Валидацията на ReCaptcha не беше успешна", + "register": "Създаване на акаунт", + "title": "Потвърдете вашата паролна фраза" + } + }, + "errors": { + "badge": "Счупи се", + "details": "Детайли за грешката", + "reloadPage": "Презаредете страницата", + "showError": "Покажи детайлите за грешката", + "title": "Сблъскахме се с грешка!" + }, + "footer": { + "legal": { + "disclaimer": "Внимание", + "disclaimerText": "SkoolTV не хоства никакви файлове, а просто предоставя връзки към услуги от трета страна. Правните въпроси следва да се разглеждат с доставчиците на файлове. SkoolTV не носи отговорност за никакви медийни файлове, предоставени от видео доставчици." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "Github", + "twitter": "Twitter" + }, + "tagline": "Гледайте любимите си предавания и филми с това отворено-код стрийминг приложение." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "За нас", + "dmca": "DMCA", + "login": "Вход", + "pagetitle": "{{title}} - SkoolTV", + "register": "Регистрация", + "settings": "Настройки", + "discover": "Открийте", + "support": "поддържа", + "onboarding": "Настройвам" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Отметки" + }, + "continueWatching": { + "sectionTitle": "Продължи гледането" + }, + "mediaList": { + "stopEditing": "Спри редактирането" + }, + "search": { + "allResults": "Това е всичко, което имаме!", + "failed": "Неуспешно намиране на медия, опитайте отново!", + "loading": "Зареждане...", + "noResults": "Не успяхме да намерим нищо!", + "placeholder": { + "default": "Какво искате да гледате?", + "extra": [ + "За какво имаш настроение?", + "Трябва ли да изтрием историята на браузъра ви?", + "Какво искате да предавате?", + "SkoolTV е най-добрият сайт досега!", + "Какво е в списъка ви за гледане днес?", + "Как беше денят ти?", + "Лошото ми е, че сайтът никога не работи...", + "Не е ли SkoolTV най-добрият?", + ">ᴗ<" + ] + }, + "sectionTitle": "Резултати от търсенето", + "empty": { + "default": "Добре дошли, намерете медии за гледане тук!", + "extra": [ + "Тук няма нищо :(", + "Толкова празно...", + "Такава празнота.", + "Здравей нов потребител :3" + ] + }, + "discoverMore": "Открий повече", + "discover": "Открийте" + }, + "titles": { + "day": { + "default": "Какво бихте искали да гледате този следобед?", + "extra": [ + "Viva la SkoolTV!" + ] + }, + "morning": { + "default": "Какво бихте искали да гледате тази сутрин?", + "extra": [ + "Viva la SkoolTV!" + ] + }, + "night": { + "default": "Какво бихте искали да гледате тази вечер?", + "extra": [ + "Viva la SkoolTV!" + ] + }, + "69": { + "default": "За нещо пикантно?", + "extra": [ + "Честит 69 ден 😘!" + ] + }, + "420": { + "extra": [ + "Честит 4/20 🥳!" + ], + "default": "Какво бихте искали да гледате този 4/20?" + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Филм", + "show": "Сериал" + }, + "unreleased": "Неиздавана" + }, + "navigation": { + "banner": { + "offline": "Проверете вашата интернет връзка" + }, + "menu": { + "about": "За нас", + "logout": "Излез", + "register": "Синхронизиране с облак", + "settings": "Настройки", + "support": "поддържа", + "discover": "Открийте" + } + }, + "notFound": { + "badge": "Не е намерено", + "goHome": "Обратно към началото", + "message": "Търсихме навсякъде: под кошчетата, в килера, зад проксито, но в крайна сметка не успяхме да намерим страницата, която търсите. (ಥ﹏ಥ)", + "title": "Тази страница не можа да бъде намерена", + "reloadButton": "Опитай пак" + }, + "overlays": { + "close": "Затвори" + }, + "player": { + "back": { + "default": "Обратно към началото", + "short": "Назад" + }, + "casting": { + "enabled": "Предава се към устройството..." + }, + "menus": { + "downloads": { + "disclaimer": "Изтеглянията се вземат директно от доставчика. SkoolTV няма контрол върху това как се предоставят изтеглянията.", + "downloadSubtitle": "Изтеглете текущите субтитри", + "downloadVideo": "Изтегляне на видео", + "hlsDisclaimer": "Изтеглянията се вземат директно от доставчика. SkoolTV няма контрол върху това как се предоставят изтеглянията. Моля, имайте предвид, че изтегляте HLS плейлист, това е предназначено за потребители, запознати с усъвършенствано мултимедийно поточно предаване.", + "onAndroid": { + "1": "За да изтеглите на Android, щракнете върху бутона за изтегляне, след което на новата страница докоснете и задръжте видеоклипа, след което изберете запазване.", + "shortTitle": "Изтегляне / Android", + "title": "Изтегляне на Android" + }, + "onIos": { + "1": "За да изтеглите на iOS, щракнете върху бутона за изтегляне, след което на новата страница щракнете върху , след което върху Запазване във файлове .", + "shortTitle": "Изтегляне / iOS", + "title": "Изтегляне на iOS" + }, + "onPc": { + "1": "На компютър щракнете върху бутона за изтегляне, след което на новата страница щракнете с десния бутон върху видеоклипа и изберете Запазване на видеоклипа като", + "shortTitle": "Изтегляне / компютър", + "title": "Изтегляне на компютър" + }, + "title": "Изтегли" + }, + "episodes": { + "button": "епизоди", + "emptyState": "Няма епизоди в този сезон, проверете отново по-късно!", + "episodeBadge": "E{{episode}}", + "loadingError": "Грешка при зареждането на сезона", + "loadingList": "Зареждане...", + "loadingTitle": "Зареждане..." + }, + "playback": { + "speedLabel": "Скорост на възпроизвеждане", + "title": "Настройки за възпроизвеждане" + }, + "quality": { + "automaticLabel": "Автоматично качество", + "hint": "Можете да опитате <0>да превключите източника, за да получите различни опции за качество.", + "iosNoQuality": "Поради ограниченията, определени от Apple, изборът на качество не е наличен в iOS за този източник. Можете да опитате <0>да превключите към друг източник, за да получите различни опции за качество.", + "title": "качество" + }, + "settings": { + "downloadItem": "Изтегли", + "enableSubtitles": "включи субтитрите", + "experienceSection": "Изживяване при гледане", + "playbackItem": "Настройки за възпроизвеждане", + "qualityItem": "качество", + "sourceItem": "Видео източници", + "subtitleItem": "Настройки на субтитрите", + "videoSection": "Видео настройки" + }, + "sources": { + "failed": { + "text": "Възникна грешка при опит за намиране на видеоклипове, моля, опитайте с друг източник.", + "title": "Неуспешно изстъргване" + }, + "noEmbeds": { + "text": "Не можахме да намерим никакви вграждания, моля, опитайте с друг източник.", + "title": "Няма намерени вграждания" + }, + "noStream": { + "text": "Този източник няма потоци за този филм или шоу.", + "title": "Няма поток" + }, + "title": "Източници", + "unknownOption": "неизвестен" + }, + "subtitles": { + "customChoice": "Качете субтитри", + "customizeLabel": "Персонализиране", + "offChoice": "изключи", + "settings": { + "backlink": "Персонализирани субтитри", + "delay": "Забавяне на субтитрите", + "fixCapitals": "Коригиране на главни букви" + }, + "title": "субтитри", + "unknownLanguage": "неизвестен" + } + }, + "metadata": { + "failed": { + "badge": "Провал", + "homeButton": "Обратно към началото", + "text": "Неуспешно зареждане на метаданните на носителя от TMDB. Моля, проверете дали TMDB не работи или е блокиран във вашата интернет връзка.", + "title": "Неуспешно зареждане на метаданните" + }, + "notFound": { + "badge": "Не е намерено", + "homeButton": "Обратно към началото", + "text": "Не успяхме да намерим медията, която поискахте. Или е бил премахнат, или сте променили URL адреса.", + "title": "Тази медия не можа да бъде намерена." + } + }, + "nextEpisode": { + "cancel": "Отказ", + "next": "Следващ епизод" + }, + "playbackError": { + "badge": "Грешка при възпроизвеждане", + "errors": { + "errorAborted": "Извличането на медията беше прекратено по искане на потребителя.", + "errorDecode": "Въпреки че преди това беше определено като използваем, възникна грешка при опит за декодиране на медийния ресурс, което доведе до грешка.", + "errorGenericMedia": "Възникна неизвестна медийна грешка.", + "errorNetwork": "Възникна някакъв вид мрежова грешка, която попречи на медията да бъде успешно извлечена, въпреки че преди това е била достъпна.", + "errorNotSupported": "Обектът медия или доставчик на медия не се поддържа." + } + } + }, + "downtimeNotice": { + "badge": "Проблеми", + "goHome": "Прибирай се", + "timeFrame": "March 31th 11:00 PM - 5:00 AM EST", + "title": "Проблеми с доставчика", + "message": "SkoolTV.lol отново има проблеми с някои доставчици, ако не можете да намерите или пуснете шоу, моля, променете източника. Очаквайте тази грешка да продължи през времената по-долу." + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Отказ", + "confirm": "Използвайте настройките по подразбиране", + "title": "Сигурен ли си?", + "description": "Настройката по подразбиране няма най-добрите потоци и може да бъде непоносимо бавна. ( ͠° ͟ʖ ͡°)" + }, + "extension": { + "back": "Върни се", + "explainer": "С помощта на разширението на браузъра можете да получите най-добрите потоци, които предлагаме. Само с проста инсталация. 👌" + } + } +} diff --git a/src/assets/locales/bn.json b/src/assets/locales/bn.json new file mode 100644 index 0000000..09eeec4 --- /dev/null +++ b/src/assets/locales/bn.json @@ -0,0 +1,285 @@ +{ + "about": { + "description": "মুভি-ওয়েব একটি ওয়েব অ্যাপ্লিকেশন যা স্ট্রিমগুলির জন্য ইন্টারনেট অনুসন্ধান করে। দলটির লক্ষ্য বিষয়বস্তু গ্রহণের জন্য সবচেয়ে সংক্ষিপ্ত পদ্ধতির জন্য।", + "faqTitle": "সাধারণ প্রশ্নাবলী", + "q1": { + "body": "মুভি-ওয়েব কোনো বিষয়বস্তু হোস্ট করে না। আপনি যখন দেখার জন্য কিছুতে ক্লিক করেন, তখন নির্বাচিত মিডিয়ার জন্য ইন্টারনেট অনুসন্ধান করা হয় (লোডিং স্ক্রিনে এবং 'ভিডিও উত্স' ট্যাবে আপনি কোন উত্সটি ব্যবহার করছেন তা দেখতে পারেন)। মিডিয়া কখনই মুভি-ওয়েব দ্বারা আপলোড হয় না, সবকিছু এই অনুসন্ধান প্রক্রিয়ার মাধ্যমে হয়।", + "title": "কন্টেন্ট কোথা থেকে আসে?" + }, + "q2": { + "body": "একটি শো বা সিনেমার অনুরোধ করা সম্ভব নয়, মুভি-ওয়েব কোনো বিষয়বস্তু পরিচালনা করে না। সমস্ত বিষয়বস্তু ইন্টারনেটে উৎসের মাধ্যমে দেখা হয়।", + "title": "আমি কোথায় একটি শো বা সিনেমা অনুরোধ করতে পারি?" + }, + "q3": { + "body": "আমাদের অনুসন্ধানের ফলাফলগুলি The Movie Database (TMDB) দ্বারা চালিত হয় এবং আমাদের উত্সগুলিতে প্রকৃতপক্ষে সামগ্রী আছে কিনা তা নির্বিশেষে প্রদর্শন করা হয়।", + "title": "সার্চ রেজাল্টে শো বা মুভি দেখায়, কেন আমি এটা চালাতে পারি না?" + }, + "title": "মুভি-ওয়েব সম্পর্কে" + }, + "actions": { + "copied": "অনুলিপি করা", + "copy": "অনুলিপি" + }, + "auth": { + "createAccount": "কোনো একাউন্ট এখনও আছে না? <0>একটি অ্যাকাউন্ট তৈরি করুন৷৷", + "deviceNameLabel": "ডিভাইসের নাম", + "deviceNamePlaceholder": "ব্যক্তিগত ফোন", + "generate": { + "description": "আপনার পাসফ্রেজ আপনার ব্যবহারকারীর নাম এবং পাসওয়ার্ড হিসাবে কাজ করে। আপনার অ্যাকাউন্টে লগইন করার জন্য আপনাকে এটি প্রবেশ করতে হবে বলে এটিকে সুরক্ষিত রাখা নিশ্চিত করুন৷", + "next": "আমি আমার পাসফ্রেজ সংরক্ষণ করেছি", + "passphraseFrameLabel": "পাসফ্রেজ", + "title": "আপনার পাসফ্রেজ" + }, + "hasAccount": "ইতিমধ্যে একটি সদস্যপদ আছে? <0>এখানে লগইন করুন।", + "login": { + "description": "আপনার অ্যাকাউন্টে লগইন করতে আপনার পাসফ্রেজ লিখুন", + "deviceLengthError": "অনুগ্রহ করে একটি ডিভাইসের নাম লিখুন৷", + "passphraseLabel": "12-শব্দ পাসফ্রেজ", + "passphrasePlaceholder": "পাসফ্রেজ", + "submit": "প্রবেশ করুন", + "title": "আপনার অ্যাকাউন্টে লগ ইন করুন", + "validationError": "ভুল বা অসম্পূর্ণ পাসফ্রেজ" + }, + "register": { + "information": { + "color1": "প্রোফাইল রঙ এক", + "color2": "প্রোফাইল রঙ দুই", + "header": "আপনার ডিভাইসের জন্য একটি নাম লিখুন এবং রং এবং আপনার পছন্দের একটি ব্যবহারকারী আইকন বাছুন", + "icon": "ব্যবহারকারী আইকন", + "next": "পরবর্তী", + "title": "হিসাবের তথ্য" + } + }, + "trust": { + "failed": { + "text": "আপনি এটি সঠিকভাবে কনফিগার করেছেন?", + "title": "সার্ভারে পৌঁছাতে ব্যর্থ হয়েছে" + }, + "host": "আপনি <0>{{hostname}}-এর সাথে সংযোগ করছেন - একটি অ্যাকাউন্ট করার আগে দয়া করে নিশ্চিত করুন যে আপনি এটি বিশ্বাস করেন", + "no": "ফিরে যাও", + "title": "আপনি এই সার্ভার বিশ্বাস করেন?", + "yes": "আমি এই সার্ভার বিশ্বাস" + }, + "verify": { + "description": "আপনি এটি সংরক্ষণ করেছেন তা নিশ্চিত করতে এবং আপনার অ্যাকাউন্ট তৈরি করতে অনুগ্রহ করে আগে থেকে আপনার পাসফ্রেজ লিখুন", + "invalidData": "ডেটা বৈধ নয়", + "noMatch": "পাসফ্রেজ মেলে না", + "passphraseLabel": "আপনার 12-শব্দের পাসফ্রেজ", + "recaptchaFailed": "রিক্যাপচা যাচাইকরণ ব্যর্থ হয়েছে", + "register": "হিসাব তৈরি কর", + "title": "আপনার পাসফ্রেজ নিশ্চিত করুন" + } + }, + "errors": { + "badge": "এটা ভাঙ্গা", + "details": "ভুল তথ্য", + "reloadPage": "পৃষ্ঠাটি পুনরায় লোড করুন", + "showError": "ত্রুটি বিবরণ দেখান", + "title": "আমরা একটি ত্রুটির সম্মুখীন হয়েছি!" + }, + "footer": { + "legal": { + "disclaimer": "দাবিত্যাগ", + "disclaimerText": "মুভি-ওয়েব কোনো ফাইল হোস্ট করে না, এটি শুধুমাত্র তৃতীয় পক্ষের পরিষেবাগুলির সাথে লিঙ্ক করে। ফাইল হোস্ট এবং প্রদানকারীদের সাথে আইনি সমস্যাগুলি নেওয়া উচিত। মুভি-ওয়েব ভিডিও প্রদানকারীদের দ্বারা দেখানো কোনো মিডিয়া ফাইলের জন্য দায়ী নয়।" + }, + "links": { + "discord": "বিরোধ", + "dmca": "ডিএমসিএ", + "github": "গিটহাব" + }, + "tagline": "এই ওপেন সোর্স স্ট্রিমিং অ্যাপের মাধ্যমে আপনার প্রিয় শো এবং সিনেমা দেখুন।" + }, + "global": { + "name": "মুভি-ওয়েব", + "pages": { + "about": "সম্পর্কিত", + "dmca": "ডিএমসিএ", + "login": "প্রবেশ করুন", + "pagetitle": "{{title}} - মুভি-ওয়েব", + "register": "নিবন্ধন", + "settings": "সেটিংস" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "বুকমার্ক" + }, + "continueWatching": { + "sectionTitle": "দেখা চালিয়ে যান" + }, + "mediaList": { + "stopEditing": "সম্পাদনা বন্ধ করুন" + }, + "search": { + "allResults": "যে আমরা সব আছে!", + "failed": "মিডিয়া খুঁজে পেতে ব্যর্থ, আবার চেষ্টা করুন!", + "loading": "লোড হচ্ছে..।", + "noResults": "আমরা কিছুই খুঁজে পাইনি!", + "placeholder": { + "default": "আপনি কি দেখতে চান?" + }, + "sectionTitle": "অনুসন্ধান ফলাফল" + }, + "titles": { + "day": { + "default": "আপনি এই বিকেলে কি দেখতে চান?", + "extra": [ + "দুঃসাহসিক বোধ করছেন? জুরাসিক পার্ক নিখুঁত পছন্দ হতে পারে।" + ] + }, + "morning": { + "default": "আপনি এই সকালে কি দেখতে চান?", + "extra": [ + "শুনি সূর্যোদয়ের আগে ভালো" + ] + }, + "night": { + "default": "আপনি আজ রাতে কি দেখতে চান?", + "extra": [ + "ক্লান্ত? আমি শুনেছি দ্য এক্সরসিস্ট ভাল।" + ] + } + } + }, + "media": { + "episodeDisplay": "সিজন{{সিজন}} পর্ব{{পর্ব}}", + "types": { + "movie": "সিনেমা", + "show": "দেখান" + } + }, + "navigation": { + "banner": { + "offline": "আপনার ইন্টারনেট সংযোগ পরীক্ষা করুন" + }, + "menu": { + "about": "আমাদের সম্পর্কে", + "logout": "প্রস্থান", + "register": "ক্লাউডে সিঙ্ক করুন", + "settings": "সেটিংস", + "support": "সমর্থন" + } + }, + "notFound": { + "badge": "পাওয়া যায়নি", + "goHome": "বাড়িতে ফিরে যাও", + "message": "আমরা সর্বত্র তাকালাম: বিনের নীচে, পায়খানায়, প্রক্সির পিছনে কিন্তু শেষ পর্যন্ত আপনি যে পৃষ্ঠাটি খুঁজছেন তা খুঁজে পাইনি।", + "title": "সেই পৃষ্ঠাটি খুঁজে পাওয়া যায়নি" + }, + "overlays": { + "close": "বন্ধ" + }, + "player": { + "back": { + "default": "বাড়িতে ফিরে যাও", + "short": "পেছনে" + }, + "casting": { + "enabled": "ডিভাইসে কাস্ট করা হচ্ছে..।" + }, + "menus": { + "downloads": { + "disclaimer": "ডাউনলোড সরাসরি প্রদানকারী থেকে নেওয়া হয়. কিভাবে ডাউনলোড দেওয়া হয় তার উপর মুভি-ওয়েবের নিয়ন্ত্রণ নেই।", + "downloadSubtitle": "বর্তমান সাবটাইটেল ডাউনলোড করুন", + "downloadVideo": "ভিডিও ডাউনলোড", + "hlsDisclaimer": "ডাউনলোড সরাসরি প্রদানকারী থেকে নেওয়া হয়. কিভাবে ডাউনলোড দেওয়া হয় তার উপর মুভি-ওয়েবের নিয়ন্ত্রণ নেই। অনুগ্রহ করে মনে রাখবেন যে আপনি একটি HLS প্লেলিস্ট ডাউনলোড করছেন, এটি উন্নত মাল্টিমিডিয়া স্ট্রিমিংয়ের সাথে পরিচিত ব্যবহারকারীদের জন্য।", + "onAndroid": { + "1": "অ্যান্ড্রয়েডে ডাউনলোড করতে, ডাউনলোড বোতামে ক্লিক করুন তারপর, নতুন পৃষ্ঠায়, ভিডিওতে ট্যাপ করুন এবং ধরে রাখুন, তারপরে সংরক্ষণ করুন নির্বাচন করুন।", + "shortTitle": "ডাউনলোড/অ্যান্ড্রয়েড", + "title": "অ্যান্ড্রয়েডে ডাউনলোড হচ্ছে" + }, + "onIos": { + "1": "iOS-এ ডাউনলোড করতে, ডাউনলোড বোতামে ক্লিক করুন তারপর, নতুন পৃষ্ঠায়, -এ ক্লিক করুন, তারপর ফাইলে সংরক্ষণ করুন ।", + "shortTitle": "ডাউনলোড / iOS", + "title": "iOS এ ডাউনলোড হচ্ছে" + }, + "onPc": { + "1": "পিসিতে, ডাউনলোড বোতামে ক্লিক করুন তারপর, নতুন পৃষ্ঠায়, ভিডিওটিতে ডান ক্লিক করুন এবং ভিডিওটিকে এই হিসাবে সংরক্ষণ করুন নির্বাচন করুন", + "shortTitle": "ডাউনলোড/পিসি", + "title": "পিসিতে ডাউনলোড হচ্ছে" + }, + "title": "ডাউনলোড করুন" + }, + "episodes": { + "button": "পর্বগুলি", + "emptyState": "এই মরসুমে কোন পর্ব নেই, পরে আবার চেক করুন!", + "episodeBadge": "E{{episode}}", + "loadingError": "ঋতু লোড করার সময় ত্রুটি৷", + "loadingList": "লোড হচ্ছে..।", + "loadingTitle": "লোড হচ্ছে..।", + "unairedEpisodes": "এই সিজনের এক বা একাধিক পর্ব অক্ষম করা হয়েছে কারণ সেগুলি এখনও সম্প্রচার করা হয়নি।" + }, + "playback": { + "speedLabel": "প্লেব্যাক গতি", + "title": "প্লেব্যাক সেটিংস" + }, + "quality": { + "automaticLabel": "স্বয়ংক্রিয় গুণমান", + "hint": "আপনি বিভিন্ন গুণমানের বিকল্প পেতে <0>উৎস পরিবর্তন করে দেখতে পারেন।", + "iosNoQuality": "অ্যাপল-সংজ্ঞায়িত সীমাবদ্ধতার কারণে, এই উৎসের জন্য গুণমান নির্বাচন iOS-এ উপলব্ধ নয়। বিভিন্ন মানের বিকল্প পেতে আপনি <0>অন্য উৎসে স্যুইচ করার চেষ্টা করতে পারেন।", + "title": "গুণমান" + }, + "settings": { + "downloadItem": "ডাউনলোড করুন", + "enableSubtitles": "সাবটাইটেল সক্রিয় করুন", + "experienceSection": "দেখার অভিজ্ঞতা", + "playbackItem": "প্লেব্যাক সেটিংস", + "qualityItem": "গুণমান", + "sourceItem": "ভিডিও সূত্র", + "subtitleItem": "সাবটাইটেল সক্রিয় করুন", + "videoSection": "ভিডিও সেটিংস" + }, + "sources": { + "failed": { + "text": "কোনো ভিডিও খুঁজে বের করার চেষ্টা করার সময় একটি ত্রুটি ছিল, অনুগ্রহ করে একটি ভিন্ন উত্স চেষ্টা করুন।", + "title": "স্ক্র্যাপ করতে ব্যর্থ" + }, + "noEmbeds": { + "text": "আমরা কোনো এম্বেড খুঁজে পেতে অক্ষম, একটি ভিন্ন উৎস চেষ্টা করুন।", + "title": "কোনো এম্বেড পাওয়া যায়নি" + }, + "noStream": { + "text": "এই উৎসের এই সিনেমা বা শোর জন্য কোনো স্ট্রিম নেই।", + "title": "অজানা" + }, + "title": "সূত্র", + "unknownOption": "অজানা" + }, + "subtitles": { + "customChoice": "ফাইল থেকে সাবটাইটেল নির্বাচন করুন", + "customizeLabel": "কাস্টমাইজ করুন", + "offChoice": "বন্ধ", + "settings": { + "backlink": "কাস্টম সাবটাইটেল", + "delay": "সাবটাইটেল বিলম্ব", + "fixCapitals": "মূলধন ঠিক করুন" + }, + "title": "সাবটাইটেল", + "unknownLanguage": "অজানা" + } + }, + "metadata": { + "api": { + "text": "API মেটাডেটা লোড করা যায়নি, অনুগ্রহ করে আপনার ইন্টারনেট সংযোগ পরীক্ষা করুন।", + "title": "API মেটাডেটা লোড করতে ব্যর্থ হয়েছে" + }, + "failed": { + "badge": "ব্যর্থ", + "homeButton": "বাড়িতে যেতে", + "text": "TMDB থেকে মিডিয়ার মেটাডেটা লোড করা যায়নি। আপনার ইন্টারনেট সংযোগে TMDB ডাউন বা ব্লক করা আছে কিনা তা অনুগ্রহ করে চেক করুন।", + "title": "মেটাডেটা লোড করতে ব্যর্থ হয়েছে" + }, + "notFound": { + "badge": "পাওয়া যায়নি", + "homeButton": "বাড়িতে ফিরে যাও", + "text": "আপনার অনুরোধ করা মিডিয়া আমরা খুঁজে পাইনি। হয় এটি সরানো হয়েছে অথবা আপনি URL-এর সাথে হেরফের করেছেন।" + } + }, + "turnstile": { + "description": "ডানদিকে ক্যাপচা সম্পূর্ণ করে আপনি যে মানুষ তা যাচাই করুন। সিনেমা-ওয়েবকে নিরাপদ রাখতেই এই!", + "error": "আপনার মানবতা যাচাই করতে ব্যর্থ হয়েছে. অনুগ্রহপূর্বক আবার চেষ্টা করুন।", + "title": "আপনি যে মানুষ তা আমাদের যাচাই করতে হবে।", + "verifyingHumanity": "আপনার মানবতা যাচাই করা হচ্ছে..।" + } + } +} diff --git a/src/assets/locales/ca.json b/src/assets/locales/ca.json new file mode 100644 index 0000000..1704970 --- /dev/null +++ b/src/assets/locales/ca.json @@ -0,0 +1,547 @@ +{ + "about": { + "description": "SkoolTV és una aplicació web que cerca fluxos a internet. L'equip té com a objectiu un enfocament majoritàriament minimalista del consum de contingut.", + "faqTitle": "Preguntes freqüents", + "q1": { + "body": "SkoolTV no allotja cap contingut. Quan feu clic a alguna cosa per a mirar-la, es busca a Internet el contingut seleccionat (a la pantalla de càrrega i a la pestanya «Fonts de vídeo» podeu veure quina font utilitzeu). SkoolTV mai hi puja contingut, tot és a través d'aquest mecanisme de cerca.", + "title": "D'on prové el contingut?" + }, + "q2": { + "body": "No és possible sol·licitar un programa o una pel·lícula, SkoolTV no gestiona cap contingut. Tot el contingut es visualitza a través de fonts a internet.", + "title": "On puc sol·licitar un programa o una pel·lícula?" + }, + "q3": { + "body": "Els resultats de cerca funcionen amb The Movie Database (TMDB) i es mostren independentment de si les nostres fonts realment tenen el contingut.", + "title": "Els resultats de la cerca mostren el programa o la pel·lícula, per què no puc reproduir-lo?" + }, + "title": "Sobre SkoolTV" + }, + "actions": { + "copied": "S'ha copiat", + "copy": "Copia" + }, + "auth": { + "createAccount": "Encara no teniu un compte? <0>Creeu un compte.", + "deviceNameLabel": "Nom del dispositiu", + "deviceNamePlaceholder": "Telèfon personal", + "generate": { + "description": "La frase de contrasenya actua com a nom d'usuari i contrasenya. Assegureu-vos de mantenir-la segura, ja que haureu d'introduir-la per a iniciar la sessió al vostre compte", + "next": "He desat la frase de contrasenya", + "passphraseFrameLabel": "Frase de contrasenya", + "title": "La vostra frase de contrasenya" + }, + "hasAccount": "Ja teniu un compte? <0>Inicieu sessió aquí.", + "login": { + "description": "Introduïu la vostra frase de contrasenya per a iniciar sessió al vostre compte", + "deviceLengthError": "Introduïu un nom per al dispositiu", + "passphraseLabel": "Frase de contrasenya de 12 paraules", + "passphrasePlaceholder": "Frase de contrasenya", + "submit": "Inicia sessió", + "title": "Inicieu sessió al vostre compte", + "validationError": "Frase de contrasenya incorrecta o incompleta" + }, + "register": { + "information": { + "color1": "Color de perfil 1", + "color2": "Color de perfil 2", + "header": "Introduïu un nom per al dispositiu i trieu els colors i la icona d'usuari que vulgueu", + "icon": "Icona d'usuari", + "next": "Següent", + "title": "Informació del compte" + } + }, + "trust": { + "failed": { + "text": "L'heu configurada correctament?", + "title": "No s'ha pogut accedir al servidor" + }, + "host": "Us esteu connectant a <0>{{hostname}}. Confirmeu que hi confieu abans de crear un compte", + "no": "Torna", + "noHost": "El servidor no s'ha configurat, per tant, no es pot crear un compte", + "noHostTitle": "El servidor no està configurat!", + "title": "Confieu en aquest servidor?", + "yes": "Confie en aquest servidor" + }, + "verify": { + "description": "Introduïu la vostra frase de contrasenya anterior per a confirmar que l'heu desat, i crear el compte", + "invalidData": "La data no és vàlida", + "noMatch": "La frase de contrasenya no coincideix", + "passphraseLabel": "Frase de contrasenya de 12 paraules", + "recaptchaFailed": "Ha fallat la validació de ReCaptcha", + "register": "Crea el compte", + "title": "Confirmeu la frase de contrasenya" + } + }, + "errors": { + "badge": "S'ha trencat", + "details": "Detalls de l'error", + "reloadPage": "Recarrega la pàgina", + "showError": "Mostra els detalls de l'error", + "title": "Hem trobat un error!" + }, + "footer": { + "legal": { + "disclaimer": "Avís d'exempció de responsabilitat", + "disclaimerText": "SkoolTV no allotja cap fitxer, només enllaça a serveis de tercers. Els problemes legals s'han d'abordar amb qui allotja i els proveïdors de fitxers. SkoolTV no es fa responsable del contingut mostrat pels proveïdors de vídeo." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Mireu els vostres programes i pel·lícules preferits amb aquesta aplicació de codi obert de reproducció en temps real." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Quant a", + "dmca": "DMCA", + "login": "Inicia sessió", + "onboarding": "Configura", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registra", + "settings": "Configuració" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Marcadors" + }, + "continueWatching": { + "sectionTitle": "Continueu mirant" + }, + "mediaList": { + "stopEditing": "Deixa d'editar" + }, + "search": { + "allResults": "Això és tot el que tenim!", + "failed": "No s'ha pogut trobar cap contingut, torneu-ho a provar!", + "loading": "S'està carregant…", + "noResults": "No hem pogut trobar res!", + "placeholder": { + "default": "Què voleu mirar?", + "extra": [ + "Què voleu explorar?", + "Què hi ha a la vostra llista de seguiment?", + "Quina és la vostra pel·lícula preferida?", + "Quina és la vostra sèrie preferida?" + ] + }, + "sectionTitle": "Resultats de la cerca" + }, + "titles": { + "day": { + "default": "Què us agradaria mirar aquesta vesprada/tarda?", + "extra": [ + "Voleu aventura? Jurassic Park podria ser l'elecció perfecta." + ] + }, + "morning": { + "default": "Què us agradaria mirar aquest matí?", + "extra": [ + "He sentit que «Abans de l'alba» és bona" + ] + }, + "night": { + "default": "Què us agradaria mirar aquesta nit?", + "extra": [ + "Esteu cansat? He sentit que «L'exorcista» és bona." + ] + } + } + }, + "media": { + "episodeDisplay": "T{{season}} E{{episode}}", + "types": { + "movie": "Pel·lícula", + "show": "Sèrie/Programa" + } + }, + "navigation": { + "banner": { + "offline": "Comproveu la connexió a internet" + }, + "menu": { + "about": "Quant a nosaltres", + "logout": "Tanca la sessió", + "register": "Sincronitza al núvol", + "settings": "Configuració", + "support": "Ajuda" + } + }, + "notFound": { + "badge": "No s'ha trobat", + "goHome": "Torna a l'inici", + "message": "Hem mirat per tot arreu: davall de les papereres, a l'armari, darrere del servidor intermediari, però al remat no hem pogut trobar la pàgina que busqueu.", + "title": "No s'ha pogut trobar la pàgina" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Cancel·la", + "confirm": "Usa la configuració per defecte", + "description": "La configuració per defecte no té els millors fluxos i pot ser insuportablement lenta.", + "title": "Segur?" + }, + "extension": { + "back": "Torna", + "explainer": "Mitjançant l'extensió del navegador, podeu obtenir els millors fluxos que oferim. Amb només una simple instal·lació.", + "explainerIos": "Lamentablement, l'extensió del navegador no és compatible amb iOS, premeu Torna per a triar una altra opció.", + "extensionHelp": "Si heu instal·lat l'extensió, però no es detecta, obriu l'extensió al menú d'extensions del navegador i seguiu els passos en pantalla.", + "linkChrome": "Instal·la l'extensió de Chrome", + "linkFirefox": "Instal·la l'extensió de Firefox", + "notDetecting": "S'ha instal·lat a Chrome, però el lloc no el detecta? Proveu de recarregar la pàgina.", + "notDetectingAction": "Recarrega la pàgina", + "status": { + "disallowed": "L'extensió no està activada per a aquesta pàgina", + "disallowedAction": "Activa l'extensió", + "failed": "No s'ha pogut sol·licitar l'estat", + "loading": "Esperant que instal·leu l'extensió", + "outdated": "La versió de l'extensió és massa antiga", + "success": "L'extensió funciona com s'esperava!" + }, + "submit": "Continua", + "title": "Comencem amb una extensió" + }, + "proxy": { + "back": "Torna", + "explainer": "Amb el mètode del servidor intermediari, podeu obtenir fluxos d'alta qualitat fent un servidor intermediari propi.", + "input": { + "errorConnection": "No s'ha pogut connectar al servidor intermediari", + "errorInvalidUrl": "URL no vàlid", + "errorNotProxy": "S'esperava un servidor intermediari, però és un lloc web", + "label": "URL del servidor intermediari", + "placeholder": "https://" + }, + "link": "Com fer un servidor intermediari", + "submit": "Envia el servidor intermediari", + "title": "Fem un nou servidor intermediari" + }, + "start": { + "explainer": "Per a obtenir els millors fluxos possibles, haureu de triar quin mètode de transmissió voleu utilitzar.", + "options": { + "default": { + "text": "No vull fluxos de bona qualitat,<0 /> <1>utilitza la configuració per defecte" + }, + "extension": { + "action": "Instal·la l'extensió", + "description": "Instal·leu l'extensió del navegador i accediu a les millors fonts.", + "quality": "Millor qualitat", + "title": "Extensió del navegador" + }, + "proxy": { + "action": "Configura el servidor intermediari", + "description": "Configureu un servidor intermediari en només 5 minuts i accediu a bones fonts.", + "quality": "Bona qualitat", + "title": "Servidor intermediari personalitzat" + } + }, + "title": "Configurem el SkoolTV" + } + }, + "overlays": { + "close": "Tanca" + }, + "player": { + "back": { + "default": "Torna a l'inici", + "short": "Torna" + }, + "casting": { + "enabled": "S'està emetent al dispositiu…" + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Copia l'enllaç de la llista HLS", + "disclaimer": "Les baixades s'obtenen directament del proveïdor. SkoolTV no té control sobre com es proporcionen les baixades.", + "downloadSubtitle": "Baixa els subtítols actuals", + "downloadVideo": "Baixa el vídeo", + "hlsDisclaimer": "Les baixades s'obtenen directament del proveïdor. SkoolTV no té control sobre com es proporcionen les baixades.

Tingueu en compte que esteu baixant una llista de reproducció HLS, no es recomana baixar-la si no esteu familiaritzat amb formats de transmissió avançats. Proveu diferents fonts per a diferents formats.", + "onAndroid": { + "1": "Per a baixar-lo a Android, feu clic al botó de baixada i, a la pàgina nova, manteniu premut el vídeo i, a continuació, seleccioneu Desa.", + "shortTitle": "Baixa / Android", + "title": "Baixada a Android" + }, + "onIos": { + "1": "Per a baixar a iOS, feu clic al botó de baixada i, a la pàgina nova, feu clic a /> i, a continuació, Desa als Arxius .", + "shortTitle": "Baixa / iOS", + "title": "Baixada a iOS" + }, + "onPc": { + "1": "En un PC, feu clic al botó de baixada i, a la pàgina nova, feu clic amb el botó dret al vídeo i seleccioneu Anomena i desa el vídeo", + "shortTitle": "Baixa / PC", + "title": "Baixada a un PC" + }, + "title": "Baixa" + }, + "episodes": { + "button": "Episodi", + "emptyState": "No hi ha episodis en aquesta temporada, torneu-ho a comprovar més tard!", + "episodeBadge": "E{{episode}}", + "loadingError": "Error en carregar la temporada", + "loadingList": "S'està carregant…", + "loadingTitle": "S'està carregant…", + "unairedEpisodes": "Un o més episodis d'aquesta temporada s'han desactivat perquè encara no s'han emés." + }, + "playback": { + "speedLabel": "Velocitat de la reproducció", + "title": "Configuració de la reproducció" + }, + "quality": { + "automaticLabel": "Qualitat automàtica", + "hint": "Podeu provar a <0>canviar la font per a obtenir diferents opcions de qualitat.", + "iosNoQuality": "A causa de les limitacions definides per Apple, la selecció de qualitat no està disponible a iOS per a aquesta font. Podeu provar a <0>canviar a una altra font per a obtenir diferents opcions de qualitat.", + "title": "Qualitat" + }, + "settings": { + "downloadItem": "Baixa", + "enableSubtitles": "Activa els subtítols", + "experienceSection": "Experiència de visualització", + "playbackItem": "Configuració de la reproducció", + "qualityItem": "Qualitat", + "sourceItem": "Fonts de vídeo", + "subtitleItem": "Configuració dels subtítols", + "videoSection": "Configuració de vídeo" + }, + "sources": { + "failed": { + "text": "S'ha produït un error en intentar trobar vídeos, proveu una font diferent.", + "title": "No s'ha pogut obtenir" + }, + "noEmbeds": { + "text": "No hem pogut trobar cap incrustat, proveu una font diferent.", + "title": "No s'ha trobat cap incrustació" + }, + "noStream": { + "text": "Aquesta font no té fluxos per a aquesta pel·lícula o programa.", + "title": "Cap flux" + }, + "title": "Fonts", + "unknownOption": "Desconeguda" + }, + "subtitles": { + "customChoice": "Selecciona un fitxer de subtítols", + "customizeLabel": "Personalitza", + "offChoice": "Desactivats", + "settings": { + "backlink": "Subtítols personalitzats", + "delay": "Retard dels subtítols", + "fixCapitals": "Corregeix les majúscules/minúscules" + }, + "title": "Subtítols", + "unknownLanguage": "Desconeguda" + } + }, + "metadata": { + "api": { + "text": "No s'han pogut carregar les metadades de l'API, comproveu la connexió a Internet.", + "title": "No s'han pogut carregar les metadades de l'API" + }, + "dmca": { + "badge": "Eliminat", + "text": "Aquest contingut ja no està disponible a causa d'un avís de retirada o d'una reclamació de drets d'autor.", + "title": "El contingut s'ha eliminat" + }, + "extensionPermission": { + "badge": "Falta el permís", + "button": "Utilitza l'extensió", + "text": "Teniu l'extensió del navegador, però necessitem el vostre permís per a començar a utilitzar l'extensió.", + "title": "Configureu l'extensió" + }, + "failed": { + "badge": "Ha fallat", + "homeButton": "Vés a l'inici", + "text": "No s'han pogut carregar les metadades del contingut des de TMDB. Comproveu si TMDB no funciona o està bloquejat a la vostra connexió a Internet.", + "title": "Ha fallat la càrrega de les metadades" + }, + "notFound": { + "badge": "No s'ha trobat", + "homeButton": "Torna a l'inici", + "text": "No hem pogut trobar el contingut sol·licitat. O bé s'ha eliminat o bé heu alterat l'URL.", + "title": "No s'ha trobat el contingut." + } + }, + "nextEpisode": { + "cancel": "Cancel·la", + "next": "Episodi següent" + }, + "playbackError": { + "badge": "Error en la reproducció", + "errors": { + "errorAborted": "S'ha interromput l'obtenció del contingut per petició de l'usuari.", + "errorDecode": "Tot i haver-se determinat prèviament que era utilitzable, s'ha produït un error en intentar descodificar el recurs multimèdia.", + "errorGenericMedia": "S'ha produït un error desconegut al contingut.", + "errorNetwork": "S'ha produït algun tipus d'error de xarxa que ha impedit que el contingut s'obtinga correctament, tot i haver estat disponibles prèviament.", + "errorNotSupported": "El contingut o el proveïdor del contingut no és compatible." + }, + "homeButton": "Torna a l'inici", + "text": "S'ha produït un error en intentar reproduir el contingut. Torneu-ho a provar.", + "title": "No s'ha pogut reproduir el vídeo!" + }, + "scraping": { + "items": { + "failure": "S'ha produït un error", + "notFound": "No té el vídeo", + "pending": "S'estan cercant vídeos…" + }, + "notFound": { + "badge": "No s'ha trobat", + "detailsButton": "Mostra els detalls", + "homeButton": "Torna a l'inici", + "text": "Hem buscat a través dels nostres proveïdors i no trobem el contingut que busqueu! No allotgem contingut i no tenim control sobre què hi ha disponible. Feu clic a «Mostra els detalls» a continuació per a més informació.", + "title": "No s'ha pogut trobar" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} restants • Acaba a les {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Verifiqueu que sou humà completant el Captcha de la dreta. Ho fem per a mantenir segura SkoolTV!", + "error": "No s'ha pogut verificar la humanitat. Torneu-ho a provar.", + "title": "Necessitem verificar que sou humà.", + "verifyingHumanity": "Verificant la vostra humanitat…" + } + }, + "screens": { + "dmca": { + "text": "Us donem la benvinguda a la pàgina de contacte DMCA de SkoolTV! Respectem els drets de propietat intel·lectual i volem resoldre qualsevol problema de drets d'autor ràpidament. Si creieu que la vostra obra protegida per drets d'autor s'ha utilitzat incorrectament a la nostra plataforma, envieu un avís detallat de la DMCA al correu electrònic següent. Incloeu una descripció del material protegit per drets d'autor, les vostres dades de contacte i una declaració de creença de bona fe. Ens comprometem a resoldre aquests assumptes amb agilitat i agraïm la vostra col·laboració per a mantenir SkoolTV en un lloc que respecta la creativitat i els drets d'autor.", + "title": "DMCA" + }, + "loadingApp": "S'està carregant l'aplicació", + "loadingUser": "S'està carregant el perfil", + "loadingUserError": { + "logout": "Tanca la sessió", + "reset": "Restableix el servidor personalitzat", + "text": "Ha fallat la càrrega del perfil", + "textWithReset": "Error en carregar el vostre perfil des del servidor personalitzat, voleu restablir el servidor per defecte?" + }, + "migration": { + "failed": "La migració de les dades ha fallat.", + "inProgress": "Espereu, estem migrant les vostres dades. No hauria de tardar massa." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nom del dispositiu", + "deviceNamePlaceholder": "Telèfon personal", + "editProfile": "Edita", + "logoutButton": "Tanca la sessió" + }, + "actions": { + "delete": { + "button": "Elimina el compte", + "confirmButton": "Elimina el compte", + "confirmDescription": "Segur que voleu eliminar el compte? Es perdran totes les dades!", + "confirmTitle": "Segur?", + "text": "Aquesta acció és irreversible. Totes les dades s'eliminaran i no es podrà recuperar res.", + "title": "Elimina el compte" + }, + "title": "Accions" + }, + "devices": { + "deviceNameLabel": "Nom del dispositiu", + "failed": "La càrrega de sessions ha fallat", + "removeDevice": "Elimina", + "title": "Dispositiu" + }, + "profile": { + "finish": "Finalitza l'edició", + "firstColor": "Color de perfil 1", + "secondColor": "Color de perfil dos", + "title": "Edita la foto de perfil", + "userIcon": "Icona d'usuari" + }, + "register": { + "cta": "Comença", + "text": "Compartiu el progrés de la visualització entre dispositius i manteniu-los sincronitzats.", + "title": "Sincronització amb el núvol" + }, + "title": "Compte" + }, + "appearance": { + "activeTheme": "Actiu", + "themes": { + "blue": "Blau", + "default": "Per defecte", + "gray": "Gris", + "red": "Vermell", + "teal": "Verd blavós" + }, + "title": "Aparença" + }, + "connections": { + "server": { + "description": "Si voleu connectar-vos a un rerefons personalitzat per a emmagatzemar les vostres dades, activeu-ho i proporcioneu l'URL. <0>Instruccions.", + "label": "Servidor personalitzat", + "urlLabel": "URL del servidor personalitzat" + }, + "setup": { + "doSetup": "Configura", + "errorStatus": { + "description": "Sembla que heu de revisar un o més elements de la configuració.", + "title": "S'ha de revisar algun element" + }, + "itemError": "Hi ha alguna cosa malament en la configuració. Torneu a fer la configuració per a solucionar-ho.", + "items": { + "default": "Configuració per defecte", + "extension": "Extensió", + "proxy": "Servidor personalitzat" + }, + "redoSetup": "Reconfigura", + "successStatus": { + "description": "Tot està preparat perquè comenceu a mirar el vostre contingut preferit.", + "title": "Tot està configurat!" + }, + "unsetStatus": { + "description": "Feu clic al botó de la dreta per a iniciar el procés de configuració.", + "title": "No heu fet la configuració" + } + }, + "title": "Connexions", + "workers": { + "addButton": "Afegeix un «worker»", + "description": "Per fer funcionar l'aplicació, tot el trànsit s'encamina a través de servidors intermediaris. Activeu-ho si voleu portar els vostres propis «workers». <0>Instruccions.", + "emptyState": "Encara no hi ha «workers», afegiu-ne un a continuació", + "label": "Utilitza «workers» intermediaris personalitzats", + "urlLabel": "URL dels «workers»", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Llengua de l'aplicació", + "languageDescription": "La llengua s'aplica a tota l'aplicació.", + "thumbnail": "Genera miniatures", + "thumbnailDescription": "Majoritàriament, els vídeos no tenen miniatures. Podeu activar aquesta opció per a generar-les sobre la marxa, però poden alentir el vídeo.", + "thumbnailLabel": "Genera miniatures", + "title": "Configuració" + }, + "reset": "Restableix", + "save": "Desa", + "sidebar": { + "info": { + "appVersion": "Versió de l'aplicació", + "backendUrl": "URL del rerefons", + "backendVersion": "Versió del rerefons", + "hostname": "Nom de l'amfitrió", + "insecure": "Insegur", + "notLoggedIn": "No heu iniciat sessió", + "secure": "Segur", + "title": "Informació de l'aplicació", + "unknownVersion": "Desconeguda", + "userId": "ID d'usuari" + } + }, + "subtitles": { + "backgroundBlurLabel": "Difuminat del fons", + "backgroundLabel": "Opacitat del fons", + "colorLabel": "Color", + "previewQuote": "No he de tenir por. La por és l'assassina de la ment.", + "textSizeLabel": "Grandària del text", + "title": "Subtítols" + }, + "unsaved": "Hi ha canvis sense desar" + } +} diff --git a/src/assets/locales/ca@valencia.json b/src/assets/locales/ca@valencia.json new file mode 100644 index 0000000..cb606e6 --- /dev/null +++ b/src/assets/locales/ca@valencia.json @@ -0,0 +1,547 @@ +{ + "about": { + "description": "SkoolTV és una aplicació web que cerca fluxos a internet. L'equip té com a objectiu un enfocament majoritàriament minimalista del consum de contingut.", + "faqTitle": "Preguntes freqüents", + "q1": { + "body": "SkoolTV no allotja cap contingut. Quan feu clic en un contingut per a mirar-lo, es busca a Internet (a la pantalla de càrrega i a la pestanya «Fonts de vídeo» podeu mirar quina font utilitzeu). SkoolTV mai puja contingut, tot és a través del mecanisme de cerca.", + "title": "D'on prové el contingut?" + }, + "q2": { + "body": "No és possible sol·licitar un programa o una pel·lícula, SkoolTV no gestiona cap contingut. Tot el contingut es visualitza a través de fonts a internet.", + "title": "On puc sol·licitar un programa o una pel·lícula?" + }, + "q3": { + "body": "Els resultats de cerca funcionen amb The Movie Database (TMDB) i es mostren independentment de si les nostres fonts realment tenen el contingut.", + "title": "Els resultats de la cerca mostren el programa o la pel·lícula, per què no puc reproduir-lo?" + }, + "title": "Sobre SkoolTV" + }, + "actions": { + "copied": "S'ha copiat", + "copy": "Copia" + }, + "auth": { + "createAccount": "Encara no teniu un compte? <0>Creeu un compte.", + "deviceNameLabel": "Nom del dispositiu", + "deviceNamePlaceholder": "Telèfon personal", + "generate": { + "description": "La frase de contrasenya actua com a nom d'usuari i contrasenya. Assegureu-vos de mantindre-la segura, ja que haureu d'introduir-la per a iniciar la sessió al vostre compte", + "next": "He desat la frase de contrasenya", + "passphraseFrameLabel": "Frase de contrasenya", + "title": "La vostra frase de contrasenya" + }, + "hasAccount": "Ja teniu un compte? <0>Inicieu sessió ací.", + "login": { + "description": "Introduïu la vostra frase de contrasenya per a iniciar sessió al vostre compte", + "deviceLengthError": "Introduïu un nom per al dispositiu", + "passphraseLabel": "Frase de contrasenya de 12 paraules", + "passphrasePlaceholder": "Frase de contrasenya", + "submit": "Inicia sessió", + "title": "Inicieu sessió al vostre compte", + "validationError": "Frase de contrasenya incorrecta o incompleta" + }, + "register": { + "information": { + "color1": "Color de perfil 1", + "color2": "Color de perfil 2", + "header": "Introduïu un nom per al dispositiu i trieu els colors i la icona d'usuari que vulgueu", + "icon": "Icona d'usuari", + "next": "Següent", + "title": "Informació del compte" + } + }, + "trust": { + "failed": { + "text": "L'heu configurada correctament?", + "title": "No s'ha pogut accedir al servidor" + }, + "host": "Esteu connectant-vos a <0>{{hostname}}. Confirmeu que hi confieu abans de crear un compte", + "no": "Torna", + "noHost": "El servidor no s'ha configurat, per tant, no es pot crear un compte", + "noHostTitle": "El servidor no està configurat!", + "title": "Confieu en este servidor?", + "yes": "Confie en este servidor" + }, + "verify": { + "description": "Introduïu la vostra frase de contrasenya anterior per a confirmar que l'heu desat, i crear el compte", + "invalidData": "La data no és vàlida", + "noMatch": "La frase de contrasenya no coincideix", + "passphraseLabel": "Frase de contrasenya de 12 paraules", + "recaptchaFailed": "Ha fallat la validació de ReCaptcha", + "register": "Crea el compte", + "title": "Confirmeu la frase de contrasenya" + } + }, + "errors": { + "badge": "S'ha trencat", + "details": "Detalls de l'error", + "reloadPage": "Recarrega la pàgina", + "showError": "Mostra els detalls de l'error", + "title": "Hem trobat un error!" + }, + "footer": { + "legal": { + "disclaimer": "Avís d'exempció de responsabilitat", + "disclaimerText": "SkoolTV no allotja cap fitxer, només enllaça a serveis de tercers. Els problemes legals s'han d'abordar amb qui allotja i els proveïdors de fitxers. SkoolTV no es fa responsable del contingut mostrat pels proveïdors de vídeo." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Mireu els vostres programes i pel·lícules preferits amb esta aplicació de codi obert de reproducció en temps real." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Quant a", + "dmca": "DMCA", + "login": "Inicia sessió", + "onboarding": "Configura", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registra", + "settings": "Configuració" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Marcadors" + }, + "continueWatching": { + "sectionTitle": "Continueu mirant" + }, + "mediaList": { + "stopEditing": "Deixa d'editar" + }, + "search": { + "allResults": "Això és tot el que tenim!", + "failed": "No s'ha pogut trobar cap contingut, torneu-ho a provar!", + "loading": "S'està carregant…", + "noResults": "No hem pogut trobar res!", + "placeholder": { + "default": "Què voleu mirar?", + "extra": [ + "Què voleu explorar?", + "Què hi ha a la vostra llista de seguiment?", + "Quina és la vostra pel·lícula preferida?", + "Quina és la vostra sèrie preferida?" + ] + }, + "sectionTitle": "Resultats de la cerca" + }, + "titles": { + "day": { + "default": "Què vos agradaria mirar esta vesprada?", + "extra": [ + "Voleu aventura? Jurassic Park podria ser l'elecció perfecta." + ] + }, + "morning": { + "default": "Què vos agradaria mirar este matí?", + "extra": [ + "He sentit que «Abans de l'alba» és bona" + ] + }, + "night": { + "default": "Què vos agradaria mirar esta nit?", + "extra": [ + "Esteu cansat? He sentit que «L'exorcista» és bona." + ] + } + } + }, + "media": { + "episodeDisplay": "T{{season}} E{{episode}}", + "types": { + "movie": "Pel·lícula", + "show": "Sèrie/Programa" + } + }, + "navigation": { + "banner": { + "offline": "Comproveu la connexió a internet" + }, + "menu": { + "about": "Quant a nosaltres", + "logout": "Tanca la sessió", + "register": "Sincronitza al núvol", + "settings": "Configuració", + "support": "Ajuda" + } + }, + "notFound": { + "badge": "No s'ha trobat", + "goHome": "Torna a l'inici", + "message": "Hem mirat per tot arreu: davall de les papereres, a l'armari, darrere del servidor intermediari, però al remat no hem pogut trobar la pàgina que busqueu.", + "title": "No s'ha pogut trobar la pàgina" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Cancel·la", + "confirm": "Usa la configuració per defecte", + "description": "La configuració per defecte no té els millors fluxos i pot ser insuportablement lenta.", + "title": "Segur?" + }, + "extension": { + "back": "Torna", + "explainer": "Mitjançant l'extensió del navegador, podeu obtindre els millors fluxos que oferim. Amb només una simple instal·lació.", + "explainerIos": "Lamentablement, l'extensió del navegador no és compatible amb iOS, premeu Torna per a triar una altra opció.", + "extensionHelp": "Si heu instal·lat l'extensió, però no es detecta, obriu l'extensió al menú d'extensions del navegador i seguiu els passos en pantalla.", + "linkChrome": "Instal·la l'extensió de Chrome", + "linkFirefox": "Instal·la l'extensió de Firefox", + "notDetecting": "S'ha instal·lat a Chrome, però el lloc no el detecta? Proveu de recarregar la pàgina.", + "notDetectingAction": "Recarrega la pàgina", + "status": { + "disallowed": "L'extensió no està activada per a esta pàgina", + "disallowedAction": "Activa l'extensió", + "failed": "No s'ha pogut sol·licitar l'estat", + "loading": "Esperant que instal·leu l'extensió", + "outdated": "La versió de l'extensió és massa antiga", + "success": "L'extensió funciona com s'esperava!" + }, + "submit": "Continua", + "title": "Comencem amb una extensió" + }, + "proxy": { + "back": "Torna", + "explainer": "Amb el mètode del servidor intermediari, podeu obtindre fluxos d'alta qualitat fent un servidor intermediari propi.", + "input": { + "errorConnection": "No s'ha pogut connectar al servidor intermediari", + "errorInvalidUrl": "URL no vàlid", + "errorNotProxy": "S'esperava un servidor intermediari, però és un lloc web", + "label": "URL del servidor intermediari", + "placeholder": "https://" + }, + "link": "Com fer un servidor intermediari", + "submit": "Envia el servidor intermediari", + "title": "Fem un nou servidor intermediari" + }, + "start": { + "explainer": "Per a obtindre els millors fluxos possibles, haureu de triar quin mètode de transmissió voleu utilitzar.", + "options": { + "default": { + "text": "No vull fluxos de bona qualitat,<0 /> <1>utilitza la configuració per defecte" + }, + "extension": { + "action": "Instal·la l'extensió", + "description": "Instal·leu l'extensió del navegador i accediu a les millors fonts.", + "quality": "Millor qualitat", + "title": "Extensió del navegador" + }, + "proxy": { + "action": "Configura el servidor intermediari", + "description": "Configureu un servidor intermediari en només 5 minuts i accediu a bones fonts.", + "quality": "Bona qualitat", + "title": "Servidor intermediari personalitzat" + } + }, + "title": "Configurem el SkoolTV" + } + }, + "overlays": { + "close": "Tanca" + }, + "player": { + "back": { + "default": "Torna a l'inici", + "short": "Torna" + }, + "casting": { + "enabled": "S'està emetent al dispositiu…" + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Copia l'enllaç de la llista HLS", + "disclaimer": "Les baixades s'obtenen directament del proveïdor. SkoolTV no té control sobre com es proporcionen les baixades.", + "downloadSubtitle": "Baixa els subtítols actuals", + "downloadVideo": "Baixa el vídeo", + "hlsDisclaimer": "Les baixades s'obtenen directament del proveïdor. SkoolTV no té control sobre com es proporcionen les baixades.

Tingueu en compte que esteu baixant una llista de reproducció HLS, no es recomana baixar-la si no esteu familiaritzat amb formats de transmissió avançats. Proveu diferents fonts per a diferents formats.", + "onAndroid": { + "1": "Per a baixar-lo a Android, feu clic al botó de baixada i, a la pàgina nova, manteniu premut el vídeo i, a continuació, seleccioneu Desa.", + "shortTitle": "Baixa / Android", + "title": "Baixada a Android" + }, + "onIos": { + "1": "Per a baixar a iOS, feu clic al botó de baixada i, a la pàgina nova, feu clic a /> i, a continuació, Desa als Arxius .", + "shortTitle": "Baixa / iOS", + "title": "Baixada a iOS" + }, + "onPc": { + "1": "En un PC, feu clic al botó de baixada i, a la pàgina nova, feu clic amb el botó dret al vídeo i seleccioneu Anomena i desa el vídeo", + "shortTitle": "Baixa / PC", + "title": "Baixada a un PC" + }, + "title": "Baixa" + }, + "episodes": { + "button": "Episodi", + "emptyState": "No hi ha episodis en esta temporada, torneu-ho a comprovar més tard!", + "episodeBadge": "E{{episode}}", + "loadingError": "Error en carregar la temporada", + "loadingList": "S'està carregant…", + "loadingTitle": "S'està carregant…", + "unairedEpisodes": "Un o més episodis d'esta temporada s'han desactivat perquè encara no s'han emés." + }, + "playback": { + "speedLabel": "Velocitat de la reproducció", + "title": "Configuració de la reproducció" + }, + "quality": { + "automaticLabel": "Qualitat automàtica", + "hint": "Podeu provar a <0>canviar la font per a obtindre diferents opcions de qualitat.", + "iosNoQuality": "A causa de les limitacions definides per Apple, la selecció de qualitat no està disponible a iOS per a esta font. Podeu provar a <0>canviar a una altra font per a obtindre diferents opcions de qualitat.", + "title": "Qualitat" + }, + "settings": { + "downloadItem": "Baixa", + "enableSubtitles": "Activa els subtítols", + "experienceSection": "Experiència de visualització", + "playbackItem": "Configuració de la reproducció", + "qualityItem": "Qualitat", + "sourceItem": "Fonts de vídeo", + "subtitleItem": "Configuració dels subtítols", + "videoSection": "Configuració de vídeo" + }, + "sources": { + "failed": { + "text": "S'ha produït un error en intentar trobar vídeos, proveu una font diferent.", + "title": "No s'ha pogut obtindre" + }, + "noEmbeds": { + "text": "No hem pogut trobar cap incrustat, proveu una font diferent.", + "title": "No s'ha trobat cap incrustació" + }, + "noStream": { + "text": "esta font no té fluxos per a esta pel·lícula o programa.", + "title": "Cap flux" + }, + "title": "Fonts", + "unknownOption": "Desconeguda" + }, + "subtitles": { + "customChoice": "Selecciona un fitxer de subtítols", + "customizeLabel": "Personalitza", + "offChoice": "Desactivats", + "settings": { + "backlink": "Subtítols personalitzats", + "delay": "Retard dels subtítols", + "fixCapitals": "Corregeix les majúscules/minúscules" + }, + "title": "Subtítols", + "unknownLanguage": "Desconeguda" + } + }, + "metadata": { + "api": { + "text": "No s'han pogut carregar les metadades de l'API, comproveu la connexió a Internet.", + "title": "No s'han pogut carregar les metadades de l'API" + }, + "dmca": { + "badge": "Eliminat", + "text": "este contingut ja no està disponible a causa d'un avís de retirada o d'una reclamació de drets d'autor.", + "title": "El contingut s'ha eliminat" + }, + "extensionPermission": { + "badge": "Falta el permís", + "button": "Utilitza l'extensió", + "text": "Teniu l'extensió del navegador, però necessitem el vostre permís per a començar a utilitzar l'extensió.", + "title": "Configureu l'extensió" + }, + "failed": { + "badge": "Ha fallat", + "homeButton": "Vés a l'inici", + "text": "No s'han pogut carregar les metadades del contingut des de TMDB. Comproveu si TMDB no funciona o està bloquejat a la vostra connexió a Internet.", + "title": "Ha fallat la càrrega de les metadades" + }, + "notFound": { + "badge": "No s'ha trobat", + "homeButton": "Torna a l'inici", + "text": "No hem pogut trobar el contingut sol·licitat. O bé s'ha eliminat o bé heu alterat l'URL.", + "title": "No s'ha trobat el contingut." + } + }, + "nextEpisode": { + "cancel": "Cancel·la", + "next": "Episodi següent" + }, + "playbackError": { + "badge": "Error en la reproducció", + "errors": { + "errorAborted": "S'ha interromput l'obtenció del contingut per petició de l'usuari.", + "errorDecode": "Tot i haver-se determinat prèviament que era utilitzable, s'ha produït un error en intentar descodificar el recurs multimèdia.", + "errorGenericMedia": "S'ha produït un error desconegut al contingut.", + "errorNetwork": "S'ha produït algun tipus d'error de xarxa que ha impedit que el contingut s'obtinga correctament, tot i haver estat disponibles prèviament.", + "errorNotSupported": "El contingut o el proveïdor del contingut no és compatible." + }, + "homeButton": "Torna a l'inici", + "text": "S'ha produït un error en intentar reproduir el contingut. Torneu-ho a provar.", + "title": "No s'ha pogut reproduir el vídeo!" + }, + "scraping": { + "items": { + "failure": "S'ha produït un error", + "notFound": "No té el vídeo", + "pending": "S'estan cercant vídeos…" + }, + "notFound": { + "badge": "No s'ha trobat", + "detailsButton": "Mostra els detalls", + "homeButton": "Torna a l'inici", + "text": "Hem buscat a través dels nostres proveïdors i no trobem el contingut que busqueu! No allotgem contingut i no tenim control sobre què hi ha disponible. Feu clic a «Mostra els detalls» a continuació per a més informació.", + "title": "No s'ha pogut trobar" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} restants • Acaba a les {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Verifiqueu que sou humà completant el Captcha de la dreta. Ho fem per a mantindre segura SkoolTV!", + "error": "No s'ha pogut verificar la humanitat. Torneu-ho a provar.", + "title": "Necessitem verificar que sou humà.", + "verifyingHumanity": "Verificant la vostra humanitat…" + } + }, + "screens": { + "dmca": { + "text": "Vos donem la benvinguda a la pàgina de contacte DMCA de SkoolTV! Respectem els drets de propietat intel·lectual i volem resoldre qualsevol problema de drets d'autor ràpidament. Si creieu que la vostra obra protegida per drets d'autor s'ha utilitzat incorrectament a la nostra plataforma, envieu un avís detallat de la DMCA al correu electrònic següent. Incloeu una descripció del material protegit per drets d'autor, les vostres dades de contacte i una declaració de creença de bona fe. Ens comprometem a resoldre estes assumptes amb agilitat i agraïm la vostra col·laboració per a mantindre SkoolTV en un lloc que respecta la creativitat i els drets d'autor.", + "title": "DMCA" + }, + "loadingApp": "S'està carregant l'aplicació", + "loadingUser": "S'està carregant el perfil", + "loadingUserError": { + "logout": "Tanca la sessió", + "reset": "Restableix el servidor personalitzat", + "text": "Ha fallat la càrrega del perfil", + "textWithReset": "Error en carregar el vostre perfil des del servidor personalitzat, voleu restablir el servidor per defecte?" + }, + "migration": { + "failed": "La migració de les dades ha fallat.", + "inProgress": "Espereu, estem migrant les vostres dades. No hauria de tardar massa." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nom del dispositiu", + "deviceNamePlaceholder": "Telèfon personal", + "editProfile": "Edita", + "logoutButton": "Tanca la sessió" + }, + "actions": { + "delete": { + "button": "Elimina el compte", + "confirmButton": "Elimina el compte", + "confirmDescription": "Segur que voleu eliminar el compte? Es perdran totes les dades!", + "confirmTitle": "Segur?", + "text": "Esta acció és irreversible. Totes les dades s'eliminaran i no es podrà recuperar res.", + "title": "Elimina el compte" + }, + "title": "Accions" + }, + "devices": { + "deviceNameLabel": "Nom del dispositiu", + "failed": "La càrrega de sessions ha fallat", + "removeDevice": "Elimina", + "title": "Dispositiu" + }, + "profile": { + "finish": "Finalitza l'edició", + "firstColor": "Color de perfil 1", + "secondColor": "Color de perfil dos", + "title": "Edita la foto de perfil", + "userIcon": "Icona d'usuari" + }, + "register": { + "cta": "Comença", + "text": "Compartiu el progrés de la visualització entre dispositius i manteniu-los sincronitzats.", + "title": "Sincronització amb el núvol" + }, + "title": "Compte" + }, + "appearance": { + "activeTheme": "Actiu", + "themes": { + "blue": "Blau", + "default": "Per defecte", + "gray": "Gris", + "red": "Vermell", + "teal": "Verd blavós" + }, + "title": "Aparença" + }, + "connections": { + "server": { + "description": "Si voleu connectar-vos a un rerefons personalitzat per a emmagatzemar les vostres dades, activeu-ho i proporcioneu l'URL. <0>Instruccions.", + "label": "Servidor personalitzat", + "urlLabel": "URL del servidor personalitzat" + }, + "setup": { + "doSetup": "Configura", + "errorStatus": { + "description": "Sembla que heu de revisar un o més elements de la configuració.", + "title": "S'ha de revisar algun element" + }, + "itemError": "Hi ha alguna cosa malament en la configuració. Torneu a fer la configuració per a solucionar-ho.", + "items": { + "default": "Configuració per defecte", + "extension": "Extensió", + "proxy": "Servidor personalitzat" + }, + "redoSetup": "Reconfigura", + "successStatus": { + "description": "Tot està preparat perquè comenceu a mirar el vostre contingut preferit.", + "title": "Tot està configurat!" + }, + "unsetStatus": { + "description": "Feu clic al botó de la dreta per a iniciar el procés de configuració.", + "title": "No heu fet la configuració" + } + }, + "title": "Connexions", + "workers": { + "addButton": "Afig un «worker»", + "description": "Per fer funcionar l'aplicació, tot el trànsit s'encamina a través de servidors intermediaris. Activeu-ho si voleu portar els vostres propis «workers». <0>Instruccions.", + "emptyState": "Encara no hi ha «workers», afegiu-ne un a continuació", + "label": "Utilitza «workers» intermediaris personalitzats", + "urlLabel": "URL dels «workers»", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Llengua de l'aplicació", + "languageDescription": "La llengua s'aplica a tota l'aplicació.", + "thumbnail": "Genera miniatures", + "thumbnailDescription": "Majoritàriament, els vídeos no tenen miniatures. Podeu activar esta opció per a generar-les sobre la marxa, però poden alentir el vídeo.", + "thumbnailLabel": "Genera miniatures", + "title": "Configuració" + }, + "reset": "Restableix", + "save": "Desa", + "sidebar": { + "info": { + "appVersion": "Versió de l'aplicació", + "backendUrl": "URL del rerefons", + "backendVersion": "Versió del rerefons", + "hostname": "Nom de l'amfitrió", + "insecure": "Insegur", + "notLoggedIn": "No heu iniciat sessió", + "secure": "Segur", + "title": "Informació de l'aplicació", + "unknownVersion": "Desconeguda", + "userId": "ID d'usuari" + } + }, + "subtitles": { + "backgroundBlurLabel": "Difuminat del fons", + "backgroundLabel": "Opacitat del fons", + "colorLabel": "Color", + "previewQuote": "No he de tindre por. La por és l'assassina de la ment.", + "textSizeLabel": "Grandària del text", + "title": "Subtítols" + }, + "unsaved": "Hi ha canvis sense desar" + } +} diff --git a/src/assets/locales/cs.json b/src/assets/locales/cs.json new file mode 100644 index 0000000..4e90675 --- /dev/null +++ b/src/assets/locales/cs.json @@ -0,0 +1,540 @@ +{ + "about": { + "description": "SkoolTV je webová aplikace, která vyhledává na internetu proudy médií. Cílem týmu je převážně minimalistický přístup ke konzumaci obsahu.", + "faqTitle": "Často kladené otázky", + "q1": { + "body": "SkoolTV nehostuje žádný obsah. Když kliknete na něco, co chcete sledovat, na internetu se vyhledá vybrané médium (Na obrazovce načítání a na kartě 'zdroje videa' můžete vidět, který zdroj používáte). Média se nikdy nenahrávají SkoolTVem, vše probíhá prostřednictvím tohoto vyhledávacího mechanismu.", + "title": "Kde bereme obsah?" + }, + "q2": { + "body": "Není možné požádat o pořad nebo film, SkoolTV nespravuje žádný obsah. Veškerý obsah je prohlížen prostřednictvím zdrojů na internetu.", + "title": "Kde můžu požádat o pořad nebo film?" + }, + "q3": { + "body": "Naše výsledky vyhledávání jsou založeny na The Movie Database (TMDB) a zobrazují se bez ohledu na to, zda naše zdroje skutečně obsah mají.", + "title": "Ve výsledcích vyhledávání se zobrazuje pořad nebo film, proč jej nemůžu přehrát?" + }, + "title": "O SkoolTVu" + }, + "actions": { + "copied": "Zkopírováno", + "copy": "Zkopírovat" + }, + "auth": { + "createAccount": "Ještě nemáte účet? <0>Vytvořte si účet.", + "deviceNameLabel": "Název zařízení", + "deviceNamePlaceholder": "Osobní telefon", + "generate": { + "description": "Vaše přístupová fráze se chová jako vaše přezdívka a heslo. Uchovejte jí v bezpečí, protože jí budete muset zadat, abyste se mohli přihlásit ke svému účtu", + "next": "Uložil jsem si moji přístupovou frázi", + "passphraseFrameLabel": "Přístupová fráze", + "title": "Vaše přístupová fráze" + }, + "hasAccount": "Již máte účet? <0> Přihlaste se zde.", + "login": { + "description": "Pro přihlášení ke svému účtu zadejte svou přístupovou frázi", + "deviceLengthError": "Zadejte název zařízení", + "passphraseLabel": "12slovná přístupová fráze", + "passphrasePlaceholder": "Přístupová fráze", + "submit": "Přihlásit", + "title": "Přihlaste se ke svému účtu", + "validationError": "Nesprávná nebo neúplná přístupová fráze" + }, + "register": { + "information": { + "color1": "První barva profilu", + "color2": "Druhá barva profilu", + "header": "Zadejte název pro vaše zařízení a vyberte barvy a ikonu uživatele podle vašeho výběru", + "icon": "Ikona uživatele", + "next": "Další", + "title": "Informace o účtu" + } + }, + "trust": { + "failed": { + "text": "Nastavili jste to správně?", + "title": "Selhalo připojení k serveru" + }, + "host": "Připojujete se k <0>{{hostname}} - potvrďte, že mu věříte před vytvořením účtu", + "no": "Zpět", + "noHost": "Server nebyl nakonfigurován, tudíž si nemůžete vytvořit účet", + "noHostTitle": "Server není nakonfigurován!", + "title": "Věříte tomuto serveru?", + "yes": "Věřím tomuto serveru" + }, + "verify": { + "description": "Zadejte prosím svou přístupovou frázi, abyste potvrdili, že jste si ji uložili, a vytvořte si účet", + "invalidData": "Data nejsou platná", + "noMatch": "Přístupová fráze neodpovídá", + "passphraseLabel": "Vaše 12slovná přístupová fráze", + "recaptchaFailed": "ReCaptcha ověření se nezdařilo", + "register": "Založit účet", + "title": "Potvrďte vaši přístupovou frázi" + } + }, + "errors": { + "badge": "Rozbilo se to", + "details": "Detaily chyby", + "reloadPage": "Znovu načíst stránku", + "showError": "Ukázat detaily chyby", + "title": "Narazili jsme na chybu!" + }, + "footer": { + "legal": { + "disclaimer": "Zřeknutí odpovědnosti", + "disclaimerText": "SkoolTV nehostuje žádné soubory, pouze odkazuje na služby třetích stran. Právní záležitosti by měly být řešeny s hostiteli souborů a poskytovateli. SkoolTV nenese odpovědnost za žádné mediální soubory zobrazené poskytovateli videa." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Sledujte své oblíbené pořady a filmy s touto aplikací pro streamování s otevřeným zdrojovým kódem." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "O nás", + "dmca": "DMCA", + "login": "Přihlásit se", + "onboarding": "Nastavení", + "pagetitle": "{{title}} - SkoolTV", + "register": "Zaregistrovat se", + "settings": "Nastavení" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Záložky" + }, + "continueWatching": { + "sectionTitle": "Pokračujte ve sledování" + }, + "mediaList": { + "stopEditing": "Přestat upravovat" + }, + "search": { + "allResults": "To je vše co máme!", + "failed": "Nepodařilo se najít média, zkuste to znovu!", + "loading": "Načítání...", + "noResults": "Nemohli jsme nic najít!", + "placeholder": { + "default": "Co si přejete sledovat?", + "extra": [ + "Co chcete objevit?", + "Co je na vašem seznamu sledovaných filmů?", + "Jaký je váš oblíbený film?", + "Jaký je tvůj oblíbený seriál?" + ] + }, + "sectionTitle": "Výsledky vyhledávání" + }, + "titles": { + "day": { + "default": "Na co byste se chtěli dnes odpoledne dívat?", + "extra": ["Chceš zažít dobrodružství? Jurský Park je pro tebe."] + }, + "morning": { + "default": "Na co byste se chtěli dnes ráno dívat?", + "extra": ["Slyšel jsem, že Před úsvitem je super"] + }, + "night": { + "default": "Na co byste se chtěli dnes večer dívat?", + "extra": ["Unaven? Slyšel jsem, že Vymítač ďábla je super."] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Seriál" + } + }, + "navigation": { + "banner": { + "offline": "Zkontrolujte své internetové připojení" + }, + "menu": { + "about": "O nás", + "logout": "Odhlásit se", + "register": "Synchronizovat do sudo-cloudu", + "settings": "Nastavení", + "support": "Podpořte nás" + } + }, + "notFound": { + "badge": "Nenalezeno", + "goHome": "Zpátky domů", + "message": "Dívali jsme se všude: pod koši, ve skříni, za proxy, ale nakonec jsme nemohli najít stránku, kterou hledáte.", + "title": "Tuto stránku se nepodařilo najít" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Zrušit", + "confirm": "Použít výchozí nastavení", + "description": "Výchozí nastavení nemá nejlepší streamy a může být strašně pomalá.", + "title": "Jste si jist?" + }, + "extension": { + "back": "Zpět", + "explainer": "Pomocí rozšíření prohlížeče můžete získat nejlepší streamy, které nabízíme. S pouhou instalací.", + "explainerIos": "Bohužel rozšíření není podporováno na iOS. Stiskněte Zpět pro výběr jiné možnosti.", + "extensionHelp": "Pokud jste rozšíření nainstalovali, ale nebylo zjištěno, otevřete rozšíření pomocí nabídky rozšíření ve vašem prohlížeči a postupujte podle pokynů na obrazovce.", + "linkChrome": "Instalovat rozšíření pro Chrome", + "linkFirefox": "Instalovat rozšíření pro Firefox", + "notDetecting": "Nainstalováno na Chromu, ale stránka to nezaznamenala? Skuste přenačíst stránku!", + "notDetectingAction": "Obnovit stránku", + "status": { + "disallowed": "Rozšíření není pro tuto stránku povoleno", + "disallowedAction": "Povolit rozšíření", + "failed": "Nezdařilo se získávání stavu", + "loading": "Čekání na instalaci rozšíření", + "outdated": "Verze rozšíření je příliš stará", + "success": "Rozšíření funguje podle očekávání!" + }, + "submit": "Pokračovat", + "title": "Začněme s rozšířením" + }, + "proxy": { + "back": "Zpět", + "explainer": "Pomocí metody proxy můžete získat streamy ve skvělé kvalitě vytvořením proxy serveru.", + "input": { + "errorConnection": "Nelze se připojit k proxy", + "errorInvalidUrl": "Adresa URL není platná", + "errorNotProxy": "Byla očekávaná proxy, ale byla předána webová stránka", + "label": "Proxy URL", + "placeholder": "https://" + }, + "link": "Naučit se vytvořit proxy", + "submit": "Předložit proxy", + "title": "Pojďme uďelat novou proxy" + }, + "start": { + "explainer": "Abyste získali co nejlepší streamy, musíte zvolit, kterou streamovací metodu chcete použít.", + "options": { + "default": { + "text": "Nechci zdroje s dobrou kvalitou,<0 /> <1>použít výchozí nastavení" + }, + "extension": { + "action": "Nainstalujte si rozšíření", + "description": "Nainstalujte si rozšíření prohlížeče a získejte přístup k nejlepším zdrojům.", + "quality": "Nejlepší kvalita", + "title": "Rozšíření prohlížeče" + }, + "proxy": { + "action": "Nastavit proxy", + "description": "Nastavte si proxy během 5 minut, pro získání přístupu k skvělým zdrojům.", + "quality": "Dobrá kvalita", + "title": "Vlastní proxy" + } + }, + "title": "Pojďme vám nastavit SkoolTV" + } + }, + "overlays": { + "close": "Zavřít" + }, + "player": { + "back": { + "default": "Zpátky domů", + "short": "Zpět" + }, + "casting": { + "enabled": "Odesílání do zařízení..." + }, + "menus": { + "downloads": { + "disclaimer": "Stahování probíhá přímo u poskytovatele. SkoolTV nemá kontrolu nad tím, jak jsou stahování poskytovány.", + "downloadSubtitle": "Stáhnout aktuální titulky", + "downloadVideo": "Stáhnout video", + "hlsDisclaimer": "Stahování probíhá přímo u poskytovatele. SkoolTV nemá kontrolu nad tím, jak jsou stahování poskytovány.

Vezměte prosím na vědomí, že stahujete HLS playlist, který není doporučen stahovat pokud nejste obeznámeni s pokročilým streamováním médií. Raději skuste jiný zdroj pro jiný formát.", + "onAndroid": { + "1": "Na Androidu klikněte na tlačítko stahování, poté na nové stránce klepněte a podržte na videu a poté vyberte uložit.", + "shortTitle": "Stahování / Android", + "title": "Stahování na Androidu" + }, + "onIos": { + "1": "Na iOS klikněte na tlačítko stahování a poté na nové stránce klikněte na a poté na Uložit do souborů .", + "shortTitle": "Stahování / iOS", + "title": "Stahování na iOS" + }, + "onPc": { + "1": "Na počítači klikněte na tlačítko stahování, poté na nové stránce klikněte pravým tlačítkem na video a vyberte Uložit video jako", + "shortTitle": "Stahování / počítač", + "title": "Stahování na počítači" + }, + "title": "Stáhnout" + }, + "episodes": { + "button": "Epizody", + "emptyState": "V této sezóně nejsou žádné epizody, vraťte se později!", + "episodeBadge": "E{{episode}}", + "loadingError": "Chyba při načítání sezóny", + "loadingList": "Načítání...", + "loadingTitle": "Načítání...", + "unairedEpisodes": "Jedna nebo více epizod v této sezóně nejsou dostupné, protože ještě nebyly odvysílány." + }, + "playback": { + "speedLabel": "Rychlost přehrávání", + "title": "Nastavení přehrávání" + }, + "quality": { + "automaticLabel": "Automatická kvalita", + "hint": "Chcete-li získat jinou kvalitu, můžete zkusit <0>přepnout zdroj.", + "iosNoQuality": "Kvůli omezením definovaným společností Apple není pro tento zdroj v iOS k dispozici výběr kvality. Chcete-li získat jinou kvalitu, můžete zkusit <0>přepnout zdroj.", + "title": "Kvalita" + }, + "settings": { + "downloadItem": "Stáhnout", + "enableSubtitles": "Zapnout titulky", + "experienceSection": "Zážitek sledování", + "playbackItem": "Nastavení přehrávání", + "qualityItem": "Kvalita", + "sourceItem": "Zdroje videa", + "subtitleItem": "Nastavení titulků", + "videoSection": "Nastavení videa" + }, + "sources": { + "failed": { + "text": "Při pokusu o nalezení videí došlo k chybě. Zkuste prosím jiný zdroj.", + "title": "Nepodařilo se extrahovat data" + }, + "noEmbeds": { + "text": "Nepodařilo se nám najít žádný vklad, zkuste prosím jiný zdroj.", + "title": "Žádné vklady" + }, + "noStream": { + "text": "Tento zdroj nemá pro tento film nebo pořad žádné proudy média.", + "title": "Žádný proud média" + }, + "title": "Zdroje", + "unknownOption": "Neznámý" + }, + "subtitles": { + "customChoice": "Vybrat titulky ze souboru", + "customizeLabel": "Přizpůsobit", + "offChoice": "Vypnuto", + "settings": { + "backlink": "Vlastní titulky", + "delay": "Posunutí titulků", + "fixCapitals": "Opravit velká písmena" + }, + "title": "Titulky", + "unknownLanguage": "Neznámé" + } + }, + "metadata": { + "api": { + "text": "Metadata API nelze načíst, zkontrolujte prosím vaše připojení k internetu.", + "title": "Nepodařilo se načíst API metadata" + }, + "dmca": { + "badge": "Odstraněno", + "text": "Toto média není dostupné, kvůli oznámení o zastavení šíření nebo nároku na autorská práva.", + "title": "Média byla odstraněna" + }, + "extensionPermission": { + "badge": "Chybí povolení", + "button": "Použít rozšíření", + "text": "Máte rozšíření, ale k jeho použití potřebujeme vaše povolení.", + "title": "Konfigurace rozšíření" + }, + "failed": { + "badge": "Neúspěšný", + "homeButton": "Jít domů", + "text": "Nelze načíst metadata média z TMDB. Zkontrolujte, zda není TMDB nefunkční nebo blokovaný na vašem internetovém připojení.", + "title": "Načtení metadat se nezdařilo" + }, + "notFound": { + "badge": "Nenalezeno", + "homeButton": "Zpátky domů", + "text": "Nemohli jsme najít média o které jste požádali. Buď bylo odstraňeno, nebo jste manipulovali s URL.", + "title": "Nemohli jsme najít Vaše média." + } + }, + "nextEpisode": { + "cancel": "Zrušit", + "next": "Další epizoda" + }, + "playbackError": { + "badge": "Chyba přehrávání", + "errors": { + "errorAborted": "Načítání média bylo přerušeno uživatelem.", + "errorDecode": "Navzdory tomu, že bylo dříve určeno jako použitelné došlo při pokusu o dekódování média k chybě.", + "errorGenericMedia": "Nastala chyba neznámého média.", + "errorNetwork": "Nastala nějaká chyba síťě, která zabránila načtení média, přestože bylo předtím dostupné.", + "errorNotSupported": "Médium nebo poskytovatel média není podporovaný." + }, + "homeButton": "Jít domů", + "text": "Nastala chyba při přehrávání média. Prosíme skuste to znovu.", + "title": "Video se nepodařilo přehrát!" + }, + "scraping": { + "items": { + "failure": "Nastala chyba", + "notFound": "Nemá toto video", + "pending": "Ověřování videí..." + }, + "notFound": { + "badge": "Nenalezeno", + "detailsButton": "Zobrazit podrobnosti", + "homeButton": "Jít domů", + "text": "Prohledali jsme naše poskytovatele a nenašli jsme média, která hledáte! Nehostujeme žádné média a nemáme žádnou kontrolu nad tím, co je k dispozici. Pro více podrobností klikněte níže na 'Zobrazit podrobnosti'.", + "title": "Nedokázali jsme to najít" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} zbývá • Dokončeno v {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Ověřte, prosím, že jste člověk, vyplněním Captchy napravo. Toto je pro zajištění bezpečnosti SkoolTV!", + "error": "Nepodařilo se ověřit vaši lidskost. Zkuste to prosím znovu.", + "title": "Potřebujeme ověřit, zda jste člověk.", + "verifyingHumanity": "Ověřování vaši lidskosti..." + } + }, + "screens": { + "dmca": { + "text": "Vítejte na DMCA kontaktní stránce SkoolTVu! Respektujeme práva duševního vlastnictví a chceme rychle řešit jakékoli problémy s autorským právem. Pokud se domníváte, že vaše dílo chráněné autorskými právy bylo na naší platformě neoprávněně použito, zašlete prosím podrobné oznámení DMCA na níže uvedený e-mail. Uveďte prosím popis materiálu chráněného autorským právem, své kontaktní údaje a prohlášení o dobré víře. Jsme odhodláni tyto záležitosti rychle vyřešit a oceňujeme vaši spolupráci při udržování SkoolTVu jako místa, které respektuje kreativitu a autorská práva.", + "title": "DMCA" + }, + "loadingApp": "Načítání aplikace", + "loadingUser": "Načítání vášeho profilu", + "loadingUserError": { + "logout": "Odhlásit se", + "reset": "Resetovat vlastní server", + "text": "Nezdařilo se načíst váš profil", + "textWithReset": "Nezdařilo se načíst váš profil z vašeho serveru, chcete ho přepnout na výchozí server?" + }, + "migration": { + "failed": "Migrace dat se nezdařila.", + "inProgress": "Počkejte prosím, migrujeme vaše data. Nemělo by to trvat dlouho." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Název zařízení", + "deviceNamePlaceholder": "Osobní telefon", + "editProfile": "Upravit", + "logoutButton": "Odhlásit se" + }, + "actions": { + "delete": { + "button": "Smazat účet", + "confirmButton": "Smazat účet", + "confirmDescription": "Jste si jisti, že chcete smazat váš účet? Všechny data budou ztracena!", + "confirmTitle": "Jste si jisti?", + "text": "Tato akce nejde vrátit. Všechny data budou smazána a nic nepůjde zachránit.", + "title": "Smazat účet" + }, + "title": "Akce" + }, + "devices": { + "deviceNameLabel": "Název zařízení", + "failed": "Načtení relací se nezdařilo", + "removeDevice": "Odstranit", + "title": "Zařízení" + }, + "profile": { + "finish": "Dokončit", + "firstColor": "První barva profilu", + "secondColor": "Druhá barva profilu", + "title": "Upravit profilovou fotografii", + "userIcon": "Ikona uživatele" + }, + "register": { + "cta": "Začněte", + "text": "Sdílejte průběh sledování mezi zařízeními a udržujte je synchronizovaná.", + "title": "Synchronizace do sudo-cloudu" + }, + "title": "Účet" + }, + "appearance": { + "activeTheme": "Aktivní", + "themes": { + "blue": "Modrá", + "default": "Výchozí", + "gray": "Šedá", + "red": "Červená", + "teal": "Modrozelená" + }, + "title": "Vzhled" + }, + "connections": { + "server": { + "description": "Pokud se chcete připojit k vlastnímu backendu pro ukládání dat, povolte toto a zadejte URL adresu. <0>Instrukce.", + "label": "Vlastní server", + "urlLabel": "URL adresa vlastního serveru" + }, + "setup": { + "doSetup": "Proveďte nastavení", + "errorStatus": { + "description": "Vypadá to, že jedna nebo více položek v tomto nastavení potřebuje vaši pozornost.", + "title": "Něco potřebuje vaši pozornost" + }, + "itemError": "S tímto nastavením je něco špatně. Projděte znovu nastavením abyste to opravili.", + "items": { + "default": "Výchozí nastavení", + "extension": "Rozšíření", + "proxy": "Vlastní proxy" + }, + "redoSetup": "Proveďte znovu nastavení", + "successStatus": { + "description": "Všechny věci jsou připraveny, abyste mohli začít sledovat svá oblíbená média.", + "title": "Všechno je nastaveno!" + }, + "unsetStatus": { + "description": "Prosím klikněte na vedlejší tlačítko abyste začali proces nastavování.", + "title": "Neprošli jste nastavením" + } + }, + "title": "Spojení", + "workers": { + "addButton": "Přidat nového pracovníka", + "description": "Aby byla aplikace funkční, veškerá trafika prochází přes proxy. Povolte toto, pokud chcete používat svoje vlastní pracovníky. <0>Instrukce.", + "emptyState": "Zatím žádní pracovníci, přidej jednoho dolů", + "label": "Použít vlastní proxy pracovníky", + "urlLabel": "URL adresy pracovníků", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Jazyk aplikace", + "languageDescription": "Jazyk aplikován na celou aplikaci.", + "thumbnail": "Generovat miniatury", + "thumbnailDescription": "Videa většinou nemají miniatury. Toto nastavení můžete povolit, ale mohou zpomalit vaše video.", + "thumbnailLabel": "Generovat miniatury", + "title": "Preference" + }, + "reset": "Resetovat", + "save": "Uložit", + "sidebar": { + "info": { + "appVersion": "Verze aplikace", + "backendUrl": "URL backendu", + "backendVersion": "Verze backendu", + "hostname": "Název hostitele", + "insecure": "nebezpečný", + "notLoggedIn": "Nejste přihlášen", + "secure": "bezpečný", + "title": "Informace o aplikaci", + "unknownVersion": "Neznámo", + "userId": "Uživatelské ID" + } + }, + "subtitles": { + "backgroundBlurLabel": "Rozostření pozadí", + "backgroundLabel": "Neprůhlednost pozadí", + "colorLabel": "Barva", + "previewQuote": "Nesmím se bát. Strach zabíjí myšlení.", + "textSizeLabel": "Velikost textu", + "title": "Titulky" + }, + "unsaved": "Máte neuložené změny" + } +} diff --git a/src/assets/locales/da.json b/src/assets/locales/da.json new file mode 100644 index 0000000..5fb665c --- /dev/null +++ b/src/assets/locales/da.json @@ -0,0 +1,626 @@ +{ + "about": { + "faqTitle": "Ofte stillede spørgsmål", + "q1": { + "title": "Hvor kommer indholdet fra?", + "body": "SkoolTV er ikke udbyder af indholdet. Når du klikker på et medie for at se det, søges der på internettet efter det valgte medie (på indlæsningsskærmen og i fanen 'videokilder' kan du se, hvilken kilde du bruger). Medier bliver aldrig uploadet af SkoolTV, alt sker gennem denne søgemaskine." + }, + "q2": { + "body": "Det er ikke muligt at anmode om en serie eller film, SkoolTV administrerer ikke noget indhold. Alt indhold ses gennem kilder på internettet.", + "title": "Hvor kan jeg ønske en serie eller film?" + }, + "q3": { + "body": "Vores søgeresultater er leveret af The Movie Database (TMDB) og vises, uanset om kilderne rent faktisk har indholdet.", + "title": "Søgeresultaterne viser serien eller filmen, men hvorfor kan jeg ikke afspille den?" + }, + "q4": { + "title": "Hvad med mine data og andet?", + "body": "Alle oplysninger synkroniseres til sudo-backend, som er anderledes end community-backend og hostes selvstændigt af mig, men alle er velkomne til at bruge den." + }, + "q5": { + "body": "SkoolTV har en twitter-bruger, som du kan finde i bunden af denne side, samt et link til kildekoden på Github.", + "title": "Hvordan kan jeg finde ud af mere?" + }, + "title": "Om SkoolTV (^▽^)", + "description": "SkoolTV er en variant af movie-web, som er sikret at forblive oppe, selv efter at movie-web.app er lukket ned. SkoolTV.lol kører på en privat, selvhostet VPS. Jeg driver denne hjemmeside med underskud; der er ingen reklamer på grund af min tro på gratis medie." + }, + "actions": { + "copied": "Kopieret", + "copy": "Kopier" + }, + "auth": { + "createAccount": "Du har ikke en profil endnu 😬 <0>Opret en profil.", + "deviceNameLabel": "Navn på enhed", + "deviceNamePlaceholder": "Personlig telefon", + "generate": { + "next": "Jeg har gemt min adgangssætning", + "passphraseFrameLabel": "Adgangssætning", + "title": "Din adgangssætning", + "description": "Din adgangssætning fungerer som dit brugernavn og adgangskode. Sørg for at opbevare den sikkert, da du skal bruge den til at logge ind på din profil. Husk IKKE at glemme din adgangskode!" + }, + "hasAccount": "Har du allerede en profil? <0>Log ind her.", + "login": { + "description": "Indtast din adgangssætning for at logge ind på din profil", + "deviceLengthError": "Indtast venligst et enhedens navn", + "passphraseLabel": "Adgangssætning på 12 ord", + "passphrasePlaceholder": "Adgangssætning", + "submit": "Log ind", + "title": "Log ind på din profil", + "validationError": "Forkert eller ukomplet adgangssætning /ᐠ. .ᐟ\\" + }, + "register": { + "information": { + "icon": "Brugerikon", + "next": "Næste", + "title": "Oplysninger om din profil", + "color1": "Profil farve 1", + "color2": "Profil farve 2", + "header": "Indtast et navn til din enhed, vælg farver og et brugerikon efter eget valg!" + } + }, + "trust": { + "failed": { + "text": "Har du konfigureret det korrekt?", + "title": "Det lykkedes ikke at kontakte serveren" + }, + "noHostTitle": "Serveren er ikke konfigureret!", + "noHost": "Serveren er ikke konfigureret, derfor kan du ikke oprette en profil", + "title": "Stoler du på den her server?", + "no": "Gå tilbage", + "yes": "Jeg stoler på denne server 🤞", + "host": "Du forbinder til <0>{{hostname}} - vær sikker på, at du stoler på den, før du opretter en profil..." + }, + "verify": { + "invalidData": "Oplysningerne er ikke gyldige", + "noMatch": "Adgangssætningen stemmer ikke overens 😭", + "passphraseLabel": "Din adgangssætning på 12 ord", + "recaptchaFailed": "ReCaptcha validering mislykkedes", + "register": "Opret profil", + "title": "Bekræft din adgangssætning", + "description": "Indtast din adgangssætning fra tidligere for at bekræfte, at du har gemt den, og for at oprette din profil" + } + }, + "errors": { + "details": "Fejloplysninger", + "reloadPage": "Genindlæs siden", + "showError": "Vis fejloplysninger", + "title": "Der er opstået en fejl!", + "badge": "Noget gik galt 💀" + }, + "footer": { + "legal": { + "disclaimer": "Ansvarsfraskrivelse ◝(ᵔᵕᵔ)◜", + "disclaimerText": "Bemærk: SkoolTV hoster ikke selv nogen filer, men viser i stedet kun indhold fra tredjepartsudbydere. Lovmæssige forhold bør afklares med dem." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub", + "twitter": "Twitter" + }, + "tagline": "Se dine favoritserier og -film gratis og uden reklamer! (っ'ヮ'c)" + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Om os", + "dmca": "DMCA", + "support": "Support", + "login": "Log ind", + "onboarding": "Opsætning", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registrer", + "settings": "Indstillinger", + "discover": "Opdag" + } + }, + "home": { + "continueWatching": { + "sectionTitle": "Fortsæt med at se..." + }, + "mediaList": { + "stopEditing": "Stop med at redigere" + }, + "search": { + "allResults": "Det er alt, hvad vi har...", + "failed": "Kunne ikke finde noget, prøv igen!", + "loading": "Indlæser...", + "noResults": "Vi kunne ikke finde noget :(", + "placeholder": { + "extra": [ + "Hvad har du lyst til?", + "Skal vi slette din browserhistorik?", + "Hvad ønsker du at streame?", + "SkoolTV er den bedste side nogensinde!", + "Hvad er der på din favoritliste i dag?", + "Hvordan har din dag været?", + "Min fejl, siden virker aldrig...", + "Er SkoolTV ikke bare det bedste?", + ">ᴗ<" + ], + "default": "Hvad har du lyst til at se?" + }, + "empty": { + "default": "Velkommen, find noget at se her!", + "extra": [ + "Der er intet her :(", + "Så tomt...", + "Sikke en masse luft.", + "Hej nye medlem :3" + ] + }, + "sectionTitle": "Søgeresultater", + "discoverMore": "Opdag mere", + "discover": "Opdag" + }, + "bookmarks": { + "sectionTitle": "Bogmærker" + }, + "titles": { + "day": { + "default": "Hvad vil du gerne se i eftermiddag?", + "extra": ["Længe leve SkoolTV!"] + }, + "morning": { + "default": "Hvad vil du gerne se her til morgen?", + "extra": ["Længe leve SkoolTV!"] + }, + "night": { + "extra": ["Længe leve SkoolTV!"], + "default": "Hvad vil du gerne se i aften?" + }, + "420": { + "default": "Hvad vil du gerne se denne 4/20?", + "extra": ["Glædelig 4/20 🥳!"] + }, + "69": { + "default": "Har du lyst til at \"hygge\"?", + "extra": ["Glædelig 69-dag 😘!"] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} - E{{episode}}", + "unreleased": "Ikke udgivet", + "types": { + "movie": "Film", + "show": "Serie" + } + }, + "navigation": { + "menu": { + "about": "Om os", + "logout": "Log ud", + "register": "Synkroniser til sudo-cloud", + "settings": "Indstillinger", + "support": "Support", + "discover": "Opdag" + }, + "banner": { + "offline": "Kontroller din internetforbindelse, fjollehoved!" + } + }, + "notFound": { + "badge": "Ikke fundet", + "reloadButton": "Prøv igen", + "title": "Kunne ikke finde den side", + "goHome": "Tilbage til hjem", + "message": "Vi har ledt overalt: under skraldespandene, i skabet, bag proxy'en, men i sidste ende kunne vi ikke finde den side, du leder efter. (ಥ﹏ಥ)" + }, + "downtimeNotice": { + "badge": "Problemer", + "timeFrame": "31. marts kl. 23:00 - 5:00 EST", + "goHome": "Gå til hjem", + "title": "Problemer med udbydere", + "message": "SkoolTV.lol har igen problemer med nogle udbydere. Hvis du ikke kan finde eller afspille et afsnit, skal du skifte kilde. Vi forventer, at denne fejl fortsætter i tidsrummet nedenfor." + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Annuller", + "confirm": "Brug standardopsætning", + "description": "Standardopsætningen har ikke de bedste streams og kan være ulideligt langsom ( ͠° ͟ʖ ͡°)", + "title": "Er du sikker?" + }, + "extension": { + "back": "Gå tilbage", + "explainer": "Ved hjælp af browserudvidelsen kan du få de bedste streams, vi har at byde på. Med blot en simpel installation. 👌", + "explainerIos": "Desværre understøttes browserudvidelsen ikke på iOS, tryk på Gå tilbage for at vælge en anden mulighed.", + "extensionHelp": "Hvis du har installeret udvidelsen, men den ikke registreres, skal du åbne udvidelsen via din browsers udvidelsesmenu og følge trinnene på skærmen.", + "linkChrome": "Installer Chrome-udvidelse", + "linkFirefox": "Installer Firefox-udvidelse", + "notDetecting": "Installeret på Chrome, men siden registrerer den ikke? Prøv at genindlæse siden!", + "notDetectingAction": "Genindlæs siden", + "status": { + "disallowed": "Udvidelse er ikke aktiveret for denne side (,,>﹏<,,)", + "failed": "Anmodning om status mislykkedes", + "loading": "Venter på, at du installerer udvidelsen", + "outdated": "Udvidelsesversion for gammel", + "success": "Udvidelsen fungerer som forventet!", + "disallowedAction": "Aktiver udvidelse" + }, + "submit": "Fortsæt", + "title": "Lad os starte med en udvidelse" + }, + "proxy": { + "back": "Gå tilbage", + "input": { + "errorConnection": "Kunne ikke forbinde til proxy", + "errorInvalidUrl": "Ikke en gyldig webadresse", + "errorNotProxy": "Forventede en proxy, men fik en hjemmeside", + "label": "Proxy URL", + "placeholder": "https://" + }, + "link": "Lær, hvordan du laver en proxy", + "submit": "Indsend proxy", + "title": "Lad os lave en ny proxy", + "explainer": "Med proxymetoden kan du få streams af høj kvalitet ved at lave en selvbetjent proxy." + }, + "start": { + "options": { + "extension": { + "action": "Installer udvidelse", + "description": "Installer browserudvidelsen og få adgang til de bedste kilder, men husk at aktivere den for denne side.", + "quality": "Bedste kvalitet", + "title": "Browserudvidelse" + }, + "proxy": { + "quality": "God kvalitet", + "title": "Brugerdefineret proxy", + "description": "Opret en gratis proxy på bare 5 minutter, og få adgang til gode kilder...", + "action": "Opsæt proxy" + }, + "default": { + "text": "Jeg vil ikke have god kvalitet, <0 /> <1>brug standardopsætningen ▄︻デ══━一 ʕ-͡--ʔ" + } + }, + "title": "Lad os få dig sat op med SkoolTV 🥳", + "explainer": "For at få de bedst mulige streams skal du vælge, hvilken streamingmetode du vil bruge." + } + }, + "overlays": { + "close": "Luk" + }, + "player": { + "back": { + "default": "Tilbage til hjem", + "short": "Tilbage" + }, + "casting": { + "enabled": "Cast til enhed 🎬" + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Kopier link til HLS-playliste", + "downloadSubtitle": "Download aktuel undertekst", + "downloadVideo": "Download video", + "onAndroid": { + "1": "For at downloade på Android skal du klikke på download-knappen og derefter, på den nye side, trykke og holde på videoen og derefter vælge gem.", + "shortTitle": "Download / Android", + "title": "Download på Android" + }, + "onIos": { + "1": "For at downloade på iOS skal du klikke på download-knappen og derefter på den nye side klikke på og derefter Save to Files .", + "shortTitle": "Download / iOS", + "title": "Download på iOS" + }, + "onPc": { + "shortTitle": "Download / PC", + "title": "Download på pc", + "1": "På PC skal du klikke på download-knappen og derefter højreklikke på videoen på den nye side og vælge Gem video som" + }, + "title": "Download", + "hlsDisclaimer": "Downloads tages direkte fra udbyderen. SkoolTV har ikke kontrol over, hvordan downloads leveres.

Vær opmærksom på, at du downloader en HLS-playliste, det anbefales ikke at downloade, hvis du ikke er bekendt med avancerede streamingformater. Prøv forskellige kilder til forskellige formater.", + "disclaimer": "Downloads tages direkte fra udbyderen. SkoolTV har ikke kontrol over, hvordan downloads leveres." + }, + "episodes": { + "button": "Episoder", + "emptyState": "Der er ingen episoder i denne sæson, kom tilbage senere (undskyld :3)...", + "episodeBadge": "E{{episode}}", + "loadingError": "Fejl under indlæsning af sæson", + "loadingList": "Indlæser...", + "loadingTitle": "Indlæser...", + "unairedEpisodes": "Et eller flere afsnit i denne sæson er blevet deaktiveret, fordi de ikke er blevet udgivet endnu.", + "seasons": "Sæsoner" + }, + "playback": { + "title": "Afspilningsindstillinger", + "speedLabel": "Afspilningshastighed" + }, + "quality": { + "automaticLabel": "Automatisk kvalitet", + "title": "Kvalitet", + "hint": "Du kan prøve <0>at skifte kilde for at få forskellige muligheder for kvalitet.", + "iosNoQuality": "På grund af Apple-definerede (almindelige IOS L) begrænsninger er valg af kvalitet ikke tilgængelig på iOS for denne kilde. Du kan prøve <0>at skifte til en anden kilde for at få forskellige muligheder for kvalitet." + }, + "settings": { + "downloadItem": "Download", + "experienceSection": "Oplevelse af visning", + "playbackItem": "Afspilningsindstillinger", + "audioItem": "Lyd", + "qualityItem": "Kvalitet", + "sourceItem": "Videokilder", + "subtitleItem": "Undertekstindstillinger", + "videoSection": "Videoindstillinger", + "enableSubtitles": "Aktiver undertekster" + }, + "sources": { + "failed": { + "text": "Der skete en fejl under søgningen efter videoer... Prøv en anden kilde?", + "title": "Kunne ikke scrape" + }, + "noEmbeds": { + "text": "Vi kunne ikke finde nogen embeds, prøv venligst en anden kilde.", + "title": "Ingen embeds fundet" + }, + "noStream": { + "text": "Denne kilde har ingen streams for denne film eller serie. /ᐠ - ˕ -マ Ⳋ", + "title": "Ingen stream :(" + }, + "title": "Kilder", + "unknownOption": "Ukendt" + }, + "subtitles": { + "customChoice": "Drop eller upload fil", + "customizeLabel": "Tilpasning", + "offChoice": "Fra", + "OpenSubtitlesChoice": "OpenSubtitles", + "settings": { + "delay": "Undertekstforsinkelse", + "fixCapitals": "Ret store bogstaver", + "backlink": "Brugerdefinerede undertekster" + }, + "title": "Undertekster", + "unknownLanguage": "Ukendt", + "dropSubtitleFile": "Drop undertekstfilen her! >_<", + "scrapeButton": "Scrape undertekster", + "empty": "Der er ingen undertekster til dette." + } + }, + "metadata": { + "api": { + "text": "API-metadata kunne ikke indlæses, tjek venligst din internetforbindelse.", + "title": "API-metadata kunne ikke indlæses" + }, + "dmca": { + "badge": "Fjernet", + "title": "Mediet er blevet fjernet", + "text": "Dette medie er ikke længere tilgængeligt på grund af en meddelelse om fjernelse eller krav om ophavsret. 😨" + }, + "extensionPermission": { + "badge": "Tilladelse mangler", + "button": "Brug udvidelse", + "text": "Du har browserudvidelsen, men vi har brug for din tilladelse til at komme i gang med at bruge udvidelsen. (¬_¬)", + "title": "Konfigurer udvidelsen" + }, + "failed": { + "homeButton": "Gå til hjem", + "title": "Kunne ikke indlæse metadata", + "badge": "Fejlede", + "text": "Mediets metadata kunne ikke indlæses fra TMDB. Tjek venligst, om TMDB er nede eller blokeret på din internetforbindelse." + }, + "notFound": { + "badge": "Ikke fundet", + "homeButton": "Tilbage til hjem", + "title": "Kunne ikke finde det medie.", + "text": "Vi kunne ikke finde det medie, du bad om. Enten er det blevet fjernet, eller også har du pillet ved URL'en (din pillefinger)." + } + }, + "playbackError": { + "homeButton": "Gå til hjem", + "badge": "Afspilningsfejl", + "errors": { + "errorAborted": "Indlæsningen af mediet blev afbrudt efter brugerens anmodning.", + "errorDecode": "På trods af at mediet tidligere er blevet vurderet til at være brugbart, opstod der en fejl under forsøget på at afkode medieressourcen, hvilket resulterede i en fejl.", + "errorGenericMedia": "Der opstod en ukendt mediefejl.", + "errorNotSupported": "Mediet eller medieudbyderobjektet understøttes ikke.", + "errorNetwork": "Der opstod en netværksfejl, som forhindrede, at mediet kunne hentes, selv om det tidligere havde været tilgængeligt." + }, + "text": "Der opstod en fejl under forsøget på at afspille mediet 😖. Prøv venligst igen!", + "title": "Kunne ikke afspille videoen!" + }, + "scraping": { + "notFound": { + "homeButton": "Gå til hjem", + "badge": "Ikke fundet", + "detailsButton": "Vis detaljer", + "title": "Vi kunne ikke finde det", + "discoverButton": "Opdag mere", + "text": "Vi har søgt gennem vores udbydere og kan ikke finde de medier, du leder efter! Vi hoster ikke medierne og har ingen kontrol over, hvad der er tilgængeligt. Klik på 'Vis detaljer' nedenfor for at få flere detaljer." + }, + "extensionFailure": { + "homeButton": "Gå til hjem", + "badge": "Udvidelse deaktiveret", + "text": "Du har installeret SkoolTV-udvidelsen. For at begynde at bruge den skal du aktivere udvidelsen for dette websted.", + "enableExtension": "Aktiver udvidelse", + "title": "Aktiver venligst udvidelsen" + }, + "items": { + "failure": "Der opstod en fejl", + "notFound": "Har ikke videoen (╥﹏╥)", + "pending": "Tjekker for videoer..." + } + }, + "nextEpisode": { + "replay": "Gentag", + "next": "Næste episode", + "nextSeason": "Næste sæson" + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} tilbage • Færdig til {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Bevis at du er et menneske ved at udføre den hurtige opgave, det er for at holde SkoolTV sikker.", + "verifyingHumanity": "Bekræfter at du er et menneske... (^▽^)👍", + "title": "Er du en robot 🤖?", + "error": "Kunne ikke bekræfte at du er et menneske! Prøv venligst igen." + } + }, + "support": { + "title": "Support", + "q1": { + "body": "Du kan deltage i den officielle <0>SkoolTV discord og stille spørgsmål der, eller du kan sende en e-mail til den, der er angivet nederst på denne side.", + "title": "Hvor kan jeg få hjælp?" + }, + "q2": { + "title": "Hvordan kan jeg rapportere en fejl eller et problem?", + "body": "Vi har en <0>GitHub, hvor du kan oprette et detaljeret problem i vores repository. Hvis du ønsker det, kan du desuden oprette en pull request for selv at løse problemet." + }, + "text": "SkoolTV er designet til at være så brugervenlig som muligt. Men folk har stadig spørgsmål og problemer. Denne side er her for at hjælpe med at løse disse problemer" + }, + "screens": { + "dmca": { + "title": "DMCA :(", + "text": "Velkommen til SkoolTV' DMCA-kontaktside. Hvis du mener, at dit ophavsretligt beskyttede arbejde er blevet brugt forkert på vores platform (😢), bedes du sende en detaljeret DMCA-meddelelse til: {{dmca}} nedenfor. Inkluder venligst en beskrivelse af det ophavsretligt beskyttede materiale, dine kontaktoplysninger og en erklæring om, at du er i god tro. Vi er forpligtet til at løse disse sager hurtigt og sætter pris på dit samarbejde." + }, + "loadingApp": "Indlæser applikation", + "loadingUser": "Indlæser din profil", + "loadingUserError": { + "logout": "Log ud", + "reset": "Nulstil brugerdefineret server", + "text": "Kunne ikke indlæse din profil", + "reload": "Genindlæs", + "textWithReset": "Kunne du ikke indlæse din profil fra din brugerdefinerede server, og vil du nulstille til standardserveren?" + }, + "migration": { + "failed": "Det lykkedes ikke at migrere dine data. 😿", + "inProgress": "Vent venligst, vi er ved at overfører dine data. Det burde ikke tage lang tid..." + } + }, + "settings": { + "account": { + "devices": { + "deviceNameLabel": "Navn på enhed", + "failed": "Kunne ikke indlæse sessioner", + "removeDevice": "Fjern", + "title": "Enheder" + }, + "accountDetails": { + "deviceNameLabel": "Navn på enhed", + "deviceNamePlaceholder": "Personlig telefon", + "editProfile": "Rediger", + "logoutButton": "Log ud" + }, + "admin": { + "title": "Administratorpanel", + "text": "Brug værktøjer, der er lavet til at teste SkoolTV' tilstand.", + "button": "Tjek det ud" + }, + "actions": { + "delete": { + "title": "Slet profil", + "confirmButton": "Slet profil", + "button": "Slet profil", + "confirmDescription": "Er du sikker på, at du vil slette din profil? Alle dine data vil gå tabt! ૮₍˶Ó﹏Ò ⑅₎ა", + "confirmTitle": "Er du sikker?", + "text": "Denne handling er permanent. Alle data slettes, og intet kan gendannes." + }, + "title": "Handlinger" + }, + "profile": { + "finish": "Afslut redigering", + "firstColor": "Profil farve 1", + "secondColor": "Profil farve 2", + "title": "Rediger profilbillede", + "userIcon": "Brugerikon" + }, + "register": { + "text": "Del fremskridt mellem enheder, og hold dem synkroniseret. ( ̧⸝⸝⍢⸝⸝)ෆ", + "title": "Synkroniser med sudo-cloud", + "cta": "Kom godt i gang" + }, + "title": "Profil" + }, + "appearance": { + "activeTheme": "Aktiv", + "themes": { + "blue": "Blå", + "default": "Standard", + "gray": "Grå", + "red": "Rød", + "teal": "Blågrøn", + "blck": "BLCK" + }, + "title": "Udseende" + }, + "connections": { + "server": { + "label": "Brugerdefineret server", + "urlLabel": "Brugerdefineret server URL", + "description": "Hvis du gerne vil oprette forbindelse til en brugerdefineret server for at gemme dine data, skal du aktivere dette og angive URL'en. <0>Instruktioner." + }, + "setup": { + "doSetup": "Lav opsætning", + "errorStatus": { + "description": "Det ser ud til, at en eller flere ting i denne opsætning kræver din opmærksomhed.", + "title": "Noget kræver din opmærksomhed 😱" + }, + "itemError": "Der er noget galt med denne indstilling. Gå gennem opsætningen igen for at rette det. (ᴗ_ ᴗ。)", + "items": { + "default": "Standardopsætning", + "extension": "Udvidelse", + "proxy": "Brugerdefineret proxy" + }, + "redoSetup": "Gentag opsætning", + "successStatus": { + "title": "Alt er sat op!", + "description": "Alt er på plads, så du kan begynde at se dine yndlingsmedier. (๑>◡<๑)" + }, + "unsetStatus": { + "description": "Klik på knappen til højre for at starte opsætningen.", + "title": "Du har ikke gennemgået opsætningen" + } + }, + "title": "Forbindelser", + "workers": { + "addButton": "Tilføj ny arbejder", + "emptyState": "Ingen arbejdere endnu (。-́︿-̀。), tilføj en nedenfor", + "label": "Brug brugerdefinerede proxy-arbejdere", + "urlLabel": "Arbejder-URL'er", + "urlPlaceholder": "https://", + "description": "For at få applikationen til at fungere dirigeres al trafik gennem proxyer. Aktiver dette, hvis du vil have dine egne arbejdere. <0>Instruktioner." + } + }, + "preferences": { + "language": "Applikationens sprog", + "languageDescription": "Sproget gælder for hele applikationen, kun engelsk har fjollede ting 🙁.", + "thumbnailLabel": "Generer miniaturebilleder", + "thumbnail": "Generer miniaturebilleder", + "autoplay": "Autoplay", + "autoplayLabel": "Autoplay", + "sourceOrder": "Omorganisering af kilder", + "sourceOrderDescription": "Træk og slip for at omarrangere kilder. Det afgør, i hvilken rækkefølge kilderne tjekkes for de medier, du prøver at se. Hvis en kilde er nedtonet, betyder det, at den ikke er tilgængelig på din enhed.", + "title": "Præferencer", + "thumbnailDescription": "Det meste af tiden har videoer ikke miniaturebilleder. Du kan aktivere denne indstilling for at generere dem undervejs, men de kan gøre din video mere langsom.", + "autoplayDescription": "Afspil automatisk den næste episode i en serie, når den er slut. Kan aktiveres af brugere med browserudvidelsen, en brugerdefineret proxy eller med standardopsætningen, hvis hosten tillader det." + }, + "reset": "Nulstil", + "save": "Gem", + "sidebar": { + "info": { + "appVersion": "App version", + "backendUrl": "Backend URL", + "backendVersion": "Backend version", + "hostname": "Hostname", + "insecure": "Usikker", + "notLoggedIn": "Du er ikke logget ind", + "secure": "Sikker", + "title": "Appstatistik (for nørder) 🤓", + "unknownVersion": "Ukendt", + "userId": "Bruger ID" + } + }, + "subtitles": { + "backgroundLabel": "Baggrundsopacitet", + "colorLabel": "Farve", + "previewQuote": "Vil du helst have en lesbisk datter eller en homoseksuel søn? 🤔", + "textSizeLabel": "Tekststørrelse", + "title": "Undertekster", + "textBoldLabel": "Fed tekst", + "backgroundBlurLabel": "Sløring af baggrund" + }, + "unsaved": "Du har ændringer, der ikke er gemt... ฅ^•ﻌ•^ฅ" + } +} diff --git a/src/assets/locales/de.json b/src/assets/locales/de.json new file mode 100644 index 0000000..7c7c454 --- /dev/null +++ b/src/assets/locales/de.json @@ -0,0 +1,553 @@ +{ + "about": { + "description": "SkoolTV ist eine Web-App, welche das Internet nach Streams durchsucht. Das Team versucht einen minimalistischen Ansatz umzusetzen.", + "faqTitle": "Häufig gestellte Fragen", + "q1": { + "body": "SkoolTV hostet keinen eigenen Inhalt. Wenn du auf etwas zum Anschauen klickst, wird das Internet danach durchsucht (Auf dem Ladebildschirm und im Tab \"Videoquellen\" kannst du einstellen, welche Quellen verwendet werden sollen). SkoolTV lädt keine Videos hoch, alleVideos stammen aus der Suche.", + "title": "Woher stammen die Videos?" + }, + "q2": { + "body": "Das Anfragen von Serien oder Filmen ist nicht möglich. SkoolTV verwaltet keine Inhalte. Alle Videos stammen vom Quellen aus dem Internet.", + "title": "Wo kann ich eine Serie oder einen Film anfragen?" + }, + "q3": { + "body": "Unsere Suchergebnisse werden von The Movie Database (TMDB) bereitgestellt und, egal ob unsere Videoquellen über dieses Video verfügen, angezeigt.", + "title": "Die Suche zeigt eine Serie oder einen Film an, warum kann ich den dann nicht abspielen?" + }, + "title": "Über SkoolTV" + }, + "actions": { + "copied": "Kopiert", + "copy": "Kopieren" + }, + "auth": { + "createAccount": "Du hast noch keinen Account? <0>Registriere dich jetzt.", + "deviceNameLabel": "Gerätename", + "deviceNamePlaceholder": "Handy", + "generate": { + "description": "Deine Passphrase dient als dein Nutzername und Passwort. Speichere sie sicher ab, damit du dich in deinem Konto anmelden kannst", + "next": "Ich habe meine Passphrase gespeichert", + "passphraseFrameLabel": "Passphrase", + "title": "Deine Passphrase" + }, + "hasAccount": "Du hast bereits einen Account? <0>Anmelden.", + "login": { + "description": "Gebe deine Passphrase ein, um dich in deinem Konto anzumelden", + "deviceLengthError": "Gebe einen Gerätenamen ein", + "passphraseLabel": "12-Wort Passphrase", + "passphrasePlaceholder": "Passphrase", + "submit": "Anmelden", + "title": "Melde dich in deinem Konto an", + "validationError": "Falsche oder unvollständige Passphrase" + }, + "register": { + "information": { + "color1": "Profilfarbe 1", + "color2": "Profilfarbe 2", + "header": "Gebe einen Namen für dein Gerät ein und wähle ein Symbol", + "icon": "Symbol", + "next": "Weiter", + "title": "Kontoinformationen" + } + }, + "trust": { + "failed": { + "text": "Hast du es korrekt konfiguriert?", + "title": "Server nicht erreichbar" + }, + "host": "Du verbindest dich mit <0>{{hostname}} - stelle sicher das du dem Server vertraust, bevor du ein Konto erstellst", + "no": "Zurück", + "noHost": "Da der Server nicht eingerichtet wurde, kannst du keinen Account erstellen", + "noHostTitle": "Server nicht eingerichtet!", + "title": "Vertraust du diesem Server?", + "yes": "Ich vertraue diesem Server" + }, + "verify": { + "description": "Bitte gebe deine Passphrase ein, um zu bestätigen, dass du sie gespeichert hast und um dein Konto zu erstellen", + "invalidData": "Daten sind ungültig", + "noMatch": "Passphrasen stimmen nicht überein", + "passphraseLabel": "Deine 12-Wort Passphrase", + "recaptchaFailed": "ReCaptcha Verifizierung ist fehlgeschlagenen", + "register": "Konto erstellen", + "title": "Bestätige deine Passphrase" + } + }, + "errors": { + "badge": "Kaputt", + "details": "Fehlerdetails", + "reloadPage": "Seite neuladen", + "showError": "Zeige Fehlerdetails an", + "title": "Ein Fehler ist aufgetreten!" + }, + "footer": { + "legal": { + "disclaimer": "Hinweis", + "disclaimerText": "SkoolTV hostet keine Dateien, sondern verlinkt lediglich auf Dienste Dritter. Rechtliche Fragen sollten mit den Dateihostern und -anbietern geklärt werden. SkoolTV übernimmt keine Verantwortung für die von den Videoanbietern angezeigten Mediendateien." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Schau deine Lieblingsserien und Filme mit dieser quelloffenen Streaming App." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Über", + "dmca": "DMCA", + "login": "Anmelden", + "onboarding": "Einrichtung", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registrieren", + "settings": "Einstellungen" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Favoriten" + }, + "continueWatching": { + "sectionTitle": "Weiter ansehen" + }, + "mediaList": { + "stopEditing": "Bearbeiten beenden" + }, + "search": { + "allResults": "Das ist alles!", + "failed": "Das Medium wurde nicht gefunden, bitte versuchen Sie es erneut!", + "loading": "Wird geladen...", + "noResults": "Wir haben nichts gefunden!", + "placeholder": { + "default": "Was möchtest du schauen?", + "extra": [ + "Was möchtest du entdecken?", + "Was ist auf deiner Merkliste?", + "Was ist dein Lieblingsfilm?", + "Was ist deine Lieblingsserie?" + ] + }, + "sectionTitle": "Suchergebnisse" + }, + "titles": { + "day": { + "default": "Was würdest du diesem Nachmittag gerne schauen?", + "extra": [ + "Lust auf ein Abenteuer? Dann ist Jurassic Park genau das Richtige." + ] + }, + "morning": { + "default": "Was würdest du diesen Morgen gerne schauen?", + "extra": ["Before Sunrise soll gut sein"] + }, + "night": { + "default": "Was möchtest du diesen Abend gerne schauen?", + "extra": ["Müde? Ich hab gehört The Exorcist soll gut sein."] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Serie" + }, + "unreleased": "Unveröffentlicht" + }, + "navigation": { + "banner": { + "offline": "Internetverbindung ist instabil" + }, + "menu": { + "about": "Über uns", + "logout": "Abmelden", + "register": "Mit der sudo-cloud synchronisieren", + "settings": "Einstellungen", + "support": "Support" + } + }, + "notFound": { + "badge": "Nicht gefunden", + "goHome": "Zurück zur Startseite", + "message": "Wir haben überall gesucht: Unter den Eimern, im Schrank, hinter dem Proxy. Wir konnten die gesuchte Seite nicht finden.", + "title": "Diese Seite wurde nicht gefunden" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Abbrechen", + "confirm": "Standard-Setup verwenden", + "description": "Das Standard-Setup verfügt nicht über die besten Streams und kann unerträglich langsam sein.", + "title": "Sicher?" + }, + "extension": { + "back": "Zurück gehen", + "explainer": "Mit der Browser-Erweiterung kannst du die besten Streams benutzen, die wir zu bieten haben. Mit nur einer einfachen Installation.", + "explainerIos": "Leider ist die Browser-Extension unter iOS nicht unterstützt. Klicken Sie auf Zurück, um eine andere Option auszuwählen.", + "extensionHelp": "Falls du die Erweiterung installiert hast, aber sie aber nicht erkannt wird, öffne die Erweiterung über das Erweiterungsmenü Ihres Browsers und befolge die Schritte auf dem Bildschirm.", + "linkChrome": "Chrome Erweiterung installieren", + "linkFirefox": "Firefox Erweiterung installieren", + "notDetecting": "Auf Chrome Installiert, aber die Website erkennt es nicht? Versuche, die Seite wieder zu laden!", + "notDetectingAction": "Seite neuladen", + "status": { + "disallowed": "Browser-Erweiterung ist für diese Website nicht aktiviert", + "disallowedAction": "Browser-Erweiterung aktivieren", + "failed": "Statusanforderung fehlgeschlagen", + "loading": "Wartet dass du die Erweiterung installierst", + "outdated": "Erweiterungsversion zu alt", + "success": "Die Browser-Erweiterung funktioniert wie erwartet!" + }, + "submit": "Weiter", + "title": "Lass uns mit einer Erweiterung starten" + }, + "proxy": { + "back": "Zurück gehen", + "explainer": "Mit der Proxy-Methode kannst du Streams mit guter Qualität benutzen, indem du einen eigenen Proxy einstellst.", + "input": { + "errorConnection": "Es konnte keine Verbindung zum Proxy hergestellt werden", + "errorInvalidUrl": "Keine gültige URL", + "errorNotProxy": "Ein Proxy wurde erwartet, aber eine Website wurde eingegeben", + "label": "Proxy-URL", + "placeholder": "https://" + }, + "link": "Erfahre, wie man einen Proxy einstellt", + "submit": "Proxy einreichen", + "title": "Lass uns eine neue Proxy erstellen" + }, + "start": { + "explainer": "Um die bestmöglichen Streams zu erhalten, müssen Sie auswählen, welche Streaming-Methode Sie verwenden möchten.", + "options": { + "default": { + "text": "Ich möchte keine Streams mit guter Qualität. <0 /> <1>Standardeinstellung benutzen" + }, + "extension": { + "action": "Browser-Erweitung installieren", + "description": "Installiere die Browser-Erweitung, um Zugriff auf die besten Quellen zu bekommen.", + "quality": "Beste Qualität", + "title": "Browser extension" + }, + "proxy": { + "action": "Proxy einstellen", + "description": "Richte in nur 5 Minuten einen Proxy ein und erhalte Zugriff auf großartige Quellen.", + "quality": "Gute Qualität", + "title": "Eigene Proxy" + } + }, + "title": "Lass uns mit der Einrichtung von SkoolTV starten" + } + }, + "overlays": { + "close": "Schließen" + }, + "player": { + "back": { + "default": "Zurück zur Startseite", + "short": "Zurück" + }, + "casting": { + "enabled": "Casting zum Gerät..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "HLS-Playlist Link kopieren", + "disclaimer": "Videos werden direkt vom Provider heruntergeladen. SkoolTV hat keinen Einfluss darauf, wie Downloads bereitgestellt werden.", + "downloadSubtitle": "Aktuelle Untertitel herunterladen", + "downloadVideo": "Video herunterladen", + "hlsDisclaimer": "SkoolTV hat keinen Einfluss darauf, wie Downloads bereitgestellt werden. Downloads werden direkt vom Anbieter bezogen.

Bitte beachte, dass du eine HLS-Wiedergabeliste herunterlädst, dies ist nicht empfohlen für Nutzer die nicht mit Erweiterten Streaming Formaten vertraut sind. Probiere andere Anbieter für andere Formate.", + "onAndroid": { + "1": "Um auf Android Herunterzuladen, tippe auf den Download-Button, tippe und halte auf der neuen Seite auf das Video und wähle Speichern aus.", + "shortTitle": "Download / Android", + "title": "Auf Android herunterladen" + }, + "onIos": { + "1": "Um Auf iOS herunterzuladen, klick auf den Download-Button. Klicke dann auf der neuen Seite auf , dann auf In Dateien sichern .", + "shortTitle": "Download / iOS", + "title": "Auf iOS herunterladen" + }, + "onPc": { + "1": "Um am PC herunterzuladen, klicke auf den Download-Button. Klicke dann mit der rechten Maustaste auf das Video und klicke auf Video speichern als", + "shortTitle": "Download / PC", + "title": "Am PC herunterladen" + }, + "title": "Download" + }, + "episodes": { + "button": "Folgen", + "emptyState": "Keine Folgen in dieser Staffel, schau später noch einmal!", + "episodeBadge": "E{{episode}}", + "loadingError": "Fehler beim Laden der Sitzung", + "loadingList": "Wird geladen...", + "loadingTitle": "Wird geladen...", + "unairedEpisodes": "Eine oder mehrere Episoden dieser Staffel wurden deaktiviert, weil sie noch nicht ausgestrahlt wurden." + }, + "playback": { + "speedLabel": "Wiedergabegeschwindigkeit", + "title": "Wiedergabeeinstellungen" + }, + "quality": { + "automaticLabel": "Automatische Qualitätseinstellung", + "hint": "Du kannst versuchen die <0>Quelle zu ändern um andere Qualitätsoptionen zu erhalten.", + "iosNoQuality": "Durch eine Einschränkung von Apple ist die Qualitätsauswahl für iOS für diese Quelle nicht verfügbar. Du kannst versuchen <0>einen andere Quelle auszuwählen um andere Qualitätsoptionen zu erhalten.", + "title": "Qualität" + }, + "settings": { + "audioItem": "Audio", + "downloadItem": "Download", + "enableSubtitles": "Untettitel aktivieren", + "experienceSection": "Anzeigeerlebnis", + "playbackItem": "Wiedergabeeinstellungen", + "qualityItem": "Qualität", + "sourceItem": "Videoquellen", + "subtitleItem": "Untertiteleinstellungen", + "videoSection": "Videoeinstellungen" + }, + "sources": { + "failed": { + "text": "Beim Versuch, Videos zu finden, ist ein Fehler aufgetreten. Bitte versuche es mit einer anderen Quelle.", + "title": "Fehler beim Laden" + }, + "noEmbeds": { + "text": "Es konnten keine Embeds gefunden werden. Bitte versuchen es mit einer anderen Quelle.", + "title": "Keine Embeds gefunden" + }, + "noStream": { + "text": "Diese Quelle bietet keine Streams für diesen Film oder diese Serie.", + "title": "Kein Stream" + }, + "title": "Quellen", + "unknownOption": "Unbekannt" + }, + "subtitles": { + "customChoice": "Untertiteldatei auswählen oder hier ablegen", + "customizeLabel": "Anpassen", + "dropSubtitleFile": "Untertiteldatei hier ablegen", + "offChoice": "Aus", + "settings": { + "backlink": "Eigene Untertitel", + "delay": "Untertitelverzögerung", + "fixCapitals": "Großschreibung korrigieren" + }, + "title": "Untertitel", + "unknownLanguage": "Unbekannt" + } + }, + "metadata": { + "api": { + "text": "API Metadaten konnten nicht geladen werden, überprüfe deine Netzwerkverbindung.", + "title": "API Metadaten konnten nicht geladen werden" + }, + "dmca": { + "badge": "Entfernt", + "text": "Das Video ist aufgrund einer Takedown-Anfrage oder eines Urheberrechtsanspruchs nicht mehr verfügbar.", + "title": "Video wurde entfernt" + }, + "extensionPermission": { + "badge": "Berechtigung fehlt", + "button": "Verwende Erweiterung", + "text": "Du hast die Browser-Erweiterung, aber wir brauchen deine Berechtigung um mit der Erweiterung zu starten.", + "title": "Konfiguriere die Erweiterung" + }, + "failed": { + "badge": "Fehlgeschlagen", + "homeButton": "Zurück zur Startseite", + "text": "Konnte die Videometadaten nicht von TMDB laden. Überprüfe ob TMDB funktioniert oder von deiner Internetverbindung gesperrt wird.", + "title": "Laden der Metadaten ist fehlgeschlagen" + }, + "notFound": { + "badge": "Nicht gefunden", + "homeButton": "Zurück zur Startseite", + "text": "Wir konnten das angeforderte Video nicht finden.", + "title": "Das Video konnte nicht gefunden werden." + } + }, + "nextEpisode": { + "cancel": "Abbrechen", + "next": "Nächste Folge" + }, + "playbackError": { + "badge": "Wiedergabefehler", + "errors": { + "errorAborted": "Das Laden des Videos wurde vom Nutzer abgebrochen.", + "errorDecode": "Beim Versuch, das Video zu dekodieren, ist ein Fehler aufgetreten, obwohl sie zuvor als brauchbar eingestuft worden war.", + "errorGenericMedia": "Unbekannter Videofehler ist aufgetreten.", + "errorNetwork": "Es ist ein Netzwerkfehler aufgetreten, der verhindert hat, dass das Video erfolgreich abgerufen werden konnten, obwohl es verfügbar waren.", + "errorNotSupported": "Das Video- oder Videoanbieter wird nicht unterstützt." + }, + "homeButton": "Zurück zur Startseite", + "text": "Während der Wiedergabe ist ein Fehler aufgetreten. Versuche es erneut.", + "title": "Hoppla, etwas ist schiefgegangen!" + }, + "scraping": { + "extensionFailure": { + "badge": "Erweiterung deaktiviert", + "enableExtension": "Erweiterung aktivieren", + "homeButton": "Zur Startseite", + "text": "Du hast die SkoolTVe Erweiterung installiert. Um die Erweiterung zu benutzen, musst du sie für diese Seite aktivieren.", + "title": "Bitte aktiviere die Erweiterung" + }, + "items": { + "failure": "Ein Fehler ist aufgetreten", + "notFound": "Video nicht gefunden", + "pending": "Suche nach Videos..." + }, + "notFound": { + "badge": "Nicht gefunden", + "detailsButton": "Details anzeigen", + "homeButton": "Zurück zur Startseite", + "text": "Wir haben alle Anbieter durchsucht, konnten aber nicht das Video finden nach dem du suchst! Wir stellen keine eigenen Videos bereit und haben keine Kontrolle darüber, was verfügbar ist. Bitte klicke auf \"Details anzeigen\" für mehr Details.", + "title": "Wir konnten das nicht finden" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} übrig • Fertig um {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Bitte verifiziere deine Menschlichkeit mit dem Captcha auf der Rechten Seite. Dies ist um SkoolTV sicher zu halten!", + "error": "Menschlichkeit konnte nicht verifiziert werden. Bitte versuche es erneut.", + "title": "Wir müssen sicherstellen, dass du Menschlich bist.", + "verifyingHumanity": "Verifiziere deine Menschlichkeit..." + } + }, + "screens": { + "dmca": { + "text": "Willkommen zu SkoolTVs DMCA-Kontaktseite! Wir respektieren geistiges Eigentum und wollen uns schnell um urheberrechtlichen Anliegen kümmern. Falls du glaubst, dass dein urheberrechtlich geschütztes Werk unsachgemäß auf unserer Plattform verwendet wurde, sende uns bitte eine genaue DMCA-Anfrage an die unten stehende E-Mail. Diese sollte eine Beschreibung des urheberrechtlich geschützten Material, deine Kontaktinformationen sowie einer Erklärung des guten Glaubens beinhalten. Wir sind engagiert diese Anliegen schnell zu lösen und schätzen deine Hilfe dabei SkoolTV zu einer Plattform, welche Kreativität und Urheberrechte respektiert.", + "title": "DMCA" + }, + "loadingApp": "Die App wird geladen", + "loadingUser": "Dein Profil wird geladen", + "loadingUserError": { + "logout": "Abmelden", + "reset": "Eigenen Server zurücksetzen", + "text": "Beim Laden deines Profils ist ein Fehler aufgetreten", + "textWithReset": "Beim Laden deines Profils von deinem Server ist ein Fehler aufgetreten, zurück zum Standard-Server wechseln?" + }, + "migration": { + "failed": "Beim Migrieren deiner Daten ist ein Fehler aufgetreten.", + "inProgress": "Bitte warte, wir migrieren deine Daten. Das sollte nicht lange dauern." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Gerätename", + "deviceNamePlaceholder": "Handy", + "editProfile": "Bearbeiten", + "logoutButton": "Abmelden" + }, + "actions": { + "delete": { + "button": "Konto löschen", + "confirmButton": "Konto löschen", + "confirmDescription": "Konto wirklich löschen? Alle deine Daten gehen dabei verloren!", + "confirmTitle": "Bist du sicher?", + "text": "Diese Aktion kann nicht rückgängig gemacht werden. Alle Daten werden gelöscht und können nicht wiederhergestellt werden.", + "title": "Konto löschen" + }, + "title": "Aktionen" + }, + "devices": { + "deviceNameLabel": "Gerätename", + "failed": "Laden der Sitzungen fehlgeschlagen", + "removeDevice": "Entfernen", + "title": "Geräte" + }, + "profile": { + "finish": "Bearbeiten beenden", + "firstColor": "Profilfarbe 1", + "secondColor": "Profilfarbe 2", + "title": "Profilbild bearbeiten", + "userIcon": "Symbol" + }, + "register": { + "cta": "Los geht's", + "text": "Teilen deinen Fortschritt zwischen Geräten und halte sie synchronisiert.", + "title": "Mit der sudo-cloud synchronisieren" + }, + "title": "Konto" + }, + "appearance": { + "activeTheme": "Aktiv", + "themes": { + "blue": "Blau", + "default": "Standard", + "gray": "Grau", + "red": "Rot", + "teal": "Türkis" + }, + "title": "Aussehen" + }, + "connections": { + "server": { + "description": "Falls du dich mit einem anderen Server verbinden willst, um deine Daten zu speichern. Aktiviere dies und gebe die URL an. <0>Anweisungen.", + "label": "Eigener Server", + "urlLabel": "Eigene Server-URL" + }, + "setup": { + "doSetup": "Einrichten", + "errorStatus": { + "description": "Es scheint so, als bräuchte eine oder mehrere Schritte in dieser Einrichtung deine Aufmerksamkeit.", + "title": "Etwas braucht deine Aufmerksamkeit" + }, + "itemError": "Mit diesem Setup stimmt etwas nicht. Führen Sie das Setup erneut durch, um das Problem zu beheben.", + "items": { + "default": "Standard Einstellungen", + "extension": "Erweiterung", + "proxy": "Eigene Proxy" + }, + "redoSetup": "Erneut einrichten", + "successStatus": { + "description": "Alles ist bereit, damit du deine Lieblingsserien und Filme ansehen kannst.", + "title": "Alles eingerichtet!" + }, + "unsetStatus": { + "description": "Klicken Sie bitte auf den Button rechts, um die Setup zu starten.", + "title": "Du hast das Setup noch nicht durchgeführt" + } + }, + "title": "Verbindung", + "workers": { + "addButton": "Neuen Worker hinzufügen", + "description": "Damit die App funktioniert werden alle Anfrage durch einen Proxy geleitet. Aktiviere dies, falls du deinen eigenen Worker verwenden willst. <0>Anweisungen.", + "emptyState": "Keine Worker vorhanden, füge einen unten hinzu", + "label": "Verwenden deinen eigenen Worker-Proxys", + "urlLabel": "Worker-URLs", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "App-Sprache", + "languageDescription": "Sprache für die ganze App.", + "thumbnail": "Miniaturansichten generieren", + "thumbnailDescription": "Meistens haben Videos keine Miniaturansicht. Du kannst diese Einstellung anmachen, um sie automatisch zu generieren, aber sie können dein Video langsamer machen.", + "thumbnailLabel": "Miniaturansichten generieren", + "title": "Einstellungen" + }, + "reset": "Zurücksetzen", + "save": "Speichern", + "sidebar": { + "info": { + "appVersion": "App-Version", + "backendUrl": "Server-URL", + "backendVersion": "Server-Version", + "hostname": "Hostname", + "insecure": "Unsicher", + "notLoggedIn": "Du bist nicht angemeldet", + "secure": "Sicher", + "title": "App-Informationen", + "unknownVersion": "Unbekannt", + "userId": "Nutzer-ID" + } + }, + "subtitles": { + "backgroundBlurLabel": "Hintergrundunschärfe", + "backgroundLabel": "Hintergrunddeckkraft", + "colorLabel": "Farbe", + "previewQuote": "Das Gras wächst nicht schneller, wenn man daran zieht.", + "textSizeLabel": "Schriftgröße", + "title": "Untertitel" + }, + "unsaved": "Du hast ungespeicherte Änderungen" + } +} diff --git a/src/assets/locales/el.json b/src/assets/locales/el.json new file mode 100644 index 0000000..229de0c --- /dev/null +++ b/src/assets/locales/el.json @@ -0,0 +1,428 @@ +{ + "about": { + "description": "Το SkoolTV είναι μία διαδικτυακή εφαρμογή που αναζητά το ίντερνετ για streams. Η ομάδα επιδιώκει μία κυρίως μινιμαλιστική προσέγγιση στην κατανάλωση περιεχομένου.", + "faqTitle": "Συχνές ερωτήσεις", + "q1": { + "body": "Το SkoolTV δεν φιλοξενεί περιεχόμενο. Σε κάθε κλικ για οτιδήποτε θέλετε να παρακολουθήσετε, το SkoolTV πραγματοποιεί αναζήτηση στο διαδίκτυο για το επιλεγμένο πολυμέσο (Στην οθόνη φόρτωσης και στην καρτέλα \"πηγές βίντεο\" μπορείτε να δείτε ποια πηγή χρησιμοποιείτε). Τα πολυμέσα δεν φορτώνονται ποτέ από το SkoolTV, όλα γίνονται μέσω του παραπάνω μηχανισμού.", + "title": "Από πού προέρχεται το περιεχόμενο;" + }, + "q2": { + "body": "Δεν είναι εφικτό να αιτηθούν σειρές ή ταινίες, το SkoolTV δεν διαχειρίζεται το περιεχόμενο. Όλα τα πολυμέσα προβάλονται από πηγές στο διαδίκτυο.", + "title": "Που μπορώ να αιτηθώ μία σειρά ή ταινία;" + }, + "q3": { + "body": "Τα αποτελέσματα των αναζητήσεων τροφοδοτούνται από το The Movie Database (TMDB) και προβάλλονται ανεξάρτητα με το αν οι πηγές διαθέτουν το εν λόγω πολυμέσο.", + "title": "Τα αποτελέσματα της αναζήτησης εμφανίζουν την σειρά ή την ταινία, γιατί δεν μπορώ να την αναπαράγω;" + }, + "title": "Σχετικά με το SkoolTV" + }, + "actions": { + "copied": "Αντιγράφθηκε", + "copy": "Αντιγραφή" + }, + "auth": { + "createAccount": "Δεν έχετε ακόμη λογαριασμό; <0>Δημιουργήστε ένα λογαριασμό.", + "deviceNameLabel": "Όνομα συσκευής", + "deviceNamePlaceholder": "Προσωπικό τηλέφωνο", + "generate": { + "description": "Η συνθηματική σας φράση λειτουργεί ταυτόχρονα ως όνομα χρήστη και κωδικός πρόσβασης. Φροντίστε να το φυλάξετε, καθώς θα χρειαστεί να το εισάγετε για να συνδεθείτε στο λογαριασμό σας", + "next": "Έχω αποθηκέυση την συνθηματική μου φράση", + "passphraseFrameLabel": "Συνθηματική φράση", + "title": "Η συνθηματική σας φράση" + }, + "hasAccount": "Έχετε ήδη λογαριασμό; <0>Συνδεθείτε εδώ.", + "login": { + "description": "Παρακαλώ εισάγετε τη συνθηματική σας φράση για να συνδεθείτε στο λογαριασμό σας", + "deviceLengthError": "Παρακαλώ εισάγετε όνομα συσκευής", + "passphraseLabel": "Συνθηματική φράση 12 λέξεων", + "passphrasePlaceholder": "Συνθηματική φράση", + "submit": "Σύνδεση", + "title": "Συνδεθείτε στον λογαριασμό σας", + "validationError": "Λανθασμένη ή ελλιπής συνθηματική φράση" + }, + "register": { + "information": { + "color1": "Πρωτεύον χρώμα προφίλ", + "color2": "Δευτερεύον χρώμα προφίλ", + "header": "Εισάγετε ένα όνομα για τη συσκευή σας και επιλέξτε χρώματα και ένα εικονίδιο χρήστη της αρεσκείας σας", + "icon": "Εικονίδιο χρήστη", + "next": "Επόμενο", + "title": "Πληροφορίες λογαριασμού" + } + }, + "trust": { + "failed": { + "text": "Το ρυθμίσατε σωστά;", + "title": "Αδυναμία σύνδεσης με τον διακομιστή" + }, + "host": "Συνδέεστε στον διακομιστή <0>{{hostname}} - παρακαλούμε επιβεβαιώστε ότι τον εμπιστεύεστε πριν δημιουργήσετε λογαριασμό", + "no": "Επιστροφή", + "title": "Εμπιστεύεστε αυτόν τον διακομιστή;", + "yes": "Εμπιστεύομαι αυτόν τον διακομιστή" + }, + "verify": { + "description": "Παρακαλώ εισάγετε τη συνθηματική σας φράση από τα προηγούμενα βήματα για να επιβεβαιώσετε ότι την έχετε αποθηκεύσει και να δημιουργήσετε τον λογαριασμό σας", + "invalidData": "Τα δεδομένα δεν είναι έγκυρα", + "noMatch": "Η φράση πρόσβασης δεν ταυτίζεται", + "passphraseLabel": "Η συνθηματική σας φράση 12 λέξεων", + "recaptchaFailed": "Η επικύρωση του ReCaptcha απέτυχε", + "register": "Δημιουργία λογαριασμού", + "title": "Επικυρώστε τη συνθηματική σας φράση" + } + }, + "errors": { + "badge": "Χάλασε", + "details": "Λεπτομέρειες σφάλματος", + "reloadPage": "Επαναφόρτωση της σελίδας", + "showError": "Εμφάνιση λεπτομερειών σφάλματος", + "title": "Αντιμετωπίσαμε ένα σφάλμα!" + }, + "footer": { + "legal": { + "disclaimer": "Αποποίηση ευθύνης", + "disclaimerText": "Το SkoolTV δεν φιλοξενεί κανένα αρχείο, απλώς παραπέμπει σε υπηρεσίες τρίτων. Τα νομικά ζητήματα θα πρέπει να διευθετηθούν με τους παρόχους και τους διακομιστές που φιλοξενούν τα εν λόγω αρχεία. Το SkoolTV δεν είναι υπεύθυνο για τα αρχεία πολυμέσων που προβάλλονται από τους παρόχους βίντεο." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA (νόμος περί πνευματικών δικαιωμάτων)", + "github": "GitHub" + }, + "tagline": "Παρακολουθήστε τις αγαπημένες σας σειρές και ταινίες με αυτή την εφαρμογή streaming ανοιχτού κώδικα." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Σχετικά", + "dmca": "DMCA (νόμος περί πνευματικών δικαιωμάτων)", + "login": "Σύνδεση", + "pagetitle": "{{title}} - SkoolTV", + "register": "Εγγραφή", + "settings": "Ρυθμίσεις" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Σελιδοδείκτες" + }, + "continueWatching": { + "sectionTitle": "Συνεχίστε να παρακολουθείτε" + }, + "mediaList": { + "stopEditing": "Σταματήστε την επεξεργασία" + }, + "search": { + "allResults": "Αυτά είναι όλα όσα έχουμε!", + "failed": "Απέτυχε η εύρεση πολυμέσων, δοκιμάστε ξανά!", + "loading": "Φόρτωση...", + "noResults": "Δεν μπορέσαμε να βρούμε τίποτα!", + "placeholder": { + "default": "Τι θέλετε να παρακολουθήσετε;" + }, + "sectionTitle": "Αποτελέσματα αναζήτησης" + }, + "titles": { + "day": { + "default": "Τι θα θέλατε να παρακολουθήσετε σήμερα το απόγευμα;", + "extra": [ + "Νιώθετε περιπετειώδης; Το Jurassic Park μπορεί να είναι η τέλεια επιλογή." + ] + }, + "morning": { + "default": "Τι θα θέλατε να παρακολουθήσετε σήμερα το πρωί;", + "extra": ["Έχω ακούσει ότι το Before Sunrise είναι καλό"] + }, + "night": { + "default": "Τι θα θέλατε να παρακολουθήσετε απόψε;", + "extra": ["Κούραση; Έχω ακούσει ότι ο Εξορκιστής είναι καλός."] + } + } + }, + "media": { + "episodeDisplay": "Σ{{season}} Ε{{episode}}", + "types": { + "movie": "Ταινία", + "show": "Σειρά" + } + }, + "navigation": { + "banner": { + "offline": "Ελέγξτε τη σύνδεσή σας στο διαδίκτυο" + }, + "menu": { + "about": "Σχετικά με εμάς", + "logout": "Αποσύνδεση", + "register": "Συγχρονισμός με το sudo-cloud", + "settings": "Ρυθμίσεις", + "support": "Υποστήριξη" + } + }, + "notFound": { + "badge": "Δεν βρέθηκε", + "goHome": "Επιστροφή στην αρχική", + "message": "Ψάξαμε παντού: κάτω από τους κάδους, στην ντουλάπα, πίσω από το proxy, αλλά τελικά δεν μπορέσαμε να βρούμε τη σελίδα που ψάχνετε.", + "title": "Δεν μπόρεσε να βρεθεί η σελίδα" + }, + "overlays": { + "close": "Κλείσιμο" + }, + "player": { + "back": { + "default": "Επιστροφή στην αρχική", + "short": "Επιστροφή" + }, + "casting": { + "enabled": "Αναμετάδοση στην συσκευή..." + }, + "menus": { + "downloads": { + "disclaimer": "Οι λήψεις προέρχονται απευθείας από τον πάροχο. Το SkoolTV δεν ελέγχει τον τρόπο με τον οποίο παρέχονται οι λήψεις.", + "downloadSubtitle": "Κατέβασμα τρέχοντος υπότιτλου", + "downloadVideo": "Λήψη βίντεο", + "hlsDisclaimer": "Οι λήψεις προέρχονται απευθείας από τον πάροχο. Το SkoolTV δεν ελέγχει τον τρόπο με τον οποίο παρέχονται οι λήψεις. Παρακαλώ λάβετε υπόψη ότι κατεβάζετε μια λίστα αναπαραγωγής HLS, η οποία προορίζεται για χρήστες που είναι εξοικειωμένοι με την προηγμένη ροή πολυμέσων.", + "onAndroid": { + "1": "Για να κάνετε λήψη σε συσκευή Android, κάντε κλικ στο κουμπί λήψης και, στη νέα σελίδα, πατήστε παρατεταμένα στο βίντεο και, στη συνέχεια, επιλέξτε αποθήκευση.", + "shortTitle": "Λήψη / Android", + "title": "Λήψη σε συσκευή Android" + }, + "onIos": { + "1": "Για να κάνετε λήψη σε συσκευή iOS, κάντε κλικ στο κουμπί λήψης και, στη νέα σελίδα, κάντε κλικ στο και, στη συνέχεια, στο Αποθήκευση στα αρχεία .", + "shortTitle": "Λήψη / iOS", + "title": "Λήψη σε συσκευή iOS" + }, + "onPc": { + "1": "Στον υπολογιστή, κάντε κλικ στο κουμπί λήψης και, στη νέα σελίδα, κάντε δεξί κλικ στο βίντεο και επιλέξτε Αποθήκευση βίντεο ως", + "shortTitle": "Λήψη / PC", + "title": "Λήψη στο PC" + }, + "title": "Λήψη" + }, + "episodes": { + "button": "Επεισόδια", + "emptyState": "Δεν υπάρχουν επεισόδια σε αυτή τη σεζόν, επιστρέψτε αργότερα!", + "episodeBadge": "Ε{{episode}}", + "loadingError": "Σφάλμα φόρτωσης της σεζόν", + "loadingList": "Φόρτωση...", + "loadingTitle": "Φόρτωση...", + "unairedEpisodes": "Ένα ή περισσότερα επεισόδια αυτής της σεζόν έχουν απενεργοποιηθεί επειδή δεν έχουν προβληθεί ακόμα." + }, + "playback": { + "speedLabel": "Ταχύτητα αναπαραγωγής", + "title": "Ρυθμίσεις αναπαραγωγής" + }, + "quality": { + "automaticLabel": "Αυτόματη ποιότητα", + "hint": "Μπορείτε να δοκιμάσετε <0>να αλλάξετε πηγή για να έχετε διαφορετικές επιλογές ποιότητας.", + "iosNoQuality": "Λόγω των περιορισμών που έχει ορίσει η Apple, η επιλογή ποιότητας δεν είναι διαθέσιμη σε συσκευές iOS για αυτή την πηγή. Μπορείτε να δοκιμάσετε <0>να αλλάξετε πηγή για να έχετε διαφορετικές επιλογές ποιότητας.", + "title": "Ποιότητα" + }, + "settings": { + "downloadItem": "Λήψη", + "enableSubtitles": "Ενεργοποίηση υποτίτλων", + "experienceSection": "Εμπειρία θέασης", + "playbackItem": "Ρυθμίσεις αναπαραγωγής", + "qualityItem": "Ποιότητα", + "sourceItem": "Πηγές βίντεο", + "subtitleItem": "Ρυθμίσεις υποτίτλων", + "videoSection": "Ρυθμίσεις βίντεο" + }, + "sources": { + "failed": { + "text": "Υπήρξε σφάλμα κατά την προσπάθεια εύρεσης βίντεο, παρακαλούμε δοκιμάστε μια άλλη πηγή.", + "title": "Το scrape απέτυχε" + }, + "noEmbeds": { + "text": "Δεν μπορέσαμε να βρούμε κανένα embed, παρακαλούμε δοκιμάστε μια άλλη πηγή.", + "title": "Δεν βρέθηκε κανένα embed" + }, + "noStream": { + "text": "Αυτή η πηγή δεν έχει streams για αυτή την ταινία ή σειρά.", + "title": "Δεν υπάρχει stream" + }, + "title": "Πηγές", + "unknownOption": "Άγνωστο" + }, + "subtitles": { + "customChoice": "Επιλογή υποτίτλων από αρχείο", + "customizeLabel": "Προσαρμογή", + "offChoice": "Σβηστό", + "settings": { + "backlink": "Προσαρμοσμένοι υπότιτλοι", + "delay": "Καθυστέρηση υποτίτλων", + "fixCapitals": "Επιδιόρθωση κεφαλαιοποίησης" + }, + "title": "Υπότιτλοι", + "unknownLanguage": "Άγνωστο" + } + }, + "metadata": { + "api": { + "text": "Δεν ήταν δυνατή η φόρτωση των μεταδεδομένων του API, ελέγξτε τη σύνδεσή σας στο διαδίκτυο.", + "title": "Αποτυχία φόρτωσης μεταδεδομένων API" + }, + "failed": { + "badge": "Απέτυχε", + "homeButton": "Επιστοφή στην αρχική", + "text": "Δεν ήταν δυνατή η φόρτωση των μεταδεδομένων του πολυμέσου από την TMDB. Ελέγξτε αν η TMDB είναι εκτός λειτουργίας ή αποκλεισμένη στη σύνδεσή σας στο διαδίκτυο.", + "title": "Αποτυχία φόρτωσης μεταδεδομένων" + }, + "notFound": { + "badge": "Δεν βρέθηκε", + "homeButton": "Επιστροφή στην αρχική σελίδα", + "text": "Δεν μπορέσαμε να βρούμε το πολυμέσο που ζητήσατε. Είτε έχει αφαιρεθεί είτε παραποιήσατε τη διεύθυνση URL.", + "title": "Το συγκεκριμένο πολυμέσο δεν μπόρεσε να βρεθεί." + } + }, + "nextEpisode": { + "cancel": "Ακύρωση", + "next": "Επόμενο επεισόδιο" + }, + "playbackError": { + "badge": "Σφάλμα αναπαραγωγής", + "errors": { + "errorAborted": "Η λήψη των πολυμέσων διακόπηκε κατόπιν αιτήματος του χρήστη.", + "errorDecode": "Παρά το γεγονός ότι προηγουμένως είχε διαπιστωθεί ότι μπορεί να χρησιμοποιηθεί, προέκυψε σφάλμα κατά την αποκωδικοποίηση του πολυμέσου, με αποτέλεσμα την εμφάνιση σφάλματος.", + "errorGenericMedia": "Εμφανίστηκε άγνωστο σφάλμα πολυμέσου.", + "errorNetwork": "Παρουσιάστηκε κάποιο σφάλμα δικτύου που εμπόδισε την επιτυχή ανάκτηση των πολυμέσων, παρόλο που προηγουμένως ήταν διαθέσιμα.", + "errorNotSupported": "Το αντικείμενο πολυμέσων ή ο πάροχος πολυμέσων δεν υποστηρίζεται." + }, + "homeButton": "Επιστροφή στην αρχική", + "text": "Υπήρξε σφάλμα κατά την προσπάθεια αναπαραγωγής του πολυμέσου. Προσπαθήστε ξανά.", + "title": "Αποτυχία αναπαραγωγής βίντεο!" + }, + "scraping": { + "items": { + "failure": "Παρουσιάστηκε σφάλμα", + "notFound": "Δεν έχει το βίντεο", + "pending": "Έλεγχος για βίντεο..." + }, + "notFound": { + "badge": "Δεν βρέθηκε", + "detailsButton": "Εμφάνιση λεπτομερειών", + "homeButton": "Επιστροφή στην αρχική", + "text": "Ψάξαμε στους παρόχους μας και δεν μπορέσαμε να βρούμε το πολυμέσο που αναζητάτε! Δεν φιλοξενούμε τα πολυμέσα και δεν έχουμε κανέναν έλεγχο για το τι είναι διαθέσιμο. Παρακαλούμε κάντε κλικ στο 'Εμφάνιση λεπτομερειών' παρακάτω για περισσότερες λεπτομέρειες.", + "title": "Δεν μπορέσαμε να το βρούμε αυτό" + } + }, + "time": { + "regular": "{{timeWatched}}/{{duration}}", + "remaining": "{{timeLeft}} απέμεινε • Ολοκλήρωση στις {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Επαληθεύστε ότι είστε άνθρωπος συμπληρώνοντας το Captcha στα δεξιά. Αυτό γίνεται για να διατηρηθεί ο ιστός της ταινίας ασφαλής!", + "error": "Αποτυχία επαλήθευσης της ανθρωπιάς σας. ΠΑΡΑΚΑΛΩ προσπαθησε ξανα.", + "title": "Πρέπει να επαληθεύσουμε ότι είστε άνθρωπος.", + "verifyingHumanity": "Επαλήθευση της ανθρωπιάς σας..." + } + }, + "screens": { + "dmca": { + "text": "Καλώς ήρθατε στη σελίδα επικοινωνίας DMCA (νόμου περί πνευματικών δικαιωμάτων) της SkoolTV! Σεβόμαστε τα δικαιώματα πνευματικής ιδιοκτησίας και επιθυμούμε να αντιμετωπίσουμε γρήγορα τυχόν νομικά ζητήματα πνευματικών δικαιωμάτων. Εάν πιστεύετε ότι το έργο σας που προστατεύεται από πνευματικά δικαιώματα έχει χρησιμοποιηθεί αθέμιτα στην πλατφόρμα μας, παρακαλούμε στείλτε μια λεπτομερή ειδοποίηση στην παρακάτω διεύθυνση ηλεκτρονικού ταχυδρομίου. Παρακαλούμε να συμπεριλάβετε μια περιγραφή του υλικού που προστατεύεται από πνευματικά δικαιώματα, τα στοιχεία επικοινωνίας σας και μια δήλωση καλής πίστης. Δεσμευόμαστε να επιλύουμε αυτά τα θέματα άμεσα και εκτιμούμε τη συνεργασία σας για να διατηρήσουμε το SkoolTV ένα μέρος που σέβεται τη δημιουργικότητα και τα πνευματικά δικαιώματα.", + "title": "DMCA (νόμος περί πνευματικών δικαιωμάτων)" + }, + "loadingApp": "Φόρτωση εφαρμογής", + "loadingUser": "Φόρτωση του προφίλ σας", + "loadingUserError": { + "logout": "Αποσύνδεση", + "reset": "Επαναφορά προσαρμοσμένου διακομιστή", + "text": "Απέτυχε η φόρτωση του προφίλ σας", + "textWithReset": "Αποτυχία φόρτωσης του προφίλ σας από τον προσαρμοσμένο διακομιστή σας, θα θέλετε να επιστρέψετε στον προεπιλεγμένο διακομιστή;" + }, + "migration": { + "failed": "Απέτυχε η μεταφορά των δεδομένων σας.", + "inProgress": "Παρακαλώ περιμένετε, μεταφέρουμε τα δεδομένα σας. Αυτό δεν θα διαρκέσει πολύ." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Όνομα συσκευής", + "deviceNamePlaceholder": "Προσωπικό τηλέφωνο", + "editProfile": "Επεξεργασία", + "logoutButton": "Αποσύνδεση" + }, + "actions": { + "delete": { + "button": "Διαγραφή λογαριασμού", + "confirmButton": "Διαγραφή λογαριασμού", + "confirmDescription": "Είστε σίγουροι ότι θέλετε να διαγράψετε τον λογαριασμό σας; Όλα τα δεδομένα σας θα χαθούν!", + "confirmTitle": "Είστε σίγουροι;", + "text": "Η ενέργεια αυτή είναι μη αναστρέψιμη. Όλα τα δεδομένα θα διαγραφούν και τίποτα δεν μπορεί να ανακτηθεί.", + "title": "Διαγραφή λογαριασμού" + }, + "title": "Ενέργειες" + }, + "devices": { + "deviceNameLabel": "Όνομα συσκευής", + "failed": "Αποτυχία φόρτωσης συνεδριών", + "removeDevice": "Αφαίρεση", + "title": "Συσκευές" + }, + "profile": { + "finish": "Ολοκλήρωση της επεξεργασίας", + "firstColor": "Πρωτεύον χρώμα προφίλ", + "secondColor": "Δευτερεύον χρώμα προφίλ", + "title": "Επεξεργασία εικονιδίου προφίλ", + "userIcon": "Εικονίδιο χρήστη" + }, + "register": { + "cta": "Ξεκινήστε", + "text": "Μοιραστείτε την πρόοδο παρακολούθησης σας μεταξύ των συσκευών και διατηρήστε τις συγχρονισμένες.", + "title": "Συγχρονισμός με το sudo-cloud" + }, + "title": "Λογαριασμός" + }, + "appearance": { + "activeTheme": "Ενεργός", + "themes": { + "blue": "Μπλε", + "default": "Προεπιλογή", + "gray": "Γκρι", + "red": "Κόκκινο", + "teal": "Πετρόλ" + }, + "title": "Εμφάνιση" + }, + "connections": { + "server": { + "description": "Αν θέλετε να συνδεθείτε σε ένα προσαρμοσμένο backend για την αποθήκευση των δεδομένων σας, ενεργοποιήστε το και παραχωρήστε τη διεύθυνση URL.", + "label": "Προσαρμοσμένος διακομιστής", + "urlLabel": "Διεύθυνση URL προσαρμοσμένου διακομιστή" + }, + "title": "Συνδέσεις", + "workers": { + "addButton": "Προσθήκη νέου worker", + "description": "Για να λειτουργήσει η εφαρμογή, όλη η κυκλοφορία δρομολογείται μέσω διακομιστών μεσολάβησης. Ενεργοποιήστε το εάν θέλετε να φέρετε τους δικούς σας workers.", + "emptyState": "Δεν υπάρχουν ακόμη workers, προσθέστε έναν παρακάτω", + "label": "Χρήση προσαρμοσμένων proxy workers", + "urlLabel": "Διευθύνσεις URL των worker", + "urlPlaceholder": "https://" + } + }, + "reset": "Επαναφορά", + "save": "Αποθήκευση", + "sidebar": { + "info": { + "appVersion": "Έκδοση εφαρμογής", + "backendUrl": "Διεύθυνση URL του backend", + "backendVersion": "Έκδοση του backend", + "hostname": "Όνομα διακομιστή", + "insecure": "Ανασφαλές", + "notLoggedIn": "Δεν είστε συνδεδεμένοι", + "secure": "Ασφαλές", + "title": "Πληροφορίες εφαρμογής", + "unknownVersion": "Άγνωστο", + "userId": "Αναγνωριστικό χρήστη" + } + }, + "subtitles": { + "backgroundLabel": "Διαφάνεια φόντου", + "colorLabel": "Χρώμα", + "previewQuote": "Δεν πρέπει να φοβάμαι. Ο φόβος είναι ο δολοφόνος του μυαλού.", + "textSizeLabel": "Μέγεθος κειμένου", + "title": "Υπότιτλοι" + }, + "unsaved": "Έχετε μη αποθηκευμένες αλλαγές" + } +} diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json new file mode 100644 index 0000000..7ceb59f --- /dev/null +++ b/src/assets/locales/en.json @@ -0,0 +1,650 @@ +{ + "about": { + "description": "SkoolTV is a fork of movie-web that is ensured to stay up even after the shutdown of movie-web.app. SkoolTV.lol runs on a private, self-hosted VPS. I run this site at a loss; there are no ads due to my beliefs in free media.", + "faqTitle": "Common questions", + "q1": { + "body": "SkoolTV does not host any content. When you click on something to watch, the internet is searched for the selected media (On the loading screen and in the 'video sources' tab you can see which source you're using). Media never gets uploaded by SkoolTV, everything is through this searching mechanism.", + "title": "Where does the content come from?" + }, + "q2": { + "body": "It's not possible to request a show or movie, SkoolTV does not manage any content. All content is viewed through sources on the internet.", + "title": "Where can I request a show or movie?" + }, + "q3": { + "body": "Our search results are powered by The Movie Database (TMDB) and display regardless of whether our sources actually have the content.", + "title": "The search results display the show or movie, why can't I play it?" + }, + "q4": { + "body": "All data is synced to the sudo-backend which is different than the community backend and is independently hosted by me, anyone is free to use this as well.", + "title": "What about my data and stuff?" + }, + "q5": { + "body": "Well SkoolTV has a twitter account that can be found in the footer of this page as well as a link to the source code on Github.", + "title": "How can I find out more?" + }, + "title": "About SkoolTV (^▽^)" + }, + "actions": { + "copied": "Copied", + "copy": "Copy" + }, + "auth": { + "createAccount": "Don't have an account yet 😬 <0>Create an account.", + "deviceNameLabel": "Device name", + "deviceNamePlaceholder": "Personal phone", + "generate": { + "description": "Your passphrase acts as your username and password. Make sure to keep it safe as you will need to enter it to login to your account. Do NOT lose your passphrase!", + "next": "I have saved my passphrase", + "passphraseFrameLabel": "Passphrase", + "title": "Your passphrase" + }, + "hasAccount": "Already have an account? <0>Login here.", + "login": { + "description": "Please enter your passphrase to login to your account", + "deviceLengthError": "Please enter a device name", + "passphraseLabel": "12-Word passphrase", + "passphrasePlaceholder": "Passphrase", + "submit": "Login", + "title": "Login to your account", + "validationError": "Incorrect or incomplete passphrase /ᐠ. .ᐟ\\" + }, + "register": { + "information": { + "color1": "Profile color one", + "color2": "Profile color two", + "header": "Enter a name for your device then pick colors and a user icon of your choosing!", + "icon": "User icon", + "next": "Next", + "title": "Account information" + } + }, + "trust": { + "failed": { + "text": "Did you configure it correctly?", + "title": "Failed to reach server" + }, + "noHostTitle": "Server not configured!", + "noHost": "The server has not been configured, therefore you cannot create an account", + "host": "You are connecting to <0>{{hostname}} - please confirm you trust it before making an account...", + "no": "Go back", + "title": "Do you trust this server?", + "yes": "I trust this server 🤞" + }, + "verify": { + "description": "Please enter your passphrase from earlier to confirm you have saved it and to create your account", + "invalidData": "Data is not valid", + "noMatch": "Passphrase doesn't match 😭", + "passphraseLabel": "Your 12-word passphrase", + "recaptchaFailed": "ReCaptcha validation failed", + "register": "Create account", + "title": "Confirm your passphrase" + } + }, + "errors": { + "badge": "It broke 💀", + "details": "Error details", + "reloadPage": "Reload the page", + "showError": "Show error details", + "title": "We encountered an error!" + }, + "footer": { + "legal": { + "disclaimer": "Disclaimer ◝(ᵔᵕᵔ)◜", + "disclaimerText": "Please note: SkoolTV does not host any files itself but instead only display's content from 3rd party providers. Legal issues should be taken up with them." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub", + "twitter": "Twitter" + }, + "tagline": "Watch your favorite shows and movies for free with no ads ever! (っ'ヮ'c)" + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "About", + "dmca": "DMCA", + "discover": "Discover", + "support": "Support", + "login": "Login", + "onboarding": "Setup", + "pagetitle": "{{title}} - SkoolTV", + "register": "Register", + "settings": "Settings", + "jip": "Jip" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Bookmarks" + }, + "continueWatching": { + "sectionTitle": "Continue Watching..." + }, + "mediaList": { + "stopEditing": "Stop editing" + }, + "search": { + "allResults": "That's all we have...", + "failed": "Failed to find media, try again!", + "loading": "Loading...", + "noResults": "We couldn't find anything :(", + "placeholder": { + "default": "What do you want to watch?", + "extra": [ + "What are you in the mood for?", + "Should we delete your browser history?", + "What do you want to stream?", + "SkoolTV is the best site ever!", + "What's on your watchlist today?", + "How was your day?", + "My bad the site never works...", + "Isn't SkoolTV just the best?", + ">ᴗ<" + ] + }, + "empty": { + "default": "Welcome, find media to watch here!", + "extra": [ + "There's nothing here :(", + "So empty...", + "Such emptiness.", + "Hi new user :3" + ] + }, + "sectionTitle": "Search results", + "discoverMore": "Discover more", + "discover": "Discover" + }, + "titles": { + "day": { + "default": "What would you like to watch this afternoon?", + "extra": ["Have you seen Blazing Saddles?"], + "extra": ["Welcome to SkoolTV!"], + "extra": [" /ᐠ>ヮ<ᐟ\\ฅ"], + "extra": ["Viva la SkoolTV!"] + }, + "morning": { + "default": "What would you like to watch this morning?", + "extra": ["Can't go wrong with Friends"], + "extra": ["I hear The Expanse is popular"], + "extra": ["\"૮₍ ˶•⤙•˶ ₎ა"], + "extra": ["Viva la SkoolTV!"] + }, + "night": { + "default": "What would you like to watch tonight?", + "extra": ["Rick & Morty is great with friends!"], + "extra": ["Go smoke and watch The Simpsons!"], + "extra": ["(づ ᴗ _ᴗ)づ♡"], + "extra": ["Viva la SkoolTV!"] + }, + "420": { + "default": "What would you like to watch this 4/20?", + "extra": ["Happy 4/20 🥳!"] + }, + "69": { + "default": "Up for something spicy?", + "extra": ["Happy 69 day 😘!"] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} - E{{episode}}", + "unreleased": "Unreleased", + "types": { + "movie": "Movie", + "show": "Show" + } + }, + "navigation": { + "banner": { + "offline": "Check your internet connection, silly goose! 🦢" + }, + "menu": { + "about": "About us", + "logout": "Log out", + "register": "Sync to sudo-cloud", + "settings": "Settings", + "support": "Support", + "discover": "Discover" + } + }, + "notFound": { + "badge": "Not found", + "goHome": "Back to home", + "reloadButton": "Try again", + "message": "We looked everywhere: under the bins, in the closet, behind the proxy but ultimately couldn't find the page you are looking for. (ಥ﹏ಥ)", + "title": "Couldn't find that page" + }, + "downtimeNotice": { + "badge": "Issues", + "goHome": "Go home", + "message": "SkoolTV.lol is experiencing issues with some providers again, if you cant find or play a show please change the source. Expect this error to persist throughout the below times.", + "timeFrame": "March 31th 11:00 PM - 5:00 AM EST", + "title": "Provider issues" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Cancel", + "confirm": "Use default setup", + "description": "The default setup does not have the best streams and can be unbearably slow. ( ͠° ͟ʖ ͡°)", + "title": "Are you sure?" + }, + "extension": { + "back": "Go back", + "explainer": "Using the browser extension, you can get the best streams we have to offer. With just a simple install. 👌", + "explainerIos": "Unfortunately, the browser extension is not supported on iOS, Press Go back to choose another option.", + "extensionHelp": "If you've installed the extension but it's not detected, open the extension through your browsers extension menu and follow the steps on screen.", + "linkChrome": "Install Chrome extension", + "linkFirefox": "Install Firefox extension", + "notDetecting": "Installed on Chrome, but the site isn't detecting it? Try reloading the page!", + "notDetectingAction": "Reload page", + "status": { + "disallowed": "Extension is not enabled for this page (,,>﹏<,,)", + "disallowedAction": "Enable extension", + "failed": "Failed to request status", + "loading": "Waiting for you to install the extension", + "outdated": "Extension version too old", + "success": "Extension is working as expected!" + }, + "submit": "Continue", + "title": "Let's start with an extension" + }, + "proxy": { + "back": "Go back", + "explainer": "With the proxy method, you can get great quality streams by making a self-service proxy.", + "input": { + "errorConnection": "Could not connect to proxy", + "errorInvalidUrl": "Not a valid URL", + "errorNotProxy": "Expected a proxy but got a website", + "label": "Proxy URL", + "placeholder": "https://" + }, + "link": "Learn how to make a proxy", + "submit": "Submit proxy", + "title": "Let's make a new proxy" + }, + "start": { + "explainer": "To get the best streams possible, you will need to choose which streaming method you want to use.", + "options": { + "default": { + "text": "I don't want good quality streams,<0 /> <1>use the default setup ▄︻デ══━一 ʕ•͡-•ʔ" + }, + "extension": { + "action": "Install extension", + "description": "Install browser extension and gain access to the best sources, but remember to enable it for this site.", + "quality": "Best quality", + "title": "Browser extension" + }, + "proxy": { + "action": "Setup proxy", + "description": "Setup a free proxy in just 5 minutes and gain access to great sources...", + "quality": "Good quality", + "title": "Custom proxy" + } + }, + "title": "Let's get you setup with SkoolTV 🥳" + } + }, + "overlays": { + "close": "Close" + }, + "player": { + "back": { + "default": "Back to home", + "short": "Back" + }, + "casting": { + "enabled": "Casting to device 🎬" + }, + "menus": { + "downloads": { + "disclaimer": "Downloads are taken directly from the provider. SkoolTV does not have control over how the downloads are provided.", + "copyHlsPlaylist": "Copy HLS playlist link", + "downloadSubtitle": "Download current subtitle", + "downloadVideo": "Download video", + "hlsDisclaimer": "Downloads are taken directly from the provider. SkoolTV does not have control over how the downloads are provided.

Please note you are downloading an HLS playlist, it is not recommended to download if you are not familiar with advanced streaming formats. Try different sources for different formats.", + "onAndroid": { + "1": "To download on Android, click the download button then, on the new page, tap and hold on the video, then select save.", + "shortTitle": "Download / Android", + "title": "Downloading on Android" + }, + "onIos": { + "1": "To download on iOS, click the download button then, on the new page, click , then Save to Files .", + "shortTitle": "Download / iOS", + "title": "Downloading on iOS" + }, + "onPc": { + "1": "On PC, click the download button then, on the new page, right click the video and select Save video as", + "shortTitle": "Download / PC", + "title": "Downloading on PC" + }, + "title": "Download" + }, + "episodes": { + "button": "Episodes", + "emptyState": "There are no episodes in this season, check back later (sorry :3)...", + "episodeBadge": "E{{episode}}", + "loadingError": "Error loading season", + "loadingList": "Loading...", + "loadingTitle": "Loading...", + "unairedEpisodes": "One or more episodes in this season have been disabled because they haven't been aired yet.", + "seasons": "Seasons" + }, + "playback": { + "speedLabel": "Playback speed", + "title": "Playback settings" + }, + "quality": { + "automaticLabel": "Automatic quality", + "hint": "You can try <0>switching source to get different quality options.", + "iosNoQuality": "Due to Apple-defined (common IOS L) limitations, quality selection is not available on iOS for this source. You can try <0>switching to another source to get different quality options.", + "title": "Quality" + }, + "settings": { + "downloadItem": "Download", + "enableSubtitles": "Enable Subtitles", + "experienceSection": "Viewing experience", + "playbackItem": "Playback settings", + "audioItem": "Audio", + "qualityItem": "Quality", + "sourceItem": "Video sources", + "subtitleItem": "Subtitle settings", + "videoSection": "Video settings" + }, + "sources": { + "failed": { + "text": "There was an error while trying to find any videos... Try a different source?", + "title": "Failed to scrape" + }, + "noEmbeds": { + "text": "We were unable to find any embeds, please try a different source.", + "title": "No embeds found" + }, + "noStream": { + "text": "This source has no streams for this movie or show. /ᐠ - ˕ -マ Ⳋ", + "title": "No stream :(" + }, + "title": "Sources", + "unknownOption": "Unknown" + }, + "subtitles": { + "customChoice": "Drop or upload file", + "customizeLabel": "Customize", + "offChoice": "Off", + "SourceChoice": "Source Captions", + "OpenSubtitlesChoice": "OpenSubtitles", + "settings": { + "backlink": "Custom subtitles", + "delay": "Subtitle delay", + "fixCapitals": "Fix capitalization" + }, + "title": "Subtitles", + "unknownLanguage": "Unknown", + "dropSubtitleFile": "Drop subtitle file here! >_<", + "scrapeButton": "Scrape subtitles", + "empty": "There are no provided subtitles for this.", + "notFound": "None of the available options match your query" + } + }, + "metadata": { + "api": { + "text": "Could not load API metadata, please check your internet connection.", + "title": "Failed to load API metadata" + }, + "dmca": { + "badge": "Removed", + "text": "This media is no longer available due to a takedown notice or copyright claim. 😨", + "title": "Media has been removed" + }, + "extensionPermission": { + "badge": "Permission Missing", + "button": "Use extension", + "text": "You have the browser extension, but we need your permission to get started using the extension. (¬_¬)", + "title": "Configure the extension" + }, + "failed": { + "badge": "Failed", + "homeButton": "Go home", + "text": "Could not load the media's metadata from TMDB. Please check whether TMDB is down or blocked on your internet connection.", + "title": "Failed to load metadata" + }, + "notFound": { + "badge": "Not found", + "homeButton": "Back to home", + "text": "We couldn't find the media you requested. Either it's been removed or you tampered with the URL (naughty, naughty).", + "title": "Couldn't find that media." + } + }, + "nextEpisode": { + "replay": "Replay", + "next": "Next episode", + "nextSeason": "Next season" + }, + "playbackError": { + "badge": "Playback error", + "errors": { + "errorAborted": "The fetching of the media was aborted by the user's request.", + "errorDecode": "Despite having previously been determined to be usable, an error occurred while trying to decode the media resource, resulting in an error.", + "errorGenericMedia": "Unknown media error occurred.", + "errorNetwork": "Some kind of network error occurred which prevented the media from being successfully fetched, despite having previously been available.", + "errorNotSupported": "The media or media provider object is not supported." + }, + "homeButton": "Go home", + "text": "There was an error trying to play the media 😖. Please try again!", + "title": "Failed to play video!" + }, + "scraping": { + "items": { + "failure": "Error occurred", + "notFound": "Doesn't have the video (╥﹏╥)", + "pending": "Checking for videos..." + }, + "notFound": { + "badge": "Not found", + "detailsButton": "Show details", + "homeButton": "Go home", + "discoverButton": "Discover more", + "text": "We have searched through our providers and cannot find the media you are looking for! We do not host the media and have no control over what is available. Please click 'Show details' below for more details.", + "title": "We couldn't find that" + }, + "extensionFailure": { + "badge": "Extension disabled", + "homeButton": "Go home", + "enableExtension": "Enable extension", + "title": "Please enable the extension", + "text": "You've installed the SkoolTV extension. To start using it, you need to enable the extension for this site." + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} left • Finish at {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Please prove your humanity by completing the quick challenge, this is to keep SkoolTV safe.", + "error": "Failed to verify your humanity! Please try again.", + "title": "Are You a Robot 🤖?", + "verifyingHumanity": "Verifying your humanity... (^▽^)👍" + } + }, + "support": { + "title": "Support", + "text": "SkoolTV is designed to be as user-friendly as possible. However, people still have questions and issues. This page is here to help resolve these shortcomings", + "q1": { + "body": "Well, you can join the official <0>SkoolTV discord and ask questions there or you can email the one provided at the bottom of this page.", + "title": "Where can I get help?" + }, + "q2": { + "body": "We have a <0>GitHub where you can create a detailed issue in our repository. Additionally, if you wish, you can create a pull request to fix the issue yourself.", + "title": "How can I report a bug or issue?" + } + }, + "jip": { + "title": "Jip", + "text": "SkoolTV didn't fall out of a coconut tree, it was made mostly by a single person (a very epic one at that).", + "q1": { + "body": "Well, you can join the official <0>SkoolTV discord and ask questions there or you can email the one provided at the bottom of this page.", + "title": "Where can I get help?" + }, + "q2": { + "body": "We have a <0>GitHub where you can create a detailed issue in our repository. Additionally, if you wish, you can create a pull request to fix the issue yourself.", + "title": "How can I report a bug or issue?" + } + }, + "screens": { + "dmca": { + "text": "Welcome to SkoolTV's DMCA contact page. If you believe your copyrighted work has been improperly used on our platform (😢), please send a detailed DMCA notice to: {{dmca}} below. Please include a description of the copyrighted material, your contact details, and a statement of good faith belief. We're committed to resolving these matters promptly and appreciate your cooperation.", + "title": "DMCA :(" + }, + "loadingApp": "Loading application", + "loadingUser": "Loading your profile", + "loadingUserError": { + "logout": "Logout", + "reset": "Reset custom server", + "text": "Failed to load your profile", + "reload": "Reload", + "textWithReset": "Failed to load your profile from your custom server, want to reset back to the default server?" + }, + "migration": { + "failed": "Failed to migrate your data. 😿", + "inProgress": "Please hold, we are migrating your data. This shouldn't take long..." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Device name", + "deviceNamePlaceholder": "Personal phone", + "editProfile": "Edit", + "logoutButton": "Log out" + }, + "admin": { + "title": "Admin panel", + "text": "Utilize tools made for testing SkoolTV's condition.", + "button": "Check it out" + }, + "actions": { + "delete": { + "button": "Delete account", + "confirmButton": "Delete account", + "confirmDescription": "Are you sure you want to delete your account? All your data will be lost! ૮₍˶Ó﹏Ò ⑅₎ა", + "confirmTitle": "Are you sure?", + "text": "This action is irreversible. All data will be deleted and nothing can be recovered.", + "title": "Delete account" + }, + "title": "Actions" + }, + "devices": { + "deviceNameLabel": "Device name", + "failed": "Failed to load sessions", + "removeDevice": "Remove", + "title": "Devices" + }, + "profile": { + "finish": "Finish editing", + "firstColor": "Profile color one", + "secondColor": "Profile color two", + "title": "Edit profile picture", + "userIcon": "User icon" + }, + "register": { + "cta": "Get started", + "text": "Share your watch progress between devices and keep them synced. ( ̧⸝⸝⍢⸝⸝)ෆ", + "title": "Sync to the sudo-cloud" + }, + "title": "Account" + }, + "appearance": { + "activeTheme": "Active", + "themes": { + "blue": "Blue", + "default": "Default", + "gray": "Gray", + "red": "Red", + "teal": "Teal", + "blck": "BLCK" + }, + "title": "Appearance" + }, + "connections": { + "server": { + "description": "If you would like to connect to a custom backend to store your data, enable this and provide the URL. <0>Instructions.", + "label": "Custom server", + "urlLabel": "Custom server URL" + }, + "setup": { + "doSetup": "Do setup", + "errorStatus": { + "description": "It seems that one or more items in this setup need your attention.", + "title": "Something needs your attention 😱" + }, + "itemError": "There is something wrong with this setting. Go through setup again to fix it. (ᴗ_ ᴗ。)", + "items": { + "default": "Default setup", + "extension": "Extension", + "proxy": "Custom proxy" + }, + "redoSetup": "Redo setup", + "successStatus": { + "description": "All things are in place for you to start watching your favorite media. (๑>◡<๑)", + "title": "Everything is set up!" + }, + "unsetStatus": { + "description": "Please click the button to the right to start the setup process.", + "title": "You haven't gone through setup" + } + }, + "title": "Connections", + "workers": { + "addButton": "Add new worker", + "description": "To make the application function, all traffic is routed through proxies. Enable this if you want to bring your own workers. <0>Instructions.", + "emptyState": "No workers yet (。•́︿•̀。), add one below", + "label": "Use custom proxy workers", + "urlLabel": "Worker URLs", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Application language", + "languageDescription": "Language applied to the entire application, only English has silly stuff 🙁.", + "thumbnail": "Generate thumbnails", + "thumbnailDescription": "Most of the time, videos don't have thumbnails. You can enable this setting to generate them on the fly but they can make your video slower.", + "thumbnailLabel": "Generate thumbnails", + "autoplay": "Autoplay", + "autoplayDescription": "Automatically play the next episode in a series after reaching the end. Can be enabled by users with the browser extension, a custom proxy, or with the default setup if allowed by the host.", + "autoplayLabel": "Autoplay", + "sourceOrder": "Reordering sources", + "sourceOrderDescription": "Drag and drop to reorder sources. This will determine the order in which sources are checked for the media you are trying to watch. If a source is greyed out, it means it is not available on your device.", + "title": "Preferences" + }, + "reset": "Reset", + "save": "Save", + "sidebar": { + "info": { + "appVersion": "App version", + "backendUrl": "Backend URL", + "backendVersion": "Backend version", + "hostname": "Hostname", + "insecure": "Insecure", + "notLoggedIn": "You are not logged in", + "secure": "Secure", + "title": "App stats (for nerds) 🤓", + "unknownVersion": "Unknown", + "userId": "User ID" + } + }, + "subtitles": { + "backgroundLabel": "Background opacity", + "backgroundBlurLabel": "Background blur", + "colorLabel": "Color", + "previewQuote": "Would you rather have a thot daughter or a gay son? 🤔", + "textSizeLabel": "Text size", + "title": "Subtitles", + "textBoldLabel": "Bold text" + }, + "unsaved": "You have unsaved changes... ฅ^•ﻌ•^ฅ" + } +} diff --git a/src/assets/locales/es.json b/src/assets/locales/es.json new file mode 100644 index 0000000..88da01d --- /dev/null +++ b/src/assets/locales/es.json @@ -0,0 +1,549 @@ +{ + "about": { + "description": "SkoolTV es una aplicación web que busca transmisiones en internet. El equipo tiene como objetivo un enfoque principalmente minimalista para consumir contenido.", + "faqTitle": "Preguntas frecuentes", + "q1": { + "body": "SkoolTV no aloja ningún contenido. Cuando haces clic en algo para ver, se busca en internet el medio seleccionado (En la pantalla de carga y en la pestaña 'fuentes de vídeo' puedes ver qué fuente estás utilizando). El contenido nunca se carga en SkoolTV, todo se realiza a través de este mecanismo de búsqueda.", + "title": "¿De dónde proviene el contenido?" + }, + "q2": { + "body": "No es posible solicitar una serie o película, SkoolTV no gestiona ningún contenido. Todo el contenido se ve a través de fuentes en internet.", + "title": "¿Dónde puedo solicitar una serie o película?" + }, + "q3": { + "body": "Nuestros resultados de búsqueda están alimentados por The Movie Database (TMDB) y se muestran independientemente de si nuestras fuentes realmente tienen el contenido.", + "title": "Los resultados de búsqueda muestran la serie o película, ¿Por qué no puedo reproducirla?" + }, + "title": "Acerca de SkoolTV" + }, + "actions": { + "copied": "Copiado", + "copy": "Copiar" + }, + "auth": { + "createAccount": "¿Todavía no tienes una cuenta? <0>Crea una cuenta.", + "deviceNameLabel": "Nombre del dispositivo", + "deviceNamePlaceholder": "Teléfono personal", + "generate": { + "description": "Tu frase de contraseña actúa como tu nombre de usuario y contraseña. Asegúrate de mantenerlas seguras, ya que las necesitarás para iniciar sesión en tu cuenta", + "next": "He guardado mi frase de contraseña", + "passphraseFrameLabel": "Frase de contraseña", + "title": "Tu frase de contraseña" + }, + "hasAccount": "¿Ya tienes una cuenta? <0>Inicia sesión aquí.", + "login": { + "description": "Por favor, ingresa tu frase de contraseña para iniciar sesión en tu cuenta", + "deviceLengthError": "Por favor, ingresa un nombre de dispositivo", + "passphraseLabel": "Frase de contraseña de 12 palabras", + "passphrasePlaceholder": "Frase de contraseña", + "submit": "Iniciar sesión", + "title": "Inicia sesión en tu cuenta", + "validationError": "Contraseña incorrecta o incompleta" + }, + "register": { + "information": { + "color1": "Color de perfil uno", + "color2": "Color de perfil dos", + "header": "Ingresa un nombre para tu dispositivo, elige colores, y un ícono de usuario de tu elección", + "icon": "Ícono de usuario", + "next": "Siguiente", + "title": "Información de la cuenta" + } + }, + "trust": { + "failed": { + "text": "¿Lo configuraste correctamente?", + "title": "No se pudo conectar al servidor" + }, + "host": "Te estás conectando a <0>{{hostname}} - por favor, confirma si confías en este antes de crear una cuenta", + "no": "Regresar", + "noHost": "El servidor no se ha configurado, por lo tanto, no puede crear una cuenta", + "noHostTitle": "¡El servidor no está configurado!", + "title": "¿Confías en este servidor?", + "yes": "Confío en este servidor" + }, + "verify": { + "description": "Por favor, ingresa tu frase de contraseña anterior para confirmar que la has guardado y para crear tu cuenta", + "invalidData": "Los datos no son válidos", + "noMatch": "La frase de contraseña no coincide", + "passphraseLabel": "Tu frase de contraseña de 12 palabras", + "recaptchaFailed": "La validación de ReCaptcha falló", + "register": "Crear cuenta", + "title": "Confirma tu frase de contraseña" + } + }, + "errors": { + "badge": "Se descompuso", + "details": "Detalles del error", + "reloadPage": "Recargar la página", + "showError": "Mostrar detalles del error", + "title": "¡Encontramos un error!" + }, + "footer": { + "legal": { + "disclaimer": "Descargo de responsabilidad", + "disclaimerText": "SkoolTV no aloja ningún archivo, simplemente enlaza a servicios de terceros. Los problemas legales deben ser tratados con los proveedores de archivos y servicios. SkoolTV no se hace responsable de los archivos multimedia mostrados por los proveedores de vídeo." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Ve tus series y películas favoritas con esta aplicación de transmisión de código abierto." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Acerca de", + "dmca": "DMCA", + "login": "Iniciar sesión", + "onboarding": "Configurar", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registrarse", + "settings": "Configuración" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Marcadores" + }, + "continueWatching": { + "sectionTitle": "Continuar viendo" + }, + "mediaList": { + "stopEditing": "Detener edición" + }, + "search": { + "allResults": "¡Eso es todo lo que tenemos!", + "failed": "¡Error al encontrar contenido, inténtalo de nuevo!", + "loading": "Cargando...", + "noResults": "¡No pudimos encontrar nada!", + "placeholder": { + "default": "¿Qué te gustaría ver?", + "extra": [ + "¿Qué quieres explorar?", + "¿Qué hay en tu lista de reproducción?", + "¿Cuál es tu película favorita?", + "¿Cuál es tu serie favorita?" + ] + }, + "sectionTitle": "Resultados de búsqueda" + }, + "titles": { + "day": { + "default": "¿Qué te gustaría ver esta tarde?", + "extra": [ + "¿Te sientes aventurero? Jurassic Park podría ser la elección perfecta." + ] + }, + "morning": { + "default": "¿Qué te gustaría ver esta mañana?", + "extra": [ + "Escuché que “Antes del amanecer” es buena" + ] + }, + "night": { + "default": "¿Qué te gustaría ver esta noche?", + "extra": [ + "¿Cansado? Escuché que “El Exorcista” es buena." + ] + } + } + }, + "media": { + "episodeDisplay": "T{{season}} E{{episode}}", + "types": { + "movie": "Película", + "show": "Serie" + } + }, + "navigation": { + "banner": { + "offline": "Verifica tu conexión a internet" + }, + "menu": { + "about": "Acerca de nosotros", + "logout": "Cerrar sesión", + "register": "Sincronizar con la nube", + "settings": "Configuración", + "support": "Soporte" + } + }, + "notFound": { + "badge": "No encontrado", + "goHome": "Volver a inicio", + "message": "Buscamos en todas partes: debajo de los contenedores, en el armario, detrás del proxy, pero al final no pudimos encontrar la página que estás buscando.", + "title": "No se puede encontrar esa página" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Cancelar", + "confirm": "Usar configuración por defecto", + "description": "La configuración predeterminada no tiene las mejores transmisiones y puede ser insoportablemente lenta.", + "title": "¿Estás seguro?" + }, + "extension": { + "back": "Volver atrás", + "explainer": "Usando la extensión de navegador, puedes obtener las mejores transiciones que ofrecemos. Simplemente con una simple instalación.", + "explainerIos": "Desafortunadamente, la extensión para el navegador no es compatible con IOS. Pulsa ir atrás para elegir otra opción.", + "extensionHelp": "Si has instalado la extensión pero no es detectada, abre la extensión desde la sección en el menú de extensiones y sigue los pasos de la pantalla.", + "linkChrome": "Instalar extensión para Chrome", + "linkFirefox": "Instalar extensión para Firefox", + "notDetecting": "Instalada en Chrome, pero la página no la está detectado. ¡Prueba a recargar la web!", + "notDetectingAction": "Recargar página", + "status": { + "disallowed": "La extensión no está activada para esta página", + "disallowedAction": "Activar extensión", + "failed": "No se pudo solicitar el estado", + "loading": "Esperando que instales la extensión", + "outdated": "La versión de la extensión es muy antigua", + "success": "¡La extensión está funcionando como se esperaba!" + }, + "submit": "Continuar", + "title": "Vamos a empezar con la extensión" + }, + "proxy": { + "back": "Volver atrás", + "explainer": "Con el método de proxy, puede obtener una my buena calidad de las transmisiones creando un proxy propio.", + "input": { + "errorConnection": "No se pudo conectar al proxy", + "errorInvalidUrl": "URL no válida", + "errorNotProxy": "Esperaba un proxy pero obtuve un sitio web", + "label": "URL del Proxy", + "placeholder": "https://" + }, + "link": "Aprender a crear un proxy", + "submit": "Enviar proxy", + "title": "Vamos a crear un nuevo proxy" + }, + "start": { + "explainer": "Para conseguir las mejores transmisiones, necesitarás elegir que método de transmisión quieres usar.", + "options": { + "default": { + "text": "No quiero buena calidad en las transmisiones,<0 /> <1>usar la configuración por defecto" + }, + "extension": { + "action": "Instalar extensión", + "description": "Instala la extensión de navegador y gana acceso a las mejore fuentes.", + "quality": "La mejor calidad", + "title": "Extensión de navegador" + }, + "proxy": { + "action": "Configurar proxy", + "description": "Configura un proxy en tan solo 5 minutos y obtén acceso a buenas fuentes.", + "quality": "Buena calidad", + "title": "Proxy personalizado" + } + }, + "title": "Vamos a configurar SkoolTV" + } + }, + "overlays": { + "close": "Cerrar" + }, + "player": { + "back": { + "default": "Volver al inicio", + "short": "Volver" + }, + "casting": { + "enabled": "Transmitiendo a dispositivo..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Copiar enlace de reproducción HLS", + "disclaimer": "Las descargas se realizan directamente desde el proveedor. SkoolTV no tiene control sobre cómo se proporcionan las descargas.", + "downloadSubtitle": "Descargar subtítulo actual", + "downloadVideo": "Descargar vídeo", + "hlsDisclaimer": "Las descargas se realizan directamente del proveedor. SkoolTV no tiene control sobre cómo se proporcionan las descargas.

Tenga en cuenta que está descargando una lista de reproducción HLS, dirigida a usuarios familiarizados con la transmisión multimedia avanzada. Prueba con diferentes fuentes para diferentes formatos.", + "onAndroid": { + "1": "Para descargar en Android, haz clic en el botón de descarga y luego, en la nueva página, mantén presionado el vídeo y selecciona guardar.", + "shortTitle": "Descargar / Android", + "title": "Descargando en Android" + }, + "onIos": { + "1": "Para descargar en iOS, haz clic en el botón de descarga y luego, en la nueva página, haz clic en , luego Guardar en archivos .", + "shortTitle": "Descargar / iOS", + "title": "Descargando en iOS" + }, + "onPc": { + "1": "En una PC, haz clic en el botón de descarga y luego, en la nueva página, haz clic derecho en el vídeo y selecciona Guardar vídeo como...", + "shortTitle": "Descargar / PC", + "title": "Descargando en PC" + }, + "title": "Descargar" + }, + "episodes": { + "button": "Episodios", + "emptyState": "No hay episodios en esta temporada, ¡Intenta más tarde!", + "episodeBadge": "E{{episode}}", + "loadingError": "Error al cargar la temporada", + "loadingList": "Cargando...", + "loadingTitle": "Cargando...", + "unairedEpisodes": "Uno o más episodios de esta temporada se han desactivado porque aún no se han emitido." + }, + "playback": { + "speedLabel": "Velocidad de reproducción", + "title": "Configuración de reproducción" + }, + "quality": { + "automaticLabel": "Calidad automática", + "hint": "Puedes intentar <0>cambiar de fuente para obtener diferentes opciones de calidad.", + "iosNoQuality": "Debido a limitaciones definidas por Apple, la selección de calidad no está disponible en iOS para esta fuente. Puedes intentar <0>cambiar a otra fuente para obtener diferentes opciones de calidad.", + "title": "Calidad" + }, + "settings": { + "audioItem": "Audio", + "downloadItem": "Descargar", + "enableSubtitles": "Habilitar subtítulos", + "experienceSection": "Experiencia de visualización", + "playbackItem": "Configuración de reproducción", + "qualityItem": "Calidad", + "sourceItem": "Fuentes de vídeo", + "subtitleItem": "Configuración de subtítulos", + "videoSection": "Configuración de vídeo" + }, + "sources": { + "failed": { + "text": "Se produjo un error al intentar encontrar vídeos, por favor intenta con una fuente diferente.", + "title": "Error al obtener" + }, + "noEmbeds": { + "text": "No pudimos encontrar ninguna embed, por favor intenta con una fuente diferente.", + "title": "No se encontraron embeds" + }, + "noStream": { + "text": "Esta fuente no tiene transmisiones para esta película o serie.", + "title": "Sin transmisión" + }, + "title": "Fuentes", + "unknownOption": "Desconocida" + }, + "subtitles": { + "customChoice": "Sube o arrastra un archivo", + "customizeLabel": "Personalizar", + "dropSubtitleFile": "Suelta el archivo de subtítulos aquí", + "offChoice": "Apagado", + "settings": { + "backlink": "Subtítulos personalizados", + "delay": "Retraso de subtítulos", + "fixCapitals": "Arreglar capitalización" + }, + "title": "Subtítulos", + "unknownLanguage": "Desconocido" + } + }, + "metadata": { + "api": { + "text": "No ha sido posible cargar la metadata de la API, por favor, comprueba tu conexión a internet.", + "title": "No ha sido posible cargar los metadatos de la API" + }, + "dmca": { + "badge": "Eliminado", + "text": "Este contenido no va a estar disponible debido a un aviso de eliminación o un reclamo de derechos de autor.", + "title": "El contenido ha sido eliminado" + }, + "extensionPermission": { + "badge": "Permisos insuficientes", + "button": "Usar extensión", + "text": "Tienes la extensión de navegador, pero necesitamos tu permiso para empezar a usarla.", + "title": "Configura la extensión" + }, + "failed": { + "badge": "Error", + "homeButton": "Ir al inicio", + "text": "No se pudieron cargar los metadatos del contenido de TMDB. Por favor, verifica si TMDB está caído o bloqueado en tu conexión a internet.", + "title": "Error al cargar los metadatos" + }, + "notFound": { + "badge": "No encontrado", + "homeButton": "Volver al inicio", + "text": "No pudimos encontrar el contenido que solicitaste. Ya sea que se haya eliminado o se haya modificado la URL.", + "title": "No se pudo encontrar ese contenido." + } + }, + "nextEpisode": { + "cancel": "Cancelar", + "next": "Siguiente episodio" + }, + "playbackError": { + "badge": "Error de reproducción", + "errors": { + "errorAborted": "La obtención del contenido fue cancelada por solicitud del usuario.", + "errorDecode": "A pesar de haber sido determinado previamente como utilizable, se produjo un error al intentar decodificar el recurso del contenido, lo que resultó en un error.", + "errorGenericMedia": "Se produjo un error desconocido en el contenido.", + "errorNetwork": "Se produjo un error de red que impidió obtener el contenido de manera exitosa, a pesar de haber estado disponible anteriormente.", + "errorNotSupported": "El contenido o el proveedor del contenido no es compatible." + }, + "homeButton": "Ir al inicio", + "text": "Se produjo un error al intentar reproducir el contenido. Por favor, inténtalo de nuevo.", + "title": "¡No se pudo reproducir el vídeo!" + }, + "scraping": { + "items": { + "failure": "Ocurrió un error", + "notFound": "No tiene el vídeo", + "pending": "Verificando vídeos..." + }, + "notFound": { + "badge": "No encontrado", + "detailsButton": "Mostrar detalles", + "homeButton": "Ir al inicio", + "text": "Hemos buscado en nuestros proveedores y no podemos encontrar el contenido que estás buscando. No alojamos el contenido y no tenemos control sobre lo que está disponible. Haz clic en 'Mostrar detalles' a continuación para obtener más información.", + "title": "No pudimos encontrar eso" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} restante • Finaliza a las {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Por favor, confirma que eres humano completando el Captcha. ¡Esto es para mantener SkoolTV seguro!", + "error": "Ha habido un error al verificar tu humanidad. Por favor, prueba de nuevo.", + "title": "Necesitamos verificar que eres humano.", + "verifyingHumanity": "Verificando tu hunanidad…" + } + }, + "screens": { + "dmca": { + "text": "¡Bienvenido a la página de contacto DMCA de SkoolTV! Respetamos los derechos de propiedad intelectual y queremos abordar cualquier problema de derechos de autor de manera rápida. Si cree que su trabajo con derechos de autor se ha utilizado incorrectamente en nuestra plataforma, envíe un aviso DMCA detallado al correo electrónico que se muestra a continuación. Incluya una descripción del material con derechos de autor, sus datos de contacto y una declaración de buena fe. Estamos comprometidos a resolver estos asuntos de manera pronta y agradecemos su cooperación para mantener a SkoolTV como un lugar que respeta la creatividad y los derechos de autor.", + "title": "DMCA" + }, + "loadingApp": "Cargando la aplicación", + "loadingUser": "Cargando tu perfil", + "loadingUserError": { + "logout": "Cerrar sesión", + "reset": "Restablecer servidor personalizado", + "text": "Error al cargar tu perfil", + "textWithReset": "Error al cargar tu perfil desde tu servidor personalizado, ¿Quieres restablecerlo al servidor predeterminado?" + }, + "migration": { + "failed": "Error al migrar tus datos.", + "inProgress": "Por favor espera, estamos migrando tus datos. Esto no debería tomar mucho tiempo." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nombre del dispositivo", + "deviceNamePlaceholder": "Teléfono personal", + "editProfile": "Editar", + "logoutButton": "Cerrar sesión" + }, + "actions": { + "delete": { + "button": "Eliminar cuenta", + "confirmButton": "Eliminar cuenta", + "confirmDescription": "¿Estás seguro de que quieres eliminar tu cuenta? ¡Todos tus datos se perderán!", + "confirmTitle": "¿Estás seguro?", + "text": "Esta acción es irreversible. Todos los datos se eliminarán y no se podrán recuperar.", + "title": "Eliminar cuenta" + }, + "title": "Acciones" + }, + "devices": { + "deviceNameLabel": "Nombre del dispositivo", + "failed": "Error al cargar las sesiones", + "removeDevice": "Eliminar", + "title": "Dispositivos" + }, + "profile": { + "finish": "Finalizar edición", + "firstColor": "Color de perfil uno", + "secondColor": "Color de perfil dos", + "title": "Editar imagen de perfil", + "userIcon": "Icono de usuario" + }, + "register": { + "cta": "Empezar", + "text": "Comparte tu progreso de visualización entre dispositivos y manténlos sincronizados.", + "title": "Sincronizar con la nube" + }, + "title": "Cuenta" + }, + "appearance": { + "activeTheme": "Activo", + "themes": { + "blue": "Azul", + "default": "Predeterminado", + "gray": "Gris", + "red": "Rojo", + "teal": "Turquesa" + }, + "title": "Apariencia" + }, + "connections": { + "server": { + "description": "Si deseas conectarte a un backend personalizado para almacenar tus datos, habilita esto y proporciona la URL. <0>Instrucciones.", + "label": "Servidor personalizado", + "urlLabel": "URL del servidor personalizado" + }, + "setup": { + "doSetup": "Configurar", + "errorStatus": { + "description": "Parece que hay uno o más items en esta configuración que requieren de tu atención.", + "title": "Algo necesita de tu atención" + }, + "itemError": "Hay algo que no fue bien con esta configuración. Ve otra vez a la configuración para solucionarlo.", + "items": { + "default": "Configuración por defecto", + "extension": "Extensión", + "proxy": "Proxy personalizado" + }, + "redoSetup": "Rehacer configuración", + "successStatus": { + "description": "Todo lo necesario está en su sitio para que empieces a ver tu contenido favorito.", + "title": "¡Todo está configurado!" + }, + "unsetStatus": { + "description": "Haga clic en el botón a la derecha para iniciar el proceso de configuración.", + "title": "No has pasado por la configuración" + } + }, + "title": "Conexiones", + "workers": { + "addButton": "Agregar nuevo worker", + "description": "Para que la aplicación funcione, todo el tráfico se enruta a través de proxies. Habilita esto si quieres usar tus propios workers. <0>Instrucciones.", + "emptyState": "Aún no hay workers, agrega uno a continuación", + "label": "Usar proxy workers personalizados", + "urlLabel": "URL de los workers", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Idioma de la aplicación", + "languageDescription": "Idioma aplicado a toda la aplicación.", + "thumbnail": "Generar miniaturas", + "thumbnailDescription": "La mayor parte del tiempo, los videos no tienen miniaturas. Puedes activar esta configuración para generarlas sobre la marcha, pero pueden realentizar tu video.", + "thumbnailLabel": "Generar miniaturas", + "title": "Preferencias" + }, + "reset": "Restablecer", + "save": "Guardar", + "sidebar": { + "info": { + "appVersion": "Versión de la aplicación", + "backendUrl": "URL del backend", + "backendVersion": "Versión del backend", + "hostname": "Nombre de host", + "insecure": "No seguro", + "notLoggedIn": "No has iniciado sesión", + "secure": "Seguro", + "title": "Información de la aplicación", + "unknownVersion": "Desconocida", + "userId": "ID de usuario" + } + }, + "subtitles": { + "backgroundBlurLabel": "Desefoque de fondo", + "backgroundLabel": "Opacidad del fondo", + "colorLabel": "Color", + "previewQuote": "No debo temer. El miedo es el asesino de la mente.", + "textSizeLabel": "Tamaño del texto", + "title": "Subtítulos" + }, + "unsaved": "Tienes cambios sin guardar" + } +} diff --git a/src/assets/locales/et.json b/src/assets/locales/et.json new file mode 100644 index 0000000..ff0b95b --- /dev/null +++ b/src/assets/locales/et.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "SkoolTV on veebirakendus, mis otsib internetti striimide jaoks. Meie eesmärk on enamasti minimalistlik lähenemine sisu tarbimisele.", + "faqTitle": "Tihti küsitud küsimused", + "q1": { + "body": "SkoolTV ei hoiusta enda sisu. Kui klõpsate, et midagi vaadata, otsitakse valitud meediat internetist (laadimisekraanil ja vahekaardil \"videoallikad\" näete, millist allikat te kasutate). Meediat ei lae SkoolTV kunagi üles, kõik toimub selle otsingumehhanismi kaudu.", + "title": "Kust tuleb meie sisu?" + }, + "q2": { + "body": "Saadet või filmi ei ole võimalik taotelda, SkoolTV ei halda mingit sisu. Kogu sisu vaadatakse interneti allikate kaudu.", + "title": "Kust ma saan kindlat saadet või filmi paluda?" + }, + "q3": { + "body": "Meie otsingutulemusi toetab The Movie Database (TMDB) ja need kuvatakse sõltumata sellest, kas meie allikates on sisu tegelikult olemas.", + "title": "Otsingutulemustes kuvatakse saade või film. Miks ma ei saa seda esitada?" + }, + "title": "SkoolTV'i kohta" + }, + "actions": { + "copied": "Kopeeritud", + "copy": "Kopeeri" + }, + "auth": { + "createAccount": "Ei ole kontot veel?<0>Loo konto.", + "deviceNameLabel": "Seadme nimi", + "deviceNamePlaceholder": "Isiklik telefon", + "generate": { + "description": "Teie paroolifraas toimib teie kasutajanime ja paroolina. Veenduge, et see oleks ohutus kohas, kuna peate kasutama seda, et logida oma kontosse sisse", + "next": "Olen salvestanud oma paroolifraasi", + "passphraseFrameLabel": "Paroolifraas", + "title": "Sinu paroolifraas" + }, + "hasAccount": "On juba konto? <0>Logi sisse.", + "login": { + "description": "Palun sisestage paroolifraas, et logida kontosse sisse", + "deviceLengthError": "Palun sisesta seadme nimi", + "passphraseLabel": "12-Sõnaline paroolifraas", + "passphrasePlaceholder": "Paroolifraas", + "submit": "Logi sisse", + "title": "Logi sisse oma kontosse", + "validationError": "Vale vōi mittetäielik paroolifraas" + }, + "register": { + "information": { + "color1": "Profiili värv üks", + "color2": "Profiili värv kaks", + "header": "Sisestage oma seadme nimi ja valige värvid ning kasutajaikoon", + "icon": "Kasutaja ikoon", + "next": "Järgmine", + "title": "Kontoteave" + } + }, + "trust": { + "failed": { + "text": "Kas sa seadistasid selle õigesti?", + "title": "Serveriga ühenduse loomine ebaõnnestus" + }, + "host": "Ühendate <0>{{hostname}} - enne konto tegemist kinnitage, et usaldate seda", + "no": "Tagasi", + "noHost": "Server ei ole konfigureeritud, seega ei saa kontot luua", + "noHostTitle": "Server ei ole konfigureeritud!", + "title": "Kas usaldate seda serverit?", + "yes": "Usaldan seda serverit" + }, + "verify": { + "description": "Palun sisestage oma paroolifraas, et kinnitada, et olete selle salvestanud ja luua oma konto", + "invalidData": "Andmed ei kehti", + "noMatch": "Paroolifraas ei klapi", + "passphraseLabel": "Sinu 12-sõnaline paroolifraas", + "recaptchaFailed": "ReCaptcha valideerimine ebaõnnestua", + "register": "Loo konto", + "title": "Kinnita oma paroolifraas" + } + }, + "errors": { + "badge": "Läks katki", + "details": "Vea üksikasjad", + "reloadPage": "Värskenda leht", + "showError": "Näita vea üksikasju", + "title": "Tekkis viga!" + }, + "footer": { + "legal": { + "disclaimer": "Lahtiütlemine", + "disclaimerText": "SkoolTV ei hoiusta ühtegi faili, vaid ainult lingib kolmandate osapoolte teenustele. Juriidilised küsimused tuleks lahendada failihostide ja teenusepakkujatega. SkoolTV ei vastuta videopakkujate poolt näidatud meediafailide eest." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Vaadake selle avatud lähtekoodiga striimimis rakendusega oma lemmiksaateid ja -filme." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Meist", + "dmca": "DMCA", + "login": "Logi sisse", + "onboarding": "Seadistamine", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registreeri", + "settings": "Sätted" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Järjehoidjad" + }, + "continueWatching": { + "sectionTitle": "Jätka vaatamist" + }, + "mediaList": { + "stopEditing": "Lõpeta redigeerimine" + }, + "search": { + "allResults": "See on kõik, mis meil on!", + "failed": "Meedia leidmine ebaõnnestus, proovige uuesti!", + "loading": "Laadimine....", + "noResults": "Me ei leidnud midagi!", + "placeholder": { + "default": "Mida tahate vaadata?", + "extra": [ + "Mida soovite uurida?", + "Mis on teie nimekirjas?", + "Milline on teie lemmikfilm?", + "Milline on teie lemmiksari?" + ] + }, + "sectionTitle": "Otsingutulemused" + }, + "titles": { + "day": { + "default": "Mida te soovite täna pärastlõunal vaadata?", + "extra": [ + "Kas tunnete end seiklushimulisena? Jurassic Park võib olla ideaalne valik." + ] + }, + "morning": { + "default": "Mida te soovite täna hommikul vaadata?", + "extra": [ + "Ma kuulsin, et Before Sunrise on hea" + ] + }, + "night": { + "default": "Mida te soovite täna õhtul vaadata?", + "extra": [ + "Väsinud? Olen kuulnud, et The Exorcist on hea." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Saade" + }, + "unreleased": "Avaldamata" + }, + "navigation": { + "banner": { + "offline": "Kontrollige oma Interneti-ühendust" + }, + "menu": { + "about": "Meie kohta", + "logout": "Logi välja", + "register": "Sünkrooni pilvega", + "settings": "Sätted", + "support": "Abi" + } + }, + "notFound": { + "badge": "Ei leitud", + "goHome": "Tagasi koju", + "message": "Otsisime kõikjalt: prügikastide alt, kapist, proksi tagant, kuid lõpuks ei leidnud otsitud lehte.", + "title": "Ei leidnud seda lehekülge" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Tühista", + "confirm": "Kasuta tavalist seadistust", + "description": "Tavalises seadistuses ei ole parimad striimid ja see võib olla talumatult aeglane.", + "title": "Oled kindel?" + }, + "extension": { + "back": "Mine tagasi", + "explainer": "Kasutades brauserilaiendust, saate parimaid striime, mida meil on pakkuda. Seda saab paigaldada vaid paari hetkega.", + "explainerIos": "Kahjuks ei toeta iOS meie brauserilaiendust, Vajutage Minge tagasi, et valida teine valik.", + "extensionHelp": "Kui olete laienduse paigaldanud, kuid seda ei tuvastata, avage laiendus oma brauseri laienduste menüüst ja järgige ekraanil olevaid juhendeid.", + "linkChrome": "Paigalda Chrome laiendus", + "linkFirefox": "Paigalda Firefox'i laiendus", + "notDetecting": "Paigaldasite laienduse Chrome'ile, kuid sait ei tuvasta seda? Proovige lehte värskendada!", + "notDetectingAction": "Värskenda leht", + "status": { + "disallowed": "Laiendus ei ole lubatud sellel lehel", + "disallowedAction": "Laienduse lubamine", + "failed": "Päring staatuse saamiseks ei õnnestunud", + "loading": "Ootame, et paigaldaksite laienduse", + "outdated": "Laienduse versioon liiga vana", + "success": "Laiendus töötab ootuspäraselt!" + }, + "submit": "Jätka", + "title": "Alustame laiendusega" + }, + "proxy": { + "back": "Mine tagasi", + "explainer": "Proksi abiga saate suurepärase kvaliteediga striime.", + "input": { + "errorConnection": "Ei saanud proksiga ühendatud", + "errorInvalidUrl": "Ei ole kehtiv URL", + "errorNotProxy": "Oodati proksit, kuid saadi veebileht", + "label": "Proksi URL", + "placeholder": "https://" + }, + "link": "Õpi kuidas teha proksi", + "submit": "Esita proksi", + "title": "Teeme uue proksi" + }, + "start": { + "explainer": "Parimate võimalike striimide saamiseks peate valima, millist striimimismeetodit soovite kasutada.", + "options": { + "default": { + "text": "Ma ei taha hea kvaliteediga striimi, <0 /> <1>kasuta tavalist seadistust" + }, + "extension": { + "action": "Paigalda laiendus", + "description": "Paigaldage brauseri laiendus ja saage ligi parimatele allikatele.", + "quality": "Parim kvaliteet", + "title": "Brauseri laiendus" + }, + "proxy": { + "action": "Proxy seadistamine", + "description": "Seadistage proksi kõigest 5 minutiga ja pääsete ligi suurepärastele allikatele.", + "quality": "Hea kvaliteet", + "title": "Kohandatud proxy" + } + }, + "title": "Teeme algust SkoolTVi kasutamisega" + } + }, + "overlays": { + "close": "Sulge" + }, + "player": { + "back": { + "default": "Tagasi koju", + "short": "Tagasi" + }, + "casting": { + "enabled": "Seadmesse ülekandmine..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Kopeeri HLS esitusloendi link", + "disclaimer": "Allalaadimine toimub otse teenusepakkujalt. SkoolTV ei saa kontrollida, kuidas allalaadimine toimub.", + "downloadSubtitle": "Laadige alla praegune subtiiter", + "downloadVideo": "Lae alla video", + "hlsDisclaimer": "Allalaadimised võetakse otse teenusepakkujalt. SkoolTV ei kontrolli, kuidas allalaadimisi pakutakse.

Pange tähele, et laadite alla HLS-i esitusloendit, see on mõeldud kasutajatele, kes on tuttavad multimeediumi striimimisega.", + "onAndroid": { + "1": "Et allalaadida Androidi telefonil, vajuta allalaadimise nupule, siis uuel leheküljel vajuta ja hoia video peal, siis vali salvesta.", + "shortTitle": "Allalaadimine / Android", + "title": "Androidil allalaadimine" + }, + "onIos": { + "1": "Et allalaadida iOS telefonil, vajuta allalaadimise nupule, siis uuel leheküljel vajuta , siis Salvesta failidesse .", + "shortTitle": "Allalaadimine / iOS", + "title": "iOSil allalaadimine" + }, + "onPc": { + "1": "Klõpsake arvutis allalaadimise nupule, seejärel klõpsake uuel lehel parema klõpsuga videol ja valige Salvesta video", + "shortTitle": "Allalaadimine / Arvutis", + "title": "Arvutis allalaadimine" + }, + "title": "Lae alla" + }, + "episodes": { + "button": "Episoodid", + "emptyState": "Selles hooajas puuduvad episoodid, vaadake hiljem uuesti!", + "episodeBadge": "E{{episode}}", + "loadingError": "Hooaja laadimine ebaōnnestus", + "loadingList": "Laadimine...", + "loadingTitle": "Laadimine...", + "unairedEpisodes": "Üks või mitu selle hooaja episoodi on välja lülitatud, sest neid ei ole veel eetris olnud." + }, + "playback": { + "speedLabel": "Taasesituse kiirus", + "title": "Taasesituse sätted" + }, + "quality": { + "automaticLabel": "Automaatne kvaliteet", + "hint": "Võid proovida <0>vahetada allikat, et saada teisi kvaliteedi valikuid.", + "iosNoQuality": "Apple'i poolt määratletud piirangute tõttu ei ole sellel allikal kvaliteedivalik saadaval. Te võite proovida <0>vahetada teisele allikale, et saada erinevaid kvaliteedivalikuid.", + "title": "Kvaliteet" + }, + "settings": { + "audioItem": "Audio", + "downloadItem": "Lae alla", + "enableSubtitles": "Luba Subtiitrid", + "experienceSection": "Vaatamise kogemus", + "playbackItem": "Taasesituse sätted", + "qualityItem": "Kvaliteet", + "sourceItem": "Video allikad", + "subtitleItem": "Subtiitri sätted", + "videoSection": "Video sätted" + }, + "sources": { + "failed": { + "text": "Videote leidmisel tekkis viga, palun proovige mõnda muud allikat.", + "title": "Ei õnnestunud kraapida" + }, + "noEmbeds": { + "text": "Me ei leidnud ühtegi manust, proovige twist allikat.", + "title": "Ei leitud manuseid" + }, + "noStream": { + "text": "Sellel allikal ei ole selle filmi või seriaali jaoks ühtegi striimi.", + "title": "Puudub striim" + }, + "title": "Allikad", + "unknownOption": "Teadmata" + }, + "subtitles": { + "customChoice": "Kukuta või vali subtiitri fail", + "customizeLabel": "Kohanda", + "dropSubtitleFile": "Kukuta subtiitri fail siia", + "offChoice": "Välja", + "settings": { + "backlink": "Kohandatud subtiitrid", + "delay": "Subtiitrite viivitus", + "fixCapitals": "Parandage suurtähtede kasutamine" + }, + "title": "Subtiitrid", + "unknownLanguage": "Tundmatu" + } + }, + "metadata": { + "api": { + "text": "API metaandmete laadimine ebaõnnestus, palun kontrollige oma internetiühendust.", + "title": "API metaandmete laadimine ebaõnnestus" + }, + "dmca": { + "badge": "Eemaldatud", + "text": "See meedia pole enam saadaval kas eemaldamisteate või autoriõiguse nõue tõttu.", + "title": "Meedia on eemaldatud" + }, + "extensionPermission": { + "badge": "Luba puudub", + "button": "Kasuta laiendust", + "text": "Sul on meie laiendus aga meil on vaja sinu luba, et saaksid alustada laienduse kasutamist.", + "title": "Seadistage laiendus" + }, + "failed": { + "badge": "Ebaōnnestus", + "homeButton": "Mine koju", + "text": "Meedia metaandmeid ei õnnestunud TMDB-st laadida. Palun kontrollige, kas TMDB on maas või see on teie internetiühenduses blokeeritud.", + "title": "Metaandmete laadimine ebaõnnestus" + }, + "notFound": { + "badge": "Ei leitud", + "homeButton": "Tagasi koju", + "text": "Me ei leidnud teie soovitud meediat. Kas see on eemaldatud või olete URL-i muutnud.", + "title": "Ei leidnud seda meediat." + } + }, + "nextEpisode": { + "cancel": "Tühista", + "next": "Järgmine episood" + }, + "playbackError": { + "badge": "Taasesituse viga", + "errors": { + "errorAborted": "Meedia kättesaamine katkestati kasutaja taotlusel.", + "errorDecode": "Vaatamata sellele, et eelnevalt oli kindlaks tehtud, et see on kasutatav, tekkis viga meediaressursi dekodeerimisel, mille tulemuseks oli viga.", + "errorGenericMedia": "Tekkis tundmatu meediaviga.", + "errorNetwork": "Tekkis võrguviga, mis takistas meedia edukat kättesaamist, kuigi see oli varem saadaval.", + "errorNotSupported": "Meedia või meediapakkuja objekt ei ole toetatud." + }, + "homeButton": "Mine koju", + "text": "Tekkis viga meedia mängimisel. Palun proovige uuesti.", + "title": "Video mängimine ebaōnnestus!" + }, + "scraping": { + "extensionFailure": { + "badge": "Brauserilaiendus väljalülitatud", + "enableExtension": "Lülita brauserilaiendus sisse", + "homeButton": "Tagasi", + "text": "Olete allalaadinud SkoolTV'i brauserilaiendue. Selle kasutamiseks peate vajutama brauserilaienduse peale ning andma ligipääsu praegusele saidile.", + "title": "Palun lülita brauserilaiendus sisse" + }, + "items": { + "failure": "Tekkis viga", + "notFound": "Ei ole videot", + "pending": "Otsin videoid..." + }, + "notFound": { + "badge": "Ei leitud", + "detailsButton": "Näita üksikasju", + "homeButton": "Mine koju", + "text": "Me otsisime läbi meie teenusepakkujad ja ei leidnud teie poolt otsitud meediat! Me ei halda meediat ja meil ei ole kontrolli selle üle, mis on saadaval. Täpsema teabe saamiseks klõpsake allpool nupule \"Näita üksikasju\".", + "title": "Me ei leidnud seda" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} alles • Lõppeb {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Palun kinnitage, et olete inimene, täites paremal asuva Captcha. See on selleks, et hoida SkoolTV turvalisena!", + "error": "Ei õnnestunud kontrollida teie inimlikkust. Palun proovige uuesti.", + "title": "Me peame kontrollima, et te olete inimene.", + "verifyingHumanity": "Kontrollime kas olete robot..." + } + }, + "screens": { + "dmca": { + "text": "Tere tulemast SkoolTVi DMCA kontaktilehele! Me austame intellektuaalomandi õigusi ja soovime kiiresti lahendada kõik autoriõigusega seotud probleemid. Kui usute, et teie autoriõigusega kaitstud tööd on meie platvormil vääralt kasutatud, saatke palun üksikasjalik DMCA-teade alljärgnevale e-posti aadressile. Palun lisage autoriõigusega kaitstud materjali kirjeldus, oma kontaktandmed ja avaldus heauskse veendumuse kohta. Oleme pühendunud nende küsimuste kiirele lahendamisele ja hindame teie koostööd, et SkoolTV oleks koht, kus austatakse loovust ja autoriõigusi.", + "title": "DMCA" + }, + "loadingApp": "Rakenduse laadimine", + "loadingUser": "Teie profiili laadimine", + "loadingUserError": { + "logout": "Logi välja", + "reset": "Lähtestage kohandatud server", + "text": "Profiili laadimine ebaōnnestus", + "textWithReset": "Profiili laadimine kohandatud serverist ebaõnnestus. Kas soovite lähtestada vaikeserverile?" + }, + "migration": { + "failed": "Teie andmete üleviimine ebaõnnestus.", + "inProgress": "Palun oodake, me viime teie andmeid üle. See ei tohiks kaua aega võtta." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Seadme nimi", + "deviceNamePlaceholder": "Isiklik telefon", + "editProfile": "Muuda", + "logoutButton": "Logi välja" + }, + "actions": { + "delete": { + "button": "Kustuta konto", + "confirmButton": "Kustuta konto", + "confirmDescription": "Kas olete kindel, et soovite oma konto kustutada? Kõik teie andmed lähevad kaotsi!", + "confirmTitle": "Oled sa kindel?", + "text": "See toiming on pöördumatu. Kõik andmed kustutatakse ja midagi ei saa taastada.", + "title": "Kustuta konto" + }, + "title": "Tegevused" + }, + "devices": { + "deviceNameLabel": "Seadme nimi", + "failed": "Seansside laadimine ebaõnnestus", + "removeDevice": "Eemalda", + "title": "Seadmed" + }, + "profile": { + "finish": "Lõpeta redigeerimine", + "firstColor": "Profiili värv üks", + "secondColor": "Profiili värv kaks", + "title": "Redigeeri profiilipilti", + "userIcon": "Kasutaja ikoon" + }, + "register": { + "cta": "Alustama", + "text": "Jagage oma vaatamise edenemist seadmete vahel ja hoidke neid sünkroonituna.", + "title": "Sünkrooni pilvega" + }, + "title": "Konto" + }, + "appearance": { + "activeTheme": "Aktiivne", + "themes": { + "blue": "Sinine", + "default": "Vaikimisi", + "gray": "Hall", + "red": "Punane", + "teal": "Tumesinine" + }, + "title": "Välimus" + }, + "connections": { + "server": { + "description": "Kui soovite kohandatud backend'i kasutada oma andmete hoidmiseks, siis lubage see ja varustage URL. Juhised.", + "label": "Kohandatud server", + "urlLabel": "Kohandatud serveri URL" + }, + "setup": { + "doSetup": "Seadista", + "errorStatus": { + "description": "Üks või mitu selle seadistuse üksust vajavad teie tähelepanu.", + "title": "Midagi vajab teie tähelepanu" + }, + "itemError": "Midagi on valesti selle sättega. Selle parandamiseks läbige seadistus uuesti.", + "items": { + "default": "Tavaline seadistamine", + "extension": "Laiendus", + "proxy": "Kohandatud proksi" + }, + "redoSetup": "Seadista uuesti", + "successStatus": { + "description": "Kõik on paigas, et saaksite enda lemmikmeediat nautima hakata.", + "title": "Kõik on seadistatud!" + }, + "unsetStatus": { + "description": "Seadistusprotsessi alustamiseks klõpsake paremal asuvat nuppu.", + "title": "Te pole seadistamist läbinud" + } + }, + "title": "Ühendused", + "workers": { + "addButton": "Lisa uus töötaja", + "description": "Rakenduse toimimiseks suunatakse kogu liiklus puhverserverite kaudu. Lubage see, kui soovite oma puhverserverit kasutada. <0>Juhised.", + "emptyState": "Töötajaid pole veel, lisage üks", + "label": "Kasutage kohandatud puhverserveri töötajaid", + "urlLabel": "Töötajate URL-id", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Rakenduse keel", + "languageDescription": "Keel, mis on rakendatud tervele rakendusele.", + "thumbnail": "Genereeri pisipilte", + "thumbnailDescription": "Enamasti pole videodel pisipilte. Selle sätte lubamisega genereeritakse pispildid vaatamise ajal, kuid need võivad teie video aeglasemaks muuta.", + "thumbnailLabel": "Genereeri pisipilte", + "title": "Eelistused" + }, + "reset": "Lähtesta", + "save": "Salvesta", + "sidebar": { + "info": { + "appVersion": "Rakenduse versioon", + "backendUrl": "Backend'i URL", + "backendVersion": "Backend'i versioon", + "hostname": "Hostinimi", + "insecure": "Ebakindel", + "notLoggedIn": "Sa pole sisse loginud", + "secure": "Turvaline", + "title": "Rakenduse teave", + "unknownVersion": "Teadmatu", + "userId": "Kasutaja ID" + } + }, + "subtitles": { + "backgroundBlurLabel": "Tausta hägusus", + "backgroundLabel": "Tausta läbipaistmatus", + "colorLabel": "Värv", + "previewQuote": "Ma ei tohi karta. Hirm on meelemõrvar.", + "textSizeLabel": "Teksti suurus", + "title": "Subtiitrid" + }, + "unsaved": "Teil on salvestamata muudatusi" + } +} diff --git a/src/assets/locales/fa.json b/src/assets/locales/fa.json new file mode 100644 index 0000000..a434dd8 --- /dev/null +++ b/src/assets/locales/fa.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "مووی-وب یک برنامه تحت وب است که در اینترنت به دنبال استریم ها می‌گردد. هدف تیم تجربه‌ای ساده برای استفاده از محتوا است.", + "faqTitle": "سوالات متداول", + "q1": { + "body": "مووی-وب هیچ محتوایی را میزبانی نمی‌کند. وقتی برای تماشا روی چیزی کلیک می‌کنید، ما در اینترنت به دنبال محتوای مورد نظر شما می‌گردیم (در صفحه دانلود و در برگه 'منابع ویدیو' می‌توانید ببینید که از کدام منبع استفاده می‌کنید). محتوا هرگز در مووی-وب آپلود نمی‌شود، همه چیز از طریق این مکانیزم جستجو اتفاق می‌افتد.", + "title": "فیلم ها از کجا می‌آیند؟" + }, + "q2": { + "body": "از آنجایی که محتوا ها توسط مووی-وب مدیریت نمی‌شوند، امکان درخواست فیلم وجود ندارد. تمام محتوا از طریق منابع در اینترنت به شما نشان داده می‌شوند.", + "title": "از کجا میتونم درخواست فیلم کنم؟" + }, + "q3": { + "body": "نتایج جستجوی ما توسط پایگاه داده فیلم (TMDB) تامین می‌شوند و نمایش داده می‌شوند، بدون اینکه مهم باشد که منابع ما واقعاً محتوا را داشته باشند یا خیر.", + "title": "جستجو همراه با نتیجه است، اما چرا فیلم پخش نمی‌شود؟" + }, + "title": "درباره مووی-وب" + }, + "actions": { + "copied": "کپی شد", + "copy": "کپی" + }, + "auth": { + "createAccount": "آیا هنوز حساب کاربری ندارید؟ <0>حساب ایجاد کنید.", + "deviceNameLabel": "نام دستگاه", + "deviceNamePlaceholder": "تلفن شخصی", + "generate": { + "description": "عبارت عبور شما به عنوان نام کاربری و رمز عبور عمل می‌کند. آن را در جایی ذخیره کنید چون برای ورود به آن نیاز دارید", + "next": "عبارت عبور امنیتی خود را ذخیره کرده‌ام", + "passphraseFrameLabel": "عبارت عبور امنیتی", + "title": "عبارت عبور امنیتی شما" + }, + "hasAccount": "حساب کاربری دارید؟ <0>اینجا وارد شوید.", + "login": { + "description": "لطفاً عبارت عبور امنیتی خود را وارد کنید تا وارد حساب کاربری شوید", + "deviceLengthError": "لطفا نامی برای دستگاه انتخاب کنید", + "passphraseLabel": "عبارت عبور 12 کلمه‌ای", + "passphrasePlaceholder": "عبارت عبور امنیتی", + "submit": "ورود", + "title": "ورود به حساب کاربری", + "validationError": "عبارت عبور امنیتی نادرست یا ناقص است" + }, + "register": { + "information": { + "color1": "رنگ پروفایل اول", + "color2": "رنگ پروفایل دوم", + "header": "نام دستگاه، رنگ‌ها و نماد کاربری مورد نظر خود را انتخاب کنید", + "icon": "نماد کاربری", + "next": "بعدی", + "title": "اطلاعات حساب کاربری" + } + }, + "trust": { + "failed": { + "text": "درست پیکربندیش کردی؟", + "title": "مشکلی در ارتباط با سرور رخ داده" + }, + "host": "شما در حال اتصال به <0>{{hostname}} هستید - لطفا قبل از ایجاد حساب کاربری خود از اعتماد به آن اطمینان حاصل کنید", + "no": "بازگشت", + "noHost": "سرور پیکربندی نشده، بنابرین نمیتوانید حسابی ایجاد کنید", + "noHostTitle": "سرور پیکر بندی نشده!", + "title": "آیا به این سرور اعتماد دارید؟", + "yes": "بله اعتماد دارم" + }, + "verify": { + "description": "لطفا عبارت عبور که به شما داده شده را مجدد وارد تا کنید تا حساب کاربری ساخته شود", + "invalidData": "داده نامعتبر است", + "noMatch": "عبارت عبور مطابقت ندارد", + "passphraseLabel": "عبارت عبور 12 کلمه ای شما", + "recaptchaFailed": "اعتبارسنجی ReCaptcha ناموفق بود", + "register": "ساخت حساب کاربری", + "title": "عبارت عبور خود را تایید کنید" + } + }, + "errors": { + "badge": "مشکلی رخ داد", + "details": "جزئیات خطا", + "reloadPage": "صفحه را دوباره بارگذاری کنید", + "showError": "نمایش جزئیات خطا", + "title": "با خطا مواجه شدیم!" + }, + "footer": { + "legal": { + "disclaimer": "سلب مسئولیت", + "disclaimerText": "مووی-وب هیچ فایلی را میزبانی نمی‌کند، صرفاً به سرویس‌های ثالث لینک می‌دهد. مسائل قانونی باید با میزبان‌ها و ارائه‌دهندگان فایل مطرح شود. مووی-وب مسئولیتی در قبال هیچ فایل محتوایی که توسط ارائه‌دهندگان ویدیو نشان داده می‌شود ندارد." + }, + "links": { + "discord": "دیسکورد", + "dmca": "DMCA", + "github": "گیت هاب" + }, + "tagline": "فیلم و سریال مورد علاقه‌تان را با این برنامه استریم اوپن سورس تماشا کنید." + }, + "global": { + "name": "مووی-وب", + "pages": { + "about": "درباره", + "dmca": "DMCA", + "login": "ورود", + "onboarding": "راه اندازی", + "pagetitle": "{{title}} - مووی-وب", + "register": "ثبت نام", + "settings": "تنظیمات" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "علاقه مندی ها" + }, + "continueWatching": { + "sectionTitle": "به تماشا ادامه دهید" + }, + "mediaList": { + "stopEditing": "ویرایش را متوقف کنید" + }, + "search": { + "allResults": "همه چیزی بود که داشتیم!", + "failed": "چیزی پیدا نشد، دوباره تلاش کنید!", + "loading": "در حال بارگذاری...", + "noResults": "نتونستیم چیزی پیدا کنیم!", + "placeholder": { + "default": "چه می‌خواهید تماشا کنید؟", + "extra": [ + "دنبال چی میگردی؟", + "چی تو لیست تماشات داری؟", + "فیلم مورد علاقت چیه؟", + "سریال مورد علاقت چیه؟" + ] + }, + "sectionTitle": "نتایج جستجو" + }, + "titles": { + "day": { + "default": "دوست دارید امروز بعدازظهر چه چیزی تماشا کنید؟", + "extra": [ + "به دنبال ماجراجویی هستید؟ \"پارک ژوراسیک\" انتخابی عالی است." + ] + }, + "morning": { + "default": "دوست دارید امروز صبح چه چیزی تماشا کنید؟", + "extra": [ + "شنیدم فیلم \"پیش از طلوع\" عالیه" + ] + }, + "night": { + "default": "دوست دارید امشب چه چیزی تماشا کنید؟", + "extra": [ + "خسته اید؟ شنیده ام که \"جن گیر\" فیلم خوبی است." + ] + } + } + }, + "media": { + "episodeDisplay": "فصل {{season}} قسمت {{episode}}", + "types": { + "movie": "فیلم", + "show": "سریال" + }, + "unreleased": "منتشر نشده" + }, + "navigation": { + "banner": { + "offline": "اتصال اینترنت خود را بررسی کنید" + }, + "menu": { + "about": "درباره ما", + "logout": "خروج", + "register": "همگام سازی", + "settings": "تنظیمات", + "support": "پشتیبانی" + } + }, + "notFound": { + "badge": "پیدا نشد", + "goHome": "بازگشت به خانه", + "message": "همه جا را جستجو کردیم: زیر سطل‌ها، در کمد، پشت پروکسی، اما در نهایت نتوانستیم صفحه‌ای که به دنبال آن هستید را پیدا کنیم.", + "title": "نتواستیم صفحه را پیدا کنیم" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "لغو کنید", + "confirm": "از تنظیمات پیش فرض استفاده کنید", + "description": "راه‌اندازی پیش‌فرض بهترین جریان‌ها را ندارد و می‌تواند به طور غیرقابل تحملی کند باشد.", + "title": "مطمئنی؟" + }, + "extension": { + "back": "برگرد", + "explainer": "با استفاده از افزونه مرورگر، می‌توانید بهترین جریان‌های ارائه شده را دریافت کنید. فقط با یک نصب ساده.", + "explainerIos": "متأسفانه افزونه مرورگر در iOS پشتیبانی نمی‌شود، برای انتخاب گزینه دیگری Go back را فشار دهید.", + "extensionHelp": "اگر برنامه افزودنی را نصب کرده اید اما شناسایی نشده است.، افزونه را از طریق منوی افزونه مرورگر خود باز کنید و مراحل روی صفحه را دنبال کنید.", + "linkChrome": "افزونه کروم را نصب کنید", + "linkFirefox": "افزونه فایرفاکس را نصب کنید", + "notDetecting": "روی کروم نصب شده است، اما سایت آن را شناسایی نمی کند؟ سعی کنید صفحه را دوباره بارگیری کنید!", + "notDetectingAction": "بارگذاری مجدد صفحه", + "status": { + "disallowed": "برنامه افزودنی برای این صفحه فعال نیست", + "disallowedAction": "افزونه را فعال کنید", + "failed": "درخواست وضعیت ناموفق بود", + "loading": "منتظر نصب افزونه هستیم", + "outdated": "نسخه افزونه خیلی قدیمی است", + "success": "برنامه افزودنی همانطور که انتظار می رود کار می کند!" + }, + "submit": "ادامه دهید", + "title": "بیایید با یک افزونه شروع کنیم" + }, + "proxy": { + "back": "برگرد", + "explainer": "با روش پروکسی می توانید با ساخت یک پراکسی سلف سرویس استریم های با کیفیت عالی دریافت کنید.", + "input": { + "errorConnection": "نمی توان به پروکسی وصل شد", + "errorInvalidUrl": "لینک معتبر نیست", + "errorNotProxy": "انتظار یک پروکسی داشتم اما یک وب سایت دریافت کردم", + "label": "لینک پروکسی", + "placeholder": "https://" + }, + "link": "آموزش ساخت پروکسی", + "submit": "پروکسی را ثبت کنید", + "title": "بیایید یک پروکسی جدید بسازیم" + }, + "start": { + "explainer": "برای دریافت بهترین استریم های ممکن، باید روش پخش جریانی را که می خواهید استفاده کنید، انتخاب کنید.", + "options": { + "default": { + "text": "من پخش جریانی با کیفیت خوب نمی‌خواهم،<0 /> <1>از تنظیمات پیش‌فرض استفاده کنید" + }, + "extension": { + "action": "افزونه را نصب کنید", + "description": "افزونه مرورگر را نصب کنید و به بهترین منابع دسترسی پیدا کنید.", + "quality": "بهترین کیفیت", + "title": "افزونه مرورگر" + }, + "proxy": { + "action": "راه اندازی پروکسی", + "description": "یک پروکسی را فقط در 5 دقیقه راه اندازی کنید و به منابع عالی دسترسی پیدا کنید.", + "quality": "کیفیت خوب", + "title": "پروکسی سفارشی" + } + }, + "title": "بیایید با مووی-وب راه اندازی کنیم" + } + }, + "overlays": { + "close": "بستن" + }, + "player": { + "back": { + "default": "بازگشت به خانه", + "short": "بازگشت" + }, + "casting": { + "enabled": "ارسال روی دستگاه..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "لینک HLS لیست پخش را کپی کنید", + "disclaimer": "دانلود ها به طور مستقیم از ارائه دهنده گرفته می شوند. مووی-وب کنترلی بر نحوه ارائه دانلود ها ندارد.", + "downloadSubtitle": "دانلود زیرنویس فعلی", + "downloadVideo": "دانلود ویدیو", + "hlsDisclaimer": "دانلودها مستقیماً از ارائه دهنده گرفته می شوند. SkoolTV کنترلی بر نحوه ارائه دانلودها ندارد.

لطفاً توجه داشته باشید که در حال دانلود یک لیست پخش HLS هستید، اگر با فرمت های پخش جریانی پیشرفته آشنایی ندارید، دانلود آن توصیه نمی شود. . منابع مختلف را برای فرمت های مختلف امتحان کنید.", + "onAndroid": { + "1": "برای دانلود در اندروید، روی دکمه دانلود کلیک کنید و سپس در صفحه جدید، روی ویدیو ضربه بزنید و نگه دارید، سپس ذخیره را انتخاب کنید.", + "shortTitle": "دانلود / اندروید", + "title": "دانلود در اندروید" + }, + "onIos": { + "1": "برای دانلود در iOS، روی دکمه دانلود کلیک کنید و سپس در صفحه جدید، روی و سپس روی Save to Files کلیک کنید.", + "shortTitle": "دانلود / iOS", + "title": "دانلود در iOS" + }, + "onPc": { + "1": "در کامپیوتر، روی دکمه دانلود کلیک کنید و سپس در صفحه جدید، روی ویدیو کلیک راست کنید و ذخیره ویدیو به عنوانرا انتخاب کنید", + "shortTitle": "دانلود / کامپیوتر", + "title": "دانلود در کامپیوتر" + }, + "title": "دانلود" + }, + "episodes": { + "button": "قسمت ها", + "emptyState": "هنوز هیچ قسمتی در این فصل وجود ندارد، بعدا سر بزنید!", + "episodeBadge": "قسمت {{episode}}", + "loadingError": "خطایی در بارگیری فصل رخ داد", + "loadingList": "در حال بارگذاری...", + "loadingTitle": "در حال بارگذاری...", + "unairedEpisodes": "یک یا چند قسمت در این فصل غیرفعال شده است به دلیل اینکه هنوز پخش نشده است." + }, + "playback": { + "speedLabel": "سرعت پخش", + "title": "تنظیمات پخش" + }, + "quality": { + "automaticLabel": "کیفیت خودکار", + "hint": "شما می توانید با <0>تغییر منبع به گزینه های مختلف کیفیت دسترسی داشته باشید.", + "iosNoQuality": "با توجه به محدودیت های تعریف شده توسط اپل، انتخاب کیفیت در iOS برای این منبع در دسترس نیست. شما می توانید با <0>تغییر منبع گزینه های مختلف کیفیت را به دست آورید.", + "title": "کیفیت" + }, + "settings": { + "audioItem": "صدا", + "downloadItem": "دانلود", + "enableSubtitles": "فعال کردن زیرنویس", + "experienceSection": "تجربه مشاهده", + "playbackItem": "تنظیمات پخش", + "qualityItem": "کیفیت", + "sourceItem": "منبع ویدیو", + "subtitleItem": "تنظیمات زیرنویس", + "videoSection": "تنظیمات ویدیو" + }, + "sources": { + "failed": { + "text": "یک خطا در هنگام تلاش برای پیدا کردن فیلم وجود دارد، لطفا یک منبع دیگر را امتحان کنید.", + "title": "دریافت اطلاعات ناموفق بود" + }, + "noEmbeds": { + "text": "نتوانستیم اطلاعات را پیدا کنیم، لطفا منبع دیگری را امتحان کنید.", + "title": "هیج اطلاعاتی پیدا نشد" + }, + "noStream": { + "text": "فیلم یا سریال شما در این منبع وجود ندارد.", + "title": "استریمی وجود ندارد" + }, + "title": "منابع", + "unknownOption": "ناشناخته" + }, + "subtitles": { + "customChoice": "فایل را رها یا آپلود کنید", + "customizeLabel": "شخصی سازی", + "dropSubtitleFile": "فایل زیرنویس را اینجا بکشید", + "offChoice": "خاموش", + "settings": { + "backlink": "زیرنویس سفارشی", + "delay": "تاخیر زیرنویس", + "fixCapitals": "تصحیح حروف اول بزرگ (انگلیسی)" + }, + "title": "زیرنویس ها", + "unknownLanguage": "ناشناخته" + } + }, + "metadata": { + "api": { + "text": "داده API بارگیری نشد، لطفا اتصال اینترنت خود را بررسی کنید.", + "title": "داده API بارگیری نشد" + }, + "dmca": { + "badge": "حذف شد", + "text": "این محتوا به دلیل اطلاع حذف یا ادعای حق نسخه‌برداری دیگر در دسترس نیست.", + "title": "محتوا حذف شده است" + }, + "extensionPermission": { + "badge": "مجوز وجود ندارد", + "button": "از افزونه استفاده کنید", + "text": "شما افزونه مرورگر را دارید، اما برای شروع استفاده از برنامه افزودنی به اجازه شما نیاز داریم.", + "title": "افزونه را پیکربندی کنید" + }, + "failed": { + "badge": "ناموفق", + "homeButton": "بازگشت به خانه", + "text": "دریافت اطلاعات از TMDB ناموفق بود، ممکن است TMDB موقتا غیرفعال باشد یا توسط ارائه دهنده شما فیلتر باشد.", + "title": "اطلاعات بارگیری نشد" + }, + "notFound": { + "badge": "پیدا نشد", + "homeButton": "بازگشت به خانه", + "text": "محتوایی که شما به دنبالش هستید رو پیدا نکردیم. ممکن است حذف شده باشد یا شما لینک این صفحه دستکاری شده باشید.", + "title": "محتوا ای پیدا نشد." + } + }, + "nextEpisode": { + "cancel": "لغو", + "next": "قسمت بعدی" + }, + "playbackError": { + "badge": "مشکلی در پخش به وجود آمده", + "errors": { + "errorAborted": "دریافت محتوا با درخواست کاربر لغو شد.", + "errorDecode": "با وجود اینکه قبلا مشخص شده بود که قابل استفاده است، یک خطا در هنگام تلاش برای رمزگشایی محتوا رخ داد که باعث مشکل شد.", + "errorGenericMedia": "خطای محتوای ناشناخته رخ داد.", + "errorNetwork": "با وجود اینکه قبلا در دسترس بود، نوعی خطای شبکه رخ داد که مانع از دریافت محتوا شد.", + "errorNotSupported": "محتوا یا ارائه دهنده محتوا پشتیبانی نمی‌شود." + }, + "homeButton": "بازگشت به خانه", + "text": "مشکلی در پخش محتوا وجود داشت. لطفا دوباره تلاش کنید.", + "title": "پخش ویدئو موفقیت آمیز نبود!" + }, + "scraping": { + "extensionFailure": { + "badge": "اکستنشن غیر فعال شد", + "enableExtension": "اکستنشن را فعال کنید", + "homeButton": "خانه", + "text": "شما اکستنشن مووی-وب را نصب کردید. برای شروع استفاده از ان، نیاز به فعال کردن آن دارید", + "title": "لطفا اکستنشن را فعال کنید" + }, + "items": { + "failure": "مشکلی پیش آمده", + "notFound": "این ویدیو وجود ندارد", + "pending": "در حال بررسی ویدیوها..." + }, + "notFound": { + "badge": "پیدا نشد", + "detailsButton": "نمایش جزئیات", + "homeButton": "بازگشت به خانه", + "text": "ما در ارائه دهندگان جستجو کرده ایم ولی نمی توانیم محتوایی را که به دنبال آن را هستید پیدا کنیم! ما محتواها را میزبانی نمی کنیم و هیچ کنترلی بر آنچه در دسترس است نداریم. لطفا برای جزئیات بیشتر روی \"نمایش جزئیات\" در زیر کلیک کنید.", + "title": "نتونستیم پیداش کنیم" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} مشاهده شده • {{timeFinished, datetime}} دیگر تمام می‌شود", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "لطفا انسانیت خود را با تموم کردن چالش های کپچا به طور درست ثابت کنید. برای ایمن نگه داشتن مووی-وب!", + "error": "انسانیت شما تأیید نشد. لطفا دوباره تلاش کنید.", + "title": "ما باید تایید کنیم که شما انسان هستید.", + "verifyingHumanity": "تایید کردن انسانیت شما..." + } + }, + "screens": { + "dmca": { + "text": "به صفحه تماس DMCA مووی-وب خوش آمدید! ما به حقوق مالکیت معنوی احترام می گذاریم و می خواهیم به سرعت به هر گونه نگرانی کپی رایت رسیدگی کنیم. اگر فکر می کنید کار کپی رایت شما به طور نادرست در پلت فرم ما استفاده شده است، لطفا یک اطلاعیه DMCA دقیق را به ایمیل زیر ارسال کنید. لطفا شرح مواد کپی رایت، جزئیات تماس خود و بیانیه ای از اعتقاد حسن نیت را شامل شوید. ما متعهد به حل و فصل سریع این مسائل هستیم و از همکاری شما در حفظ وب فیلم به عنوان مکانی که به خلاقیت و کپی رایت احترام می گذارند، قدردانی می کنیم.", + "title": "DMCA" + }, + "loadingApp": "در حال بارگیری برنامه", + "loadingUser": "درحال بارگیری حساب کاربری شما", + "loadingUserError": { + "logout": "خروج", + "reset": "بازنشانی سرور سفارشی", + "text": "حساب کاربری شما بارگیری نشد", + "textWithReset": "بارگیری حساب کاربری شما از سرور سفارشی شکست خورد، آیا می خواهید به سرور پیش فرض بازگردید؟" + }, + "migration": { + "failed": "انتقال داده های شما انجام نشد.", + "inProgress": "لطفا صبر کنید، ما در حال انتقال داده های شما هستیم. زیاد طول نمیکشد." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "نام دستگاه", + "deviceNamePlaceholder": "تلفن شخصی", + "editProfile": "ویرایش", + "logoutButton": "خروج" + }, + "actions": { + "delete": { + "button": "حذف حساب کاربری", + "confirmButton": "حذف حساب کاربری", + "confirmDescription": "آیا مطمئن هستید که می خواهید حساب خود را حذف کنید؟ تمام اطلاعات شما از دست خواهد رفت!", + "confirmTitle": "مطمئنی؟", + "text": "این اقدام غیر قابل برگشت است. تمام اطلاعات حذف خواهد شد و هیچ چیز دیگر بازگردانی نمی‌شود.", + "title": "حذف حساب کاربری" + }, + "title": "اقدامات" + }, + "devices": { + "deviceNameLabel": "نام دستگاه", + "failed": "دریافت نشست ها شکست خورد", + "removeDevice": "حذف", + "title": "دستگاه ها" + }, + "profile": { + "finish": "تمام کردن ویرایش", + "firstColor": "رنگ پروفایل اول", + "secondColor": "رنگ پروفایل دوم", + "title": "ویرایش عکس نمایه", + "userIcon": "نماد کاربری" + }, + "register": { + "cta": "شروع کنید", + "text": "جریان تماشای خود را بین دستگاه‌ها به اشتراک بگذارید و آنها را با یکدیگر همگام سازی کنید.", + "title": "همگام سازی" + }, + "title": "حساب کاربری" + }, + "appearance": { + "activeTheme": "فعال", + "themes": { + "blue": "آبی", + "default": "پیشفرض", + "gray": "خاکستری", + "red": "قرمز", + "teal": "سبز" + }, + "title": "ظاهر" + }, + "connections": { + "server": { + "description": "اگر میخواید به یک بک-اند سفارشی برای ذخیره داده متصل شوید، با فعال و ارائه استفاده این لینک ادامه دهید. <0>دستورالعمل ها.", + "label": "سرور سفارشی", + "urlLabel": "لینک سرور کاستوم" + }, + "setup": { + "doSetup": "راه اندازی کنید", + "errorStatus": { + "description": "به نظر می رسد که یک یا چند مورد در این تنظیم نیاز به توجه شما دارد.", + "title": "چیزی به توجه شما نیاز دارد" + }, + "itemError": "مشکلی در این تنظیمات وجود دارد. برای رفع آن دوباره تنظیمات را انجام دهید.", + "items": { + "default": "تنظیم پیش فرض", + "extension": "افزونه", + "proxy": "پروکسی سفارشی" + }, + "redoSetup": "تنظیم مجدد", + "successStatus": { + "description": "همه چیز برای شروع تماشای فیلم مورد علاقه‌تان آماده است.", + "title": "همه چیز تنظیم شده است!" + }, + "unsetStatus": { + "description": "لطفاً روی دکمه سمت راست کلیک کنید تا فرآیند نصب شروع شود.", + "title": "شما هنوز راه‌اندازی را طی نکرده‌اید" + } + }, + "title": "اتصالات", + "workers": { + "addButton": "اضافه کردن worker جدید", + "description": "برای ایجاد عملکرد برنامه، تمام ترافیک از طریق پروکسی ها هدایت می شود. اگر میخواید این کار انجام دهید حتما از worker های خودتان استفاده کنید. <0>دستورالعمل ها.", + "emptyState": "هنوز هیچ worker ای وجود ندارد، یکی اضافه کنید", + "label": "از پروکسی worker کاستوم استفاده کنید", + "urlLabel": "لینک worker ها", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "زبان برنامه", + "languageDescription": "زبان برای کل برنامه اعمال شد.", + "thumbnail": "ایجاد تامبنیل", + "thumbnailDescription": "بیشتر اوقات، ویدیوها تامبنیل ندارند. شما می توانید این تنظیم را فعال کنید تا آنها را در لحظه ببینید، اما آنها می توانند ویدیوی شما را کندتر کنند.", + "thumbnailLabel": "ایجاد تامبنیل", + "title": "اولویت ها" + }, + "reset": "بازنشانی", + "save": "ذخیره", + "sidebar": { + "info": { + "appVersion": "نسخه برنامه", + "backendUrl": "لینک بک-اند", + "backendVersion": "نسخه بک-اند", + "hostname": "نام هاست", + "insecure": "ناامن", + "notLoggedIn": "شما وارد نشده اید", + "secure": "امن", + "title": "اطلاعات برنامه", + "unknownVersion": "ناشناخته", + "userId": "شناسه کاربری" + } + }, + "subtitles": { + "backgroundBlurLabel": "تاری پس زمینه", + "backgroundLabel": "شفافیت پس‌زمینه", + "colorLabel": "رنگ", + "previewQuote": "نباید بترسم، ترس قاتل ذهن است.", + "textSizeLabel": "اندازه متن", + "title": "زیرنویسها" + }, + "unsaved": "شما تغییرات ذخیره نشده دارید" + } +} diff --git a/src/assets/locales/fi-FI.json b/src/assets/locales/fi-FI.json new file mode 100644 index 0000000..e915dd0 --- /dev/null +++ b/src/assets/locales/fi-FI.json @@ -0,0 +1,288 @@ +{ + "about": { + "description": "SkoolTV on verkkosovellus, joka etsii suoratoistoja internetistä. Tiimi pyrkii enimmäkseen minimalistiseen lähestymistapaan sisällön kuluttamiseen.", + "faqTitle": "Yleisiä kysymyksiä", + "q1": { + "body": "SkoolTV ei isännöi mitään sisältöä. Kun klikkaat jotain katsottavaa, valittua mediaa etsitään internetistä (latausnäytössä ja 'videolähteet'-välilehdellä näet, mitä lähdettä käytät). SkoolTV ei koskaan lataa mediaa, kaikki tapahtuu tämän hakumekanismin kautta.", + "title": "Mistä sisältö tulee?" + }, + "q2": { + "body": "Ohjelmaa tai elokuvaa ei voi pyytää, SkoolTV ei hallinnoi sisältöä. Kaikki sisältö katsotaan internetin lähteistä.", + "title": "Missä voin pyytää sarjaa tai elokuvaa?" + }, + "q3": { + "body": "Hakutuloksemme perustuvat The Movie Database (TMDB) -tietokantaan, ja ne näkyvät riippumatta siitä, onko sisältöä oikeasti lähteissämme.", + "title": "Hakutuloksissa näytetään ohjelma tai elokuva. Miksi en voi toistaa sitä?" + }, + "title": "Tietoja SkoolTVistä" + }, + "actions": { + "copied": "Kopioitu", + "copy": "Kopioi" + }, + "auth": { + "createAccount": "Eikö sinulla ole vielä tiliä? <0>Luo tili.", + "deviceNameLabel": "Laitteen nimi", + "deviceNamePlaceholder": "Henkilökohtainen puhelin", + "generate": { + "description": "Tunnuslauseesi toimii käyttäjätunnuksena ja salasanana. Varmista, että pidät sen turvassa, sillä sinun on annettava se kirjautuaksesi tilillesi", + "next": "Olen tallentanut tunnuslauseeni", + "passphraseFrameLabel": "Tunnuslause", + "title": "Sinun tunnuslause" + }, + "hasAccount": "Onko sinulla jo tili? <0>Kirjaudu sisään tästä.", + "login": { + "description": "Anna tunnuslauseesi kirjautuaksesi tilillesi", + "deviceLengthError": "Anna laitteen nimi", + "passphraseLabel": "12-sanainen tunnuslause", + "passphrasePlaceholder": "Tunnuslause", + "submit": "Kirjaudu sisään", + "title": "Kirjaudu tilillesi", + "validationError": "Väärä tai puutteellinen tunnuslause" + }, + "register": { + "information": { + "color1": "Profiilin väri yksi", + "color2": "Profiilin väri kaksi", + "header": "Anna laitteellesi nimi ja valitse haluamasi värit ja käyttäjäkuvake", + "icon": "Käyttäjäkuvake", + "next": "Seuraava", + "title": "Tilitiedot" + } + }, + "trust": { + "failed": { + "text": "Oletko määrittänyt sen oikein?", + "title": "Palvelimeen ei saada yhteyttä" + }, + "host": "Olet muodostamassa yhteyttä <0>{{hostname}} - vahvista, että luotat siihen ennen kuin luot tilin", + "no": "Mene takaisin", + "title": "Luotatko tähän palvelimeen?", + "yes": "Luotan tähän palvelimeen" + }, + "verify": { + "description": "Anna aikaisemmin saamasi tunnuslause vahvistaaksesi, että olet tallentanut sen ja luodaksesi tilisi", + "invalidData": "Tiedot eivät kelpaa", + "noMatch": "Tunnuslause ei täsmää", + "passphraseLabel": "12-sanainen tunnuslauseesi", + "recaptchaFailed": "ReCaptcha-tarkistus epäonnistui", + "register": "Luo tili", + "title": "Vahvista tunnuslauseesi" + } + }, + "errors": { + "badge": "Se hajosi", + "details": "Virheen tiedot", + "reloadPage": "Lataa sivu uudelleen", + "showError": "Näytä virheen tiedot", + "title": "Havaitsimme virheen!" + }, + "footer": { + "legal": { + "disclaimer": "Vastuuvapauslauseke", + "disclaimerText": "SkoolTV ei isännöi tiedostoja, se vain linkittää kolmannen osapuolen palveluihin. Lakiasioista tulee ottaa yhteyttä tiedostoisäntään ja palveluntarjoajiin. SkoolTV ei ole vastuussa videontarjoajien näyttämistä mediatiedostoista." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Katso suosikkiohjelmiasi ja elokuviasi tällä avoimen lähdekoodin suoratoistosovelluksella." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Meistä", + "dmca": "DMCA", + "login": "Kirjaudu sisään", + "onboarding": "asetus", + "pagetitle": "{{title}} - SkoolTV", + "register": "Rekisteröidy", + "settings": "Asetukset" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Kirjanmerkit" + }, + "continueWatching": { + "sectionTitle": "Jatka katselua" + }, + "mediaList": { + "stopEditing": "Lopeta muokkaaminen" + }, + "search": { + "allResults": "Siinä kaikki mitä meillä on!", + "failed": "Mediaa ei löytynyt, yritä uudelleen!", + "loading": "Ladataan...", + "noResults": "Emme löytäneet mitään!", + "placeholder": { + "default": "Mitä haluat katsoa?", + "extra": [] + }, + "sectionTitle": "Hakutulokset" + }, + "titles": { + "day": { + "default": "Mitä haluaisit katsoa tänä iltapäivänä?", + "extra": [ + "Onko seikkailunhaluinen olo? Jurassic Park saattaa olla täydellinen valinta." + ] + }, + "morning": { + "default": "Mitä haluaisit katsoa tänä aamuna?", + "extra": ["Kuulen, että Rakkautta ennen aamua (Before Sunrise) on hyvä"] + }, + "night": { + "default": "Mitä haluaisit katsoa tänä iltana?", + "extra": ["Väsynyt? Kuulin, että Manaaja (The Exorcist) on hyvä."] + } + } + }, + "media": { + "episodeDisplay": "K{{season}} J{{episode}}", + "types": { + "movie": "Elokuva", + "show": "Sarja" + } + }, + "navigation": { + "banner": { + "offline": "Tarkista Internet-yhteytesi" + }, + "menu": { + "about": "Meistä", + "logout": "Kirjaudu ulos", + "register": "Synkronoi pilveen", + "settings": "Asetukset", + "support": "Tuki" + } + }, + "notFound": { + "badge": "Ei löydetty", + "goHome": "Takaisin kotiin", + "message": "Etsimme kaikkialta: roskakorien alta, kaapista, välityspalvelimen takaa, mutta emme lopulta löytäneet etsimääsi sivua.", + "title": "Sivua ei löytynyt" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Peruuta", + "confirm": "Käytä oletuksia", + "description": "Oletuksissa ei ole parhaita suoratoistoja ja se voi olla sietämättömän hidasta.", + "title": "Oletko varma?" + }, + "extension": { + "back": "Mene takaisin", + "explainer": "Käyttämällä selainlaajennusta voit saada parhaat tarjoamamme suoratoistot. Yksinkertaisella asennuksella.", + "explainerIos": "Valitettavasti selainlaajennusta ei tueta iOS:ssä. Valitse toinen vaihtoehto painamalla Palaa.", + "extensionHelp": "Jos olet asentanut laajennuksen, mutta se ei havaitse sitä, avaa laajennus selaimen laajennusvalikosta ja noudata näytön ohjeita.", + "linkChrome": "Asenna Chromen laajennus", + "linkFirefox": "Asenna Firefoxin laajennus", + "notDetecting": "Asensitko sen Chromelle, mutta sivusto ei havaitse sitä? Kokeile ladata sivu uudelleen!", + "notDetectingAction": "Lataa sivu uudelleen", + "status": { + "disallowed": "Laajennus ei ole otettu käyttöön tälle sivulle", + "disallowedAction": "Ota laajennus käyttöön", + "failed": "Pyynnön tilan hakeminen epäonnistui", + "loading": "Odottaa, että asennat laajennuksen", + "outdated": "Laajennuksen versio on liian vanha", + "success": "Laajennus toimii odotetusti!" + }, + "submit": "Jatketaan", + "title": "Aloitetaan laajennuksella" + }, + "proxy": { + "back": "Mene takaisin", + "explainer": "Proxy-menetelmällä voit saada erinomaisen laadukkaita suoratoistoja luomalla itsepalveluvaltuutetun proxyn.", + "input": { + "errorConnection": "Yhteys proxyn kanssa ei onnistunut", + "errorInvalidUrl": "Ei kelvollinen URL-osoite", + "errorNotProxy": "Odotettiin proxya, mutta saatiinkin verkkosivu", + "label": "Proxyn URL-osoite", + "placeholder": "https://" + }, + "link": "Opi luomaan proxy", + "submit": "Toimita proxy", + "title": "Luodaan uusi proxy" + }, + "start": { + "explainer": "Parhaiden suoratoistojen saamiseksi sinun täytyy valita, mitä suoratoistomenetelmää haluat käyttää.", + "options": { + "default": { + "text": "En halua hyvälaatuisia suoratoistoja,<0 /> <1>käytä oletusasetusta" + }, + "extension": { + "action": "Asenna laajennus", + "description": "Asenna selaimen laajennus ja saa pääsy parhaisiin lähteisiin." + } + }, + "title": "Aloitetaan asennus elokuva-webin kanssa" + } + }, + "player": { + "menus": { + "episodes": { + "emptyState": "Tässä kaudessa ei ole jaksoja, tarkista myöhemmin!" + }, + "quality": { + "hint": "Voit kokeilla <0>vaihtaa lähdettä saadaksesi eri laatuasetuksia." + }, + "sources": { + "noEmbeds": { + "text": "Emme löytäneet upotuksia, kokeile toista lähdettä." + }, + "noStream": { + "text": "Tässä lähteessä ei ole suoratoistoja tälle elokuvalle tai ohjelmalle." + } + } + }, + "metadata": { + "api": { + "text": "API-metatietoja ei voitu ladata, tarkista internet-yhteys.", + "title": "Ei voitu ladata API:n metatietoja." + } + }, + "playbackError": { + "errors": { + "errorAborted": "Mediatiedon haku keskeytettiin käyttäjän pyynnöstä.", + "errorNotSupported": "Mediaa tai mediantarjoajaa ei tueta." + }, + "text": "Tapahtui virhe yritettäessä toistaa mediaa. Yritä uudelleen." + }, + "time": { + "remaining": "{{timeLeft}} jäljellä • Päättyy {{timeFinished, datetime}}" + }, + "turnstile": { + "error": "Ei voitu varmistaa inhimillisyyttäsi. Yritä uudelleen.", + "title": "Meidän täytyy varmistaa, että olet ihminen." + } + }, + "screens": { + "migration": { + "inProgress": "Pysy hetkisen odotuksessa, siirrämme tietojasi. Tämä ei kestä kauan." + } + }, + "settings": { + "account": { + "register": { + "text": "Jaa katseluetenemisesi laitteiden välillä ja pidä ne synkronoituina." + } + }, + "connections": { + "setup": { + "unsetStatus": { + "description": "Käynnistä asennusprosessi napsauttamalla oikealla olevaa painiketta." + } + }, + "workers": { + "emptyState": "Ei vielä työntekijöitä, lisää yksi alle" + } + }, + "preferences": { + "languageDescription": "Kieli sovellettu koko sovellukseen." + }, + "subtitles": { + "previewQuote": "Minun ei pidä pelätä. Pelko on mielen tappaja." + } + } +} diff --git a/src/assets/locales/fr.json b/src/assets/locales/fr.json new file mode 100644 index 0000000..0afcba9 --- /dev/null +++ b/src/assets/locales/fr.json @@ -0,0 +1,566 @@ +{ + "about": { + "description": "SkoolTV est une application web qui recherche des flux sur Internet. L'équipe vise une approche minimaliste de la consommation de contenu.", + "faqTitle": "Questions fréquentes", + "q1": { + "body": "SkoolTV n'héberge aucun contenu. Lorsque vous cliquez sur un élément à regarder, une recherche est effectuée sur Internet pour trouver le média sélectionné (sur l'écran de chargement et dans l'onglet \"sources vidéo\", vous pouvez voir quelle source vous utilisez). Les médias ne sont jamais téléchargés par SkoolTV, tout passe par ce mécanisme de recherche.", + "title": "D'où vient le contenu ?" + }, + "q2": { + "body": "Il est impossible de demander un film ou une série, car SkoolTV ne gère aucun contenu. Le contenu est récupéré en explorant d'autres sites sur Internet.", + "title": "Où puis-je demander une série ou un film ?" + }, + "q3": { + "body": "Nos résultats de recherche sont alimentés par The Movie Database (TMDB) et s'affichent indépendamment de la disponibilité réelle du contenu dans nos sources.", + "title": "Les résultats de la recherche affichent la série ou le film, pourquoi ne puis-je pas le lire ?" + }, + "title": "À propos de SkoolTV", + "q4": { + "body": "La synchronisation de toutes les données se fait sur la sudo-backend, qui diffère de la backend de communauté et est hébergé indépendamment par moi. Tout le monde peut également l'utiliser.", + "title": "Qu'en est-il de mes données ?" + }, + "q5": { + "body": "SkoolTV possède un compte twitter qui peut être trouvé en bas de cette page ainsi qu'un lien vers le code source sur Github.", + "title": "Comment puis-je en savoir plus ?" + } + }, + "actions": { + "copied": "Copié", + "copy": "Copier" + }, + "auth": { + "createAccount": "N'avez-vous pas encore de compte ? <0>Créer un compte.", + "deviceNameLabel": "Nom de l'appareil", + "deviceNamePlaceholder": "Téléphone personnel", + "generate": { + "description": "Le nom d'utilisateur et le mot de passe sont obtenus à partir de votre phrase d'accès. Vous devrez la saisir pour accéder à votre compte, alors gardez-la précieusement", + "next": "J'ai sauvegardé ma phrase d'accès", + "passphraseFrameLabel": "Phrase d'accès", + "title": "Votre phrase d'accès" + }, + "hasAccount": "Avez-vous déjà un compte ? <0>Connectez-vous ici.", + "login": { + "description": "Veuillez saisir votre phrase d'accès pour accéder à votre compte", + "deviceLengthError": "Veuillez saisir un nom d'appareil", + "passphraseLabel": "Phrase d'accès de 12 mots", + "passphrasePlaceholder": "Phrase d'accès", + "submit": "Se connecter", + "title": "Connectez-vous à votre compte", + "validationError": "Phrase d'accès incorrecte ou incomplète" + }, + "register": { + "information": { + "color1": "Première couleur de profil", + "color2": "Seconde couleur de profil", + "header": "Veuillez entrer un nom pour votre appareil, choisir vos couleurs et une icône utilisateur de votre choix", + "icon": "Icône d'utilisateur", + "next": "Suivant", + "title": "Informations du compte" + } + }, + "trust": { + "failed": { + "text": "L'avez-vous configuré correctement ?", + "title": "Échec de la connexion au serveur" + }, + "host": "Vous êtes en train de vous connecter à <0>{{hostname}} - veuillez confirmer que vous lui faites confiance avant de créer un compte", + "no": "Retour", + "noHost": "Le serveur n'a pas été configuré, vous ne pouvez donc pas créer de compte", + "noHostTitle": "Serveur non configuré !", + "title": "Avez-vous confiance en ce serveur ?", + "yes": "Je fais confiance à ce serveur" + }, + "verify": { + "description": "Veuillez saisir votre phrase d'accès pour confirmer que vous l'avez enregistrée et pour créer votre compte", + "invalidData": "Les données ne sont pas valides", + "noMatch": "La phrase d'accès ne correspond pas", + "passphraseLabel": "Votre phrase d'accès de 12 mots", + "recaptchaFailed": "La validation ReCaptcha a échoué", + "register": "Créer un compte", + "title": "Ressaisissez votre phrase d'accès" + } + }, + "errors": { + "badge": "Tout est cassé", + "details": "Détails de l'erreur", + "reloadPage": "Actualiser la page", + "showError": "Afficher les détails de l'erreur", + "title": "Nous avons rencontré une erreur !" + }, + "footer": { + "legal": { + "disclaimer": "Avertissement", + "disclaimerText": "SkoolTV ne stocke pas de fichiers, mais propose des liens vers des services externes. Les problèmes juridiques doivent être traités avec les fournisseurs et les hébergeurs de fichiers. Les fichiers multimédias diffusés par les fournisseurs de vidéos ne sont pas couverts par SkoolTV." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub", + "twitter": "Twitter" + }, + "tagline": "Regardez vos séries et films préférés avec cette application de streaming open source." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "À propos", + "dmca": "DMCA", + "login": "Se connecter", + "onboarding": "Mise en place", + "pagetitle": "{{title}} - SkoolTV", + "register": "Créer un compte", + "settings": "Paramètres", + "discover": "Découvrir", + "support": "Support" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Favoris" + }, + "continueWatching": { + "sectionTitle": "Reprendre la lecture" + }, + "mediaList": { + "stopEditing": "Arrêter l'édition" + }, + "search": { + "allResults": "C'est tout ce que nous avons !", + "failed": "Le média n'a pas été trouvé, veuillez réessayer !", + "loading": "Chargement...", + "noResults": "Nous n'avons rien trouvé !", + "placeholder": { + "default": "Que voulez-vous voir ?", + "extra": [ + "Que voulez-vous explorer ?", + "Qu'y a-t-il dans votre liste de lecture ?", + "Quel est votre film préféré ?", + "Quelle est votre série préférée ?" + ] + }, + "sectionTitle": "Résultats de la recherche" + }, + "titles": { + "day": { + "default": "Que voulez-vous regarder cet après-midi ?", + "extra": [ + "Amoureux des films d'animation ? Suzume est un incontournable." + ] + }, + "morning": { + "default": "Que voulez-vous regarder ce matin ?", + "extra": ["Les films, c'est comme les voyages : ça nous ouvre l'esprit"] + }, + "night": { + "default": "Que voulez-vous regarder ce soir ?", + "extra": [ + "À la recherche d'un bon film d'horreur à regarder ? J'ai entendu dire que Scream était bien." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Série" + }, + "unreleased": "Non publié" + }, + "navigation": { + "banner": { + "offline": "Veuillez vérifier votre connexion internet" + }, + "menu": { + "about": "À propos de nous", + "logout": "Se déconnecter", + "register": "Synchroniser au sudo-cloud", + "settings": "Paramètres", + "support": "Support" + } + }, + "notFound": { + "badge": "Introuvable", + "goHome": "Retourner à l'accueil", + "message": "Nous avons cherché partout : sous les poubelles, dans le placard, derrière le proxy, mais nous n'avons pas pu trouver la page que vous cherchez.", + "title": "Impossible de trouver cette page" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Annuler", + "confirm": "Utiliser la configuration par défaut", + "description": "La configuration par défaut n'offre pas les meilleurs flux et peut-être insupportablement lente.", + "title": "Êtes-vous sûr ?" + }, + "extension": { + "back": "Revenir en arrière", + "explainer": "En utilisant l'extension de navigateur, vous pouvez obtenir les meilleurs flux que nous avons à offrir. Avec juste une simple installation.", + "explainerIos": "Malheureusement, l'extension web n'est pas prise en charge sur iOS, appuyez sur Retour pour choisir une autre option.", + "extensionHelp": "Si vous avez installé l'extension, mais qu'elle n'est pas détectée, ouvrez l'extension via le menu des extensions de votre navigateur et suivez les étapes à l'écran.", + "linkChrome": "Installer l'extension Chrome", + "linkFirefox": "Installer l'extension Firefox", + "notDetecting": "L'extension est installée sur Chrome, mais le site ne la détecte pas ? Essayez de rafraîchir la page !", + "notDetectingAction": "Rafraîchir la page", + "status": { + "disallowed": "L'extension n'est pas activée pour cette page", + "disallowedAction": "Activer l'extension", + "failed": "Échec de la demande de statut", + "loading": "En attente que vous installiez l'extension", + "outdated": "Version d'extension trop ancienne", + "success": "L'extension fonctionne comme prévu !" + }, + "submit": "Continuer", + "title": "Commençons par une extension" + }, + "proxy": { + "back": "Retour", + "explainer": "Avec la méthode du proxy, vous pouvez obtenir des flux de bonne qualité en créant un proxy en libre-service.", + "input": { + "errorConnection": "Impossible de se connecter au proxy", + "errorInvalidUrl": "URL non valide", + "errorNotProxy": "Je m'attendais à un proxy, mais j'ai obtenu un site Web", + "label": "URL du proxy", + "placeholder": "https://" + }, + "link": "Apprenez à créer un proxy", + "submit": "Valider le proxy", + "title": "Créons un nouveau proxy" + }, + "start": { + "explainer": "Pour obtenir les meilleurs flux possibles, vous devrez choisir la méthode de streaming que vous souhaitez utiliser.", + "options": { + "default": { + "text": "Je ne veux pas de flux de bonne qualité,<0 /> <1>utiliser le flux par défaut" + }, + "extension": { + "action": "Installer l'extension", + "description": "Installez l'extension pour navigateur et accédez aux meilleures sources.", + "quality": "Meilleure qualité", + "title": "Extension du navigateur" + }, + "proxy": { + "action": "Configurez le proxy", + "description": "Configurez un proxy en seulement cinq minutes et accédez à d'excellentes sources.", + "quality": "Bonne qualité", + "title": "Proxy personnalisé" + } + }, + "title": "Commençons par configurer SkoolTV" + } + }, + "overlays": { + "close": "Fermer" + }, + "player": { + "back": { + "default": "Revenir à la page d'accueil", + "short": "Retour" + }, + "casting": { + "enabled": "Casting vers l'appareil..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Copier le lien de la playlist HLS", + "disclaimer": "Les téléchargements sont effectués directement par le fournisseur. SkoolTV n'a aucun contrôle sur la manière dont les téléchargements sont effectués.", + "downloadSubtitle": "Télécharger les sous-titres", + "downloadVideo": "Télécharger la vidéo", + "hlsDisclaimer": "Les téléchargements sont effectués directement auprès du fournisseur. SkoolTV n'a aucun contrôle sur la façon dont les téléchargements sont fournis.

Veuillez noter que vous téléchargez une liste de lecture HLS, il n'est pas recommandé de la télécharger si vous n'êtes pas familier avec les formats de streaming avancés. Essayez différentes sources pour différents formats.", + "onAndroid": { + "1": "Pour télécharger sur Android, cliquez sur le bouton de téléchargement, puis, sur la nouvelle page, tapez et maintenez sur la vidéo, et sélectionnez enregistrer.", + "shortTitle": "Télécharger / Android", + "title": "Téléchargement sur Android" + }, + "onIos": { + "1": "Pour télécharger sur iOS, cliquez sur le bouton de téléchargement, puis, sur la nouvelle page, cliquez sur , et Enregistrer dans les fichiers .", + "shortTitle": "Télécharger / iOS", + "title": "Télécharger sur iOS" + }, + "onPc": { + "1": "Sur PC, cliquez sur le bouton de téléchargement puis, sur la nouvelle page, faites un clic droit sur la vidéo et sélectionnez Enregistrer la vidéo sous", + "shortTitle": "Télécharger / PC", + "title": "Téléchargement sur PC" + }, + "title": "Télécharger" + }, + "episodes": { + "button": "Épisodes", + "emptyState": "Cette saison ne contient aucun épisode, revenez plus tard !", + "episodeBadge": "E{{episode}}", + "loadingError": "Erreur lors du chargement de la saison", + "loadingList": "Chargement...", + "loadingTitle": "Chargement...", + "unairedEpisodes": "Un ou plusieurs épisodes de cette saison ont été désactivés, car ils n'ont pas encore été diffusés." + }, + "playback": { + "speedLabel": "Vitesse de lecture", + "title": "Paramètres de lecture" + }, + "quality": { + "automaticLabel": "Qualité automatique", + "hint": "Vous pouvez essayer de <0>changer de source pour obtenir différentes options de qualité.", + "iosNoQuality": "En raison des limitations définies par Apple, la sélection de la qualité n'est pas disponible sur iOS pour cette source. Vous pouvez essayer <0>de changer de source pour obtenir des options de qualité différentes.", + "title": "Qualité" + }, + "settings": { + "audioItem": "Audio", + "downloadItem": "Télécharger", + "enableSubtitles": "Activer les sous-titres", + "experienceSection": "Expérience de visionnage", + "playbackItem": "Paramètres de lecture", + "qualityItem": "Qualité", + "sourceItem": "Sources vidéo", + "subtitleItem": "Paramètres des sous-titres", + "videoSection": "Paramètres vidéo" + }, + "sources": { + "failed": { + "text": "Une erreur s'est produite lors de la recherche de vidéos, veuillez essayer une autre source.", + "title": "Échec de la récupération (scrape)" + }, + "noEmbeds": { + "text": "Nous n'avons pas trouvé de liens, veuillez essayer une autre source.", + "title": "Pas d'intégrations (embeds) trouvées" + }, + "noStream": { + "text": "Cette source n'a pas de flux pour ce film ou cette série.", + "title": "Pas de flux" + }, + "title": "Sources", + "unknownOption": "Inconnu" + }, + "subtitles": { + "customChoice": "Glisser ou charger un fichier", + "customizeLabel": "Personnaliser", + "dropSubtitleFile": "Glisser le fichier des sous-titres ici", + "offChoice": "Désactivé", + "settings": { + "backlink": "Sous-titres personnalisés", + "delay": "Délai des sous-titres", + "fixCapitals": "Corriger les capitales" + }, + "title": "Sous-titres", + "unknownLanguage": "Inconnu" + } + }, + "metadata": { + "api": { + "text": "Impossible de charger les métadonnées de l'API, veuillez vérifier votre connexion Internet.", + "title": "Échec du chargement des métadonnées de l'API" + }, + "dmca": { + "badge": "Supprimé", + "text": "Ce média n'est plus disponible en raison d'un avis de retrait ou d'une réclamation pour atteinte aux droits d'auteur.", + "title": "Le média a été supprimé" + }, + "extensionPermission": { + "badge": "Autorisation manquante", + "button": "Utiliser l'extension", + "text": "Vous disposez de l'extension de navigateur, mais nous avons besoin de votre autorisation pour commencer à utiliser l'extension.", + "title": "Configurer l'extension" + }, + "failed": { + "badge": "Échec", + "homeButton": "Revenir à l'accueil", + "text": "Impossible de charger les métadonnées du média à partir de TMDB. Veuillez vérifier si TMDB est en panne ou bloqué sur votre connexion internet.", + "title": "Échec du chargement des métadonnées" + }, + "notFound": { + "badge": "Introuvable", + "homeButton": "Revenir à l'accueil", + "text": "Nous n'avons pas trouvé le média que vous avez demandé. Soit il a été supprimé, soit vous avez modifié l'URL.", + "title": "Impossible de trouver ce média." + } + }, + "nextEpisode": { + "cancel": "Annuler", + "next": "Prochain épisode" + }, + "playbackError": { + "badge": "Erreur de lecture", + "errors": { + "errorAborted": "L'extraction du média a été interrompue à la demande de l'utilisateur.", + "errorDecode": "Bien qu'elle ait été jugée utilisable, une erreur s'est produite lors de la tentative de décodage de la ressource multimédia, ce qui a entraîné une erreur.", + "errorGenericMedia": "Une erreur de média inconnue est survenue.", + "errorNetwork": "Une erreur de réseau s'est produite qui a empêché la récupération du média, bien qu'il ait été disponible auparavant.", + "errorNotSupported": "L'objet du média ou de la source du média n'est pas supporté." + }, + "homeButton": "Revenir à l'accueil", + "text": "Une erreur s'est produite lors de la lecture du média. Veuillez réessayer.", + "title": "Oups, c'est coupé !" + }, + "scraping": { + "extensionFailure": { + "badge": "Extension désactivée", + "enableExtension": "Activer l'extension", + "homeButton": "Revenir à l'accueil", + "text": "Vous avez installé l'extension SkoolTV. Pour commencer à l'utiliser, vous devez activer l'extension pour ce site.", + "title": "Veuillez activer l'extension" + }, + "items": { + "failure": "Une erreur est survenue", + "notFound": "N'a pas la vidéo", + "pending": "Recherche de vidéos..." + }, + "notFound": { + "badge": "Non trouvé", + "detailsButton": "Afficher les détails", + "homeButton": "Revenir à l'accueil", + "text": "Nous avons cherché parmi nos sources et n'avons pas trouvé les médias que vous recherchez ! Nous n'hébergeons pas les médias et n'avons aucun contrôle sur ce qui est disponible. Veuillez cliquer sur \"Afficher les détails\" ci-dessous pour plus d'informations.", + "title": "Nous n'avons pas trouvé cela" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} restant • Fini à {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Veuillez vérifier que vous êtes bien humain en complétant le Captcha à droite. C'est pour assurer la sécurité de SkoolTV !", + "error": "Échec de la vérification de votre humanité. Veuillez réessayer.", + "title": "Nous devons vérifier que vous êtes un humain.", + "verifyingHumanity": "Vérification de votre humanité..." + } + }, + "screens": { + "dmca": { + "text": "Bienvenue sur la page de contact DMCA de SkoolTV ! Nous respectons les droits de propriété intellectuelle et souhaitons répondre rapidement à toute question relative aux droits d'auteur. Si vous pensez que votre œuvre protégée par des droits d'auteur a été utilisée de manière inappropriée sur notre plateforme, veuillez envoyer une notification DMCA détaillée à l'adresse électronique ci-dessous. Veuillez inclure une description du matériel protégé par des droits d'auteur, vos coordonnées et une déclaration de bonne foi. Nous nous engageons à résoudre ces problèmes rapidement et vous remercions pour votre coopération pour que SkoolTV reste un lieu respectueux de la créativité et des droits d'auteur.", + "title": "DMCA" + }, + "loadingApp": "Chargement de l'application", + "loadingUser": "Chargement de votre profil", + "loadingUserError": { + "logout": "Se déconnecter", + "reset": "Réinitialiser le serveur personnalisé", + "text": "Échec du chargement de votre profil", + "textWithReset": "Echec du chargement de votre profil à partir de votre serveur personnalisé, souhaitez-vous revenir au serveur par défaut ?" + }, + "migration": { + "failed": "La migration de vos données a échoué.", + "inProgress": "Veuillez patienter, nous sommes en train de migrer vos données. Cela ne devrait pas prendre longtemps." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nom de l'appareil", + "deviceNamePlaceholder": "Téléphone personnel", + "editProfile": "Éditer", + "logoutButton": "Se déconnecter" + }, + "actions": { + "delete": { + "button": "Supprimer le compte", + "confirmButton": "Supprimer le compte", + "confirmDescription": "Êtes-vous sûr de vouloir supprimer votre compte ? Toutes vos données seront perdues !", + "confirmTitle": "Êtes-vous sûr ?", + "text": "Cette action est irréversible. Toutes les données seront supprimées et rien ne pourra être récupéré.", + "title": "Supprimer le compte" + }, + "title": "Actions" + }, + "devices": { + "deviceNameLabel": "Nom de l'appareil", + "failed": "Échec du chargement des sessions", + "removeDevice": "Supprimer", + "title": "Appareils" + }, + "profile": { + "finish": "Terminer l'édition", + "firstColor": "Première couleur de profil", + "secondColor": "Seconde couleur de profil", + "title": "Modifier la photo de profil", + "userIcon": "Icône de l'utilisateur" + }, + "register": { + "cta": "Commencer", + "text": "Partagez la progression de vos films et séries entre vos appareils et gardez-les synchronisés.", + "title": "Synchroniser au sudo-cloud" + }, + "title": "Compte" + }, + "appearance": { + "activeTheme": "Actif", + "themes": { + "blue": "Bleu", + "default": "Défaut", + "gray": "Gris", + "red": "Rouge", + "teal": "Bleu canard" + }, + "title": "Apparence" + }, + "connections": { + "server": { + "description": "Si vous désirez utiliser un système de stockage externe pour enregistrer vos données, activez cette option et indiquez l'URL. <0>Instructions.", + "label": "Serveur personnalisé", + "urlLabel": "URL du serveur personnalisé" + }, + "setup": { + "doSetup": "Configurer", + "errorStatus": { + "description": "Il semble qu'un ou plusieurs éléments de cette configuration nécessitent votre attention.", + "title": "Quelque chose nécessite votre attention" + }, + "itemError": "Ce paramètre présente un problème. Résolvez le problème en recommençant la configuration.", + "items": { + "default": "Configuration par défaut", + "extension": "Extension", + "proxy": "Proxy personnalisé" + }, + "redoSetup": "Refaire la configuration", + "successStatus": { + "description": "Tout prêt pour que vous puissiez commencer à regarder vos médias préférés.", + "title": "Tout est en place !" + }, + "unsetStatus": { + "description": "Pour commencer le processus de configuration, veuillez cliquer sur le bouton à droite.", + "title": "Vous n'avez pas encore effectué la configuration" + } + }, + "title": "Connexions", + "workers": { + "addButton": "Ajouter un nouveau worker", + "description": "Pour que l'application fonctionne, tout le trafic est acheminé via des proxys. Activez cette option si vous souhaitez faire appel à vos propres workers. <0>Instructions.", + "emptyState": "Pas encore de workers, ajoutez-en un ci-dessous", + "label": "Utiliser des agents proxy personnalisés", + "urlLabel": "URLs des workers", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Langage de l'application", + "languageDescription": "Langue appliquée à l’ensemble de l’application.", + "thumbnail": "Générer les miniatures", + "thumbnailDescription": "La plupart du temps, les vidéos n'ont pas de miniatures. Vous pouvez activer ce paramètre pour les générer à la volée, mais ils peuvent ralentir votre vidéo.", + "thumbnailLabel": "Générer les miniatures", + "title": "Préférences" + }, + "reset": "Réinitialiser", + "save": "Sauvegarder", + "sidebar": { + "info": { + "appVersion": "Version de l'application", + "backendUrl": "URL du Backend", + "backendVersion": "Version du Backend", + "hostname": "Nom d'hôte", + "insecure": "Non sécurisé", + "notLoggedIn": "Vous n'êtes pas connecté", + "secure": "Sécurisé", + "title": "Informations sur l'application", + "unknownVersion": "Inconnu", + "userId": "ID de l'utilisateur" + } + }, + "subtitles": { + "backgroundBlurLabel": "Flou d'arrière-plan", + "backgroundLabel": "Opacité de l'arrière-plan", + "colorLabel": "Couleur", + "previewQuote": "Plus l'obscurité est profonde, plus la lumière brille.", + "textSizeLabel": "Taille des textes", + "title": "Sous-titres" + }, + "unsaved": "Vous avez des changements non sauvegardés" + } +} diff --git a/src/assets/locales/gl.json b/src/assets/locales/gl.json new file mode 100644 index 0000000..ec52501 --- /dev/null +++ b/src/assets/locales/gl.json @@ -0,0 +1,549 @@ +{ + "about": { + "description": "SkoolTV é unha aplicación web que busca transmisións na rede. O equipo ten como obxectivo manter un enfoque principalmente minimalista para consumir os contidos.", + "faqTitle": "Preguntas frecuentes", + "q1": { + "body": "SkoolTV non aloxa ningún contido. Cando premes en algo para ver o contenido, búscase en internet o medio seleccionado. (Na pantalla de carga e na lapela 'fontes de video' podes ver que fonte se está a empregar. O contido nunca se carga en SkoolTV, todo realízase a través deste método de busca.", + "title": "De onde proveñen os contidos?" + }, + "q2": { + "body": "Non é posible solicitar unha película. SkoolTV non xestiona ningún contido. Todo o contido é xestionado a través de fontes na rede.", + "title": "Onde poido solicitar unha película a engadir?" + }, + "q3": { + "body": "Os nosos resultados de busqueda proveñen de The Movie Database (TMDB) e se mostran independentemente de se as nosas fontes multimedia teñen realmente o contido.", + "title": "Os resultados da busca mostran a serie ou película... Por qué non poido reproducila?" + }, + "title": "Acerca de SkoolTV" + }, + "actions": { + "copied": "Copiado", + "copy": "Copiar" + }, + "auth": { + "createAccount": "Non tes unha conta aínda? <0>Crea unha conta.", + "deviceNameLabel": "Nome do dispositivo", + "deviceNamePlaceholder": "Teléfono persoal", + "generate": { + "description": "A túa contraseña actua como o teu nome de usuario e contraseña. Asegúrate de mantelas seguras, xa que as necesitarás para iniciar sesión na túa conta", + "next": "Gardei a contraseña exitosamente", + "passphraseFrameLabel": "Contraseña", + "title": "A túa contraseña" + }, + "hasAccount": "Tes xa unha conta? <0>Inicia sesión aquí.", + "login": { + "description": "Por favor, ingresa a túa contraseña para iniciar sesión na túa conta", + "deviceLengthError": "Por favor, ingresa un nome de dispositivo", + "passphraseLabel": "Contraseña de 12 caracteres", + "passphrasePlaceholder": "Contraseña", + "submit": "Iniciar sesión", + "title": "Inicia sesión na túa conta", + "validationError": "Contraseña incorrecta ou incompleta" + }, + "register": { + "information": { + "color1": "Cór de perfil un", + "color2": "Cór de perfil dous", + "header": "Ingresa un nome para o teu dispositivo, elixe cores, e un icono de usuario", + "icon": "Ícono de usuario", + "next": "Seguinte", + "title": "Información da conta" + } + }, + "trust": { + "failed": { + "text": "Configurachelo correctamente?", + "title": "Non se puido conectar ao servidor" + }, + "host": "Estaste a conectar a <0>{{hostname}} - por favor, confirma se confías antes de crear a conta", + "no": "Regresar", + "noHost": "O servidor non está configurado, polo que non podes crear unha conta", + "noHostTitle": "O servidor non está configurado!", + "title": "Confías neste servidor?", + "yes": "Si, si que confío neste servidor" + }, + "verify": { + "description": "Por favor, ingresa a túa contraseña para confirmar que está gardada para crear a túa conta", + "invalidData": "Os datos non son válidos", + "noMatch": "A contraseña non coincide", + "passphraseLabel": "A contraseña debe de ser de 12 caracteres", + "recaptchaFailed": "A validación ReCaptcha fallou", + "register": "Crear conta", + "title": "Confirma a túa contraseña" + } + }, + "errors": { + "badge": "Rompeu", + "details": "Detalles do erro", + "reloadPage": "Recargar a páxina", + "showError": "Mostrar detalles do erro", + "title": "Atopamos un erro!" + }, + "footer": { + "legal": { + "disclaimer": "Descargo de responsabilidade", + "disclaimerText": "SkoolTV non aloxa ningún arquivo, simplemente enlaza con servizos de terceiros. Os problemas legais deben ser tratados cós proovedores de arquivos e servizos. SkoolTV non se fai responsable dos arquivos multimedia mostrados polos provedores de video." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Disfruta das túas series e películas favoritas con esta aplicación de transmisión de código aberto." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Acerca de", + "dmca": "DMCA", + "login": "Iniciar sesión", + "onboarding": "Configuración", + "pagetitle": "{{title}} - SkoolTV", + "register": "Rexistrarse", + "settings": "Configuración" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Marcadores" + }, + "continueWatching": { + "sectionTitle": "Continuar vendo" + }, + "mediaList": { + "stopEditing": "Deter edición" + }, + "search": { + "allResults": "Esto é todo o que temos!", + "failed": "Error ao encontrar contido... intentao de novo!", + "loading": "Cargando...", + "noResults": "Non atopamos nada!", + "placeholder": { + "default": "Que che gustaría ver?", + "extra": [ + "Qué queres explorar?", + "Que está na túa lista se seguimiento?", + "Cal é a túa película favorita?", + "Cal é a túa serie favorita?" + ] + }, + "sectionTitle": "Resultados da busca" + }, + "titles": { + "day": { + "default": "Que che gustaría ver esta tarde?", + "extra": [ + "Sínteste aventureiro? Jurassic Park podería ser a elección perfecta." + ] + }, + "morning": { + "default": "Que che gustaría ver esta mañá?", + "extra": [ + "Escoitei que “Antes del amanecer” é boa" + ] + }, + "night": { + "default": "Que che gustaría ver esta noite?", + "extra": [ + "Canso? Escoitei que “El Exorcista” é boa." + ] + } + } + }, + "media": { + "episodeDisplay": "T{{season}} E{{episode}}", + "types": { + "movie": "Película", + "show": "Serie" + } + }, + "navigation": { + "banner": { + "offline": "Verifica a túa conexión a internet" + }, + "menu": { + "about": "Acerca de nós", + "logout": "Cerrar sesión", + "register": "Sincronizar coa nube", + "settings": "Configuración", + "support": "Soporte" + } + }, + "notFound": { + "badge": "Non atopado", + "goHome": "Volver ao inicio", + "message": "Prometocho, buscamos en todas partes: debaixo dos contenedores, no armario, detrás do proxy, pero ao final non puidemos atopar a páxina que estabas buscando.", + "title": "Non atopei a páxona que estabas a buscar" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Cancelar", + "confirm": "Usar configuración por defecto", + "description": "A configuración por defecto non ten a mellor calidade e pode ser moi lenta.", + "title": "Estás seguro?" + }, + "extension": { + "back": "Volver atrás", + "explainer": "Usando a extensión de navegador, podes obter os mellores streams á mellor calidade. Cunha simple instalación.", + "explainerIos": "Por desgraza, a extensión de navegador non é soportada en iOS. Pulsa volver atrás para escoller outra opción.", + "extensionHelp": "Se instalaches a extensión pero non é detectada, abre a extensión dende o menú de extensións do navegador e sigue os pasos na pantalla.", + "linkChrome": "Instalar extensión de Chrome", + "linkFirefox": "Instalar extensión de Firefox", + "notDetecting": "Instalada en Chrome, pero o sitio web non a está a detectar? Proba recargando a páxina!", + "notDetectingAction": "Recargar a páxina", + "status": { + "disallowed": "A extensión non está habilitada para esta páxina", + "disallowedAction": "Activar extensión", + "failed": "Error ao solicitar estado", + "loading": "Esperando a que instales a extensión", + "outdated": "A versión da extensión é moi vella", + "success": "A extensión funciona como se esperaba!" + }, + "submit": "Continuar", + "title": "Vamos a empezar coa extensión" + }, + "proxy": { + "back": "Vover atrás", + "explainer": "Có método do proxy, podes obter streams de boa calidade creando un proxy hosteado por ti mesmo.", + "input": { + "errorConnection": "Non foi posible a conexión có proxy", + "errorInvalidUrl": "URL non válida", + "errorNotProxy": "Estaba previsto obter o proxy pero obtuven unha páxina web", + "label": "URL do proxy", + "placeholder": "https://" + }, + "link": "Aprender a configurar o proxy", + "submit": "Validar proxy", + "title": "Vamos crear un novo proxy" + }, + "start": { + "explainer": "Para obter a maior calidade posible, terás que elexir que método de streaming queres usar.", + "options": { + "default": { + "text": "Non quero streams de boa calidade, <0 /> <1>usarei a configuración por defecto" + }, + "extension": { + "action": "Instalar extensión", + "description": "Instala a extensión de navegador e obtén acceso ás mellores fontes.", + "quality": "A mellor calidade", + "title": "Extensión de navegador" + }, + "proxy": { + "action": "Configurar proxy", + "description": "Configura un proxy en só 5 minutos e gaña acceso ás mellores fontes.", + "quality": "Boa calidade", + "title": "Proxy personalizado" + } + }, + "title": "Vamos a empezar coa configuración de SkoolTV" + } + }, + "overlays": { + "close": "Cerrar" + }, + "player": { + "back": { + "default": "Volver ao inicio", + "short": "Volver" + }, + "casting": { + "enabled": "Transmitiendo ao dispositivo..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Copiar a ligazón da lista HLS", + "disclaimer": "As descargas proveñen do provedor. SkoolTV non ten control sobre as descargas e a súa procedencia.", + "downloadSubtitle": "Descargar subtítulos actuais", + "downloadVideo": "Descargar video", + "hlsDisclaimer": "As descargas realizanse directamente dende o proovedor. SkoolTV non ten control sobre como se xestionan as descargas.

Ten en conta que estás a descargar unha lista de reproducción HLS, non está recomendado instalalos se non estás familiarizado con estos sistemas de contidos avanzados Proba fontes diferentes ou formatos diferentes.", + "onAndroid": { + "1": "Para descargar en Android, fai click no botón de descarga e despois, na nova páxina, mantén presionadoo vídeo e selecciona gardar.", + "shortTitle": "Descargar / Android", + "title": "Descargando en Android" + }, + "onIos": { + "1": "Para descargar en iOS, fai clic no botón de descarga e despois, na nova páxina, fai click en , e despois Gardar en archivos .", + "shortTitle": "Descargar / iOS", + "title": "Descargando en iOS" + }, + "onPc": { + "1": "Nunha PC, fai click no botón de descargas e despois, na nova páxina, fai click dereito no video e selecciona Gardar vídeo como...", + "shortTitle": "Descargar / PC", + "title": "Descargando en PC" + }, + "title": "Descargar" + }, + "episodes": { + "button": "Episodios", + "emptyState": "Non hai episodios nesta temporada, Intentao máis tarde!", + "episodeBadge": "E{{episode}}", + "loadingError": "Error cargando a sesión", + "loadingList": "Cargando...", + "loadingTitle": "Cargando...", + "unairedEpisodes": "Un ou máis episodios nesta temporada foron desactivados porque non sairon aínda." + }, + "playback": { + "speedLabel": "Velocidade de reproducción", + "title": "Configuración de reproducción" + }, + "quality": { + "automaticLabel": "Calidade automática", + "hint": "Podes intentar <0>cambiar de fonte para obter diferentes opcións de calidade.", + "iosNoQuality": "Debido a limitacións definidas por Apple, a selección de calidade no está disponible en iOS para esta fonte. Podes intentar <0>cambiar a outra fonte para obter diferentes opcións de calidade.", + "title": "Calidade" + }, + "settings": { + "audioItem": "Audio", + "downloadItem": "Descargar", + "enableSubtitles": "Activar subtítulos", + "experienceSection": "Configuración de experiencia", + "playbackItem": "Configuración do playback", + "qualityItem": "Calidade", + "sourceItem": "Fonte do video", + "subtitleItem": "Configuración dos subtítulos", + "videoSection": "Configuración de video" + }, + "sources": { + "failed": { + "text": "Acaba de producirse un erro ao intentar atopar videos, por favor, intenta cunha fonte distinta.", + "title": "Erro ao retirar" + }, + "noEmbeds": { + "text": "Non puidemos atopar ningún embed, por favor, intenta cunha fonte diferente.", + "title": "No se atoparon embeds" + }, + "noStream": { + "text": "Nesta fonte non hai contidos sobre esta película ou episodio.", + "title": "Sin fonte" + }, + "title": "Fontes", + "unknownOption": "Descoñecido" + }, + "subtitles": { + "customChoice": "Sube ou arrastra o arquivo", + "customizeLabel": "Personalizar", + "dropSubtitleFile": "Solta o arquivo de subtítulos aquí", + "offChoice": "Apagar", + "settings": { + "backlink": "Subtítulos personalizados", + "delay": "Retardo dos subtítulos", + "fixCapitals": "Arreglar capitalización" + }, + "title": "Subtítulos", + "unknownLanguage": "Descoñecido" + } + }, + "metadata": { + "api": { + "text": "Non puiden cargar os metadatos da API, por favor, comproba a túa conexión a internet.", + "title": "Non foi posible cargar os metadatos da API" + }, + "dmca": { + "badge": "Agochado", + "text": "Este contido non está dispoñible debido a unha reclamación dos dereitos de autor.", + "title": "Os contidos foron retirados" + }, + "extensionPermission": { + "badge": "Non hai permisos suficientes", + "button": "Usar extensión", + "text": "Si que tes a extensión de navegador, pero precisamos do teu permiso para empezar a usala.", + "title": "Configura a extensión" + }, + "failed": { + "badge": "Erro", + "homeButton": "Ir ao inicio", + "text": "Non se puideron cargar os metadatos do contido de TMDB. Por favor, verifica se TMDB está caído ou bloqueado na túa conexión a internet.", + "title": "Error ao cargar os metadatos" + }, + "notFound": { + "badge": "Non atopado", + "homeButton": "Volver ao inicio", + "text": "Non puidemos encontrar o contenido que solicitache. Xa seña que se eliminara ou modificara a URL.", + "title": "No se pudo atopar ese contenido." + } + }, + "nextEpisode": { + "cancel": "Cancelar", + "next": "Seguinte episodio" + }, + "playbackError": { + "badge": "Error de reproducción", + "errors": { + "errorAborted": "A obtención do contido foi cancelada pola solicitude do usuario.", + "errorDecode": "A pesar de ser determinado previamente como utilizable, produciuse un erro ao intentar decodificar o recurso do contido, o que resultou nun erro.", + "errorGenericMedia": "Produxose un erro descoñecido no contido.", + "errorNetwork": "Produxose un erro de rede que impidideu obter o contido de maneira exitosa, a pesar de estar disponible anteriormente.", + "errorNotSupported": "O contido ou o proovedor do contido non é compatible." + }, + "homeButton": "Ir ao inicio", + "text": "Produxose un erro ao intentar reproducir o contenido. Por favor, inténtao de novo.", + "title": "Non se puido reproducir o video!" + }, + "scraping": { + "items": { + "failure": "Ocurreu un erro", + "notFound": "Non ten o video", + "pending": "Verificando vídeos..." + }, + "notFound": { + "badge": "Non atopado", + "detailsButton": "Mostrar detalles", + "homeButton": "Ir ao inicio", + "text": "Buscamos nos nosos proovedores e non puidemos atopar o contido que estás a buscar. Nós, non aloxamos o contido e non temos control sobre o que está dispoñible. Fai click en 'Mostrar detalles' a continuación para obter máis información.", + "title": "Non puidemos atopar eso" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} restante • Finaliza ás {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Por favor, verifica que eres un humán completando o Captcha. Isto é para mantee SkoolTV seguro!", + "error": "Houbo un erro ao verificar a túa humanidade. Por favor, volve a intentalo.", + "title": "Necesitamos verificar que realmente eres un humán.", + "verifyingHumanity": "Verificando a túa humanidade…" + } + }, + "screens": { + "dmca": { + "text": "Benvido/a á páxona de contacto DMA de SkoolTV! Respetamos os dereitos de propiedade intelectual e queremos abordar calqueiro problema de dereitos de autor de maneira más rápida. Se crees que o teu traballo con dereitos de autor está sendo empregado incorrectamente na nosa plataforma, envñia un aviso DMCA detallado ao correo electrónico que se mostra a continuación. Inclue unha descripción do material con dereitos de autor, os seus datos de contacto e unha declaración de boa fé. Estamos comprometidos a resolver estos asuntos o máis rápido posible e agradecemos a túa cooperación para manter a SkoolTV como un lugar que respeta a creatividade e os dereitos de autor.", + "title": "DMCA" + }, + "loadingApp": "Cargando aplicación", + "loadingUser": "Cargando o teu perfil", + "loadingUserError": { + "logout": "Pechar sesión", + "reset": "Reiniciar servidor personalizado", + "text": "Erro ao cargar o teu perfil", + "textWithReset": "Erro ao cargar o teu perfil dende o teu servidor personalizado, queres reiniciar e volver ao servidor por defecto?" + }, + "migration": { + "failed": "Erro ao migrar os teus datos.", + "inProgress": "Porfavor, espera mientras migramos tus datos. Esto no debería llevar mucho." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nome do dispositivo", + "deviceNamePlaceholder": "Teléfono persoal", + "editProfile": "Editar", + "logoutButton": "Pechar sesión" + }, + "actions": { + "delete": { + "button": "Eliminar conta", + "confirmButton": "Eliminar conta", + "confirmDescription": "Estas seguro/a que queres eliminar a túa conta? Todos os datos serán eliminados!", + "confirmTitle": "Estás seguro/a?", + "text": "Esta acción é irreversible. Todos os datos serán eliminados e nada poderá ser recuperado.", + "title": "Eliminar conta" + }, + "title": "Accións" + }, + "devices": { + "deviceNameLabel": "Nome do dispositivo", + "failed": "Erro ao cargar sesións", + "removeDevice": "Quitar", + "title": "Dispositivos" + }, + "profile": { + "finish": "Acabar de editar", + "firstColor": "Cór de perfil un", + "secondColor": "Cór de perfil dous", + "title": "Editar foto de perfil", + "userIcon": "Icono de usuario" + }, + "register": { + "cta": "Empezar", + "text": "Compartir o teu progreso entre dispositivos e mantelos sincronizados.", + "title": "Sincronizar á nube" + }, + "title": "Conta" + }, + "appearance": { + "activeTheme": "Activo", + "themes": { + "blue": "Azul", + "default": "Por defecto", + "gray": "Gris", + "red": "Vermello", + "teal": "Turquesa" + }, + "title": "Apariencia" + }, + "connections": { + "server": { + "description": "Se che gustaría conectar un servidor personalizado de backend para almacenar os teus datos, activa esto e indica a URL. <0>Instruccións.", + "label": "Servidor personalizado", + "urlLabel": "Servidor personalizado URL" + }, + "setup": { + "doSetup": "Configurar", + "errorStatus": { + "description": "Parece que hay un ou varios puntos que precisan da tua atención.", + "title": "Hai algo que require da túa atención" + }, + "itemError": "Hai un erro nesta configuración. Volve atrás para solucionalo.", + "items": { + "default": "Configuración por defecto", + "extension": "Extensión", + "proxy": "Proxy personalizado" + }, + "redoSetup": "Retroceder na configuración", + "successStatus": { + "description": "Todo está no seu sitio para que podas empezar a ver os teus contidos favoritos.", + "title": "Todo está configurado!" + }, + "unsetStatus": { + "description": "Por favor, preme no botón para empezar o proceso de configuración.", + "title": "Non empezaches ningunha configuración" + } + }, + "title": "Conexións", + "workers": { + "addButton": "Añadir novo", + "description": "Para facer que a aplicación funcione, todo o tráfico é organizado en proxies. Activa esta opción se queres empregar os teus propios workers. <0>Instruccións.", + "emptyState": "Non hai workers aínda, engade un abaixo", + "label": "Usar proxy workers personalizados", + "urlLabel": "URLs dos workers", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Linguaxe da aplicación", + "languageDescription": "Lingua aplicada a toda a aplicación.", + "thumbnail": "Xerar miniaturas", + "thumbnailDescription": "Na maioría das veces, os videos non teñen miniaturas. Podes activar esta configuración para xeralas ao momento, pero podes realentizar o video.", + "thumbnailLabel": "Xerar miniaturas", + "title": "Preferencias" + }, + "reset": "Reinicio", + "save": "Gardar", + "sidebar": { + "info": { + "appVersion": "Versión da aplicación", + "backendUrl": "URL do Backend", + "backendVersion": "Versión do Backend", + "hostname": "Nome do Host (Hostname)", + "insecure": "Non seguro", + "notLoggedIn": "Non iniciache sesión", + "secure": "Seguro", + "title": "Información da aplicación", + "unknownVersion": "Descoñecido", + "userId": "ID do usuario" + } + }, + "subtitles": { + "backgroundBlurLabel": "Desenfoque do fondo", + "backgroundLabel": "Opacidade do fondo", + "colorLabel": "Cór", + "previewQuote": "Non debo temer. O medo é o asasino da mente.", + "textSizeLabel": "Tamaño da fonte", + "title": "Subtítulos" + }, + "unsaved": "Tes cambios sen gardar" + } +} diff --git a/src/assets/locales/gu.json b/src/assets/locales/gu.json new file mode 100644 index 0000000..5a86d84 --- /dev/null +++ b/src/assets/locales/gu.json @@ -0,0 +1,533 @@ +{ + "about": { + "description": "મૂવી-વેબ એક વેબ એપ્લિકેશન છે જે ઇન્ટરનેટ પર સ્ટ્રીમ માટે શોધ કરે છે. ટીમ વધુમાં વધુ કન્ટેન્ટ ઉપભોગ કરવાની દ્રષ્ટિકોણમાં છે.", + "faqTitle": "સામાન્ય પ્રશ્નો", + "q1": { + "body": "મૂવી-વેબ કોઈપણ કન્ટેન્ટ હોસ્ટ કરતું નથી. જ્યારે તમે જોવા માટે કંઈક પર ક્લિક કરો છો, ત્યારે ઈન્ટરનેટ પસંદ કરેલ મીડિયા માટે શોધાય છે (લોડિંગ સ્ક્રીન પર અને 'વિડિયો સ્ત્રોતો' ટૅબમાં તમે જોઈ શકો છો કે તમે કયા સ્રોતનો ઉપયોગ કરી રહ્યાં છો). મીડિયા ક્યારેય મૂવી-વેબ દ્વારા અપલોડ થતું નથી, બધું આ સર્ચિંગ મિકેનિઝમ દ્વારા થાય છે.", + "title": "કન્ટેન્ટ ક્યાંથી આવે છે?" + }, + "q2": { + "body": "શો અથવા મૂવીની વિનંતી કરવી શક્ય નથી, મૂવી-વેબ કોઈપણ કન્ટેન્ટ નું સંચાલન કરતું નથી. બધી કન્ટેન્ટ ઇન્ટરનેટ પરના સ્ત્રોતો દ્વારા જોવામાં આવે છે.", + "title": "હું શો અથવા મૂવીની વિનંતી ક્યાં કરી શકું?" + }, + "q3": { + "body": "અમારા શોધ પરિણામો ધ મૂવી ડેટાબેઝ (TMDB) દ્વારા સંચાલિત છે અને અમારા સ્ત્રોતોમાં ખરેખર કન્ટેન્ટ છે કે કેમ તે ધ્યાનમાં લીધા વિના પ્રદર્શિત થાય છે.", + "title": "શો અથવા મૂવીના શોધ પરિણામો દર્શાવવામાં આવે છે, પરંતુ હું તેને કેટલાક કારણોથી ચલાવી શકતો નથી?" + }, + "title": "મૂવી-વેબ વિશે" + }, + "actions": { + "copied": "કોપી કર્યું", + "copy": "કૉપી" + }, + "auth": { + "createAccount": "હજુ સુધી એકાઉન્ટ નથી? <0>એકાઉન્ટ બનાવો.", + "deviceNameLabel": "ડિવાઇસ નામ", + "deviceNamePlaceholder": "વ્યક્તિગત ફોન", + "generate": { + "description": "તમારો પાસફ્રેઝ તમારા યુઝરનેમ અને પાસવર્ડ તરીકે કાર્ય કરે છે. તેને સુરક્ષિત રાખવાની ખાતરી કરો કારણ કે તમારે તમારા એકાઉન્ટમાં લૉગિન કરવા માટે તેને દાખલ કરવાની જરૂર પડશે", + "next": "મેં મારો પાસફ્રેઝ સેવ કર્યો છે", + "passphraseFrameLabel": "પાસફ્રેઝ", + "title": "તમારો પાસફ્રેઝ" + }, + "hasAccount": "પહેલેથી જ એકાઉન્ટ છે? <0>અહીં લોગિન કરો.", + "login": { + "description": "તમારા એકાઉન્ટમાં લૉગિન કરવા માટે કૃપા કરીને તમારો પાસફ્રેઝ દાખલ કરો", + "deviceLengthError": "કૃપા કરીને ડિવાઇસનું નામ દાખલ કરો", + "passphraseLabel": "12-શબ્દનો પાસફ્રેઝ", + "passphrasePlaceholder": "પાસફ્રેઝ", + "submit": "લોગિન કરો", + "title": "તમારા એકાઉન્ટમાં લોગિન કરો", + "validationError": "ખોટો અથવા અપૂર્ણ પાસફ્રેઝ" + }, + "register": { + "information": { + "color1": "પ્રોફાઇલ રંગ એક", + "color2": "પ્રોફાઇલ રંગ બે", + "header": "તમારા ઉપકરણ માટે નામ દાખલ કરો અને રંગો અને તમારી પસંદગીના વપરાશકર્તા ચિહ્ન પસંદ કરો", + "icon": "વપરાશકર્તા ચિહ્ન", + "next": "આગળ", + "title": "એકાઉન્ટ માહિતી" + } + }, + "trust": { + "failed": { + "text": "શું તમે તેને યોગ્ય રીતે ગોઠવ્યું છે?", + "title": "સર્વર સુધી પહોંચવામાં નિષ્ફળ" + }, + "host": "તમે <0>{{hostname}} થી કનેક્ટ કરી રહ્યાં છો - એકાઉન્ટ બનાવતા પહેલા કૃપા કરીને ખાતરી કરો કે તમે તેના પર વિશ્વાસ કરો છો", + "no": "પાછા જાઓ", + "title": "શું તમે આ સર્વર પર વિશ્વાસ કરો છો?", + "yes": "મને આ સર્વર પર વિશ્વાસ છે" + }, + "verify": { + "description": "કૃપા કરીને તમારો પાસફ્રેઝ એન્ટર કરો, જેથી એકાઉન્ટ બનાવી શકાય", + "invalidData": "ડેટા માન્ય નથી", + "noMatch": "પાસફ્રેઝ મેળ ખાતો નથી", + "passphraseLabel": "તમારો 12-શબ્દનો પાસફ્રેઝ", + "recaptchaFailed": "ReCaptcha માન્યતા નિષ્ફળ", + "register": "ખાતું બનાવો", + "title": "તમારા પાસફ્રેઝની પુષ્ટિ કરો" + } + }, + "errors": { + "badge": "તે તૂટી ગયું", + "details": "ભૂલ વિગતો", + "reloadPage": "પેજને ફરીથી લોડ કરો", + "showError": "ભૂલ વિગતો બતાવો", + "title": "અમને એક ભૂલ આવી!" + }, + "footer": { + "legal": { + "disclaimer": "અસ્વીકરણ", + "disclaimerText": "મૂવી-વેબ કોઈપણ ફાઇલોને હોસ્ટ કરતું નથી, તે ફક્ત 3ર્ડ પાર્ટી સર્વિસોના સાથે લિંક કરે છે. ફાઇલ હોસ્ટ્સ અને પ્રદાતાઓ સાથે કાનૂની મુદ્દાઓ ઉઠાવવા જોઈએ. વિડિયો પ્રદાતાઓ દ્વારા બતાવવામાં આવેલી કોઈપણ મીડિયા ફાઇલો માટે SkoolTV જવાબદાર નથી." + }, + "links": { + "discord": "ડિસ્કોર્ડ", + "dmca": "DMCA", + "github": "ગિટહબ" + }, + "tagline": "આ ઓપન સોર્સ સ્ટ્રીમિંગ એપ વડે તમારા મનપસંદ શો અને મૂવીઝ જુઓ." + }, + "global": { + "name": "મૂવી-વેબ", + "pages": { + "about": "વિશે", + "dmca": "DMCA", + "login": "પ્રવેશ કરો", + "onboarding": "સ્થાપના", + "pagetitle": "{{title}} - મૂવી-વેબ", + "register": "નોંધણી કરો", + "settings": "સેટિંગ્સ" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "બુકમાર્ક્સ" + }, + "continueWatching": { + "sectionTitle": "જોવાનું ચાલુ રાખો" + }, + "mediaList": { + "stopEditing": "સંપાદન બંધ કરો" + }, + "search": { + "allResults": "અમારી પાસે એટલું જ છે!", + "failed": "મીડિયા શોધવામાં નિષ્ફળ, ફરી પ્રયાસ કરો!", + "loading": "લોડ થાય છે...", + "noResults": "અમે કંઈપણ શોધી શક્યા નથી!", + "placeholder": { + "default": "તમે શું જોવા માંગો છો?" + }, + "sectionTitle": "શોધ પરિણામો" + }, + "titles": { + "day": { + "default": "તમે આ બપોરે શું જોવા માંગો છો?", + "extra": ["સાહસિક લાગે છે? જુરાસિક પાર્ક યોગ્ય પસંદગી હોઈ શકે છે."] + }, + "morning": { + "default": "તમે આ સવારે શું જોવા માંગો છો?", + "extra": ["હું સાંભળું છું કે Before Sunrise સારું છે"] + }, + "night": { + "default": "તમે આજે રાત્રે શું જોવા માંગો છો?", + "extra": [ + "થાકી ગયા છો? મેં સાંભળ્યું છે કે The Exorcise ફિલ્મ સારી છે." + ] + } + } + }, + "media": { + "episodeDisplay": "સિઝન{{season}} એપિસોડ{{episode}}", + "types": { + "movie": "ફિલ્મ", + "show": "શો" + } + }, + "navigation": { + "banner": { + "offline": "તમારું ઇન્ટરનેટ કનેક્શન તપાસો" + }, + "menu": { + "about": "અમારા વિશે", + "logout": "લૉગ આઉટ", + "register": "sudo-cloud સાથે સમન્વયિત કરો", + "settings": "સેટિંગ્સ", + "support": "આધાર" + } + }, + "notFound": { + "badge": "મળી નથી", + "goHome": "ઘરે પાછા", + "message": "અમે બધે જોયું: ડબ્બાની નીચે, કબાટમાં, પ્રોક્સીની પાછળ, પરંતુ આખરે તમે જે page શોધી રહ્યાં છો તે શોધી શક્યા નહીં.", + "title": "page શોધી શક્યું નથી" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "રદ કરો", + "confirm": "ડિફૉલ્ટ સેટઅપનો ઉપયોગ કરો", + "description": "ડિફૉલ્ટ સેટઅપમાં શ્રેષ્ઠ સ્ટ્રીમ્સ નથી અને તે અસહ્ય રીતે ધીમું હોઈ શકે છે.", + "title": "શું તમને ખાતરી છે?" + }, + "extension": { + "back": "પાછા જાવ", + "explainer": "બ્રાઉઝર એક્સ્ટેંશનનો ઉપયોગ કરીને, તમે શ્રેષ્ઠ સ્ટ્રીમ મેળવી શકો છો જે અમે ઓફર કરીએ છીએ. માત્ર એક સરળ ઇન્સ્ટોલ સાથે.", + "explainerIos": "કમનસીબે, બ્રાઉઝર એક્સ્ટેંશન iOS પર સમર્થિત નથી, બીજો વિકલ્પ પસંદ કરવા માટે Go back દબાવો.", + "extensionHelp": "જો તમે એક્સ્ટેંશન ઇન્સ્ટોલ કર્યું છે પરંતુ તે શોધાયેલ નથી, તો તમારા બ્રાઉઝર એક્સ્ટેંશન મેનૂ દ્વારા એક્સ્ટેંશન ખોલો અને સ્ક્રીન પરના પગલાંને અનુસરો.", + "linkChrome": "Chrome એક્સ્ટેંશન ઇન્સ્ટોલ કરો", + "linkFirefox": "Firefox એક્સ્ટેંશન ઇન્સ્ટોલ કરો", + "notDetecting": "Chrome પર ઇન્સ્ટોલ કરેલું છે, પરંતુ સાઇટ તેને શોધી રહી નથી? પૃષ્ઠને ફરીથી લોડ કરવાનો પ્રયાસ કરો!", + "notDetectingAction": "પૃષ્ઠ ફરીથી લોડ કરો", + "status": { + "disallowed": "આ પૃષ્ઠ માટે એક્સ્ટેંશન સક્ષમ નથી", + "disallowedAction": "એક્સ્ટેંશન સક્ષમ કરો", + "failed": "સ્થિતિની વિનંતી કરવામાં નિષ્ફળ", + "loading": "તમે એક્સ્ટેંશન ઇન્સ્ટોલ કરવા માટે રાહ જોઈ રહ્યાં છો", + "outdated": "એક્સ્ટેંશન સંસ્કરણ ખૂબ જૂનું છે", + "success": "એક્સ્ટેંશન અપેક્ષા મુજબ કામ કરી રહ્યું છે!" + }, + "submit": "ચાલુ રાખો", + "title": "ચાલો એક્સ્ટેંશનથી શરૂઆત કરીએ" + }, + "proxy": { + "back": "પાછા જાવ", + "explainer": "પ્રોક્સી પદ્ધતિ સાથે, તમે સ્વ-સેવા પ્રોક્સી બનાવીને ઉત્તમ ગુણવત્તાની સ્ટ્રીમ્સ મેળવી શકો છો.", + "input": { + "errorConnection": "પ્રોક્સી સાથે કનેક્ટ કરી શકાયું નથી", + "errorInvalidUrl": "માન્ય URL નથી", + "errorNotProxy": "પ્રોક્સીની અપેક્ષા હતી પણ વેબસાઇટ મળી", + "label": "પ્રોક્સી URL", + "placeholder": "https://" + }, + "link": "પ્રોક્સી કેવી રીતે બનાવવી તે જાણો", + "submit": "પ્રોક્સી સબમિટ કરો", + "title": "ચાલો એક નવી પ્રોક્સી બનાવીએ" + }, + "start": { + "explainer": "શક્ય શ્રેષ્ઠ સ્ટ્રીમ્સ મેળવવા માટે, તમારે કઈ સ્ટ્રીમિંગ પદ્ધતિનો ઉપયોગ કરવો છે તે પસંદ કરવાની જરૂર પડશે.", + "options": { + "default": { + "text": "મને સારી ગુણવત્તાની સ્ટ્રીમ જોઈતી નથી,<0 /> <1>ડિફૉલ્ટ સેટઅપનો ઉપયોગ કરો" + }, + "extension": { + "action": "એક્સ્ટેંશન ઇન્સ્ટોલ કરો", + "description": "બ્રાઉઝર એક્સ્ટેંશન ઇન્સ્ટોલ કરો અને શ્રેષ્ઠ સ્ત્રોતોની ઍક્સેસ મેળવો.", + "quality": "ઉત્તમ ગુણવત્તા", + "title": "બ્રાઉઝર એક્સ્ટેંશન" + }, + "proxy": { + "action": "પ્રોક્સી સેટઅપ કરો", + "description": "માત્ર 5 મિનિટમાં પ્રોક્સી સેટ કરો અને શ્રેષ્ઠ સ્ત્રોતોની ઍક્સેસ મેળવો.", + "quality": "સારી ગુણવત્તા", + "title": "કસ્ટમ પ્રોક્સી" + } + }, + "title": "ચાલો તમને મૂવી-વેબ સાથે સેટઅપ કરાવીએ" + } + }, + "overlays": { + "close": "બંધ" + }, + "player": { + "back": { + "default": "ઘરે પાછા", + "short": "પાછા" + }, + "casting": { + "enabled": "Device પર કાસ્ટ કરી રહ્યું છે..." + }, + "menus": { + "downloads": { + "disclaimer": "ડાઉનલોડ સીધા પ્રદાતા પાસેથી લેવામાં આવે છે. મૂવી-વેબ ડાઉનલોડ્સ કેવી રીતે પ્રદાન કરવામાં આવે છે તેના પર નિયંત્રણ નથી.", + "downloadSubtitle": "વર્તમાન ઉપશીર્ષક ડાઉનલોડ કરો", + "downloadVideo": "વિડિઓ ડાઉનલોડ કરો", + "hlsDisclaimer": "ડાઉનલોડ સીધા પ્રદાતા પાસેથી લેવામાં આવે છે. કેવી રીતે ડાઉનલોડ્સ પ્રદાન કરવામાં આવે છે તેના પર મૂવી-વેબનું નિયંત્રણ નથી.

કૃપા કરીને નોંધ કરો કે તમે HLS પ્લેલિસ્ટ ડાઉનલોડ કરી રહ્યાં છો, જો તમે અદ્યતન સ્ટ્રીમિંગ ફોર્મેટથી પરિચિત ન હોવ તો તેને ડાઉનલોડ કરવાની ભલામણ કરવામાં આવતી નથી. વિવિધ ફોર્મેટ માટે વિવિધ સ્ત્રોતો અજમાવો.", + "onAndroid": { + "1": "Android પર ડાઉનલોડ કરવા માટે, ડાઉનલોડ બટનને ક્લિક કરો પછી, નવા પૃષ્ઠ પર, વિડિઓ પર ટેપ કરો અને પકડી રાખો, પછી સાચવો પસંદ કરો.", + "shortTitle": "ડાઉનલોડ કરો / Android", + "title": "એન્ડ્રોઇડ પર ડાઉનલોડ કરી રહ્યું છે" + }, + "onIos": { + "1": "iOS પર ડાઉનલોડ કરવા માટે, ડાઉનલોડ બટનને ક્લિક કરો પછી, નવા પૃષ્ઠ પર, પર ક્લિક કરો, પછી ફાઇલોમાં સાચવો .", + "shortTitle": "ડાઉનલોડ કરો / iOS", + "title": "iOS પર ડાઉનલોડ કરી રહ્યું છે" + }, + "onPc": { + "1": "પીસી પર, ડાઉનલોડ બટનને ક્લિક કરો પછી, નવા પૃષ્ઠ પર, વિડિઓ પર જમણું ક્લિક કરો અને Save video as પસંદ કરો", + "shortTitle": "ડાઉનલોડ કરો / PC", + "title": "PC પર ડાઉનલોડ કરી રહ્યું છે" + }, + "title": "ડાઉનલોડ કરો" + }, + "episodes": { + "button": "એપિસોડ્સ", + "emptyState": "આ સિઝનમાં કોઈ એપિસોડ નથી, પછીથી ફરી તપાસો!", + "episodeBadge": "એપિસોડ{{episode}}", + "loadingError": "સીઝન લોડ કરવામાં ભૂલ", + "loadingList": "લોડ થાય છે...", + "loadingTitle": "લોડ થાય છે...", + "unairedEpisodes": "આ સિઝનમાં એક અથવા વધુ એપિસોડ અક્ષમ કરવામાં આવ્યા છે કારણ કે તે હજુ સુધી પ્રસારિત થયા નથી." + }, + "playback": { + "speedLabel": "પ્લેબેક ઝડપ", + "title": "પ્લેબેક સેટિંગ્સ" + }, + "quality": { + "automaticLabel": "આપોઆપ ગુણવત્તા", + "hint": "તમે વિવિધ ગુણવત્તા વિકલ્પો મેળવવા માટે <0>સ્રોત સ્વિચ કરવાનો પ્રયાસ કરી શકો છો.", + "iosNoQuality": "Apple દ્વારા નિર્ધારિત મર્યાદાઓને લીધે, આ સ્ત્રોત માટે ગુણવત્તા પસંદગી iOS પર ઉપલબ્ધ નથી. તમે વિવિધ ગુણવત્તા વિકલ્પો મેળવવા માટે <0>બીજા સ્ત્રોત પર સ્વિચ કરવાનો પ્રયાસ કરી શકો છો.", + "title": "ગુણવત્તા" + }, + "settings": { + "downloadItem": "ડાઉનલોડ કરો", + "enableSubtitles": "સબટાઈટલ સક્ષમ કરો", + "experienceSection": "જોવાનો અનુભવ", + "playbackItem": "પ્લેબેક સેટિંગ્સ", + "qualityItem": "ગુણવત્તા", + "sourceItem": "વિડિઓ સ્ત્રોતો", + "subtitleItem": "ઉપશીર્ષક સેટિંગ્સ", + "videoSection": "વિડિઓ સેટિંગ્સ" + }, + "sources": { + "failed": { + "text": "કોઈપણ વિડિઓઝ શોધવાનો પ્રયાસ કરતી વખતે ભૂલ આવી હતી, કૃપા કરીને કોઈ અલગ સ્રોતનો પ્રયાસ કરો.", + "title": "ઉઝરડા કરવામાં નિષ્ફળ" + }, + "noEmbeds": { + "text": "અમે કોઈપણ એમ્બેડ શોધવામાં અસમર્થ હતા, કૃપા કરીને કોઈ અલગ સ્રોતનો પ્રયાસ કરો.", + "title": "કોઈ એમ્બેડ મળ્યાં નથી" + }, + "noStream": { + "text": "આ સ્રોતમાં આ મૂવી અથવા શો માટે કોઈ સ્ટ્રીમ નથી.", + "title": "કોઈ પ્રવાહ નથી" + }, + "title": "સ્ત્રોતો", + "unknownOption": "અજ્ઞાત" + }, + "subtitles": { + "customChoice": "ફાઇલમાંથી ઉપશીર્ષક પસંદ કરો", + "customizeLabel": "કસ્ટમાઇઝ કરો", + "offChoice": "બંધ", + "settings": { + "backlink": "કસ્ટમ સબટાઈટલ", + "delay": "ઉપશીર્ષક વિલંબ", + "fixCapitals": "મૂડીકરણ ઠીક કરો" + }, + "title": "સબટાઈટલ", + "unknownLanguage": "અજ્ઞાત" + } + }, + "metadata": { + "api": { + "text": "API મેટાડેટા લોડ કરી શકાયું નથી, કૃપા કરીને તમારું ઇન્ટરનેટ કનેક્શન તપાસો.", + "title": "API મેટાડેટા લોડ કરવામાં નિષ્ફળ" + }, + "dmca": { + "badge": "દૂર", + "text": "દૂર કરવાની સૂચના અથવા કૉપિરાઇટ દાવાને કારણે આ મીડિયા હવે ઉપલબ્ધ નથી.", + "title": "મીડિયા દૂર કરવામાં આવ્યું છે" + }, + "extensionPermission": { + "badge": "પરવાનગી ખૂટે છે", + "button": "એક્સ્ટેંશનનો ઉપયોગ કરો", + "text": "તમારી પાસે બ્રાઉઝર એક્સ્ટેંશન છે, પરંતુ એક્સ્ટેંશનનો ઉપયોગ શરૂ કરવા માટે અમને તમારી પરવાનગીની જરૂર છે.", + "title": "એક્સ્ટેંશનને ગોઠવો" + }, + "failed": { + "badge": "નિષ્ફળ", + "homeButton": "ઘર જાઓ", + "text": "TMDB માંથી મીડિયાનો મેટાડેટા લોડ કરી શકાયો નથી. કૃપા કરીને તપાસો કે તમારા ઇન્ટરનેટ કનેક્શન પર TMDB બંધ છે અથવા અવરોધિત છે.", + "title": "મેટાડેટા લોડ કરવામાં નિષ્ફળ" + }, + "notFound": { + "badge": "મળી નથી", + "homeButton": "ઘરે પાછા", + "text": "તમે વિનંતી કરેલ મીડિયા અમે શોધી શક્યા નથી. કાં તો તે દૂર કરવામાં આવ્યું છે અથવા તમે URL સાથે ચેડા કર્યા છે.", + "title": "તે મીડિયા શોધી શક્યું નથી." + } + }, + "nextEpisode": { + "cancel": "રદ કરો", + "next": "આગામી એપિસોડ" + }, + "playbackError": { + "badge": "પ્લેબેક ભૂલ", + "errors": { + "errorAborted": "વપરાશકર્તાની વિનંતીથી મીડિયાનું આનયન અટકાવવામાં આવ્યું હતું.", + "errorDecode": "અગાઉ ઉપયોગ કરી શકાય તેવું નક્કી કરવામાં આવ્યું હોવા છતાં, મીડિયા સંસાધનને ડીકોડ કરવાનો પ્રયાસ કરતી વખતે એક ભૂલ આવી, પરિણામે ભૂલ આવી.", + "errorGenericMedia": "અજ્ઞાત મીડિયા ભૂલ આવી.", + "errorNetwork": "કેટલીક પ્રકારની નેટવર્ક ભૂલ આવી છે જેણે અગાઉ ઉપલબ્ધ હોવા છતાં મીડિયાને સફળતાપૂર્વક આનયન થવાથી અટકાવ્યું હતું.", + "errorNotSupported": "મીડિયા અથવા મીડિયા પ્રદાતા ઑબ્જેક્ટ સપોર્ટેડ નથી." + }, + "homeButton": "ઘર જાઓ", + "text": "મીડિયા ચલાવવાનો પ્રયાસ કરવામાં ભૂલ આવી હતી. મહેરબાની કરીને ફરીથી પ્રયતન કરો.", + "title": "વિડિઓ ચલાવવામાં નિષ્ફળ!" + }, + "scraping": { + "items": { + "failure": "ભૂલ આવી", + "notFound": "વિડિયો નથી", + "pending": "વિડિઓઝ માટે તપાસ કરી રહ્યું છે..." + }, + "notFound": { + "badge": "મળી નથી", + "detailsButton": "વિગતો બતાવો", + "homeButton": "ઘર જાઓ", + "text": "અમે અમારા પ્રદાતાઓ દ્વારા શોધ કરી છે અને તમે શોધી રહ્યાં છો તે મીડિયા શોધી શકતા નથી! અમે મીડિયાને હોસ્ટ કરતા નથી અને જે ઉપલબ્ધ છે તેના પર કોઈ નિયંત્રણ નથી. વધુ વિગતો માટે કૃપા કરીને નીચે 'વિગતો બતાવો' પર ક્લિક કરો.", + "title": "અમે તે શોધી શક્યા નથી" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} બાકી • {{timeFinished, datetime}} વાગ્યે સમાપ્ત થાય છે", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "કૃપા કરીને જમણી બાજુએ કૅપ્ચા પૂર્ણ કરીને ચકાસો કે તમે માનવ છો. આ મૂવી-વેબને સુરક્ષિત રાખવા માટે છે!", + "error": "તમારી માનવતા ચકાસવામાં નિષ્ફળ. મહેરબાની કરીને ફરીથી પ્રયત્ન કરો.", + "title": "અમારે ચકાસવાની જરૂર છે કે તમે માનવ છો.", + "verifyingHumanity": "તમારી માનવતા ચકાસવી..." + } + }, + "screens": { + "dmca": { + "text": "મૂવી-વેબના DMCA સંપર્ક પૃષ્ઠ પર આપનું સ્વાગત છે! અમે બૌદ્ધિક સંપદા અધિકારોનો આદર કરીએ છીએ અને કોઈપણ કોપીરાઈટની ચિંતાઓને ઝડપથી ઉકેલવા માંગીએ છીએ. જો તમે માનતા હોવ કે તમારા કૉપિરાઇટ કરેલા કાર્યનો અમારા પ્લેટફોર્મ પર અયોગ્ય ઉપયોગ કરવામાં આવ્યો છે, તો કૃપા કરીને નીચે આપેલા ઇમેઇલ પર વિગતવાર DMCA સૂચના મોકલો. કૃપા કરીને કૉપિરાઇટ કરેલી સામગ્રીનું વર્ણન, તમારી સંપર્ક વિગતો અને સદ્ભાવનાની માન્યતાનું નિવેદન શામેલ કરો. અમે આ બાબતોને તાત્કાલિક ઉકેલવા માટે પ્રતિબદ્ધ છીએ અને મૂવી-વેબને સર્જનાત્મકતા અને કૉપિરાઇટનો આદર કરતી જગ્યા રાખવા માટે તમારા સહકારની પ્રશંસા કરીએ છીએ.", + "title": "DMCA" + }, + "loadingApp": "એપ્લિકેશન લોડ કરી રહ્યું છે", + "loadingUser": "તમારી પ્રોફાઇલ લોડ કરી રહ્યું છે", + "loadingUserError": { + "logout": "લૉગ આઉટ", + "reset": "કસ્ટમ સર્વર રીસેટ કરો", + "text": "તમારી પ્રોફાઇલ લોડ કરવામાં નિષ્ફળ", + "textWithReset": "તમારા કસ્ટમ સર્વરથી તમારી પ્રોફાઇલ લોડ કરવામાં નિષ્ફળ, ડિફોલ્ટ સર્વર પર પાછા રીસેટ કરવા માંગો છો?" + }, + "migration": { + "failed": "તમારો ડેટા સ્થાનાંતરિત કરવામાં નિષ્ફળ.", + "inProgress": "કૃપા કરીને પકડી રાખો, અમે તમારો ડેટા સ્થાનાંતરિત કરી રહ્યાં છીએ. આમાં લાંબો સમય લાગવો જોઈએ નહીં." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "ડિવાઇસ નામ", + "deviceNamePlaceholder": "વ્યક્તિગત ફોન", + "editProfile": "સંપાદિત કરો", + "logoutButton": "લૉગ આઉટ" + }, + "actions": { + "delete": { + "button": "એકાઉન્ટ કાઢી નાખો", + "confirmButton": "એકાઉન્ટ કાઢી નાખો", + "confirmDescription": "શું તમે ખરેખર તમારું એકાઉન્ટ કાઢી નાખવા માંગો છો? તમારો બધો ડેટા ખોવાઈ જશે!", + "confirmTitle": "શું તમને ખાતરી છે?", + "text": "આ ક્રિયા બદલી ન શકાય તેવી છે. તમામ ડેટા કાઢી નાખવામાં આવશે અને કંઈપણ પુનઃપ્રાપ્ત કરી શકાશે નહીં.", + "title": "એકાઉન્ટ કાઢી નાખો" + }, + "title": "ક્રિયાઓ" + }, + "devices": { + "deviceNameLabel": "ડિવાઇસ નામ", + "failed": "સત્રો લોડ કરવામાં નિષ્ફળ", + "removeDevice": "દૂર કરો", + "title": "ઉપકરણો" + }, + "profile": { + "finish": "સંપાદન સમાપ્ત કરો", + "firstColor": "પ્રોફાઇલ રંગ એક", + "secondColor": "પ્રોફાઇલ રંગ બે", + "title": "પ્રોફાઇલ ચિત્ર સંપાદિત કરો", + "userIcon": "વપરાશકર્તા ચિહ્ન" + }, + "register": { + "cta": "શરૂ કરો", + "text": "ઉપકરણો વચ્ચે તમારી ઘડિયાળની પ્રગતિ શેર કરો અને તેમને સમન્વયિત રાખો.", + "title": "sudo-cloud સાથે સમન્વયિત કરો" + }, + "title": "એકાઉન્ટ" + }, + "appearance": { + "activeTheme": "સક્રિય", + "themes": { + "blue": "વાદળી", + "default": "ડિફૉલ્ટ", + "gray": "ભૂખરા", + "red": "લાલ", + "teal": "ટીલ" + }, + "title": "દેખાવ" + }, + "connections": { + "server": { + "description": "જો તમે તમારો ડેટા સંગ્રહિત કરવા માટે કસ્ટમ બેકએન્ડ સાથે જોડાવા માંગતા હો, તો આને સક્ષમ કરો અને URL પ્રદાન કરો. <0>સૂચનો.", + "label": "કસ્ટમ સર્વર", + "urlLabel": "કસ્ટમ સર્વર URL" + }, + "setup": { + "doSetup": "સેટઅપ કરો", + "errorStatus": { + "description": "એવું લાગે છે કે આ સેટઅપમાં એક અથવા વધુ આઇટમ્સ તમારા ધ્યાનની જરૂર છે.", + "title": "કંઈક તમારા ધ્યાનની જરૂર છે" + }, + "itemError": "આ સેટિંગમાં કંઈક ખોટું છે. તેને ઠીક કરવા માટે ફરીથી સેટઅપ પર જાઓ.", + "items": { + "default": "ડિફૉલ્ટ સેટઅપ", + "extension": "વિસ્તરણ", + "proxy": "કસ્ટમ પ્રોક્સી" + }, + "redoSetup": "સેટઅપ ફરી કરો", + "successStatus": { + "description": "તમારા મનપસંદ મીડિયાને જોવાનું શરૂ કરવા માટે તમારા માટે બધી વસ્તુઓ છે.", + "title": "બધું સુયોજિત છે!" + }, + "unsetStatus": { + "description": "કૃપા કરીને સેટઅપ પ્રક્રિયા શરૂ કરવા માટે જમણી બાજુના બટનને ક્લિક કરો.", + "title": "તમે સેટઅપમાંથી પસાર થયા નથી" + } + }, + "title": "જોડાણો", + "workers": { + "addButton": "નવો કાર્યકર ઉમેરો", + "description": "એપ્લિકેશન કાર્ય કરવા માટે, તમામ ટ્રાફિકને પ્રોક્સીઓ દ્વારા રૂટ કરવામાં આવે છે. જો તમે તમારા પોતાના કામદારોને લાવવા માંગતા હોવ તો આને સક્ષમ કરો. <0>સૂચનો.", + "emptyState": "હજુ સુધી કોઈ કામદારો નથી, નીચે એક ઉમેરો", + "label": "કસ્ટમ પ્રોક્સી કાર્યકરોનો ઉપયોગ કરો", + "urlLabel": "વર્કર URL", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "એપ્લિકેશન ભાષા", + "languageDescription": "સમગ્ર એપ્લિકેશન પર લાગુ ભાષા.", + "thumbnail": "થંબનેલ્સ બનાવો", + "thumbnailDescription": "મોટાભાગે, વીડિયોમાં થંબનેલ્સ હોતા નથી. તમે આ સેટિંગને ફ્લાય પર જનરેટ કરવા માટે સક્ષમ કરી શકો છો પરંતુ તે તમારા વિડિઓને ધીમું બનાવી શકે છે.", + "thumbnailLabel": "થંબનેલ્સ બનાવો", + "title": "પસંદગીઓ" + }, + "reset": "રીસેટ કરો", + "save": "સાચવો", + "sidebar": { + "info": { + "appVersion": "એપ્લિકેશન સંસ્કરણ", + "backendUrl": "બેકએન્ડ URL", + "backendVersion": "બેકએન્ડ સંસ્કરણ", + "hostname": "હોસ્ટનામ", + "insecure": "અસુરક્ષિત", + "notLoggedIn": "તમે લૉગ ઇન નથી", + "secure": "સુરક્ષિત", + "title": "એપ્લિકેશન માહિતી", + "unknownVersion": "અજ્ઞાત", + "userId": "વપરાશકર્તા ID" + } + }, + "subtitles": { + "backgroundLabel": "પૃષ્ઠભૂમિ અસ્પષ્ટ", + "colorLabel": "રંગ", + "previewQuote": "મારે ડરવું જોઈએ નહીં. ડર એ મનનો હત્યારો છે.", + "textSizeLabel": "ટેક્સ્ટનું કદ", + "title": "સબટાઈટલ" + }, + "unsaved": "તમારી પાસે વણસાચવેલા ફેરફારો છે" + } +} diff --git a/src/assets/locales/he.json b/src/assets/locales/he.json new file mode 100644 index 0000000..75fa757 --- /dev/null +++ b/src/assets/locales/he.json @@ -0,0 +1,537 @@ +{ + "about": { + "description": "SkoolTV הוא יישום אינטרנט המחפש באינטרנט אחר זרמים. הצוות שואף לגישה מינימליסטית ברובה לצריכת תוכן.", + "faqTitle": "שאלות נפוצות", + "q1": { + "body": "SkoolTV אינו מארח תוכן כלשהו. כאשר אתה לוחץ על משהו לצפייה, האינטרנט מחפש את המדיה שנבחרה (במסך הטעינה ובכרטיסייה 'מקורות וידאו' תוכל לראות באיזה מקור אתה משתמש). מדיה אף פעם לא מועלת על ידי SkoolTV, הכל מתבצע דרך מנגנון חיפוש זה.", + "title": "מאיפה התוכן?" + }, + "q2": { + "body": "לא ניתן לבקש תוכנית או סרט, SkoolTV לא מנהלת שום תוכן. כל התוכן נצפה דרך מקורות באינטרנט.", + "title": "איפה אני יכול לבקש תוכנית או סרט?" + }, + "q3": { + "body": "תוצאות החיפוש שלנו מופעלות על ידי The Movie Database (TMDB) ומוצגות ללא קשר אם למקורות שלנו יש את התוכן.", + "title": "תוצאות החיפוש מציגות את התוכנית או הסרט, למה אני לא יכול להפעיל אותם?" + }, + "title": "על SkoolTV" + }, + "actions": { + "copied": "הועתק", + "copy": "להעתיק" + }, + "auth": { + "createAccount": "אין לך עדיין חשבון? <0>צור חשבון.", + "deviceNameLabel": "שם המכשיר", + "deviceNamePlaceholder": "פלאפון אישי", + "generate": { + "description": "ביטוי הסיסמה שלך משמש כשם המשתמש והסיסמה שלך. אנא הקפד לשמור אותו בטוח מכיוון שתצטרך להזין אותו כדי להתחבר לחשבון שלך", + "next": "אני שמרתי את משפט הסיסמה שלי", + "passphraseFrameLabel": "ביטוי סיסמה", + "title": "משפט הסיסמה שלך" + }, + "hasAccount": "כבר יש לך חשבון? <0>התחבר כאן.", + "login": { + "description": "אנא הזן את ביטוי הסיסמה שלך כדי להתחבר לחשבונך", + "deviceLengthError": "אנא הזן שם מכשיר", + "passphraseLabel": "ביטוי סיסמא בעל 12 מילים", + "passphrasePlaceholder": "ביטוי סיסמא", + "submit": "התחבר", + "title": "התחבר לחשבונך", + "validationError": "ביטוי סיסמה שגוי או לא שלם" + }, + "register": { + "information": { + "color1": "צבע פרופיל ראשון", + "color2": "צבע פרופיל שני", + "header": "הזן שם למכשירך ובחר צבעים וסמל משתמש לפי בחירתך", + "icon": "סמל משתמש", + "next": "הבא", + "title": "פרטי חשבון" + } + }, + "trust": { + "failed": { + "text": "האם הגדרת את זה נכון?", + "title": "הגישה לשרת נכשלה" + }, + "host": "אתה מתחבר אל <0>{{hostname}} - אנא אשר שאתה סומך עליו לפני יצירת חשבון", + "no": "חזור", + "title": "האם אתה סומך על שרת זה?", + "yes": "אני בוטח בשרת זה" + }, + "verify": { + "description": "אנא הזן את משפט הסיסמה שלך מקודם כדי לאשר ששמרת אותו וכדי ליצור את חשבונך", + "invalidData": "הנתונים אינם חוקיים", + "noMatch": "ביטוי הסיסמה אינו תואם", + "passphraseLabel": "ביטוי הסיסמה שלך בעל 12 מילים", + "recaptchaFailed": "אימות ReCaptcha נכשל", + "register": "צור חשבון", + "title": "אשר את ביטוי הסיסמה שלך" + } + }, + "errors": { + "badge": "זה נשבר", + "details": "פרטי שגיאה", + "reloadPage": "טען מחדש את הדף", + "showError": "הצג פרטי שגיאה", + "title": "נתקלנו בשגיאה!" + }, + "footer": { + "legal": { + "disclaimer": "תנית ויתור", + "disclaimerText": "SkoolTV אינו מארח קבצים, הוא רק מקשר לשירותי צד שלישי. יש להתייחס לסוגיות משפטיות עם המארחים והספקים של הקבצים. SkoolTV אינה אחראית לכל קבצי מדיה המוצגים על ידי ספקי הווידאו." + }, + "links": { + "discord": "דיסקורד", + "dmca": "DMCA", + "github": "גיטהאב" + }, + "tagline": "צפה בתוכניות ובסרטים האהובים עליך עם אפליקציית סטרימינג זו בקוד פתוח." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "אודות", + "dmca": "זכויות יוצרים", + "login": "התחבר", + "onboarding": "הכנה", + "pagetitle": "{{title}} - SkoolTV", + "register": "הירשם", + "settings": "הגדרות" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "סימניות" + }, + "continueWatching": { + "sectionTitle": "המשך לצפות" + }, + "mediaList": { + "stopEditing": "הפסק עריכה" + }, + "search": { + "allResults": "זה כל מה שיש לנו!", + "failed": "לא הצלחנו למצוא מדיה, נסה שוב!", + "loading": "טוען...", + "noResults": "לא יכולנו למצוא כלום!", + "placeholder": { + "default": "במה תרצה לצפות?" + }, + "sectionTitle": "תוצאות חיפוש" + }, + "titles": { + "day": { + "default": "במה תרצה לצפות באחר צהריים זה?", + "extra": [ + "מרגיש הרפתקני? פארק היורה עשוי להיות הבחירה המושלמת." + ] + }, + "morning": { + "default": "במה תרצה לצפות הבוקר?", + "extra": [ + "שמעתי שלפני הזריחה זה סרט טוב" + ] + }, + "night": { + "default": "במה תרצה לצפות הלילה?", + "extra": [ + "רוצה לישון? הפיג'מות היא בחירה מצויינת." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "סרט", + "show": "סדרה" + } + }, + "navigation": { + "banner": { + "offline": "תבדוק את חיבור האינטרנט שלך" + }, + "menu": { + "about": "עלינו", + "logout": "להתנתק", + "register": "סנכרון לענן", + "settings": "הגדרות", + "support": "תמיכה" + } + }, + "notFound": { + "badge": "לא נמצא", + "goHome": "בחזרה לבית", + "message": "חיפשנו בכל מקום: מתחת לפחים, בארון, מאחורי ה-proxy אבל בסופו של דבר לא מצאנו את הדף שאתה מחפש.", + "title": "לא יכולנו למצוא את דף זה" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "בטל", + "confirm": "השתמש בהגדרות ברירת המחדל", + "description": "הגדרת ברירת המחדל אינה כוללת את הזרמים הטובים ביותר ויכולה להיות איטית בצורה בלתי נסבלת.", + "title": "אתה בטוח?" + }, + "extension": { + "back": "חזור", + "explainer": "באמצעות תוסף הדפדפן, אתה יכול לקבל את הזרמים הטובים ביותר שיש לנו להציע. עם התקנה פשוטה בלבד.", + "explainerIos": "לצערנו, התוסף לדפדפן לא תומך בiOS, לחץ חזור כדי לבחור אפשרות אחרת.", + "extensionHelp": "אם התקנת את התוסף אך הוא לא מזוהה. פתח את התוסף דרך תפריט התוספות של הדפדפן שלך ובצע את השלבים שעל המסך.", + "linkChrome": "התקן תוסף Chrome", + "linkFirefox": "התקן תוסף Firefox", + "notDetecting": "מותקן על Chrome, אבל האתר לא מזהה את זה? נסה לטעון את הדף מחדש!", + "notDetectingAction": "טען דף מחדש", + "status": { + "disallowed": "התוסף אינו מפועל עבור דף זה", + "disallowedAction": "אפשר תוסף", + "failed": "בקשת הסטטוס נכשלה", + "loading": "מחכה שתתקין את התוסף", + "outdated": "גרסת התוסף ישנה מדי", + "success": "התוסף עובד כמצופה!" + }, + "submit": "המשך", + "title": "נתחיל עם התוסף" + }, + "proxy": { + "back": "חזור", + "explainer": "עם שיטת הפרוקסי, אתה יכול לקבל זרמים באיכות מעולה על ידי יצירת פרוקסי בשירות עצמי.", + "input": { + "errorConnection": "לא ניתן להתחבר לפרוקסי", + "errorInvalidUrl": "כתובת לא תקינה", + "errorNotProxy": "ציפה לפרוקסי אבל קיבל אתר", + "label": "כתובת פרוקסי", + "placeholder": "https://" + }, + "link": "למד כיצד ליצור פרוקסי", + "submit": "שלח פרוקסי", + "title": "בואו ניצור פרוקסי חדש" + }, + "start": { + "explainer": "כדי לקבל את הזרמים הכי טובים שאפשר. תצטרך לבחור באיזו שיטת סטרימינג תרצה להשתמש.", + "options": { + "default": { + "text": "אני לא רוצה זרמים באיכות טובה,<0 /> <1>השתמש בהגדרת ברירת המחדל" + }, + "extension": { + "action": "התקן תוסף", + "description": "התקן תוסף דפדפן וקבל גישה למקורות הטובים ביותר.", + "quality": "איכות מעולה", + "title": "תוסף הדפדפן" + }, + "proxy": { + "action": "הגדר פרוקסי", + "description": "הגדר פרוקסי תוך 5 דקות בלבד וקבל גישה למקורות מעולים.", + "quality": "איכות טובה", + "title": "פרוקסי מותאם אישית" + } + }, + "title": "בוא נעשה לך התקנה עם SkoolTV" + } + }, + "overlays": { + "close": "סגור" + }, + "player": { + "back": { + "default": "חזרה לדף הבית", + "short": "חזור" + }, + "casting": { + "enabled": "משדר למכשיר..." + }, + "menus": { + "downloads": { + "disclaimer": "ההורדות נלקחות ישירות מהספק. ל-SkoolTV אין שליטה על האופן שבו מסופקות ההורדות.", + "downloadSubtitle": "הורד את הכתוביות הנוכחיות", + "downloadVideo": "הורד וידאו", + "hlsDisclaimer": "ההורדות נלקחות ישירות מהספק. ל-SkoolTV אין שליטה על האופן שבו מסופקות ההורדות.

שים לב שאתה מוריד רשימת השמעה של HLS, לא מומלץ להוריד אם אינך מכיר פורמטים מתקדמים של סטרימינג . נסה מקורות שונים עבור פורמטים שונים.", + "onAndroid": { + "1": "כדי להוריד באנדרואיד, לחץ על כפתור ההורדה ולאחר מכן, בדף החדש, הקש והחזק על הסרטון, ולאחר מכן בחר שמור.", + "shortTitle": "הורדה / אנדרויד", + "title": "הורדה באנדרויד" + }, + "onIos": { + "1": "כדי להוריד ב-iOS, לחץ על כפתור ההורדה ולאחר מכן, בדף החדש, לחץ על ולאחר מכן על שמור לקבצים .", + "shortTitle": "הורדה / iOS", + "title": "מוריד ב-iOS" + }, + "onPc": { + "1": "במחשב, לחץ על כפתור ההורדה ולאחר מכן, בדף החדש, לחץ לחיצה ימנית על הסרטון ובחר שמור סרטון בשם", + "shortTitle": "הורדה / PC", + "title": "הורדה במחשב" + }, + "title": "הורד" + }, + "episodes": { + "button": "פרקים", + "emptyState": "אין פרקים בעונה זו, אנא בדוק שוב מאוחר יותר!", + "episodeBadge": "פ{{episode}}", + "loadingError": "ארע שגיאה בטעינת העונה", + "loadingList": "טוען...", + "loadingTitle": "טוען...", + "unairedEpisodes": "פרק אחד או יותר בעונה זו הושבת מכיוון שהם עדיין לא שודרו." + }, + "playback": { + "speedLabel": "מהירות הניגון", + "title": "הגדרות ניגון" + }, + "quality": { + "automaticLabel": "איכות אוטומטית", + "hint": "אתה יכול לנסות <0>להחליף מקור כדי לקבל אפשרויות איכות שונות.", + "iosNoQuality": "בשל מגבלות שהוגדרו על ידי אפל, בחירת איכות אינה זמינה ב-iOS עבור מקור זה. אתה יכול לנסות <0>לעבור למקור אחר כדי לקבל אפשרויות איכות שונות.", + "title": "איכות" + }, + "settings": { + "downloadItem": "הורד", + "enableSubtitles": "אפשר כתוביות", + "experienceSection": "חווית צפייה", + "playbackItem": "הגדרות ניגון", + "qualityItem": "איכות", + "sourceItem": "מקורות וידאו", + "subtitleItem": "הגדרות כתוביות", + "videoSection": "הגדרות וידאו" + }, + "sources": { + "failed": { + "text": "אירעה שגיאה בעת ניסיון למצוא סרטונים, אנא נסה מקור אחר.", + "title": "לא הצליח לחלץ" + }, + "noEmbeds": { + "text": "לא הצלחנו למצוא שום הטעמות, אנא נסה מקור אחר.", + "title": "לא נמצאו הטמעות" + }, + "noStream": { + "text": "למקור זה אין זרמים עבור הסרט או התוכנית הזו.", + "title": "אין זרם" + }, + "title": "מקורות", + "unknownOption": "לא ידוע" + }, + "subtitles": { + "customChoice": "בחר כתובית מקובץ", + "customizeLabel": "התאם", + "offChoice": "כבוי", + "settings": { + "backlink": "כתוביות מותאמות אישית", + "delay": "עיכוב בכיתוב", + "fixCapitals": "תקן שימוש באותיות גדולות" + }, + "title": "כתוביות", + "unknownLanguage": "לא ידוע" + } + }, + "metadata": { + "api": { + "text": "לא ניתן היה לטעון מטא נתונים של ה-API, אנא בדוק את חיבור האינטרנט שלך.", + "title": "טעינת מטא נתונים של ממשק API נכשלה" + }, + "dmca": { + "badge": "הוסר", + "text": "מדיה זו אינה זמינה יותר עקב הודעת הסרה או תביעה בגין זכויות יוצרים.", + "title": "מדיה הוסרה" + }, + "extensionPermission": { + "badge": "הרשאה חסר", + "button": "השתמש בתוסף", + "text": "יש לך את תוסף הדפדפן, אך אנו זקוקים לאישורך כדי להתחיל להשתמש בתוסף.", + "title": "הגדר את התוסף" + }, + "failed": { + "badge": "נכשל", + "homeButton": "חזור לדף הבית", + "text": "לא היה ניתן לטעון את הmetadata של המדיה מ-TMDB. אנא בדוק אם TMDB מושבת או חסום בחיבור האינטרנט שלך.", + "title": "טעינת הmetdata נכשלה" + }, + "notFound": { + "badge": "לא נמצא", + "homeButton": "חזרה לדף הבית", + "text": "לא הצלחנו למצוא את המדיה שביקשת. או שהוא הוסר או שהתעסקת בכתובת האתר.", + "title": "לא הצלחנו למצוא את המדיה הזו." + } + }, + "nextEpisode": { + "cancel": "בטל", + "next": "פרק הבא" + }, + "playbackError": { + "badge": "שגיאת ניגון", + "errors": { + "errorAborted": "השגת המדיה בוטלה על ידי בקשת המשתמש.", + "errorDecode": "למרות שנקבע קודם כל שהמדיה יכולה להשתמש בה, אירעה שגיאה בעת ניסיון לפענח משאבי המדיה, וכתוצאה מכך קרה שגיאה.", + "errorGenericMedia": "‍אירעה שגיאת מדיה לא ידועה.", + "errorNetwork": "אירעה סוג של שגיאת רשת שמנעה גישה למדיה, למרות שהיא הייתה זמינה מראש.", + "errorNotSupported": "המדיה או ספק המדיה אינם נתמכים." + }, + "homeButton": "חזור לדף הבית", + "text": "אירעה שגיאה בהפעלת המדיה. אנא נסה שוב.", + "title": "הפעלת הסרטון נכשלה!" + }, + "scraping": { + "items": { + "failure": "אירעה שגיאה", + "notFound": "אין את הסרטון", + "pending": "מחפש סרטונים..." + }, + "notFound": { + "badge": "לא נמצא", + "detailsButton": "הצג פרטים", + "homeButton": "חזור לדף הבית", + "text": "חיפשנו בספקים שלנו ולא מצאנו את המדיה שאתה מחפש! אנו לא מארחים את המדיה ואין לנו שליטה על מה שזמין. אנא לחץ על 'הצג פרטים' למידע נוסף.", + "title": "לא יכולנו למצוא את זה" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} נשאר • סיים ב {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "אנא ודא שאתה אנושי על ידי מילוי ה-Captcha בצד ימין. זה כדי לשמור על SkoolTV!", + "error": "נכשל אימות האנושיות שלך. בבקשה נסה שוב.", + "title": "אנחנו צריכים לאמת שאתה אנושי.", + "verifyingHumanity": "מאמת את האנושיות שלך..." + } + }, + "screens": { + "dmca": { + "text": "ברוכה הבאה לדף יצירת קשר DMCA של SkoolTV! אנו מכבדים את זכויות הקניין הרוחני ורוצים לטפל בכל חשש לזכויות יוצרים במהירות. אם אתה סבור שהעבודה שלך המוגנת בזכויות יוצרים נוצלה בצורה לא נכונה בפלטפורמה שלנו, אנא שלח הודעת DMCA מפורטת למייל למטה. אנא כלול תיאור של החומר המוגן בזכויות יוצרים, פרטי ההתקשרות שלך והצהרת תום לב. אנו מחויבים לפתור את העניינים הללו באופן מיידי ומעריכים את שיתוף הפעולה שלך בשמירה על SkoolTV מקום שמכבד יצירתיות וזכויות יוצרים.", + "title": "זכויות יוצרים" + }, + "loadingApp": "טוען את האפליקציה", + "loadingUser": "טוען את הפרופיל שלך", + "loadingUserError": { + "logout": "להתנתק", + "reset": "אפס שרת מותאם אישית", + "text": "טעינת הפרופיל שלך נכשלה", + "textWithReset": "לא הצלחנו לטעון את הפרופיל שלך מהשרת המותאם אישית שלך, תרצה לאפס בחזרה לשרת ברירת המחדל?" + }, + "migration": { + "failed": "העברת הנתונים שלך נכשלה.", + "inProgress": "אנא המתן, אנו מעבירים את הנתונים שלך. זה לא אמור לקחת הרבה זמן." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "שם מכשיר", + "deviceNamePlaceholder": "מכשיר אישי", + "editProfile": "ערוך", + "logoutButton": "התנתק" + }, + "actions": { + "delete": { + "button": "מחק משתמש", + "confirmButton": "מחק משתמש", + "confirmDescription": "אתה בטוח שתרצה למחוק את המשתמש שלך? כל הנתונים שלך יימחקו!", + "confirmTitle": "אתה בטוח?", + "text": "פעולה זו היא בלתי הפיכה. כל הנתונים יימחקו ולא ניתן יהיה לשחזר דבר.", + "title": "מחק משתמש" + }, + "title": "פעולות" + }, + "devices": { + "deviceNameLabel": "שם מכשיר", + "failed": "טעינת ההפעלות נכשלה", + "removeDevice": "הסר", + "title": "מכשירים" + }, + "profile": { + "finish": "סייםעריכה", + "firstColor": "‫‫צבע פרופיל ראשון", + "secondColor": "צבע פרופיל שני", + "title": "ערוך תמונת פרופיל", + "userIcon": "סמל משתמש" + }, + "register": { + "cta": "התחל", + "text": "שתף את התקדמות הצפייה שלך בין מכשירים ושמור אותם מסונכרנים.", + "title": "סנכרון לענן" + }, + "title": "משתמש" + }, + "appearance": { + "activeTheme": "פעיל", + "themes": { + "blue": "כחול", + "default": "ברירת מחדל", + "gray": "אפור", + "red": "אדום", + "teal": "ירוק כחלחל" + }, + "title": "מראה" + }, + "connections": { + "server": { + "description": "אם תרצה להתחבר ל-backend מותאם אישית כדי לאחסן את הנתונים שלך, הפעל זאת וספק את כתובת האתר. <0>הוראות.", + "label": "שרת אישי", + "urlLabel": "כתובת אתר מותאמת אישית של שרת" + }, + "setup": { + "doSetup": "עשה הגדרה", + "errorStatus": { + "description": "נראה כי פריט אחד או יותר בהגדרה זו זקוקים לתשומת לבך.", + "title": "משהו צריך את תשומת ליבך" + }, + "itemError": "משהו לא בסדר בהגדרה הזו. עבור שוב על ההגדרה כדי לתקן את זה.", + "items": { + "default": "הגדרת ברירת מחדל", + "extension": "תוסף", + "proxy": "פרוקסי מותאם אישית" + }, + "redoSetup": "בצע מחדש את ההגדרה", + "successStatus": { + "description": "כל הדברים נמצאים במקום כדי שתוכל להתחיל לצפות במדיה האהובה עליך.", + "title": "הכל מוכן!" + }, + "unsetStatus": { + "description": "אנא לחץ על הלחצן מימין כדי להתחיל בתהליך ההגדרה.", + "title": "לא עברת את ההגדרה" + } + }, + "title": "התחברויות", + "workers": { + "addButton": "הוסף עובד חדש", + "description": "כדי שהאפליקציה תפעל, כל התעבורה מנותבת דרך פרוקסי. הפעל זאת אם אתה רוצה להביא עובדים משלך. <0>הוראות.", + "emptyState": "עדיין אין עובדים, הוסף אחד למטה", + "label": "השתמש בעובדי פרוקסי מותאמים אישית", + "urlLabel": "כתובות אתרים של עובדים", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "שפת האפליקציה", + "languageDescription": "השפה החלה על האפליקציה כולה.", + "thumbnail": "צור טאמבניילים", + "thumbnailDescription": "לרוב, לסרטונים אין טאמבניילים. אתה יכול להפעיל את ההגדרה הזו כדי ליצור אותם, אבל הם יכולים להפוך את הסרטון שלך לאיטי יותר.", + "thumbnailLabel": "צור טאמבניילים", + "title": "העדפות" + }, + "reset": "איפוס", + "save": "לשמור", + "sidebar": { + "info": { + "appVersion": "גרסת האפליקציה", + "backendUrl": "כתובת אתר אחורי", + "backendVersion": "גרסת Backend", + "hostname": "שם מארח", + "insecure": "לא בטוח", + "notLoggedIn": "אתה לא מחובר", + "secure": "מאובטח", + "title": "מידע על האפליקציה", + "unknownVersion": "לא ידוע", + "userId": "זהות המשתמש" + } + }, + "subtitles": { + "backgroundLabel": "אטימות רקע", + "colorLabel": "צבע", + "previewQuote": "אין נחום, אני לא באמת קיים. אני למעשה, חישוק.", + "textSizeLabel": "גודל הטקסט", + "title": "כתוביות" + }, + "unsaved": "יש לך שינויים שלא נשמרו" + } +} diff --git a/src/assets/locales/hi.json b/src/assets/locales/hi.json new file mode 100644 index 0000000..335ba20 --- /dev/null +++ b/src/assets/locales/hi.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "मूवी-वेब एक वेब एप्लिकेशन है जो इंटरनेट पर स्ट्रीम्स की खोज करता है। टीम का लक्ष्य सामग्री के उपभोग के लिए अधिकतर न्यूनतम दृष्टिकोण अपनाना है।", + "faqTitle": "सामान्य प्रश्न", + "q1": { + "body": "मूवी-वेब किसी भी कंटेंट को होस्ट नहीं करता है। जब आप देखने के लिए किसी चीज़ पर क्लिक करते हैं, तो इंटरनेट पर चयनित मीडिया की खोज की जाती है (लोडिंग स्क्रीन पर और 'वीडियो स्रोत' टैब में आप देख सकते हैं कि आप किस स्रोत का उपयोग कर रहे हैं)। मीडिया कभी भी मूवी-वेब द्वारा अपलोड नहीं किया जाता है, सब कुछ इस खोज तंत्र के माध्यम से होता है।", + "title": "फिल्म कहां से आती है?" + }, + "q2": { + "body": "किसी शो या मूवी का अनुरोध करना संभव नहीं है, मूवी-वेब किसी भी फिलम का प्रबंधन नहीं करता है। सभी फिल्में इंटरनेट पर स्रोतों के माध्यम से देखी जाती है।", + "title": "मैं किसी शो या मूवी का अनुरोध कहां कर सकता हूं?" + }, + "q3": { + "body": "हमारे खोज परिणाम मूवी डेटाबेस (टीएमडीबी) द्वारा संचालित होते हैं और इस पर ध्यान दिए बिना प्रदर्शित होते हैं कि हमारे स्रोतों में वास्तव में सामग्री है या नहीं।", + "title": "खोज परिणाम शो या मूवी प्रदर्शित करते हैं, मैं फिलम क्यों नहीं चला पा रहा ?" + }, + "title": "मूवी-वेब के बारे में" + }, + "actions": { + "copied": "कॉपी किया गया हुआ है", + "copy": "कॉपी" + }, + "auth": { + "createAccount": "अब तक कोई खाता नहीं है? <0>खाता बनाएं।", + "deviceNameLabel": "डिवाइस का नाम", + "deviceNamePlaceholder": "निजी फ़ोन", + "generate": { + "description": "आपका पासफ़्रेज़ आपके नाम और पासवर्ड के रूप में कार्य करता है। इसे सुरक्षित रखना सुनिश्चित करें क्योंकि आपको अपने खाते में लॉगिन करने के लिए इसे दर्ज करना होगा", + "next": "मैंने अपना पासफ़्रेज़ सहेज कर लिया है", + "passphraseFrameLabel": "पासफ़्रेज़", + "title": "तुम्हारा पासफ़्रेज़" + }, + "hasAccount": "पहले से एक खाता मौजूद है? <0>यहां लॉगिन करें।", + "login": { + "description": "कृपया अपने खाते में लॉगिन करने के लिए अपना पासफ़्रेज़ दर्ज करें", + "deviceLengthError": "कृपया डिवाइस का नाम दर्ज करें", + "passphraseLabel": "12-शब्द का पासफ़्रेज़", + "passphrasePlaceholder": "पासफ़्रेज़", + "submit": "लॉग इन", + "title": "अपने अकाउंट में लॉग इन करें", + "validationError": "ग़लत या अपूर्ण पासफ़्रेज़" + }, + "register": { + "information": { + "color1": "प्रोफ़ाइल का पहला रंग", + "color2": "प्रोफ़ाइल का दूसरा रंग", + "header": "अपने डिवाइस के लिए एक नाम दर्ज करें और अपने पसंद का रंग और एक आइकन चुनें", + "icon": "आइकन", + "next": "अगला", + "title": "खाता संबंधी जानकारी" + } + }, + "trust": { + "failed": { + "text": "क्या आपने इसे सही ढंग से कॉन्फ़िगर किया?", + "title": "सर्वर तक पहुंचने में विफल" + }, + "host": "आप <0>{{hostname}} से कनेक्ट हो रहे हैं - खाता बनाने से पहले कृपया पुष्टि करें कि आप इस पर भरोसा करते हैं", + "no": "पीछे जाये", + "noHost": "सर्वर कॉन्फ़िगर नहीं किया गया है, इसलिए आप खाता नहीं बना सकते", + "noHostTitle": "सर्वर कॉन्फ़िगर नहीं है!", + "title": "क्या आपको इस सर्वर पर भरोसा है?", + "yes": "मुझे इस सर्वर पर भरोसा है" + }, + "verify": { + "description": "यह पुष्टि करने के लिए कि आपने इसे सहेज लिया है और अपना खाता बनाने के लिए कृपया अपना पहले का पासफ़्रेज़ दर्ज करें", + "invalidData": "डेटा मान्य नहीं है", + "noMatch": "पासफ़्रेज़ मेल नहीं खाता", + "passphraseLabel": "आपका 12-शब्दों वाला पासफ़्रेज़", + "recaptchaFailed": "कैप्चा सत्यापन विफल रहा", + "register": "खाता बनाएं", + "title": "अपने पासफ़्रेज़ की पुष्टि करें" + } + }, + "errors": { + "badge": "कुछ टूट गया है शायद", + "details": "गलतियों की जानकारी", + "reloadPage": "पृष्ठ को पुन: लोड करें", + "showError": "गलतियों का विवरण दिखाएँ", + "title": "हमें एक गलति का सामना करना पड़ा!" + }, + "footer": { + "legal": { + "disclaimer": "अस्वीकरण", + "disclaimerText": "मूवी-वेब किसी फ़ाइल को होस्ट नहीं करता है, यह केवल तृतीय पक्ष सेवाओं से लिंक करता है। कानूनी मुद्दों को फ़ाइल होस्ट और प्रदाताओं के साथ उठाया जाना चाहिए। मूवी-वेब वीडियो प्रदाताओं द्वारा दिखाई गई किसी भी मीडिया फ़ाइल के लिए ज़िम्मेदार नहीं है।" + }, + "links": { + "discord": "डीसकॉर्ड", + "dmca": "DMCA", + "github": "गिटहब" + }, + "tagline": "अपने पसंदीदा शो और फिल्में देखें, इस ओपन सोर्स स्ट्रीमिंग ऐप के साथ।" + }, + "global": { + "name": "मूवी-वेब", + "pages": { + "about": "साइट के बारे में", + "dmca": "DMCA", + "login": "लॉग इन", + "onboarding": "स्थापित करना", + "pagetitle": "{{title}} - मूवी-वेब", + "register": "नया खाता बनायें", + "settings": "सेटिंग्स" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "बुकमार्क" + }, + "continueWatching": { + "sectionTitle": "देखना जारी रखें" + }, + "mediaList": { + "stopEditing": "एडिट करना बंद करे" + }, + "search": { + "allResults": "बस यही है!", + "failed": "मीडिया ढूंढने में विफल, पुनः प्रयास करें!", + "loading": "लोड हो रहा है..।", + "noResults": "हमें कुछ नहीं मिला!", + "placeholder": { + "default": "क्या देखना चाहते हो?", + "extra": [ + "आप क्या अन्वेषण करना चाहते हैं?", + "आपकी वॉचलिस्ट में क्या है?", + "आपकी पसंदीदा फिल्म कौनसी है?", + "आपकी पसंदीदा सीरीज़ कौन सी है?" + ] + }, + "sectionTitle": "खोज के परिणाम" + }, + "titles": { + "day": { + "default": "आप आज शाम क्या देखना चाहेंगे?", + "extra": [ + "साहसी महसूस कर रहे हैं? जुरासिक पार्क शायद सबसे उत्तम विकल्प हो सकता है।" + ] + }, + "morning": { + "default": "आप आज सुबह को क्या देखना चाहेंगे?", + "extra": [ + "मैंने सुना है सूर्योदय से पहले ठीक है" + ] + }, + "night": { + "default": "आप आज रात को क्या देखना चाहेंगे?", + "extra": [ + "थके हुए हो? मैंने सुना एक्सोरसिस्ट अच्छी मूवी है।" + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "मूवी", + "show": "शृंखला" + }, + "unreleased": "रिलीज़ नहीं हुवा" + }, + "navigation": { + "banner": { + "offline": "अपना इंटरनेट संपर्क जांचे" + }, + "menu": { + "about": "हमारे बारे में", + "logout": "लॉग आउट", + "register": "क्लाउड से सिंक करें", + "settings": "सेटिंग्स", + "support": "सहायता" + } + }, + "notFound": { + "badge": "नहीं मिला", + "goHome": "घर वापिस जाइये", + "message": "हमने हर जगह देखा: डिब्बे के नीचे, कोठरी में, प्रॉक्सी के पीछे लेकिन अंततः वह पेज नहीं मिला जिसे आप ढूंढ रहे थे।", + "title": "वह पृष्ठ नहीं मिल सका" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "रद्द करना", + "confirm": "डिफ़ॉल्ट सेटअप का उपयोग करें", + "description": "डिफ़ॉल्ट सेटअप में सर्वोत्तम स्ट्रीम नहीं हैं और यह असहनीय रूप से धीमा हो सकता है।", + "title": "क्या आपको यकीन है?" + }, + "extension": { + "back": "वापस जाओ", + "explainer": "ब्राउज़र एक्सटेंशन का उपयोग करके, आप हमारे द्वारा प्रदान की जाने वाली सर्वोत्तम स्ट्रीम प्राप्त कर सकते हैं। बस एक साधारण इंस्टालेशन के साथ।", + "explainerIos": "दुर्भाग्य से, ब्राउज़र एक्सटेंशन iOS पर समर्थित नहीं है, दूसरा विकल्प चुनने के लिए वापस जाएं दबाएं।", + "extensionHelp": "यदि आपने एक्सटेंशन इंस्टॉल किया है लेकिन उसका पता नहीं चला है, तो अपने ब्राउज़र एक्सटेंशन मेनू के माध्यम से एक्सटेंशन खोलें और स्क्रीन पर दिए गए चरणों का पालन करें।", + "linkChrome": "Chrome एक्सटेंशन इंस्टॉल करें", + "linkFirefox": "Firefox एक्सटेंशन इंस्टॉल करें", + "notDetecting": "Chrome पर इंस्टॉल किया गया है, लेकिन साइट इसका पता नहीं लगा रही है? पृष्ठ को पुनः लोड करने का प्रयास करें!", + "notDetectingAction": "पृष्ठ पुनः लोड करें", + "status": { + "disallowed": "इस पृष्ठ के लिए एक्सटेंशन सक्षम नहीं है", + "disallowedAction": "एक्सटेंशन सक्षम", + "failed": "स्थिति का अनुरोध करने में विफल", + "loading": "आपके द्वारा एक्सटेंशन इंस्टॉल करने की प्रतीक्षा की जा रही है", + "outdated": "एक्सटेंशन संस्करण बहुत पुराना है", + "success": "एक्सटेंशन अपेक्षा के अनुरूप काम कर रहा है!" + }, + "submit": "जारी रखना", + "title": "आइए एक एक्सटेंशन से शुरू करें" + }, + "proxy": { + "back": "वापस जाओ", + "explainer": "प्रॉक्सी विधि से, आप स्वयं-सेवा प्रॉक्सी बनाकर बढ़िया गुणवत्ता वाली स्ट्रीम प्राप्त कर सकते हैं।", + "input": { + "errorConnection": "प्रॉक्सी से कनेक्ट नहीं हो सका", + "errorInvalidUrl": "मान्य यूआरएल नहीं", + "errorNotProxy": "एक प्रॉक्सी की उम्मीद थी लेकिन एक वेबसाइट मिली", + "label": "प्रॉक्सी यूआरएल", + "placeholder": "https://" + }, + "link": "પ્રોક્સી કેવી રીતે બનાવવી તે જાણો", + "submit": "प्रॉक्सी सबमिट करें", + "title": "आइए एक नई प्रॉक्सी बनाएं" + }, + "start": { + "explainer": "सर्वोत्तम संभव स्ट्रीम प्राप्त करने के लिए, आपको यह चुनना होगा कि आप किस स्ट्रीमिंग विधि का उपयोग करना चाहते हैं।", + "options": { + "default": { + "text": "मुझे अच्छी गुणवत्ता वाली स्ट्रीम नहीं चाहिए,<0 /> <1>डिफ़ॉल्ट सेटअप का उपयोग करें" + }, + "extension": { + "action": "एक्सटेंशन इंस्टॉल करें", + "description": "ब्राउज़र एक्सटेंशन इंस्टॉल करें और सर्वोत्तम स्रोतों तक पहुंच प्राप्त करें।", + "quality": "अच्छी गुणवत्ता", + "title": "ब्राउज़र एक्सटेंशन" + }, + "proxy": { + "action": "प्रॉक्सी सेटअप करें", + "description": "केवल 5 मिनट में एक प्रॉक्सी सेटअप करें और बेहतरीन स्रोतों तक पहुंच प्राप्त करें।", + "quality": "अच्छी गुणवत्ता", + "title": "कस्टम प्रॉक्सी" + } + }, + "title": "आइए आपको मूवी-वेब के साथ सेटअप करवाते हैं" + } + }, + "overlays": { + "close": "बंद करना" + }, + "player": { + "back": { + "default": "घर वापिस", + "short": "वापिस" + }, + "casting": { + "enabled": "डिवाइस पर कास्ट किया जा रहा है..।" + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "HLS प्लेलिस्ट लिंक कॉपी करें", + "disclaimer": "डाउनलोड सीधे प्रदाता से लिए जाते हैं। मूवी-वेब का इस पर नियंत्रण नहीं है कि डाउनलोड कैसे प्रदान किए जाते हैं।", + "downloadSubtitle": "वर्तमान उपशीर्षक डाउनलोड करें", + "downloadVideo": "वीडियो डाउनलोड करें", + "hlsDisclaimer": "डाउनलोड सीधे प्रदाता से लिए जाते हैं। मूवी-वेब का इस पर नियंत्रण नहीं है कि डाउनलोड कैसे प्रदान किए जाते हैं।

कृपया ध्यान दें कि आप एक HLS प्लेलिस्ट डाउनलोड कर रहे हैं, यदि आप उन्नत स्ट्रीमिंग प्रारूपों से परिचित नहीं हैं तो इसे डाउनलोड करने की अनुशंसा नहीं की जाती है। विभिन्न प्रारूपों के लिए अलग-अलग स्रोत आज़माएँ।", + "onAndroid": { + "1": "एंड्रॉइड पर डाउनलोड करने के लिए, डाउनलोड बटन पर क्लिक करें, फिर नए पेज पर, वीडियो पर टैप करके रखें, फिर save चुनें।", + "shortTitle": "डाउनलोड / एंड्रॉइड", + "title": "एंड्रॉइड पर डाउनलोड हो रहा है" + }, + "onIos": { + "1": "iOS पर डाउनलोड करने के लिए, डाउनलोड बटन पर क्लिक करें, फिर नए पेज पर पर क्लिक करें, फिर फ़ाइलों में सहेजें पर क्लिक करें।", + "shortTitle": "डाउनलोड / आईओएस", + "title": "आईओएस पर डाउनलोड हो रहा है" + }, + "onPc": { + "1": "पीसी पर, डाउनलोड बटन पर क्लिक करें, फिर नए पेज पर, वीडियो पर राइट क्लिक करें और वीडियो को इस रूप में सेव करें चुनें", + "shortTitle": "डाउनलोड / पीसी", + "title": "पीसी पर डाउनलोड हो रहा है" + }, + "title": "डाउनलोड" + }, + "episodes": { + "button": "एपिसोड", + "emptyState": "इस सीज़न में कोई एपिसोड नहीं है, बाद में दोबारा जाँचें!", + "episodeBadge": "E{{episode}}", + "loadingError": "सीज़न लोड करने में त्रुटि", + "loadingList": "लोड हो रहा है..।", + "loadingTitle": "लोड हो रहा है..।", + "unairedEpisodes": "इस सीज़न में एक या अधिक एपिसोड अक्षम कर दिए गए हैं क्योंकि वे अभी तक प्रसारित नहीं हुए हैं।" + }, + "playback": { + "speedLabel": "प्लेबैक गति", + "title": "प्लेबैक सेटिंग्स" + }, + "quality": { + "automaticLabel": "स्वचालित गुणवत्ता", + "hint": "आप विभिन्न गुणवत्ता विकल्प प्राप्त करने के लिए <0>स्रोत स्विचिंग का प्रयास कर सकते हैं।", + "iosNoQuality": "Apple द्वारा परिभाषित सीमाओं के कारण, इस स्रोत के लिए iOS पर गुणवत्ता चयन उपलब्ध नहीं है। आप विभिन्न गुणवत्ता विकल्प प्राप्त करने के लिए <0>किसी अन्य स्रोत पर स्विच करने का प्रयास कर सकते हैं।", + "title": "गुणवत्ता" + }, + "settings": { + "audioItem": "ऑडियो", + "downloadItem": "डाउनलोड", + "enableSubtitles": "उपशीर्षक सक्षम करें", + "experienceSection": "देखने का अनुभव", + "playbackItem": "प्लेबैक सेटिंग्स", + "qualityItem": "चित्र की गुणवत्ता", + "sourceItem": "वीडियो स्रोत", + "subtitleItem": "उपशीर्षक सेटिंग्स", + "videoSection": "वीडियो सेटिंग्स" + }, + "sources": { + "failed": { + "text": "किसी भी वीडियो को खोजने का प्रयास करते समय एक त्रुटि हुई, कृपया किसी भिन्न स्रोत का प्रयास करें।", + "title": "स्क्रैप करने में विफल" + }, + "noEmbeds": { + "text": "हम कोई एम्बेड नहीं ढूंढ पाए, कृपया कोई भिन्न स्रोत आज़माएँ।", + "title": "कोई एंबेड नहीं मिला" + }, + "noStream": { + "text": "इस स्रोत के पास इस फिल्म या शो के लिए कोई स्ट्रीम नहीं है।", + "title": "कोई धारा नहीं" + }, + "title": "स्रोत", + "unknownOption": "अज्ञात" + }, + "subtitles": { + "customChoice": "फ़ाइल ड्रॉप या अपलोड करें", + "customizeLabel": "अनुकूलित करें", + "dropSubtitleFile": "उपशीर्षक फ़ाइल यहां छोड़ें", + "offChoice": "बंद", + "settings": { + "backlink": "कस्टम उपशीर्षक", + "delay": "उपशीर्षक विलंब", + "fixCapitals": "पूंजीकरण ठीक करें" + }, + "title": "उपशीर्षक", + "unknownLanguage": "अज्ञात" + } + }, + "metadata": { + "api": { + "text": "एपीआई मेटाडेटा लोड नहीं हो सका, कृपया अपना इंटरनेट कनेक्शन जांचें।", + "title": "एपीआई मेटाडेटा लोड करने में विफल" + }, + "dmca": { + "badge": "निकाला गया", + "text": "निष्कासन नोटिस या कॉपीराइट दावे के कारण यह मीडिया अब उपलब्ध नहीं है।", + "title": "मीडिया हटा दिया गया है" + }, + "extensionPermission": { + "badge": "अनुमति अनुपलब्ध", + "button": "एक्सटेंशन का उपयोग करें", + "text": "आपके पास ब्राउज़र एक्सटेंशन है, लेकिन एक्सटेंशन का उपयोग शुरू करने के लिए हमें आपकी अनुमति की आवश्यकता है।", + "title": "एक्सटेंशन कॉन्फ़िगर करें" + }, + "failed": { + "badge": "असफल", + "homeButton": "घर जाओ", + "text": "टीएमडीबी से मीडिया का मेटाडेटा लोड नहीं किया जा सका। कृपया जांचें कि क्या आपके इंटरनेट कनेक्शन पर टीएमडीबी बंद है या अवरुद्ध है।", + "title": "मेटाडेटा लोड करने में विफल" + }, + "notFound": { + "badge": "नहीं मिला", + "homeButton": "घर वापिस", + "text": "हमें आपके द्वारा अनुरोधित मीडिया नहीं मिल सका। या तो इसे हटा दिया गया है या आपने यूआरएल के साथ छेड़छाड़ की है।", + "title": "वह मीडिया नहीं मिल सका।" + } + }, + "nextEpisode": { + "cancel": "रद्द करना", + "next": "अगले प्रकरण" + }, + "playbackError": { + "badge": "प्लेबैक त्रुटि", + "errors": { + "errorAborted": "उपयोगकर्ता के अनुरोध पर मीडिया को लाना रोक दिया गया था।", + "errorDecode": "पहले प्रयोग योग्य होने के लिए निर्धारित होने के बावजूद, मीडिया संसाधन को डीकोड करने का प्रयास करते समय एक त्रुटि उत्पन्न हुई, जिसके परिणामस्वरूप त्रुटि हुई।", + "errorGenericMedia": "अज्ञात मीडिया त्रुटि उत्पन्न हुई।", + "errorNetwork": "किसी प्रकार की नेटवर्क त्रुटि उत्पन्न हुई जिसके कारण मीडिया पहले से उपलब्ध होने के बावजूद सफलतापूर्वक प्राप्त नहीं हो सका।", + "errorNotSupported": "मीडिया या मीडिया प्रदाता ऑब्जेक्ट समर्थित नहीं है।" + }, + "homeButton": "घर जाओ", + "text": "मीडिया चलाने का प्रयास करते समय एक त्रुटि हुई. कृपया पुन: प्रयास करें।", + "title": "वीडियो चलाने में विफल!" + }, + "scraping": { + "extensionFailure": { + "badge": "एक्सटेंशन बन्द हें", + "enableExtension": "एक्सटेंशन सक्षम करें", + "homeButton": "घर जाओ", + "text": "आपने मूवी-वेब एक्सटेंशन इंस्टॉल कर लिया है. इसका उपयोग शुरू करने के लिए, आपको इस साइट के लिए एक्सटेंशन सक्षम करना होगा।", + "title": "कृपया एक्सटेंशनको सक्षम करें" + }, + "items": { + "failure": "त्रुटि हुई", + "notFound": "वीडियो नहीं है", + "pending": "वीडियो की जांच की जा रही है..।" + }, + "notFound": { + "badge": "नहीं मिला", + "detailsButton": "प्रदर्शन का विवरण", + "homeButton": "घर जाओ", + "text": "हमने अपने प्रदाताओं के माध्यम से खोज की है और आपको वह मीडिया नहीं मिल सका जिसकी आप तलाश कर रहे हैं! हम मीडिया की मेजबानी नहीं करते हैं और जो उपलब्ध है उस पर हमारा कोई नियंत्रण नहीं है। अधिक जानकारी के लिए कृपया नीचे 'विवरण दिखाएं' पर क्लिक करें।", + "title": "हमें वह नहीं मिला" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} समय बचा है • ख़तम होगा {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "कृपया दाईं ओर दिए गए कैप्चा को पूरा करके सत्यापित करें कि आप इंसान हैं। यह मूवी-वेब को सुरक्षित रखने के लिए है!", + "error": "आपकी मानवता को सत्यापित करने में विफल. कृपया पुन: प्रयास करें।", + "title": "हमें यह सत्यापित करने की आवश्यकता है कि आप इंसान हैं।", + "verifyingHumanity": "आपकी मानवता का सत्यापन..।" + } + }, + "screens": { + "dmca": { + "text": "मूवी-वेब के DMCA संपर्क पृष्ठ में आपका स्वागत है! हम बौद्धिक संपदा अधिकारों का सम्मान करते हैं और किसी भी कॉपीराइट संबंधी चिंताओं का शीघ्र समाधान करना चाहते हैं। यदि आपको लगता है कि आपके कॉपीराइट किए गए कार्य का हमारे प्लेटफ़ॉर्म पर अनुचित तरीके से उपयोग किया गया है, तो कृपया नीचे दिए गए ईमेल पर एक विस्तृत DMCA नोटिस भेजें। कृपया कॉपीराइट सामग्री का विवरण, अपना संपर्क विवरण और सद्भावना विश्वास का एक बयान शामिल करें। हम इन मामलों को तुरंत हल करने के लिए प्रतिबद्ध हैं और मूवी-वेब को रचनात्मकता और कॉपीराइट का सम्मान करने वाला स्थान बनाए रखने में आपके सहयोग की सराहना करते हैं।", + "title": "DMCA" + }, + "loadingApp": "एप्लिकेशन लोड हो रहा है", + "loadingUser": "आपकी प्रोफ़ाइल लोड हो रही है", + "loadingUserError": { + "logout": "लॉग आउट", + "reset": "कस्टम सर्वर रीसेट करें", + "text": "आपकी प्रोफ़ाइल लोड करने में विफल", + "textWithReset": "आपके कस्टम सर्वर से आपकी प्रोफ़ाइल लोड करने में विफल, डिफ़ॉल्ट सर्वर पर वापस रीसेट करना चाहते हैं?" + }, + "migration": { + "failed": "आपका डेटा स्थानांतरित करने में विफल।", + "inProgress": "कृपया रुकें, हम आपका डेटा स्थानांतरित कर रहे हैं। इसमें ज्यादा समय नहीं लगना चाहिए।" + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "डिवाइस का नाम", + "deviceNamePlaceholder": "निजी फ़ोन", + "editProfile": "संपादन करना", + "logoutButton": "लॉग आउट" + }, + "actions": { + "delete": { + "button": "खाता हटा दो", + "confirmButton": "खाता हटा दो", + "confirmDescription": "क्या आप इस खाते को हटाने के लिए सुनिश्चित हैं? आपका सारा डेटा खो जाएगा!", + "confirmTitle": "क्या आपको यकीन है?", + "text": "यह क्रिया अपरिवर्तनीय है. सारा डेटा हटा दिया जाएगा और कुछ भी पुनर्प्राप्त नहीं किया जा सकेगा।", + "title": "खाता हटा दो" + }, + "title": "कार्रवाई" + }, + "devices": { + "deviceNameLabel": "डिवाइस का नाम", + "failed": "सत्र लोड करने में विफल", + "removeDevice": "निकालना", + "title": "उपकरण" + }, + "profile": { + "finish": "संपादन समाप्त करें", + "firstColor": "प्रोफ़ाइल का रंग एक", + "secondColor": "प्रोफ़ाइल रंग दो", + "title": "प्रोफाइल तस्वीर को संपादित करें", + "userIcon": "आइकन" + }, + "register": { + "cta": "शुरू हो जाओ", + "text": "अपनी प्रगति को उपकरणों के बीच साझा करें और उन्हें समन्वयित रखें।", + "title": "क्लाउड से सिंक करें" + }, + "title": "खाता" + }, + "appearance": { + "activeTheme": "सक्रिय", + "themes": { + "blue": "नीला", + "default": "गलती करना", + "gray": "स्लेटी", + "red": "लाल", + "teal": "टील" + }, + "title": "उपस्थिति" + }, + "connections": { + "server": { + "description": "यदि आप अपना डेटा संग्रहीत करने के लिए कस्टम बैकएंड से कनेक्ट करना चाहते हैं, तो इसे सक्षम करें और URL प्रदान करें। <0>निर्देश।", + "label": "कस्टम सर्वर", + "urlLabel": "कस्टम सर्वर यूआरएल" + }, + "setup": { + "doSetup": "सेटअप करें", + "errorStatus": { + "description": "ऐसा लगता है कि इस सेटअप में एक या अधिक आइटम पर आपके ध्यान की आवश्यकता है।", + "title": "किसी चीज़ पर आपका ध्यान चाहिए" + }, + "itemError": "इस सेटिंग में कुछ गड़बड़ है। इसे ठीक करने के लिए फिर से सेटअप से गुजरें।", + "items": { + "default": "डिफ़ॉल्ट सेटअप", + "extension": "विस्तार", + "proxy": "कस्टम प्रॉक्सी" + }, + "redoSetup": "सेटअप पुनः करें", + "successStatus": { + "description": "अपना पसंदीदा मीडिया देखना शुरू करने के लिए सभी चीज़ें मौजूद हैं।", + "title": "सब कुछ व्यवस्थित है!" + }, + "unsetStatus": { + "description": "सेटअप प्रक्रिया शुरू करने के लिए कृपया दाईं ओर बटन पर क्लिक करें।", + "title": "आप सेटअप से नहीं गुजरे हैं" + } + }, + "title": "सम्बन्ध", + "workers": { + "addButton": "नया कार्यकर्ता जोड़ें", + "description": "एप्लिकेशन को कार्यशील बनाने के लिए, सभी ट्रैफ़िक को प्रॉक्सी के माध्यम से रूट किया जाता है। यदि आप अपने स्वयं के श्रमिकों को लाना चाहते हैं तो इसे सक्षम करें। <0>निर्देश।", + "emptyState": "अभी तक कोई कर्मचारी नहीं, नीचे एक जोड़ें", + "label": "कस्टम प्रॉक्सी कार्यकर्ताओं का उपयोग करें", + "urlLabel": "कार्यकर्ता यूआरएल", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "अनुप्रयोग भाषा", + "languageDescription": "भाषा संपूर्ण अनुप्रयोग पर लागू होती है।", + "thumbnail": "थंबनेल जनरेट करें", + "thumbnailDescription": "अधिकांश समय, वीडियो में थंबनेल नहीं होते हैं। आप उन्हें तुरंत उत्पन्न करने के लिए इस सेटिंग को सक्षम कर सकते हैं लेकिन वे आपके वीडियो को धीमा कर सकते हैं।", + "thumbnailLabel": "थंबनेल जनरेट करें", + "title": "पसंद" + }, + "reset": "रीसेट", + "save": "सेव", + "sidebar": { + "info": { + "appVersion": "एप्लिकेशन वेरीज़न", + "backendUrl": "बैकएंड यूआरएल", + "backendVersion": "बैकएंड संस्करण", + "hostname": "होस्ट का नाम", + "insecure": "असुरक्षित", + "notLoggedIn": "आपने लॉग - इन नहीं किया", + "secure": "सुरक्षित", + "title": "ऐप की जानकारी", + "unknownVersion": "अज्ञात", + "userId": "उपयोगकर्ता पहचान" + } + }, + "subtitles": { + "backgroundBlurLabel": "पृष्ठभूमि धुंधला", + "backgroundLabel": "पृष्ठभूमि अस्पष्टता", + "colorLabel": "रंग", + "previewQuote": "मुझे डरना नहीं चाहिए. डर मन हत्यारा है।", + "textSizeLabel": "टेक्स्ट का साइज़", + "title": "उपशीर्षक" + }, + "unsaved": "आपके पास सहेजे नहीं गए परिवर्तन हैं" + } +} diff --git a/src/assets/locales/id.json b/src/assets/locales/id.json new file mode 100644 index 0000000..ad6386e --- /dev/null +++ b/src/assets/locales/id.json @@ -0,0 +1,489 @@ +{ + "about": { + "description": "SkoolTV adalah website yang mengumpulkan sumber media streaming dari internet. Didesain khusus dengan pendekatan minimalis agar mempermudah konsumsi konten.", + "faqTitle": "Pertanyaan umum", + "q1": { + "body": "SkoolTV tidak menyimpan berkas media apapun. Ketika anda mengklik sesuatu untuk ditonton, aplikasi akan mencari berkas media di internet (saat media dimuat dan pada tab 'sumber media' anda dapat melihat sumber mana yang digunakan). SkoolTV tidak pernah mengunggah media apapun, semua media didapat melalui mekanisme pencarian di internet.", + "title": "Dari mana konten berasal?" + }, + "q2": { + "body": "Kami tidak menerima permintaan penambahan serial televisi atau film, SkoolTV tidak mengelola konten apapun. Semua konten ditonton melalui sumber-sumber dari internet.", + "title": "Di mana saya dapat meminta serial televisi atau film untuk ditambahkan?" + }, + "q3": { + "body": "Hasil pencarian aplikasi ini menggunakan API milik The Movie Database (TMDB) dan menampilkan semua hasil pencarian terlepas dari apakah sumber media tersebut dapat ditemukan di penyedia pihak ketiga atau tidak.", + "title": "Hasil pencarian menampilkan serial televisi atau film yang saya cari, tapi mengapa saya tidak bisa memutarnya?" + }, + "title": "Tentang SkoolTV" + }, + "actions": { + "copied": "Disalin", + "copy": "Salin" + }, + "auth": { + "createAccount": "Belum memiliki akun? <0>Buat akun.", + "deviceNameLabel": "Nama perangkat", + "deviceNamePlaceholder": "Perangkat personal", + "generate": { + "description": "Kombinasi kata ini berfungsi sebagai nama pengguna sekaligus kata sandi anda. Pastikan untuk menyimpannya dengan aman karena anda memerlukannya untuk masuk ke akun anda", + "next": "Saya sudah menyimpan kombinasi kata", + "passphraseFrameLabel": "Kombinasi kata", + "title": "Kombinasi kata Anda" + }, + "hasAccount": "Sudah memiliki akun? <0>Masuk disini.", + "login": { + "description": "Mohon masukkan kombinasi kata anda untuk masuk ke akun Anda", + "deviceLengthError": "Mohon masukkan nama perangkat", + "passphraseLabel": "12 kombinasi kata unik", + "passphrasePlaceholder": "Kombinasi kata", + "submit": "Masuk", + "title": "Masuk ke akun Anda", + "validationError": "Kombinasi kata salah atau tidak lengkap" + }, + "register": { + "information": { + "color1": "Warna profil pertama", + "color2": "Warna profil kedua", + "header": "Masukkan nama perangkat anda lalu pilih warna latar belakang dan ikon pengguna yang ingin anda gunakan", + "icon": "Ikon pengguna", + "next": "Berikutnya", + "title": "Informasi akun" + } + }, + "trust": { + "failed": { + "text": "Apakah Anda mengkonfigurasi server dengan benar?", + "title": "Gagal terhubung dengan server" + }, + "host": "Anda ingin terhubung ke <0>{{hostname}} - mohon konfirmasi Anda mempercayai server ini sebelum Anda membuat akun", + "no": "Kembali", + "noHost": "Server belum dikonfigurasi, maka dari itu Anda tidak dapat membuat akun", + "noHostTitle": "Server belum dikonfigurasi!", + "title": "Apakah Anda mempercayai server ini?", + "yes": "Saya percaya server ini" + }, + "verify": { + "description": "Mohon masukkan kombinasi kata pribadi Anda sebelumnya untuk mengonfirmasi bahwa Anda telah menyimpannya untuk melanjutkan proses pembuatan akun", + "invalidData": "Data tidak valid", + "noMatch": "Kombinasi kata tidak cocok", + "passphraseLabel": "12 kombinasi kata Anda", + "recaptchaFailed": "Validasi reCaptcha gagal", + "register": "Buat akun", + "title": "Konfirmasi kombinasi kata Anda" + } + }, + "errors": { + "badge": "Terjadi masalah", + "details": "Rincian kesalahan", + "reloadPage": "Muat ulang halaman", + "showError": "Lihat rincian kesalahan", + "title": "Kami mengalami galat!" + }, + "footer": { + "legal": { + "disclaimer": "Sanggahan", + "disclaimerText": "SkoolTV tidak menyimpan berkas media apapun, aplikasi ini hanya menampilkan tautan dari pihak ketiga. Sengketa hukum harus diajukan langsung kepada penyedia pihak ketiga. SkoolTV tidak bertanggung jawab atas berkas media yang ditampilkan oleh penyedia pihak ketiga." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Tonton serial televisi dan film favorit anda dengan aplikasi streaming sumber terbuka ini." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Tentang", + "dmca": "DMCA", + "login": "Masuk", + "onboarding": "Penyiapan", + "pagetitle": "{{title}} - SkoolTV", + "register": "Daftar", + "settings": "Pengaturan" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Penanda" + }, + "continueWatching": { + "sectionTitle": "Lanjut menonton" + }, + "mediaList": { + "stopEditing": "Berhenti menyunting" + }, + "search": { + "allResults": "Hanya itu yang kami punya!", + "failed": "Gagal menemukan media, coba lagi!", + "loading": "Memuat...", + "noResults": "Kami tidak dapat menemukan apapun!", + "placeholder": { + "default": "Apa yang ingin anda tonton?", + "extra": [ + "Apa yang ingin kamu jelajahi?", + "Ada apa di daftar tontonmu?", + "Apa film favoritmu?", + "Apa serial favoritmu?" + ] + }, + "sectionTitle": "Hasil pencarian" + }, + "titles": { + "day": { + "default": "Apa yang ingin anda tonton sore ini?", + "extra": [ + "Merasa suka bertualang? Jurassic Park mungkin pilihan cocok untuk Anda." + ] + }, + "morning": { + "default": "Apa yang ingin anda tonton pagi ini?", + "extra": ["Kayaknya film Before Sunrise bagus deh"] + }, + "night": { + "default": "Apa yang ingin Anda tonton malam ini?", + "extra": ["Capek? Saya dengar The Exocist bagus."] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Serial TV" + }, + "unreleased": "Belum dirilis" + }, + "navigation": { + "banner": { + "offline": "Periksa koneksi internet Anda" + }, + "menu": { + "about": "Tentang kami", + "logout": "Keluar", + "register": "Sinkronkan ke sudo-cloud", + "settings": "Pengaturan", + "support": "Bantuan" + } + }, + "notFound": { + "badge": "Tidak ditemukan", + "goHome": "Kembali", + "message": "Kami sudah mencari dimana-mana: di bawah tempat sampah, di lemari, di belakang server proxy, tetapi tidak dapat menemukan halaman yang Anda cari.", + "title": "Gagal menemukan halaman" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Batal", + "confirm": "Gunakan pengaturan bawaan", + "description": "Pengaturan bawaan tidak memiliki streaming terbaik dan bisa menjadi sangat lambat.", + "title": "Apa Anda yakin?" + }, + "extension": { + "back": "Kembali", + "explainer": "Menggunakan ekstensi browser, Anda dapat mendapatkan streaming terbaik yang kami tawarkan. Dengan instalasi sederhana.", + "explainerIos": "Sayangnya, ekstensi browser tidak didukung di iOS, Tekan Kembali untuk memilih opsi lain.", + "extensionHelp": "Jika Anda telah menginstal ekstensi tetapi tidak terdeteksi, buka ekstensi melalui menu ekstensi browser Anda dan ikuti instruksi di layar.", + "linkChrome": "Instal ekstensi Chrome", + "linkFirefox": "Instal ekstensi Firefox", + "notDetecting": "Terinstal di Chrome tetapi situs tidak mendeteksinya? Coba muat ulang halaman!", + "notDetectingAction": "Muat ulang halaman", + "status": { + "disallowed": "Ekstensi tidak diaktifkan untuk halaman ini", + "disallowedAction": "Aktifkan ekstensi", + "failed": "Gagal meminta status", + "loading": "Menunggu Anda menginstal ekstensi", + "outdated": "Versi ekstensi terlalu tua", + "success": "Ekstensi berkerja sesuai harapan!" + }, + "submit": "Lanjutkan", + "title": "Mari mulai dengan ekstensi" + }, + "proxy": { + "back": "Kembali", + "explainer": "Menggunakan metode proxy, Anda dapat mendapatkan streaming berkualitas baik dengan membuat layanan proxy mandiri.", + "input": { + "errorConnection": "Tidak dapat terhubung ke proxy", + "errorInvalidUrl": "URL tidak valid", + "errorNotProxy": "Mengharapkan proxy tapi menerima situs", + "label": "URL proxy", + "placeholder": "https://" + }, + "link": "Belajar cara membuat proxy", + "title": "Mari buat proxy baru" + }, + "start": { + "explainer": "Untuk mendapatkan streaming terbaik, Anda perlu memilih metode streaming yang Anda ingin gunakan.", + "options": { + "default": { + "text": "Saya tidak menginginkan streaming kualitas baik, <0 /> <1>gunakan pengaturan bawaan" + }, + "extension": { + "action": "Instal ekstensi", + "description": "Instal ekstensi browser dan dapatkan akses ke sumber terbaik.", + "quality": "Kualitas terbaik", + "title": "Ekstensi browser" + }, + "proxy": { + "action": "Atur proxy", + "description": "Atur proxy dalam hanya 5 menit dan dapatkan akses ke sumber terbaik.", + "quality": "Kualitas baik" + } + } + } + }, + "overlays": { + "close": "Tutup" + }, + "player": { + "back": { + "default": "Kembali", + "short": "Kembali" + }, + "casting": { + "enabled": "Casting ke perangkat..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Salin tautan daftar putar HLS", + "disclaimer": "Tautan unduhan diambil langsung dari penyedia pihak ketiga. Aplikasi ini tidak memiliki kendali bagaimana unduhan disediakan.", + "downloadSubtitle": "Unduh subtitle saat ini", + "downloadVideo": "Unduh media", + "hlsDisclaimer": "Unduhan didapatkan langsung dari penyedia. SkoolTV tidak memiliki kendali bagaimana unduan disediakan.

Harap diperhatikan bahwa Anda mengunduh daftar putar HLS, ini tidak direkomendasikan untuk diunduh jika Anda tidak terbiasa dengan format streaming tingkat lanjutCoba sumber berbeda untuk format berbeda.", + "onAndroid": { + "1": "Untuk mengunduh di Android, klik tombol unduh, lalu di halaman baru klik dan tahan pada video, lalu pilih simpan.", + "shortTitle": "Unduh / Android", + "title": "Unduh di Android" + }, + "onIos": { + "1": "Untuk mengunduh di iOS, klik tombol unduh, lalu di halaman baru, klik , lalu Save to Files .", + "shortTitle": "Unduh / iOS", + "title": "Unduh di iOS" + }, + "onPc": { + "1": "Untuk mengunduh di PC, klik tombol unduh, lalu di halaman baru klik kanan video, dan pilih Save video as", + "shortTitle": "Unduh / PC", + "title": "Unduh di PC" + }, + "title": "Unduh" + }, + "episodes": { + "button": "Episode", + "emptyState": "Tidak ada episode di season ini, periksa kembali nanti!", + "episodeBadge": "E{{episode}}", + "loadingError": "Gagal memuat season", + "loadingList": "Memuat...", + "loadingTitle": "Memuat...", + "unairedEpisodes": "Satu atau lebih episode dalam season ini telah dinonaktifkan karena mereka belum ditayangkan." + }, + "playback": { + "speedLabel": "Kecepatan pemutar", + "title": "Pengaturan pemutar" + }, + "quality": { + "automaticLabel": "Otomatis", + "hint": "Anda dapat mencoba <0>mengganti sumber untuk mendapatkan opsi kualitas yang berbeda.", + "iosNoQuality": "Karena keterbatasan dari Apple, opsi kualitas pada sumber ini tidak tersedia untuk iOS. Anda dapat mencoba <0>mengganti sumber untuk mendapatkan opsi kualitas yang berbeda.", + "title": "Kualitas" + }, + "settings": { + "downloadItem": "Unduh", + "enableSubtitles": "Aktifkan subtitle", + "experienceSection": "Pengaturan tambahan", + "playbackItem": "Pengaturan pemutar", + "qualityItem": "Kualitas", + "sourceItem": "Sumber media", + "subtitleItem": "Pengaturan subtitle", + "videoSection": "Pengaturan media" + }, + "sources": { + "failed": { + "text": "Terjadi galat saat mencoba mencari media, mohon pilih sumber lain.", + "title": "Gagal memuat data" + }, + "noEmbeds": { + "text": "Kami tidak dapat menemukan tautan, mohon pilih sumber lain.", + "title": "Tautan tidak ditemukan" + }, + "noStream": { + "text": "Sumber ini tidak memiliki media untuk film atau seri yang Anda cari.", + "title": "Tidak ada media" + }, + "title": "Sumber", + "unknownOption": "Tidak diketahui" + }, + "subtitles": { + "customChoice": "Jatuhkan atau unggah berkas", + "customizeLabel": "Sesuaikan", + "offChoice": "Matikan", + "settings": { + "backlink": "Subtitle khusus", + "delay": "Penundaan subtitle", + "fixCapitals": "Perbaiki kapitalisasi" + }, + "title": "Subtitle", + "unknownLanguage": "Tidak diketahui" + } + }, + "metadata": { + "failed": { + "badge": "Gagal", + "homeButton": "Kembali", + "text": "Tidak dapat memuat metadata dari TMDB. Mohon periksa apakah TMDB sedang nonaktif atau diblokir pada koneksi internet anda.", + "title": "Gagal memuat metadata" + }, + "notFound": { + "badge": "Tidak ditemukan", + "homeButton": "Kembali", + "text": "Kami tidak dapat menemukan media yang anda cari. Media mungkin sudah dihapus atau URL yang anda masukan salah.", + "title": "Tidak dapat menemukan media." + } + }, + "nextEpisode": { + "cancel": "Batal", + "next": "Episode selanjutnya" + }, + "playbackError": { + "badge": "Galat pemutar", + "errors": { + "errorAborted": "Proses pemuatan media dibatalkan oleh permintaan penguna.", + "errorDecode": "Meskipun sebelumnya media diputuskan dapat digunakan, terjadi masalah saat mencoba memutar berkas media, yang mengakibatkan terjadinya eror.", + "errorGenericMedia": "Terjadi masalah yang tidak diketahui pada media.", + "errorNetwork": "Terjadi kesalahan pada jaringan yang menyebabkan media gagal dimuat, meskipun sebelumnya berhasil.", + "errorNotSupported": "Berkas media atau objek penyedia media tidak didukung." + }, + "homeButton": "Kembali", + "text": "Terjadi masalah saat mencoba memutar media. Mohon coba lagi.", + "title": "Gagal memutar media!" + }, + "scraping": { + "items": { + "failure": "Terjadi masalah", + "notFound": "Media tidak ditemukan", + "pending": "Mencari media..." + }, + "notFound": { + "badge": "Tidak ditemukan", + "detailsButton": "Lihat detail", + "homeButton": "Kembali", + "text": "Kami sudah mencari ke semua penyedia yang kami miliki dan gagal menemukan media yang anda cari! Kami tidak menyimpan berkas media dan tidak memiliki kontrol atas apa yang tersedia. Periksa tombol 'Lihat detail' dibawah ini untuk informasi lebih lanjut.", + "title": "Kami tidak dapat menemukannya" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} tersisa • Selesai pada pukul {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + } + }, + "screens": { + "dmca": { + "text": "Selamat datang di halaman kontak DMCA SkoolTV! Kami menghormati hak kekayaan intelektual dan ingin menangani masalah hak cipta dengan cepat. Jika anda yakin bahwa karya berhak cipta anda telah digunakan secara tidak benar di platform kami, silakan kirim pemberitahuan DMCA secara terperinci ke email di bawah ini. Mohon sertakan deskripsi materi berhak cipta, detail kontak anda, dan pernyataan itikad baik. Kami berkomitmen untuk menyelesaikan masalah ini sesegera mungkin dan kami menghargai kerja sama anda dalam menjaga SkoolTV sebagai tempat yang menghormati kreativitas dan hak cipta.", + "title": "DMCA" + }, + "loadingApp": "Memuat aplikasi", + "loadingUser": "Memuat profil anda", + "loadingUserError": { + "logout": "Keluar", + "reset": "Reset server khusus", + "text": "Gagal memuat profil anda", + "textWithReset": "Gagal memuat profil anda dari server khusus yang anda pilih, ingin kembali ke server default?" + }, + "migration": { + "failed": "Gagal memigrasi data anda.", + "inProgress": "Mohon tunggu, kami sedang memigrasi data anda. Ini tidak akan memakan waktu lama." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nama perangkat", + "deviceNamePlaceholder": "Ponsel personal", + "editProfile": "Ubah", + "logoutButton": "Keluar" + }, + "actions": { + "delete": { + "button": "Hapus akun", + "confirmButton": "Hapus akun", + "confirmDescription": "Apakah anda yakin ingin menghapus akun anda? Seluruh data anda akan hilang!", + "confirmTitle": "Apakah anda yakin?", + "text": "Tindakan ini tidak dapat dibatalkan. Seluruh data akan dihapus dan tidak dapat dipulihkan.", + "title": "Hapus akun" + }, + "title": "Tindakan" + }, + "devices": { + "deviceNameLabel": "Nama perangkat", + "failed": "Gagal memuat sesi", + "removeDevice": "Hapus", + "title": "Perangkat" + }, + "profile": { + "finish": "Selesai mengubah", + "firstColor": "Gradasi warna profil pertama", + "secondColor": "Gradasi warna profil kedua", + "title": "Ubah foto profil", + "userIcon": "Ikon pengguna" + }, + "register": { + "cta": "Memulai", + "text": "Bagikan dan sinkronkan antar perangkat progres tontonan anda.", + "title": "Sinkronkan ke sudo-cloud" + }, + "title": "Akun" + }, + "appearance": { + "activeTheme": "Aktif", + "themes": { + "blue": "Biru", + "default": "Default", + "gray": "Abu", + "red": "Merah", + "teal": "Hijau" + }, + "title": "Tampilan" + }, + "connections": { + "server": { + "description": "Jika anda ingin menghubungkan dengan backend khusus untuk menyimpan data, hidupkan ini dan masukkan URL-nya.", + "label": "Server khusus", + "urlLabel": "URL server khusus" + }, + "title": "Koneksi", + "workers": { + "addButton": "Tambah worker baru", + "description": "Agar aplikasi dapat bekerja, seluruh koneksi dialihkan menggunakan proxy. Hidupkan ini jika anda ingin menggunakan worker khusus.", + "emptyState": "Belum ada worker, tambahkan dibawah", + "label": "Gunakan proxy worker khusus", + "urlLabel": "URL worker", + "urlPlaceholder": "https://" + } + }, + "reset": "Reset", + "save": "Simpan", + "sidebar": { + "info": { + "appVersion": "Versi aplikasi", + "backendUrl": "URL Backend", + "backendVersion": "Versi Backend", + "hostname": "Nama host", + "insecure": "Tidak aman", + "notLoggedIn": "Anda belum masuk ke akun anda", + "secure": "Aman", + "title": "Informasi aplikasi", + "unknownVersion": "Tidak diketahui", + "userId": "ID pengguna" + } + }, + "subtitles": { + "backgroundLabel": "Transparansi latar belakang", + "colorLabel": "Warna teks", + "previewQuote": "Jangan takut. Ketakutan adalah pembunuh pikiran.", + "textSizeLabel": "Ukuran teks", + "title": "Subtitle" + }, + "unsaved": "Anda memiliki perubahan yang belum disimpan" + } +} diff --git a/src/assets/locales/is-IS.json b/src/assets/locales/is-IS.json new file mode 100644 index 0000000..a7c092b --- /dev/null +++ b/src/assets/locales/is-IS.json @@ -0,0 +1,546 @@ +{ + "about": { + "description": "SkoolTV er vefforrit sem leitar á netinu að straumum. Markmið liðsins er naumhyggju nálgun á að horfa á efni.", + "faqTitle": "Algengar spurningar", + "q1": { + "body": "SkoolTV hýsir ekki neitt efni. Þegar þú ýtir á eitthvað til að horfa á, leitað er á netinu fyrir það efni (Þú getur séð hvaða heimild við erum að nota á hleðslu skjánum og í 'myndbands heimildir' flipanum). Skrár eru aldrei settar in af SkoolTV, allt er í gegnum leitarvél.", + "title": "Hvaðan kemur efnið?" + }, + "q2": { + "body": "Þú getur ekki beðið um þætti eða myndir, SkoolTV stýrir ekki neinu efni. Allt efni er skoðað í gegnum heimildir á netinu.", + "title": "Hvar get ég beðið um þætti eða myndir?" + }, + "q3": { + "body": "Leitarniðurstöður okkar eru knúnar af The Movie Database (TMDB) og eru sýndar þótt að heimildir okkar hafa ekki efnið.", + "title": "Leitarniðurstöðurnar sýna þættina eða myndina, af hverju get ég ekki spilað það?" + }, + "title": "Um SkoolTV" + }, + "actions": { + "copied": "Afritað", + "copy": "Afrita" + }, + "auth": { + "createAccount": "Hefurðu ekki reikning ennþá? <0>Búðu til reikning.", + "deviceNameLabel": "Nafn tækis", + "deviceNamePlaceholder": "Einkasími", + "generate": { + "description": "Þitt lykilorð lætur eins og notandanafn og lykilorð. Vertu viss um að halda því öruggu út að þú munt þurfa að nota það til að komast inn í reikningin þinn", + "next": "Ég hef vistað lykilorðið mitt", + "passphraseFrameLabel": "Lykilorð", + "title": "Þitt lykilorð" + }, + "hasAccount": "Hefurðu reikning nú þegar? <0>Skráðu þig inn hér.", + "login": { + "description": "Vinsamlegast sláðu inn lykilorðið þitt til þess að skrá þig inn í reikningin þinn", + "deviceLengthError": "Vinsamlegast settu inn nafn fyrir tækið þitt", + "passphraseLabel": "12-Orða lykilorð", + "passphrasePlaceholder": "Lykilorð", + "submit": "Skrá inn", + "title": "Skráðu þig inn í reikningin þinn", + "validationError": "Vitlaust eða óklárað lykilorð" + }, + "register": { + "information": { + "color1": "Prófíl litur eitt", + "color2": "Prófíl litur tvö", + "header": "Sláðu inn nafn fyrir tækið þitt og veldu liti og notanda tákn að þínu vali", + "icon": "Notanda tákn", + "next": "Næst", + "title": "Reiknings upplýsingar" + } + }, + "trust": { + "failed": { + "text": "Stilltirðu það rétt?", + "title": "Náðist ekki í netþjón" + }, + "host": "Þú ert að tengjast við <0>{{hostname}} - vinsamlegast staðfestu að þú treystir því áður en þú býrð til reikning", + "no": "Fara til baka", + "noHost": "Netjónninn hefur ekki verið stilltur, þess vegna getur þú ekki búið til reikning", + "noHostTitle": "Netþjónn ekki stilltur!", + "title": "Treystir þú þessum netþjóni?", + "yes": "Ég treysti þessum netþjóni" + }, + "verify": { + "description": "Vinsamlegst sláðu inn lykilorðið þitt frá því áðan til þess að staðfesta að þú hefur vistað það og til að stofna nýjan reikning", + "invalidData": "Gögn eru ekki gild", + "noMatch": "Lykilorð passar ekki saman", + "passphraseLabel": "Þitt 12-orða lykilorð", + "recaptchaFailed": "ReCaptcha staðfesting mistókst", + "register": "Stofna reikning", + "title": "Staðfestu þitt lykilorð" + } + }, + "errors": { + "badge": "Það bilaði", + "details": "Villu upplýsingar", + "reloadPage": "Endurhlaðaðu vefsíðuna", + "showError": "Sýna villu upplýsingar", + "title": "Við lentum í villu!" + }, + "footer": { + "legal": { + "disclaimer": "Fyrirvari", + "disclaimerText": "SkoolTV hýsir engar skrár, það tengist eingöngu þjónustu þriðja aðila. Lagleg atriði ættu að vera rædd við skráarhýsinga og veitanda. SkoolTV er ekki ábyrg fyrir neinum skrám sýndar af myndbands veitöndum." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Horfðu á uppáhalds þætti og myndirnar þínar með þessu opna hugbúnaða forriti." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Um", + "dmca": "DMCA", + "login": "Skrá inn", + "onboarding": "Setja upp", + "pagetitle": "{{title}} - SkoolTV", + "register": "Skrá", + "settings": "Stillingar" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Bókamerki" + }, + "continueWatching": { + "sectionTitle": "Haltu Áfram Að Horfa" + }, + "mediaList": { + "stopEditing": "Hætta að breyta" + }, + "search": { + "allResults": "Þetta er allt sem við höfum!", + "failed": "Mostókst að finna miðil, reyndu aftur!", + "loading": "Hlaðið...", + "noResults": "Við gátum ekki fundið neitt!", + "placeholder": { + "default": "Hvað viltu horfa á?", + "extra": [ + "Hvað viltu kanna?", + "Hvað er á áhorfslistanum þínum?", + "Hvað er uppáhalds bíómyndin þín?", + "Hvað er uppáhalds þáttaröðin þín?" + ] + }, + "sectionTitle": "Leitar niðurstöður" + }, + "titles": { + "day": { + "default": "Hvað myndirðu vilja horfa á þetta kvöldið?", + "extra": [ + "Fynnst þér þú vera ævintýralegur? Jurrasic Park gæti verið fullkomna valið." + ] + }, + "morning": { + "default": "Hvað myndirðu vilja horfa á þessum morgni?", + "extra": [ + "Ég heyrði að Before Sunrise sé góð" + ] + }, + "night": { + "default": "Hvað myndirðu vilja horfa á í nótt?", + "extra": [ + "Þreytt? Ég heyrði að The Exorcist sé góð." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} Þ{{episode}}", + "types": { + "movie": "Mynd", + "show": "Þáttur" + } + }, + "navigation": { + "banner": { + "offline": "Athugaðu net tengingu þína" + }, + "menu": { + "about": "Um okkur", + "logout": "Skrá út", + "register": "Samstilla við ský", + "settings": "Stillingar", + "support": "Stuðningur" + } + }, + "notFound": { + "badge": "Ekki fundið", + "goHome": "Aftur heim", + "message": "Við leituðum alls staðar: undir ruslafötunum, inn í skápnum, á bakvið proxy þjónin en við gátum ekki fundið síðuna sem þú ert að leita af.", + "title": "Gat ekki fundið síðu" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Hætta við", + "confirm": "Nota venjulegu uppsetninguna", + "description": "Venjulega uppsetningin hefur ekki bestu streymin og getur verið óþolandi og hæg.", + "title": "Ertu viss?" + }, + "extension": { + "back": "Til baka", + "explainer": "þú getur fengið bestu streymi sem við höfum með því að nota viðbótið. Bara með einfaldri niðurhalningu.", + "explainerIos": "Því miður, er viðbótið ekki stytt á iOS, Ýttu á Til baka til að velja annan möguleika.", + "extensionHelp": "Ef þú hefur hlaðað niður viðbótinu en það er ekki greint, opnaðu viðbótið í gegnum net viðbóts valmyndina þína og fylgdu skrefin á skjánum.", + "linkChrome": "Sækja Chrome viðbót", + "linkFirefox": "Sækja Firefox viðbót", + "notDetecting": "Hlaðað niður á Chrome, en síðan er ekki að greina það? Reyndu að endurhlaða síðunna!", + "notDetectingAction": "Endurhlaða síðu", + "status": { + "disallowed": "VIðbót er ekki virkt fyrir þessa síðu", + "disallowedAction": "Virkja viðbót", + "failed": "Mistókst að biðja um stöðu", + "loading": "Bíðandi eftir að þú sækjir viðbótið", + "outdated": "Viðbóts útgáfa of gömul", + "success": "Viðbót virkar eins og gert ráð fyrir!" + }, + "submit": "Halda áfram", + "title": "Byrjum með viðbóti" + }, + "proxy": { + "back": "Til baka", + "explainer": "Með umboðs aðferðinni, getur þú fengið frábær gæði strauma með því að búa til sjálfsafgreitt umboð.", + "input": { + "errorConnection": "Gat ekki tengst umboð", + "errorInvalidUrl": "Ekki gildur hlekkur", + "errorNotProxy": "Bjóst við umboði en fékk heimasíðu", + "label": "Umboðs hlekkur", + "placeholder": "https://" + }, + "link": "Lærðu hvernig þú býrð til umboð", + "submit": "Staðfesta umboð", + "title": "Búum til nýtt umboð" + }, + "start": { + "explainer": "Til þess að fá bestu möguleg streymi, þú verður að velja hvaða streymis aðferð þér langar að nota.", + "options": { + "default": { + "text": "Mig langar ekki í strymi með góðum gæðum,<0 /> <1>notaðu venjulegu uppsetninguna" + }, + "extension": { + "action": "Hlaðaðu niður viðbóti", + "description": "Hlaðaðu niður viðbótinu og fáðu aðgang að frábærra heimilda.", + "quality": "Bestu gæði", + "title": "Viðbót" + }, + "proxy": { + "action": "Settu upp umboð", + "description": "Settu upp umboð á 5 mínútum og fáðu aðgang til frábærra heimilda.", + "quality": "Góð gæði", + "title": "Sérsniðið umboð" + } + }, + "title": "Komum þér í uppsetningu með SkoolTV" + } + }, + "overlays": { + "close": "Loka" + }, + "player": { + "back": { + "default": "Aftur heim", + "short": "Til baka" + }, + "casting": { + "enabled": "Steypandi í tæki..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Afrita HLS spilalista hlekk", + "disclaimer": "Niðurhalningar eru teknar beint frá heimildini. SkoolTV hefur engan kraft yfir hvernig niðurhalningarnar eru gefnar.", + "downloadSubtitle": "Hlaða niður nú verandi texta", + "downloadVideo": "Hlaða niður myndbandi", + "hlsDisclaimer": "Niðurhalningar eru teknar beint frá heimildini. SkoolTV hefur engan kraft yfir hvernig niðurhalningarnar eru gefnar.

Vinsamlegast fattaðu að þú ert að niðurhala HLS spilunarlista, það er ekki mælt með að niðurhala ef þú kannt ekki mikið á háþróað streymis sniði.. Reyndu aðrar heimildir fyrir önnur sniði.", + "onAndroid": { + "1": "Til þess að niðurhala á Android, ýttu á niðurhalningar takkan síðan, á nýju síðunni, smelltu og haltu niðri á myndbandinu, veldu síðan vista.", + "shortTitle": "Hlaða niður / Android", + "title": "Að hlaða niður á Android" + }, + "onIos": { + "1": "Til þess að niðurhala á iOS, ýttu á niðurhalninga takkan síðan, á nýju síðunni, ýttu á , síðan Vista í skrár .", + "shortTitle": "Hlaða niður / iOS", + "title": "Að hlaða niður á iOS" + }, + "onPc": { + "1": "Á PC, ýttu á niðurhalningar takkan síðan, á nýju síðunni, hægri smelltu á myndbandið og veldu Vista myndband sem", + "shortTitle": "Hlaða niður / PC", + "title": "Að hlaða niður á PC" + }, + "title": "Hlaða niður" + }, + "episodes": { + "button": "Þættir", + "emptyState": "Það eru engir þættir í þessari seríu, kíktu aftur seinna!", + "episodeBadge": "Þ{{episode}}", + "loadingError": "Villa að hlaða seríu", + "loadingList": "Hleðsla...", + "loadingTitle": "Hleðsla...", + "unairedEpisodes": "Einn eða fleiri þættir í þessari seríu eru ekki komnir, út að þeir hafa ekki komið út." + }, + "playback": { + "speedLabel": "Spilunarhraði", + "title": "Spilunar stillingar" + }, + "quality": { + "automaticLabel": "Sjálfkrafa gæði", + "hint": "Þú getur reynt að <0>skipta um heimildtil að fá öðruvísi gæða valkosti.", + "iosNoQuality": "Vegna takmörkum á Apple tækjum er ekki hægt að breyta um gæði á iOS með þessari heimild. Þú getur reynt að <0>breyta í aðra heimild til að fá mismunandi gæðastillingar.", + "title": "Gæði" + }, + "settings": { + "downloadItem": "Niðurhala", + "enableSubtitles": "Virkja texta", + "experienceSection": "Útsýnis upplifun", + "playbackItem": "Spilunar stillingar", + "qualityItem": "Gæði", + "sourceItem": "Myndbands heimildir", + "subtitleItem": "Texta stillingar", + "videoSection": "Myndbands stillingar" + }, + "sources": { + "failed": { + "text": "Það kom upp villa á meðan við vorum að reyna að finna myndbönd, vinsamlegast reyndu að nota aðra heimild.", + "title": "Skröpun mistókst" + }, + "noEmbeds": { + "text": "Við gátum ekki fundið neina innfellu, vinsamlegast reyndu að nota aðra heimild.", + "title": "Engar innifellur fundnar" + }, + "noStream": { + "text": "Þessi heimild hefur engin streymi fyrir þessa mynd eða þætti.", + "title": "Ekkert streymi" + }, + "title": "Heimildir", + "unknownOption": "Óvitað" + }, + "subtitles": { + "customChoice": "Veldu texta frá skrá", + "customizeLabel": "Sérsníða", + "offChoice": "Af", + "settings": { + "backlink": "Sérsniðir textar", + "delay": "Texta seinkun", + "fixCapitals": "Lagaðu hástafi" + }, + "title": "Textar", + "unknownLanguage": "Óvitað" + } + }, + "metadata": { + "api": { + "text": "Gat ekki hlaðið API lýsigögn, vinsamlegast kíktu á nettenginguna þína.", + "title": "Mistókst að hlaða API lýsigögnum" + }, + "dmca": { + "badge": "Fjarlæga", + "text": "Þessi miðill er ekki lengur fáanlegur út af hann hefur verið tekin niður handvirkt eða vegna höfundarréttarbrota.", + "title": "Miðill hefur verið fjarlægður" + }, + "extensionPermission": { + "badge": "Leyfi vantar", + "button": "Nota viðbótina", + "text": "Þú hefur viðbótina, en við þurfum leyfið þitt til að geta byrjað að nota hana.", + "title": "Stilltu viðbótina" + }, + "failed": { + "badge": "Mistókst", + "homeButton": "Fara heim", + "text": "Gat ekki hlaðið lýsingar um miðilin frá TMDB. Vinsamlegast kíktu hvort að TMBD er niðri eða læst á netinu þínu.", + "title": "Mistókst að hlaða lýsingum" + }, + "notFound": { + "badge": "Ekki fundið", + "homeButton": "Aftur heim", + "text": "Við gátum ekki fundið miðilin sem þú baðst um. Annað hvort hefur hann verið fjarlægður eða þú hefur átt við hlekkin.", + "title": "Gat ekki fundið miðil." + } + }, + "nextEpisode": { + "cancel": "Hætta við", + "next": "Næsti þáttur" + }, + "playbackError": { + "badge": "Spilunar villa", + "errors": { + "errorAborted": "Hætt var við að sækja miðilin út af beiðni notandans.", + "errorDecode": "Þrátt fyrir að áður var sagt að þetta væro nothæft, villa kom upp meðan við vorum að reyna að afkóða miðilin, sem leiddi til villu.", + "errorGenericMedia": "Óvituð miðla villa átti sér stað.", + "errorNetwork": "Einhvernskonar net villa kom up sem kom í veg fyrir að það tókst að sækja miðilin, þrátt fyrir að áður var það hægt.", + "errorNotSupported": "Miðillin eða miðla heimildin er ekki studdar." + }, + "homeButton": "Fara heim", + "text": "Það kom upp villa meðan reynt var að horfa á miðilin. Vinsamlegast reyndu aftur.", + "title": "Spilun myndbands mistóksts!" + }, + "scraping": { + "items": { + "failure": "Villa kom upp", + "notFound": "Hefur ekki myndbandið", + "pending": "Leitandi af myndböndum..." + }, + "notFound": { + "badge": "Ekki fundið", + "detailsButton": "Sýna smáatriði", + "homeButton": "Fara heim", + "text": "Við höfun leitað í heimildum okkar og getum ekki fundið miðilin sem þú ert að leita að! Við hýsum ekki miðlana og höfum enga stjórn yfir hvað er fáanlegt. Visnamlegast ýttu á 'Sýna smáatriði' fyrir neðan þennan texta fyrir fleiri smáatriði.", + "title": "Við gátum ekki fundið þetta" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} er eftir • Þú klárar {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Vinsamlegast sannreyndu að þú sért manneskja með því að klára Captcha-ið til hægri. Þetta er til þess að halda SkoolTV öruggu!", + "error": "Mistókst að sannreyna að þú sért manneskja. Vinsamlegast reyndu aftur.", + "title": "Við þurfum að sannræna að þú ert manneskja.", + "verifyingHumanity": "Að sannræna að þú sért manneskja..." + } + }, + "screens": { + "dmca": { + "text": "Velkomin á sambands síðu SkoolTV! Við virðum hugverkarétt og viljum ræða einhver höfundarréttar áhyggjur fljótt. Ef að þú trúir að höfundarréttur þíns verks hefur verið misnotaður á okkar síðu, vinsamlegast sentu ítarlega DMCA tilkynningu til netfangsing fyrir neðan þennan texta. Vinsamlegast láttu fylgja með lýsingu af höfundaréttavarna efninu, tengiliða upplýsingat þínar, og yfirlýsingu um góða trú. Við erum staðráðin í að leysa þessi mál tafarlaust og þökkum samstarf þitt við að halda SkoolTV stað sem virðir sköpunargáfu og höfundarrétt.", + "title": "DMCA" + }, + "loadingApp": "Hlaðandi forriti", + "loadingUser": "Hlaðandi þínum reikningi", + "loadingUserError": { + "logout": "Skrá út", + "reset": "Endurstilla sérsniðin netþjón", + "text": "Mistókst að hlaða inn reikningnum þínum", + "textWithReset": "Mistókst að hlaða inn reikningnum þínum af sérsniðna netþjóninum þínum, villtu fara aftur á venjulega netþjónin?" + }, + "migration": { + "failed": "Mistókst að flytja gögnin þín.", + "inProgress": "Vinsamlegast bíddu, við erum að flytja gögnin þín. Þetta ætti ekki að taka langan tíma." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nafn tækis", + "deviceNamePlaceholder": "Einkasími", + "editProfile": "Breyta", + "logoutButton": "Skrá út" + }, + "actions": { + "delete": { + "button": "Eyða reikning", + "confirmButton": "Eyða reikning", + "confirmDescription": "Ertu viss um að þú villt eyða aðganginum þínum? Öll gögnin þín verða eydd!", + "confirmTitle": "Ertu viss?", + "text": "Það er ekki hægt að taka þetta til baka. Öll gögn munu verða eydd og ekkert getur verið tekið til baka.", + "title": "Eyða reikningi" + }, + "title": "Aðgerðir" + }, + "devices": { + "deviceNameLabel": "Nafn tækis", + "failed": "Mistókst að hlaða fundum", + "removeDevice": "Eyða", + "title": "Tæki" + }, + "profile": { + "finish": "Klára breytingar", + "firstColor": "Reiknings litur eitt", + "secondColor": "Reiknings litur tvö", + "title": "Breyta mynd reiknings", + "userIcon": "Notandatákn" + }, + "register": { + "cta": "Byrja", + "text": "Deildu áhorfunar tíma á milli tækja og haltu þeimsamstilltum.", + "title": "Samstilla við skýið" + }, + "title": "Reikningur" + }, + "appearance": { + "activeTheme": "Virkur", + "themes": { + "blue": "Blár", + "default": "Venjulegt", + "gray": "Grár", + "red": "Rauður", + "teal": "Blágló" + }, + "title": "Útlit" + }, + "connections": { + "server": { + "description": "Ef þú villt tengjast sérsniðin bakendi til að geyma gögnin þín, virktu þetta og gefðu upp hlekkin. <0>Leiðbeiningar.", + "label": "Sérsniðin netþjónn", + "urlLabel": "Sérsniðinn netþjóns hlekkur" + }, + "setup": { + "doSetup": "Gera uppsetningu", + "errorStatus": { + "description": "Það er einn að fleiri hlutir í þessari uppsetningu sem þarf athygli þína.", + "title": "Eitthvað þarf athygli þína" + }, + "itemError": "Það er eitthvað rangt við þessa stillingu. Farðu í gegnum uppsetningu aftur til að laga hana.", + "items": { + "default": "Venjuleg uppsetning", + "extension": "Viðbót", + "proxy": "Sérsniðið umboð" + }, + "redoSetup": "Endurtaka uppsetningu", + "successStatus": { + "description": "Allt er á sama stað fyrir þig að byrja að horfa á uppáhalds miðilin þinn.", + "title": "Allt er sett upp!" + }, + "unsetStatus": { + "description": "Vinsamlegast ýttu á takkan til hægri til að byrja uppsetningu.", + "title": "Þú hefur ekki farið í gegnum uppsetningu" + } + }, + "title": "Tengingar", + "workers": { + "addButton": "Bættu við nýjum starfsmanni", + "description": "Til að láta forritið virka, allri umboð er beint í gegnum umboð. Virktu þetta ef þú villt koma með þína eigin starfsmenn. <0>Leiðbeiningar.", + "emptyState": "Engir starfsmenn komnir, bættu við einum fyir neðan þennan texta", + "label": "Notaðu sérsniðaða umboðs starfsmenn", + "urlLabel": "Starfsmanna hlekkir", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Tungumál forrits", + "languageDescription": "Tungumál beitt á allt forritið.", + "thumbnail": "Búa til smámyndir", + "thumbnailDescription": "Oftast, hafa myndbönd ekki smámyndir. Þú getur látið þessa stillingu gera þær en það gæti gert myndbandið þitt hægara.", + "thumbnailLabel": "Gera smámyndir", + "title": "Valstillingar" + }, + "reset": "Endurstilla", + "save": "Vista", + "sidebar": { + "info": { + "appVersion": "Útgáfa forrits", + "backendUrl": "Bakenda hlekkur", + "backendVersion": "Bakenda útgáfa", + "hostname": "Hýsingarheiti", + "insecure": "Óöruggt", + "notLoggedIn": "Þú ert ekki skrátt inn", + "secure": "Örrugt", + "title": "Forrits upplýsingar", + "unknownVersion": "Óvitað", + "userId": "Notanda kóði" + } + }, + "subtitles": { + "backgroundLabel": "Bakgrunnar gegnsægi", + "colorLabel": "Litur", + "previewQuote": "Ég má ekki óttast. Ótti er hugardrepandi.", + "textSizeLabel": "Texta stærð", + "title": "Textar" + }, + "unsaved": "Þú hefur óvistaðar breytingar" + } +} diff --git a/src/assets/locales/it.json b/src/assets/locales/it.json new file mode 100644 index 0000000..e44ea7e --- /dev/null +++ b/src/assets/locales/it.json @@ -0,0 +1,622 @@ +{ + "about": { + "description": "SkoolTV è un fork di movie-web che garantisce di rimanere attivo anche dopo la chiusura di movie-web.app. SkoolTV.lol funziona su un VPS privato e ospitato autonomamente. Gestisco questo sito in perdita; non ci sono annunci a causa della mia fede nei media liberi.", + "faqTitle": "Domande comuni", + "q1": { + "body": "SkoolTV non ospita alcun contento. Quando clicci su qualcosa da guardare, SkoolTV cerca l'internet per media di vostra scelta (Sull schermata di caricamento e nell tab 'sorgenti video' si può vedere quale sorgente si sta utilizzando). I media non sono mai caricati da SkoolTV, tutto è attraverso questo meccanismo di ricerca.", + "title": "Da dove arriva il contenuto?" + }, + "q2": { + "body": "Non è possibile richiedere uno show o un film, SkoolTV non gestisce alcun contenuto. Tutti i contenuti sono visualizzati da sorgenti online.", + "title": "Dove posso richiedere una serie o un film?" + }, + "q3": { + "body": "I nostri risultati sono alimentati da «The Movie Database (TMDB)» e visualizzare indipendentemente dal fatto che nostri sorgenti hanno effettivamente il contenuto.", + "title": "I risultati di ricerca mostrano la serie o il film, perché non posso riprodurlo?" + }, + "title": "Su di SkoolTV (^▽^)", + "q4": { + "title": "E i miei dati?", + "body": "Tutti i dati vengono sincronizzati con il back-end sudo che è diverso dal back-end della community ed è ospitato in modo indipendente da me, chiunque è libero di utilizzare anche questo." + }, + "q5": { + "body": "be', SkoolTV ha un account Twitter che può essere trovato nel fondo della pagina insieme ad un link al codice sorgente su Github.", + "title": "Come posso sapere di più?" + } + }, + "actions": { + "copied": "Copiato", + "copy": "Copia" + }, + "auth": { + "createAccount": "Non hai ancora un account 😬 <0>Crea un account.", + "deviceNameLabel": "Nome del dispositivo", + "deviceNamePlaceholder": "Telefono personale", + "generate": { + "description": "La tua frase d'accesso funziona come nome utente e password. Assicurati di tenerla al sicuro poiché dovrai inserirla per accedere al tuo account. NON perdere la tua frase d'accesso!", + "next": "Ho salvato la mia frase d'accesso", + "passphraseFrameLabel": "Frase d'accesso", + "title": "La tua frase d'accesso" + }, + "hasAccount": "Hai già un account? <0>Accedi qua.", + "login": { + "description": "Inserisci la tua frase d'accesso per accedere al tuo account", + "deviceLengthError": "Inserisci un nome al dispositivo", + "passphraseLabel": "Frase d'accesso di 12 parole", + "passphrasePlaceholder": "Frase d'accesso", + "submit": "Accedi", + "title": "Accedi al tuo account", + "validationError": "Frase d'accesso incompleta o sbagliata /ᐠ. .ᐟ\\" + }, + "register": { + "information": { + "color1": "Colore profilo uno", + "color2": "Colore profilo due", + "header": "Inserisci un nome per il tuo dispositivo poi seleziona un colore e un'icona utente a tua scelta!", + "icon": "Icona utente", + "next": "Prossimo", + "title": "Informazioni sull'account" + } + }, + "trust": { + "failed": { + "text": "L'hai configurata correttamente?", + "title": "Impossibile raggiungere il server" + }, + "host": "Ti stai collegando a <0>{{hostname}} - conferma la tua fiducia prima di creare un account...", + "no": "Indietro", + "noHost": "Questo server non è configurato, quindi non puoi creare un account", + "noHostTitle": "Server non è configurato!", + "title": "Ti fidi di questo server?", + "yes": "Mi fido di questo server 🤞" + }, + "verify": { + "description": "Inserisci la tua frase d'accesso di prima per confermare che l'hai salvata e per creare il tuo account", + "invalidData": "I dati non sono validi", + "noMatch": "Frase d'accesso non corrisponde 😭", + "passphraseLabel": "La tua frase d'accesso di 12 parole", + "recaptchaFailed": "Validazione ReCaptcha fallita", + "register": "Crea account", + "title": "Conferma la tua frase d'accesso" + } + }, + "errors": { + "badge": "Si è rotto 💀", + "details": "Dettagli errore", + "reloadPage": "Ricarica la pagina", + "showError": "Mostra dettagli dell'errore", + "title": "Si è verificato un errore!" + }, + "footer": { + "legal": { + "disclaimer": "Disclaimer ◝(ᵔᵕᵔ)◜", + "disclaimerText": "Nota: SkoolTV non ospita alcun file ma visualizza solo il contenuto di fornitori di terze parti. Le questioni legali dovrebbero essere affrontate con loro." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub", + "twitter": "Twitter" + }, + "tagline": "Guarda i tuoi preferiti programmi televisivi e film gratis senza publicità! (っ'ヮ'c)" + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Su SkoolTV", + "dmca": "DMCA", + "login": "Accedi", + "onboarding": "Configura", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registrati", + "settings": "Impostazioni", + "discover": "Scopri", + "support": "Supporto" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Segnalibri" + }, + "continueWatching": { + "sectionTitle": "Continua a guardare..." + }, + "mediaList": { + "stopEditing": "Smetti di modificare" + }, + "search": { + "allResults": "È tutto quello che abbiamo...", + "failed": "Impossibile trovare il media, riprova!", + "loading": "Caricamento...", + "noResults": "Non abbiamo trovato nulla :(", + "placeholder": { + "default": "Cosa vuoi guardare?", + "extra": [ + "Di cosa hai voglia?", + "Dovremmo eliminare la cronologia del browser?", + "Cosa vuoi trasmettere in streaming?", + "SkoolTV è il sito migliore di sempre!", + "Cosa c'è nella tua lista oggi?", + "Com'è stata la tua giornata?", + "Colpa mia, il sito non funziona mai...", + "SkoolTV non è semplicemente il migliore?", + ">ᴗ<" + ] + }, + "sectionTitle": "Risultati di ricerca", + "empty": { + "default": "Benvenuto, trova i media da guardare qui!", + "extra": [ + "Non c'è niente qui :(", + "così vuoto...", + "Che vuoto.", + "Ciao nuovo utente :3" + ] + }, + "discoverMore": "Scopri di più", + "discover": "Scopri" + }, + "titles": { + "day": { + "default": "Cosa vorresti guardare questo pomeriggio?", + "extra": ["Viva SkoolTV!"] + }, + "morning": { + "default": "Cosa vorresti guardare questa mattina?", + "extra": ["Viva SkoolTV!"] + }, + "night": { + "default": "Cosa vorresti guardare questa sera?", + "extra": ["Viva SkoolTV!"] + }, + "420": { + "default": "Cosa ti piacerebbe guardare questo 20/4?", + "extra": ["Buon 20/4 🥳!"] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Serie" + }, + "unreleased": "Non publicato" + }, + "navigation": { + "banner": { + "offline": "Controlla la tua connessione internet, stupida oca! 🦢" + }, + "menu": { + "about": "Su di SkoolTV", + "logout": "Esci", + "register": "Sincronizza al sudo-cloud", + "settings": "Impostazioni", + "support": "Supporto", + "discover": "Scopri" + } + }, + "notFound": { + "badge": "Non trovato", + "goHome": "Torna alla pagina iniziale", + "message": "Abbiamo cercato ovunque: sotto i bidoni, nell'armadio, dietro il proxy, ma alla fine non siamo riusciti a trovare la pagina che stai cercando. (ಥ﹏ಥ)", + "title": "Impossibile trovare quella pagina", + "reloadButton": "Riprova" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Annulla", + "confirm": "Utilizza impostazione predefinita", + "description": "La impostazione predefinita non offre i migliori stream e può essere incredibilmente lenta. ( ͠° ͟ʖ ͡°)", + "title": "Sei sicuro?" + }, + "extension": { + "back": "Torna indietro", + "explainer": "Utilizzando l'estensione del browser, puoi ottenere le migliori stream che abbiamo da offrire. Con solo una semplice installazione. 👌", + "explainerIos": "Purtroppo, l'estensione del browser non è supportata su iOS, premere Torna indietro per scegliere un'altra opzione.", + "extensionHelp": "Se avete installato l'estensione ma non viene rilevata, Apri l'estensione attraverso il menu delle estensioni del browser e seguire i passaggi sullo schermo.", + "linkChrome": "Installa l'estensione su Chrome", + "linkFirefox": "Installa l'estensione su Firefox", + "notDetecting": "Installato su Chrome, ma il sito non lo rileva? Prova a ricaricare la pagina!", + "notDetectingAction": "Ricarica pagina", + "status": { + "disallowed": "L'estensione non è attivata per questa pagina (,,>﹏<,,)", + "disallowedAction": "Attiva l'estensione", + "failed": "Impossibile richiedere lo stato", + "loading": "In attesa di installare l'estensione", + "outdated": "Versione dell'estensione troppo vecchia", + "success": "L'estensione funziona come previsto!" + }, + "submit": "Continua", + "title": "Iniziamo con un'estensione" + }, + "proxy": { + "back": "Torna indietro", + "explainer": "Con il metodo proxy, è possibile ottenere stream di qualità ottima creando un proxy self-service.", + "input": { + "errorConnection": "Impossibile connettere al proxy", + "errorInvalidUrl": "URL non valido", + "errorNotProxy": "Avevamo previsto un proxy, ma abbiamo ottenuto un sito web", + "label": "URL proxy", + "placeholder": "https://" + }, + "link": "Impara a creare un proxy", + "submit": "Invia proxy", + "title": "Creiamo un nuovo proxy" + }, + "start": { + "explainer": "Per ottenere le migliori stream possibili, è necessario scegliere il metodo di streaming da utilizzare.", + "options": { + "default": { + "text": "Non voglio stream di buona qualità, <0 /> <1>usa impostazione predefinita ▄︻デ══━一 ʕ•͡-•ʔ" + }, + "extension": { + "action": "Installa l'estensione", + "description": "Installa l'estensione del browser e ottieni accesso alle migliori sorgenti, ma ricordati di abilitarla per questo sito.", + "quality": "Qualiotà migliore", + "title": "Estensione del browser" + }, + "proxy": { + "action": "Imposta proxy", + "description": "Imposta un proxy gratis in soli 5 minuti e ottieni accesso a ottimi fonti...", + "quality": "Qualità buona", + "title": "Proxy personalizzato" + } + }, + "title": "Configuriamo SkoolTV 🥳" + } + }, + "overlays": { + "close": "Chiudi" + }, + "player": { + "back": { + "default": "Torna alla pagina iniziale", + "short": "Indietro" + }, + "casting": { + "enabled": "Trasmissione al dispositivo 🎬" + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Copia link playlist HLS", + "disclaimer": "I download vengono effettuati direttamente dal provider. SkoolTV non ha il controllo sulle modalità di fornitura dei download.", + "downloadSubtitle": "Scarica sottotitolo attuale", + "downloadVideo": "Scarica video", + "hlsDisclaimer": "I download vengono effettuati direttamente dal provider. SkoolTV non ha il controllo sul modo in cui vengono forniti i download.

Tieni presente che stai scaricando una playlist HLS, non è consigliabile scaricarla se non hai familiarità con i formati di streaming avanzati. Prova diverse fonti per diversi formati.", + "onAndroid": { + "1": "Per scaricare su Android, fai clic sul pulsante di download quindi, nella nuova pagina, tocca e tieni premuto sul video, quindi seleziona salva.", + "shortTitle": "Scarica / Android", + "title": "Scaricare su Android" + }, + "onIos": { + "1": "Per scaricare su iOS, fai clic sul pulsante di scaricare, e poi nella nuova paggina, fai clic su poiSalva su FIle .", + "shortTitle": "Scarica / iOS", + "title": "Scaricare su iOS" + }, + "onPc": { + "1": "Sul PC, fare clic sul pulsante di download, poi nella nuova pagina, fai clic destro sul video e selezionare Salva video come", + "shortTitle": "Scarica / PC", + "title": "Scaricare su PC" + }, + "title": "Scarica" + }, + "episodes": { + "button": "Episodi", + "emptyState": "Non ci sono episodi in questa stagione, controlla più tardi (scusa :3)...", + "episodeBadge": "E{{episode}}", + "loadingError": "Errore nel caricare la stagione", + "loadingList": "Caricamento...", + "loadingTitle": "Caricamento...", + "unairedEpisodes": "Uno o più episodi di questa stagione sono stati disabilitati perché non sono ancora andati in onda.", + "seasons": "Stagioni" + }, + "playback": { + "speedLabel": "Velocità di riproduzione", + "title": "Impostazioni di riproduzione" + }, + "quality": { + "automaticLabel": "Qualità automatica", + "hint": "Si può provare a <0>cambiare sorgente per avere diverse opzioni di qualità.", + "iosNoQuality": "A causa delle limitazioni definite da Apple (comuni IOS L), la selezione della qualità non è disponibile su iOS per questa fonte. Puoi provare a <0>passare a un'altra sorgente per ottenere opzioni di qualità diverse.", + "title": "Qualità" + }, + "settings": { + "audioItem": "Audio", + "downloadItem": "Scarica", + "enableSubtitles": "Abilita i sottotitoli", + "experienceSection": "Esperienza di visione", + "playbackItem": "Impostazioni di riproduzione", + "qualityItem": "Qualità", + "sourceItem": "Sorgenti video", + "subtitleItem": "Impostazioni sottotitoli", + "videoSection": "Impostazioni video" + }, + "sources": { + "failed": { + "text": "Si è verificato un errore durante il tentativo di trovare il video... Provare con una fonte diversa?", + "title": "Impossibile raschiare" + }, + "noEmbeds": { + "text": "Non siamo riusciti a trovare alcun incorporamento, prova una fonte diversa.", + "title": "Nessun incorporamento trovato" + }, + "noStream": { + "text": "Questa fonte non ha streaming per questo film o programma. /ᐠ - ˕ -マ Ⳋ", + "title": "Nessuno streaming :(" + }, + "title": "Sorgenti", + "unknownOption": "Sconosciuto" + }, + "subtitles": { + "customChoice": "Trascina o carica il file", + "customizeLabel": "Personalizza", + "dropSubtitleFile": "Trascina il file dei sottotitoli qui! >_<", + "offChoice": "Spegni", + "settings": { + "backlink": "Sottotitoli personalizzati", + "delay": "Ritardo dei sottotitoli", + "fixCapitals": "Correggi le maiuscole" + }, + "title": "Sottotitoli", + "unknownLanguage": "Sconosciuto", + "OpenSubtitlesChoice": "OpenSubtitles", + "scrapeButton": "Raschia i sottotitoli", + "empty": "Non ci sono sottotitoli forniti per questo fornitore." + } + }, + "metadata": { + "api": { + "text": "Impossibile caricare i metadati dell'API, controlla la tua connessione Internet.", + "title": "Impossibile caricare i metadati dell'API" + }, + "dmca": { + "badge": "Rimosso", + "text": "Questo media non è più disponibile a causa di un avviso di rimozione o di un reclamo sul copyright. 😨", + "title": "Il media è stato rimosso" + }, + "extensionPermission": { + "badge": "Autorizzazione mancante", + "button": "Usa l'estensione", + "text": "Hai l'estensione del browser, ma abbiamo bisogno della tua autorizzazione per iniziare a utilizzare l'estensione. (¬_¬)", + "title": "Configura l'estensione" + }, + "failed": { + "badge": "Fallito", + "homeButton": "Vai alla pagina iniziale", + "text": "Impossibile caricare i metadati del media da TMDB. Controlla se TMDB è inattivo o bloccato sulla tua connessione Internet.", + "title": "Impossibile caricare i metadati" + }, + "notFound": { + "badge": "Non trovato", + "homeButton": "Torna alla pagina iniziale", + "text": "Non siamo riusciti a trovare il supporto richiesto. O è stato rimosso o hai manomesso l'URL (cattivo, cattivo).", + "title": "Impossibile trovare quel media." + } + }, + "nextEpisode": { + "cancel": "Cancella", + "next": "Prossimo", + "replay": "Riguarda", + "nextSeason": "Prossimo" + }, + "playbackError": { + "badge": "Errore di riproduzione", + "errors": { + "errorAborted": "Il recupero dei media è stato interrotto dalla richiesta dell'utente.", + "errorDecode": "Nonostante fosse stato precedentemente stabilito che era utilizzabile, si è verificato un errore durante il tentativo di decodificare la risorsa multimediale, risultando in un errore.", + "errorGenericMedia": "Si è verificato un errore multimediale sconosciuto.", + "errorNetwork": "Si è verificato qualche tipo di errore di rete che ha impedito il recupero corretto del media, nonostante fosse stato precedentemente disponibile.", + "errorNotSupported": "L'oggetto multimediale o fornitore di contenuti multimediali non è supportato." + }, + "homeButton": "Torna a pagina iniziale", + "text": "Si è verificato un errore durante il tentativo di riprodurre i contenuti multimediali 😖. Riprova!", + "title": "Impossibile riprodurre il video!" + }, + "scraping": { + "extensionFailure": { + "badge": "L'estensione è disabilitata", + "enableExtension": "Abilita l'estensione", + "homeButton": "Torna alla pagina iniziale", + "text": "Hai installato l'estensione SkoolTV. Per iniziare a usarla, devi abilitare l'estensione per questo sito.", + "title": "Abilita l'estensione" + }, + "items": { + "failure": "Si è verificato un errore", + "notFound": "Non ha il video (╥﹏╥)", + "pending": "Controllo per video..." + }, + "notFound": { + "badge": "Non trovato", + "detailsButton": "Mostra i dettagli", + "homeButton": "Torna a pagina iniziale", + "text": "Abbiamo cercato tra i nostri fornitori e non siamo riusciti a trovare i media che stai cercando! Non ospitiamo i media e non abbiamo alcun controllo su ciò che è disponibile. Fare clic su \"Mostra dettagli\" di seguito per ulteriori dettagli.", + "title": "Non siamo riusciti a trovarlo", + "discoverButton": "Scopri di più" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} rimasto • Finisce alle {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Per favore dimostra la tua umanità completando il Captcha a destra. Questo serve a mantenere SkoolTV.lol al sicuro!", + "error": "Impossibile verificare la vostra umanità! Riprova.", + "title": "Sei un Robot 🤖?", + "verifyingHumanity": "Verificando la tua umanità... (^▽^)👍" + } + }, + "screens": { + "dmca": { + "text": "Benvenuto nella pagina dei contatti DMCA di SkoolTV. Se ritieni che la tua opera protetta da copyright sia stata utilizzata in modo improprio sulla nostra piattaforma (😢), invia una notifica DMCA dettagliata a: {{dmca}} di seguito. Si prega di includere una descrizione del materiale protetto da copyright, i dettagli di contatto e una dichiarazione di buona fede. Ci impegniamo a risolvere tempestivamente queste questioni e apprezziamo la tua collaborazione.", + "title": "DMCA :(" + }, + "loadingApp": "Caricamento dell'applicazione", + "loadingUser": "Caricamento del tuo profilo", + "loadingUserError": { + "logout": "Esci", + "reset": "Ripristino del server personalizzato", + "text": "Impossibile caricare il tuo profilo", + "textWithReset": "Impossibile caricare il tuo profilo dal tuo server personalizzato, vorresti ripristinare al server predefinito?", + "reload": "Ricarica" + }, + "migration": { + "failed": "Impossibile eseguire la migrazione dei dati. 😿", + "inProgress": "Per favore aspetta, stiamo migrando i tuoi dati. Non dovrebbe volerci molto tempo..." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nome del dispositivo", + "deviceNamePlaceholder": "Telefono personale", + "editProfile": "Modifica", + "logoutButton": "Esci" + }, + "actions": { + "delete": { + "button": "Elimina l'account", + "confirmButton": "Elimina l'account", + "confirmDescription": "Sei sicuro di voler eliminare il tuo account? Tutti i tuoi dati andranno persi! ૮₍˶Ó﹏Ò ⑅₎ა", + "confirmTitle": "Sei sicuro?", + "text": "Questa azione è irreversibile. Tutti i dati verranno cancellati e nulla potrà essere recuperato.", + "title": "Elimina l'account" + }, + "title": "Azioni" + }, + "devices": { + "deviceNameLabel": "Nome dispositivo", + "failed": "Impossibile caricare sessioni", + "removeDevice": "Rimuovi", + "title": "Dispositivi" + }, + "profile": { + "finish": "Termina la modifica", + "firstColor": "Colore profilo uno", + "secondColor": "Colore profilo due", + "title": "Modifica l'immagine profilo", + "userIcon": "Icona utente" + }, + "register": { + "cta": "Inizia", + "text": "Condividi i progressi dei tuoi film e serie tra dispositivi e mantienili sincronizzati. ( ̧⸝⸝⍢⸝⸝)ෆ", + "title": "Sincronizza col sudo-cloud" + }, + "title": "Account", + "admin": { + "title": "Pannello di Amministrazione", + "text": "Utilizza strumenti realizzati per testare le condizioni di SkoolTV.", + "button": "Controlla" + } + }, + "appearance": { + "activeTheme": "Attivo", + "themes": { + "blue": "Blu", + "default": "Predefinito", + "gray": "Grigio", + "red": "Rosso", + "teal": "Verde acqua" + }, + "title": "Aspetto" + }, + "connections": { + "server": { + "description": "Se desideri connetterti a un backend personalizzato per archiviare i tuoi dati, abilitalo e fornisci l'URL. <0>Istruzioni.", + "label": "Server personalizzato", + "urlLabel": "URL del server personalizzato" + }, + "setup": { + "doSetup": "Effettua la configurazione", + "errorStatus": { + "description": "Sembra che uno o più elementi in questa configurazione richiedano la tua attenzione.", + "title": "Qualcosa ha bisogno della tua attenzione 😱" + }, + "itemError": "C'è qualcosa che non va in questa impostazione. Ripeti la configurazione per risolverlo. (ᴗ_ ᴗ。)", + "items": { + "default": "Configurazione predefinita", + "extension": "Estensione", + "proxy": "Proxy personalizzato" + }, + "redoSetup": "Rifare configurazione", + "successStatus": { + "description": "Tutto è pronto per iniziare a guardare i tuoi contenuti multimediali preferiti. (๑>◡<๑)", + "title": "Tutto è configurato!" + }, + "unsetStatus": { + "description": "Fare clic sul pulsante a destra per avviare il processo di configurazione.", + "title": "Non hai completato la configurazione" + } + }, + "title": "Connessioni", + "workers": { + "addButton": "Aggiungi nuovo lavoratore", + "description": "Per far funzionare l'applicazione, tutto il traffico viene instradato tramite proxy. Abilita questa opzione se vuoi portare i tuoi lavoratori. <0>Istruzioni.", + "emptyState": "Non ci sono ancora lavoratori (。•́︿•̀。), aggiungine uno qui sotto", + "label": "Utilizza proxy worker personalizzati", + "urlLabel": "URL dei worker", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Lingua dell'applicazione", + "languageDescription": "Lingua applicata all'intera applicazione, solo l'inglese contiene cose stupide 🙁.", + "thumbnail": "Genera miniature", + "thumbnailDescription": "Nella maggior parte dei casi, i video non hanno miniature. Puoi abilitare questa impostazione per generarli al volo, ma possono rallentare il tuo video.", + "thumbnailLabel": "Genera miniature", + "title": "Preferenze", + "sourceOrderDescription": "Trascina e rilascia per riordinare le fonti. Ciò determinerà l'ordine in cui verranno controllate le fonti per i media che stai tentando di guardare. Se una fonte è disattivata, significa che non è disponibile sul tuo dispositivo.", + "autoplay": "Riproduzione automatica", + "autoplayDescription": "Riproduci automaticamente l'episodio successivo di una serie dopo aver raggiunto la fine. Può essere abilitato dagli utenti con l'estensione del browser, un proxy personalizzato o con la configurazione predefinita se consentito dall'host.", + "autoplayLabel": "Riproduzione automatica", + "sourceOrder": "Riordina le fonti" + }, + "reset": "Ripristina", + "save": "Salva", + "sidebar": { + "info": { + "appVersion": "Versione dell'app", + "backendUrl": "URL back-end", + "backendVersion": "Versione back-end", + "hostname": "Nome host", + "insecure": "Insicuro", + "notLoggedIn": "Non sei loggato", + "secure": "Sicuro", + "title": "Statistiche dell'app (per nerd) 🤓", + "unknownVersion": "Sconosciuto", + "userId": "ID utente" + } + }, + "subtitles": { + "backgroundBlurLabel": "Sfocatura dello sfondo", + "backgroundLabel": "Opacità dello sfondo", + "colorLabel": "Colore", + "previewQuote": "Preferiresti avere una figlia puttana o un figlio gay? 🤔", + "textSizeLabel": "Dimensione testo", + "title": "Sottotitoli", + "textBoldLabel": "Testo in grassetto" + }, + "unsaved": "Hai modifiche non salvate... ฅ^•ﻌ•^ฅ" + }, + "support": { + "q2": { + "body": "Abbiamo un <0>GitHub in cui puoi creare un problema dettagliato nel nostro repository. Inoltre, se lo desideri, puoi creare una richiesta pull per risolvere tu stesso il problema.", + "title": "Come posso segnalare un bug o un problema?" + }, + "title": "Supporto", + "text": "SkoolTV è progettato per essere il più intuitivo possibile. Tuttavia, le persone hanno ancora domande e problemi. Questa pagina è qui per aiutare a risolvere queste carenze", + "q1": { + "body": "Be', puoi unirti al <0>Discord di SkoolTV ufficiale e porre domande lì oppure puoi inviare un'e-mail a quella fornita in fondo a questa pagina.", + "title": "Dove posso ottenere aiuto?" + } + }, + "downtimeNotice": { + "message": "SkoolTV.lol sta riscontrando problemi con alcuni provider, se non riesci a trovare o riprodurre uno show, cambia la fonte. È previsto che questo errore persista durante i tempi indicati di seguito.", + "badge": "Problemi", + "goHome": "Vai alla pagina iniziale", + "timeFrame": "31 Marzo 5:00 - 11:00 ", + "title": "Problemi col fornitore" + } +} diff --git a/src/assets/locales/ja.json b/src/assets/locales/ja.json new file mode 100644 index 0000000..d445edf --- /dev/null +++ b/src/assets/locales/ja.json @@ -0,0 +1,136 @@ +{ + "about": { + "description": "SkoolTVは、ウェブアプリケーションで、インターネットを検索してストリームを見つけます。チームは、コンテンツの消費において主にミニマリストなアプローチを目指しています。", + "faqTitle": "よくある質問", + "q1": { + "body": "SkoolTVはいかなるコンテンツもホストしていません。視聴するために何かをクリックすると、選択したメディアがインターネットで検索されます(ローディング画面と「ビデオソース」タブでは、使用しているソースが表示されます)。メディアは決してSkoolTVにアップロードされず、すべてがこの検索メカニズムを通じて行われます。", + "title": "コンテンツはどこから来ていますか?" + }, + "q2": { + "body": "ショーまたは映画のリクエストはできません。SkoolTVはどのコンテンツも管理していません。すべてのコンテンツはインターネット上のソースを通じて閲覧されます。", + "title": "ショーまたは映画のリクエストはどこでできますか?" + }, + "q3": { + "body": "私たちの検索結果は、The Movie Database(TMDB)によって提供され、実際にはコンテンツを持っているかどうかに関係なく表示されます。", + "title": "検索結果には番組や映画が表示されますが、なぜ再生できないのでしょうか?" + }, + "title": "SkoolTVについて" + }, + "actions": { + "copied": "コピーしました", + "copy": "コピー" + }, + "auth": { + "createAccount": "まだアカウントをお持ちでないですか? <0>アカウントを作成 してください。", + "deviceNameLabel": "デバイス名", + "deviceNamePlaceholder": "個人用の電話", + "generate": { + "description": "パスフレーズはユーザー名とパスワードとして機能します。アカウントにログインする際には必ず入力する必要があるため、安全に保管してください。", + "next": "パスフレーズを保存しました", + "passphraseFrameLabel": "パスフレーズ", + "title": "あなたのパスフレーズ" + }, + "hasAccount": "既にアカウントをお持ちですか? <0>ログインはこちら", + "login": { + "description": "ログインするにはパスフレーズを入力してください", + "deviceLengthError": "デバイス名を入力してください", + "passphraseLabel": "12単語のパスフレーズ", + "passphrasePlaceholder": "パスフレーズ", + "submit": "ログイン", + "title": "自分の口座にログインする", + "validationError": "パスワードが間違っています" + }, + "register": { + "information": { + "color1": "プロフィールカラー1", + "color2": "プロフィールカラー2", + "header": "デバイス名を入力し、色とユーザーアイコンを選んでください", + "icon": "ユーザーアイコン", + "next": "次へ", + "title": "アカウント情報" + } + }, + "trust": { + "failed": { + "text": "正しく設定しましたか?", + "title": "サーバーへの接続に失敗しました" + } + } + }, + "footer": { + "tagline": "あなたのお気に入りの番組や映画を、このオープンソースのストリーミングアプリで視聴してください。" + }, + "global": { + "name": "映画ウェブ", + "pages": { + "about": "概要", + "login": "ログイン", + "settings": "設定" + } + }, + "home": { + "continueWatching": { + "sectionTitle": "視聴を続ける" + }, + "search": { + "allResults": "それがすべてです!", + "loading": "読み込み中...", + "noResults": "見つかりませんでした!", + "placeholder": { + "default": "どんな映画を見たい?", + "extra": [] + }, + "sectionTitle": "検索結果" + }, + "titles": { + "day": { + "default": "今日の午後はどんな映画を見たい?" + }, + "morning": { + "default": "今朝はどんな映画を見たい?" + }, + "night": { + "default": "今夜はどんな映画を見たい?" + } + } + }, + "media": { + "types": { + "movie": "映画", + "show": "テレビ番組" + } + }, + "navigation": { + "menu": { + "about": "会社概要", + "logout": "退室", + "register": "クラウドに同期して", + "settings": "設定" + } + }, + "player": { + "menus": { + "episodes": { + "loadingList": "読み込み中...", + "loadingTitle": "読み込み中..." + } + } + }, + "screens": { + "loadingApp": "申込の読み込み", + "loadingUser": "プロフィールの読み込み", + "loadingUserError": { + "logout": "退出" + } + }, + "settings": { + "account": { + "accountDetails": { + "logoutButton": "退室" + }, + "register": { + "title": "クラウドに同期して" + } + } + } +} diff --git a/src/assets/locales/kitty.json b/src/assets/locales/kitty.json new file mode 100644 index 0000000..570dfdb --- /dev/null +++ b/src/assets/locales/kitty.json @@ -0,0 +1,432 @@ +{ + "about": { + "description": "meow-flix is a meow application that searches the meow for meows. The meow aims for a mostly meow approach to consuming meow.", + "faqTitle": "Meow questions", + "q1": { + "body": "meow-flix does not meow any meow. When you meow on something to meow, the meow is searched for the selected meow (On the loading meow and in the 'meow sources' meow you can meow which meow you're meow). Meow never gets meow by meow-flix, everything is meow this meow mechanism.", + "title": "Where does the meow come from?" + }, + "q2": { + "body": "It's not meow to meow a meow or meow, meow-flix does not meow any meow. All meow is meow through meows on the meow.", + "title": "Meow can I meow a meow or meow?" + }, + "q3": { + "body": "Our meow results are meow by The Meow Meow (TBMB) and meow regardless of whether our meows actually have the meow.", + "title": "The meow results meow the meow or meow, meow can't I meow it?" + }, + "title": "About meow-flix" + }, + "actions": { + "copied": "Meow", + "copy": "Meow" + }, + "auth": { + "createAccount": "Whaaaat? Don't have an account yet? <0>Create an account.", + "deviceNameLabel": "Device name", + "deviceNamePlaceholder": "Meow phone", + "generate": { + "description": "Your meow passphrase acts as your meow username and meow password. Make sure to keep it safe as you will need to enter it to meow to your account", + "next": "I have saved my meow passphrase", + "passphraseFrameLabel": "Meowphrase", + "title": "Your meow passphrase" + }, + "hasAccount": "Bello! Already have an account? <0>Login here.", + "login": { + "description": "Please enter your secret meow language passphrase to login to your account", + "deviceLengthError": "Meow! Please enter a device name", + "passphraseLabel": "12-Meow passphrase", + "passphrasePlaceholder": "Meow Passphrase", + "submit": "Bello! Login", + "title": "Login to your account", + "validationError": "Meow language not fluent or incomplete" + }, + "register": { + "information": { + "color1": "Profile color one", + "color2": "Profile color two", + "header": "Whaaat? Enter a name for your device and pick colors and a minion icon of your choosing", + "icon": "Minion icon", + "next": "Meow!", + "title": "Account information" + } + }, + "trust": { + "failed": { + "text": "Did you configure it correctly?", + "title": "Failed to reach server" + }, + "host": "You are connecting to <0>{{hostname}} - please confirm you trust it before making a meow account", + "no": "Go back, meow", + "title": "Do you trust this server?", + "yes": "I trust this server, meow!" + }, + "verify": { + "description": "Please enter your meow passphrase from earlier to confirm you have saved it and to create your meow account", + "invalidData": "Meow data is not valid", + "noMatch": "Meow! Passphrase doesn't match", + "passphraseLabel": "Your 12-meow passphrase", + "recaptchaFailed": "Meow! ReCaptcha validation failed", + "register": "Create meow account", + "title": "Confirm your meow passphrase" + } + }, + "errors": { + "badge": "It broke", + "details": "Error meow details", + "reloadPage": "Reload the meow", + "showError": "Show meow details", + "title": "We encountered a meow!" + }, + "footer": { + "legal": { + "disclaimer": "Meow", + "disclaimerText": "meow-flix does not meow any meows, it merely meow to 3rd meow meows. Meow issues should be meow up with the meow meows and meows. meow-flix is not meow for any meow meows shown by the meow meows." + }, + "links": { + "discord": "Meow", + "dmca": "Meow", + "github": "Meow" + }, + "tagline": "Meow your favorite meows and meows with this open source meow app." + }, + "global": { + "name": "meow-flix", + "pages": { + "about": "About meow", + "dmca": "DMCA", + "login": "Meow Login", + "pagetitle": "{{title}} - meow-flix", + "register": "Meow Register", + "settings": "Meow Settings" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Meow" + }, + "continueWatching": { + "sectionTitle": "Continue Meow" + }, + "mediaList": { + "stopEditing": "Stop meow" + }, + "search": { + "allResults": "Meow's all we meow!", + "failed": "Failed to meow meow, try again!", + "loading": "Loading...", + "noResults": "We couldn't meow anything!", + "placeholder": { + "default": "Meow do you want to meow?" + }, + "sectionTitle": "Meow results" + }, + "titles": { + "day": { + "default": "What would you like to meow this meow?", + "extra": [ + "Feeling meow? Jurassic meow meow meow meow perfect meow." + ] + }, + "morning": { + "default": "What would you like to meow this meow?", + "extra": [ + "Meow! I hear Meow Sunrise is meow" + ] + }, + "night": { + "default": "What would you like to meow meow?", + "extra": [ + "Meow? I hear The Meow is meow." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} - E{{episode}}", + "types": { + "movie": "Meow Movie", + "show": "Meow Show" + } + }, + "navigation": { + "banner": { + "offline": "Check your meow connection" + }, + "menu": { + "about": "Meow us", + "logout": "Meow out", + "register": "Meow to meow", + "settings": "Meow", + "support": "Meow" + } + }, + "notFound": { + "badge": "Not meow", + "goHome": "Back to meow", + "message": "We looked everywhere: under the meow, in the meow, behind the meow but ultimately couldn't find the meow you are looking for.", + "title": "Couldn't find that meow" + }, + "overlays": { + "close": "Meow" + }, + "player": { + "back": { + "default": "Back to meow", + "short": "Back meow" + }, + "casting": { + "enabled": "Casting to meow..." + }, + "menus": { + "downloads": { + "disclaimer": "Downloads are taken directly from the meow. meow-flix does not have meow over how the meow are meow.", + "downloadSubtitle": "Download current meow", + "downloadVideo": "Meow", + "hlsDisclaimer": "Downloads are taken directly from the meow. Meow-flix does not have control over how the downloads are meow. please note that you are downloading Meow playlist, this is intended for minions familiar with advanced multimedia meow.", + "onAndroid": { + "1": "To meow on Meow, click the meow meow then, on the new meow, tap and hold on the meow, then select meow.", + "shortTitle": "Meow / Meow", + "title": "Meow" + }, + "onIos": { + "1": "To meow on Meow, click the meow meow then, on the new meow, click , then Meow to meow .", + "shortTitle": "Meow / Meow", + "title": "Meow" + }, + "onPc": { + "1": "On PC, click the meow meow then, on the new meow, right click the meow and select Meow", + "shortTitle": "Meow / PC", + "title": "Meow" + }, + "title": "Meow" + }, + "episodes": { + "button": "Meow", + "emptyState": "There are no meow in this meow, check back meow!", + "episodeBadge": "E{{episode}}", + "loadingError": "Error loading meow", + "loadingList": "Loading...", + "loadingTitle": "Loading...", + "unairedEpisodes": "One or more meow in this meow have been meow because they haven't been aired yet." + }, + "playback": { + "speedLabel": "Meow speed", + "title": "Meow settings" + }, + "quality": { + "automaticLabel": "Meow", + "hint": "You can meow <0>meow to get different meow meow.", + "iosNoQuality": "Due to Meow limitations, meow selection is not meow on Meow for this meow. You can meow <0>meow to get different meow meow.", + "title": "Meow" + }, + "settings": { + "downloadItem": "Meow", + "enableSubtitles": "Enable meow", + "experienceSection": "Meow Viewing experience", + "playbackItem": "Meow settings", + "qualityItem": "Meow", + "sourceItem": "Meow sources", + "subtitleItem": "Meow settings", + "videoSection": "Meow Video settings" + }, + "sources": { + "failed": { + "text": "There was an meow while trying to meow any meow, please try a different meow.", + "title": "Meow to meow" + }, + "noEmbeds": { + "text": "We were unable to meow any meow, please try a different meow.", + "title": "No meow found" + }, + "noStream": { + "text": "This meow has no meow for this meow or meow.", + "title": "Meow stream" + }, + "title": "Meow", + "unknownOption": "Meow" + }, + "subtitles": { + "customChoice": "Select meows from meow", + "customizeLabel": "Customize meows", + "offChoice": "Off", + "settings": { + "backlink": "Custom meows", + "delay": "Meow delay", + "fixCapitals": "Fix meows" + }, + "title": "Meows", + "unknownLanguage": "Whaat? Unknown meow!" + } + }, + "metadata": { + "api": { + "text": "Could not load API meow, please check your meow connection.", + "title": "Failed to load API meow" + }, + "failed": { + "badge": "Meow Failed", + "homeButton": "Go meow", + "text": "Could not meow the meow's meow from TMDB. Please meow whether TMDB is down or meow on your meow connection.", + "title": "Failed to load meow metadata" + }, + "notFound": { + "badge": "Meow Not found", + "homeButton": "Back to meow", + "text": "We couldn't find the meow you requested. Either it's been meow or you tampered with the meow.", + "title": "Couldn't find that meow." + } + }, + "nextEpisode": { + "cancel": "Meow", + "next": "Next meow" + }, + "playbackError": { + "badge": "Meow Playback error", + "errors": { + "errorAborted": "The fetching of the meow was aborted by the user's meow.", + "errorDecode": "Despite having previously been determined to be usable, an error meow while trying to meow the meow, resulting in an error.", + "errorGenericMedia": "Unknown meow error occurred.", + "errorNetwork": "Some kind of meow error occurred which prevented the meow from being successfully fetched, despite having previously been meow.", + "errorNotSupported": "The meow or meow provider object is not meow." + }, + "homeButton": "Go home", + "text": "There was an error trying to play the meow. Please try again.", + "title": "Failed to play meow video!" + }, + "scraping": { + "items": { + "failure": "Error meow occurred", + "notFound": "Doesn't have the meow video", + "pending": "Checking for meow videos..." + }, + "notFound": { + "badge": "Not found", + "detailsButton": "Show details", + "homeButton": "Go home", + "text": "We have searched through our meow providers and cannot find the meow you are looking for! We do not host the meow and have no control over what is available. Please click 'Show details' below for more details.", + "title": "We couldn't find that meow" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} left • Finish at {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Please verify that you are meow by completing the meow on the right. This is to keep meow-flix meow!", + "error": "Failed to verify your meowness. Please try meow.", + "title": "We meow to verify that you're meow", + "verifyingHumanity": "Verifying your meow..." + } + }, + "screens": { + "dmca": { + "text": "Very long and boring meow.", + "title": "Meow" + }, + "loadingApp": "Loading meow", + "loadingUser": "Loading your meow", + "loadingUserError": { + "logout": "Meow", + "reset": "Meow meow meow", + "text": "Failed to meow your meow", + "textWithReset": "Failed to meow your meow from your meow meow, meow to meow back to the meow meow?" + }, + "migration": { + "failed": "Meow to meow your meow.", + "inProgress": "Please meow, we are meow your meow. This shouldn't meow long." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Meow name", + "deviceNamePlaceholder": "Meow phone", + "editProfile": "Meow", + "logoutButton": "Meow out" + }, + "actions": { + "delete": { + "button": "Meow", + "confirmButton": "Meow", + "confirmDescription": "Meow you meow to meow your meow? All your meows will be meow!", + "confirmTitle": "Meow you meow?", + "text": "Whaaat? This meow is irreversible. All meows will be meow and nothing can be meow.", + "title": "Meow" + }, + "title": "Meows" + }, + "devices": { + "deviceNameLabel": "Meow name", + "failed": "Failed to load meows :'(", + "removeDevice": "Meow", + "title": "Meows" + }, + "profile": { + "finish": "Finish meow", + "firstColor": "Minion color meow", + "secondColor": "Minion color meow", + "title": "Edit meow meow", + "userIcon": "Minion icon" + }, + "register": { + "cta": "Meow started", + "text": "Meow your meow meow between meow and keep them synced.", + "title": "Meow to the meow" + }, + "title": "Meow" + }, + "appearance": { + "activeTheme": "Meow", + "themes": { + "blue": "Meow", + "default": "Meow", + "gray": "Meow", + "red": "Meow", + "teal": "Meow" + }, + "title": "Meow" + }, + "connections": { + "server": { + "description": "Meow you would like to meow to a meow meow to store your meow, meow this and meow the URL.", + "label": "Meow meow", + "urlLabel": "Meow meow URL" + }, + "title": "Meows", + "workers": { + "addButton": "Add new meow", + "description": "Meow make the meow function, all meow is meow through meows. Meow this if you meow to meow your own meows.", + "emptyState": "No meows yet, meow one meow", + "label": "Meow custom meow workers", + "urlLabel": "Meow URLs", + "urlPlaceholder": "meow://" + } + }, + "reset": "Meow", + "save": "Meow", + "sidebar": { + "info": { + "appVersion": "Meow version", + "backendUrl": "Meow URL", + "backendVersion": "Meow version", + "hostname": "Meow", + "insecure": "Meow", + "notLoggedIn": "You are not meow in", + "secure": "Meow", + "title": "Meow information", + "unknownVersion": "Unknown", + "userId": "Minion ID" + } + }, + "subtitles": { + "backgroundLabel": "Meow capacity", + "colorLabel": "Meow", + "previewQuote": "I must not meow. Meow is the minion-killer.", + "textSizeLabel": "Meow size", + "title": "Meows" + }, + "unsaved": "Whaaat? You have unsaved meows" + } +} diff --git a/src/assets/locales/km.json b/src/assets/locales/km.json new file mode 100644 index 0000000..e2d349c --- /dev/null +++ b/src/assets/locales/km.json @@ -0,0 +1,38 @@ +{ + "about": { + "description": "SkoolTV គឺ​ជា​កម្មវិធី​បណ្ដាញវែបសាយ​ដែល​ស្វែងរក​អ៊ីនធឺណិត​សម្រាប់​ការ​ផ្សាយ។ ក្រុមនេះមានគោលបំណងសម្រាប់វិធីសាស្រ្តតិចតួចបំផុតក្នុងការប្រើប្រាស់មាតិកា។", + "faqTitle": "សំណួរទូទៅ", + "q1": { + "body": "SkoolTV មិនផ្ទុកមាតិកាណាមួយទេ។ នៅពេលអ្នកចុចលើអ្វីមួយដើម្បីមើល អ៊ីនធឺណិតត្រូវបានស្វែងរកសម្រាប់មេឌៀដែលបានជ្រើសរើស (នៅលើអេក្រង់ផ្ទុក និងក្នុងផ្ទាំង 'ប្រភពវីដេអូ' អ្នកអាចឃើញប្រភពណាមួយដែលអ្នកកំពុងប្រើ)។ ប្រព័ន្ធផ្សព្វផ្សាយមិនដែលត្រូវបានបង្ហោះដោយគេហទំព័រភាពយន្តនោះទេ អ្វីគ្រប់យ៉ាងគឺតាមរយៈយន្តការស្វែងរកនេះ។", + "title": "តើមាតិកាបានមកពីណា?" + }, + "q2": { + "title": "តើខ្ញុំអាចស្នើសុំកម្មវិធី ឬ ភាពយន្តបាននៅឯណា?" + }, + "q3": { + "body": "លទ្ធផលស្វែងរករបស់យើងត្រូវបានដំណើរការដោយ The Movie Database (TMDB) ហើយបង្ហាញដោយមិនខ្វល់ពីប្រភពរបស់យើងមានខ្លឹមសារឬ​អត់ទេ។", + "title": "លទ្ធផលស្វែងរកបង្ហាញកម្មវិធី ឬ ភាពយន្ត ហេតុអ្វីខ្ញុំមិនអាចមើលបាន?" + }, + "title": "អំពី SkoolTV" + }, + "actions": { + "copied": "បានចម្លង", + "copy": "ចម្លង" + }, + "auth": { + "createAccount": "មិនទាន់មានគណនីមែនទេ? <0>បង្កើតគណនី", + "deviceNameLabel": "ឈ្មោះឧបករណ៍", + "deviceNamePlaceholder": "ទូរស័ព្ទផ្ទាល់ខ្លួន", + "generate": { + "description": "ឃ្លាសម្ងាត់របស់អ្នកដើរតួជាឈ្មោះអ្នកប្រើប្រាស់ និងពាក្យសម្ងាត់របស់អ្នក។ ត្រូវប្រាកដថារក្សាវាឱ្យមានសុវត្ថិភាព ព្រោះអ្នកនឹងត្រូវបញ្ចូលវាដើម្បីចូលគណនីរបស់អ្នក", + "next": "ខ្ញុំបានរក្សាទុកឃ្លាសម្ងាត់របស់ខ្ញុំរួចហើយ", + "passphraseFrameLabel": "ឃ្លាសម្ងាត់", + "title": "ឃ្លាសម្ងាត់របស់អ្នក" + }, + "hasAccount": "មានគណនីរួចហើយ? <0>ចូលទីនេះ", + "login": { + "description": "សូមបញ្ចូលឃ្លាសម្ងាត់របស់អ្នក ដើម្បីចូលគណនីរបស់អ្នក", + "deviceLengthError": "សូមបញ្ចូលឈ្មោះឧបករណ៍" + } + } +} diff --git a/src/assets/locales/ko.json b/src/assets/locales/ko.json new file mode 100644 index 0000000..2a3f2ed --- /dev/null +++ b/src/assets/locales/ko.json @@ -0,0 +1,547 @@ +{ + "about": { + "description": "SkoolTV은 인터넷에서 스트림을 검색하는 웹 애플리케이션입니다. 저희 팀은 콘텐츠 소비에 대한 최소한의 접근 방식을 지향합니다.", + "faqTitle": "자주 묻는 질문", + "q1": { + "body": "SkoolTV은 어떠한 콘텐츠도 호스팅하지 않습니다. 시청할 콘텐츠를 클릭하면 인터넷에서 선택한 미디어가 검색됩니다(로딩 화면과 '비디오 소스' 탭에서 사용 중인 소스를 확인할 수 있습니다). 무비웹에서 미디어를 업로드하지 않으며, 모든 것이 이 검색 메커니즘을 통해 이루어집니다.", + "title": "콘텐츠의 출처는 어디인가요?" + }, + "q2": { + "body": "프로그램이나 영화를 요청할 수 없으며, SkoolTV은 어떠한 콘텐츠도 관리하지 않습니다. 모든 콘텐츠는 인터넷의 소스를 통해 볼 수 있습니다.", + "title": "프로그램이나 영화는 어디에서 요청할 수 있나요?" + }, + "q3": { + "body": "검색 결과는 영화 데이터베이스(TMDB)를 기반으로 하며, 출처에 실제 콘텐츠가 있는지 여부와 관계없이 표시됩니다.", + "title": "검색 결과에 프로그램이나 영화가 표시되는데 왜 재생할 수 없나요?" + }, + "title": "SkoolTV에 대하여" + }, + "actions": { + "copied": "복사되었습니다", + "copy": "복사하기" + }, + "auth": { + "createAccount": "계정이 없으십니까? <0>계정을 생성하세요.", + "deviceNameLabel": "기기명", + "deviceNamePlaceholder": "개인 휴대폰", + "generate": { + "description": "암호문은 사용자 아이디와 비밀번호 역할을 합니다. 계정에 로그인할 때 발급 받은 암호문을 입력해야 하므로 안전하게 보관하세요", + "next": "암호문을 저장했습니다", + "passphraseFrameLabel": "암호문", + "title": "암호 문구" + }, + "hasAccount": "이미 계정을 보유하고 있으십니까? <0>로그인 하기.", + "login": { + "description": "계정에 로그인하기위해 암호문을 입력하세요", + "deviceLengthError": "기기명을 입력하세요", + "passphraseLabel": "12단어 암호 문구", + "passphrasePlaceholder": "암호 문구", + "submit": "로그인", + "title": "계정에 로그인하기", + "validationError": "틀리거나 잘못된 암호문입니다" + }, + "register": { + "information": { + "color1": "프로필 색상 1", + "color2": "프로필 색상 2", + "header": "기기명을 입력하고 원하는 색상과 사용자 아이콘을 선택하세요", + "icon": "유저 아이콘", + "next": "다음", + "title": "계정 정보" + } + }, + "trust": { + "failed": { + "text": "올바르게 구성하셨습니까?", + "title": "서버 연결에 실패했습니다" + }, + "host": "<0>{{hostname}}에 연결 중입니다 - 계정을 만들기 전에 신뢰하는지 확인해 주세요", + "no": "뒤로 가기", + "noHost": "서버가 구성되어 있지 않기 때문에 계정을 만들 수 없습니다", + "noHostTitle": "서버가 구성되지 않았습니다!", + "title": "이 서버를 신뢰하십니까?", + "yes": "네, 신뢰합니다" + }, + "verify": { + "description": "암호문을 저장했는지 확인하고 계정을 만들려면 앞서 입력한 암호문을 입력하세요", + "invalidData": "데이터가 유효하지 않습니다", + "noMatch": "암호문이 일치하지 않습니다", + "passphraseLabel": "12단어 암호 문구", + "recaptchaFailed": "캡챠인증 실패", + "register": "계정 생성", + "title": "암호문 확인" + } + }, + "errors": { + "badge": "어딘가 고장났습니다", + "details": "에러 상세", + "reloadPage": "페이지 새로고침", + "showError": "에러 상세 보기", + "title": "오류가 발생했습니다!" + }, + "footer": { + "legal": { + "disclaimer": "면책 조항", + "disclaimerText": "SkoolTV은 어떠한 파일도 호스팅하지 않으며, 제3자 서비스에 대한 링크만 제공합니다. 법적 문제는 파일 호스트 및 제공업체와 해결해야 합니다. 동영상 제공업체가 표시하는 미디어 파일에 대해 SkoolTV은 책임을 지지 않습니다." + }, + "links": { + "discord": "디스코드", + "dmca": "DMCA", + "github": "깃허브" + }, + "tagline": "이 오픈 소스 스트리밍 앱으로 좋아하는 프로그램과 영화를 시청하세요." + }, + "global": { + "name": "무비-웹", + "pages": { + "about": "소개", + "dmca": "DMCA", + "login": "로그인", + "onboarding": "기본 구성", + "pagetitle": "{{title}} - SkoolTV", + "register": "회원가입", + "settings": "설정" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "북마크" + }, + "continueWatching": { + "sectionTitle": "이어보기" + }, + "mediaList": { + "stopEditing": "수정 중지" + }, + "search": { + "allResults": "이게 전부입니다!", + "failed": "미디어 검색에 실패하였습니다, 다시 시도해주세요!", + "loading": "로딩...", + "noResults": "검색결과가 없습니다!", + "placeholder": { + "default": "무엇을 보고 싶으신가요?", + "extra": [ + "무엇을 탐험하고 싶으신가요?", + "관심 목록에 무엇이 있나요?", + "당신이 가장 좋아하는 영화는?", + "당신이 가장 좋아하는 시리즈는?" + ] + }, + "sectionTitle": "검색 결과" + }, + "titles": { + "day": { + "default": "오늘 오후에 무엇을 보고 싶으신가요?", + "extra": [ + "모험을 즐기고 싶으신가요? 쥬라기 공원이 완벽한 선택이 될 수 있습니다." + ] + }, + "morning": { + "default": "오늘 아침에 무엇을 보고 싶으신가요?", + "extra": [ + "Before Sunrise가 좋다고 들었어요" + ] + }, + "night": { + "default": "오늘 밤에 무엇을 보고 싶으신가요?", + "extra": [ + "피곤하신가요? The Exorcist가 좋다고 들었어요." + ] + } + } + }, + "media": { + "episodeDisplay": "시즌{{season}} {{episode}}화", + "types": { + "movie": "영화", + "show": "쇼" + } + }, + "navigation": { + "banner": { + "offline": "인터넷 연결을 확인해주세요" + }, + "menu": { + "about": "서비스 소개", + "logout": "로그아웃", + "register": "클라우드 동기화", + "settings": "설정", + "support": "지원" + } + }, + "notFound": { + "badge": "찾을 수 없음", + "goHome": "메인으로 돌아가기", + "message": "쓰레기통 아래, 옷장, 프록시 뒤 등 모든 곳을 찾아보았지만 결국 원하는 페이지를 찾을 수 없었습니다.", + "title": "해당 페이지를 찾을 수 없습니다" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "취소", + "confirm": "기본 설정 사용", + "description": "기본 설정은 쾌적한 스트리밍 환경을 제공하지 않으므로 다소 시청이 불편할 수 있습니다.", + "title": "정말 진행할까요?" + }, + "extension": { + "back": "돌아가기", + "explainer": "확장 프로그램을 이용하므로서, 저희가 제공해야 할 최고 화질의 영상을 시청할 수 있습니다. 간단한 설치 한 번으로요.", + "explainerIos": "죄송하지만, 해당 확장 프로그램은 애플 모바일 환경에서 지원하지 않습니다, 돌아가기을 눌러 다른 옵션을 선택해 주세요.", + "extensionHelp": "확장 프로그램을 설치했지만 인식되지 않는다면, 브라우저의 확장 프로그램 메뉴를 열어 해당 확장 프로그램을 클릭한 후 화면의 안내를 따라주세요.", + "linkChrome": "크롬 확장 프로그램 설치", + "linkFirefox": "파이어폭스 확장 프로그램 설치", + "notDetecting": "크롬 환경에서 설치했지만 사이트가 인식하지 못하나요? 새로고침을 시도해 보세요!", + "notDetectingAction": "새로고침", + "status": { + "disallowed": "이 페이지는 확장 프로그램 사용이 불가능합니다", + "disallowedAction": "확장 프로그램 사용", + "failed": "상태 요청 실패", + "loading": "확장 프로그램 설치를 기다리는 중입니다", + "outdated": "확장 프로그램의 버전이 오래됨", + "success": "확장 프로그램 정상 작동 중!" + }, + "submit": "계속", + "title": "확장 프로그램으로 시작해 봅시다" + }, + "proxy": { + "back": "돌아가기", + "explainer": "프록시 방식을 통하여, 직접 운영하는 프록시를 만들어 훌륭한 화질의 영상을 시청할 수 있습니다.", + "input": { + "errorConnection": "프록시에 연결할 수 없음", + "errorInvalidUrl": "유효하지 않은 URL", + "errorNotProxy": "프록시가 아닌 웹사이트가 입력되었습니다", + "label": "프록시 URL", + "placeholder": "https://" + }, + "link": "프록시 만드는 방법 배우기", + "submit": "프록시 제출", + "title": "새로운 프록시를 만들어 봅시다" + }, + "start": { + "explainer": "가장 쾌적한 송출을 위하여 사용하고 싶은 송출 방식을 선택해야 합니다.", + "options": { + "default": { + "text": "화질 좋은 영상을 원하지는 않아요, <0 /><1>기본 설정 사용" + }, + "extension": { + "action": "확장 프로그램 설치", + "description": "고화질의 영상을 시청하기 위하여 브라우저 확장 프로그램을 설치해주세요.", + "quality": "최고의 화질", + "title": "브라우저 확장 프로그램" + }, + "proxy": { + "action": "프록시 설정", + "description": "단 5분 만에 프록시를 설정하고 쾌적한 송출 환경을 이용하세요.", + "quality": "좋은 화질", + "title": "커스텀 프록시" + } + }, + "title": "SkoolTV의 설정을 진행해 봅시다" + } + }, + "overlays": { + "close": "닫기" + }, + "player": { + "back": { + "default": "메인으로 돌아가기", + "short": "뒤로가기" + }, + "casting": { + "enabled": "장치로 전송 중..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "HLS 플레이리스트 링크 복사하기", + "disclaimer": "다운로드는 제공업체에서 직접 가져옵니다. SkoolTV은 다운로드 제공 방식을 통제할 수 없습니다.", + "downloadSubtitle": "현재 자막 다운로드", + "downloadVideo": "영상 다운로드", + "hlsDisclaimer": "다운로드는 제공업체에서 직접 가져옵니다. SkoolTV은 다운로드 제공 방식을 통제할 수 없습니다.

사용자께서는 HLS 플레이리스트를 다운로드 하고 있으며, 이는 고급 스트리밍 포맷의 사용에 익숙하지 않은 사용자에게는 추천하지 않는다는 것을 유의해주세요. 혹은 다른 소스와 포맷을 이용하여 보세요.", + "onAndroid": { + "1": "Android에서 다운로드하려면 다운로드 버튼을 클릭한 다음 새 페이지에서 동영상을 길게 눌러저장을 선택합니다.", + "shortTitle": "다운로드 / Android", + "title": "Android에서 다운로드하기" + }, + "onIos": { + "1": "iOS에서 다운로드하려면 다운로드 버튼을 클릭한 다음 새 페이지에서 를 클릭한 다음 파일로 저장 을 클릭합니다.", + "shortTitle": "다운로드 / iOS", + "title": "iOS에서 다운로드하기" + }, + "onPc": { + "1": "PC에서는 다운로드 버튼을 클릭한 다음 새 페이지에서 동영상을 마우스 오른쪽 버튼으로 클릭하고 다른 이름으로 동영상 저장을 선택합니다", + "shortTitle": "다운로드 / PC", + "title": "PC에서 다운로드하기" + }, + "title": "다운로드" + }, + "episodes": { + "button": "회차", + "emptyState": "이번 시즌에는 에피소드가 없으니 나중에 다시 확인하세요!", + "episodeBadge": "{{episode}}화", + "loadingError": "시즌 로딩중 에러 발생", + "loadingList": "로딩...", + "loadingTitle": "로딩...", + "unairedEpisodes": "해당 시즌의 다수의 에피소드들이 아직 방송되지 않은 이유로 비공개 처리되었습니다." + }, + "playback": { + "speedLabel": "재생 속도", + "title": "재생 설정" + }, + "quality": { + "automaticLabel": "자동 품질 제어", + "hint": "<0>소스 전환을 사용하여 다양한 화질 옵션을 확인할 수 있습니다.", + "iosNoQuality": "Apple에서 정의한 제한 사항으로 인해 이 소스에 대해 iOS에서 품질 선택을 사용할 수 없습니다. <0>다른 소스로 전환하여 다른 품질 옵션을 사용해 볼 수 있습니다.", + "title": "화질" + }, + "settings": { + "downloadItem": "다운로드", + "enableSubtitles": "자막 활성화", + "experienceSection": "시청 경험", + "playbackItem": "재생 설정", + "qualityItem": "화질", + "sourceItem": "영상 소스", + "subtitleItem": "자막 설정", + "videoSection": "영상 설정" + }, + "sources": { + "failed": { + "text": "동영상을 찾는 동안 오류가 발생했습니다. 다른 소스를 사용해 보세요.", + "title": "스크래핑 실패" + }, + "noEmbeds": { + "text": "임베드를 찾을 수 없습니다. 다른 소스를 사용해 보세요.", + "title": "발견된 임베드없음" + }, + "noStream": { + "text": "이 소스에는 해당 영화 또는 프로그램에 대한 스트림이 없습니다.", + "title": "발견된 스트림 없음" + }, + "title": "소스", + "unknownOption": "알수없음" + }, + "subtitles": { + "customChoice": "파일에서 자막 선택하기", + "customizeLabel": "사용자 정의", + "offChoice": "끔", + "settings": { + "backlink": "자막 커스텀", + "delay": "자막 딜레이", + "fixCapitals": "대문자 표기 수정" + }, + "title": "자막", + "unknownLanguage": "알수없음" + } + }, + "metadata": { + "api": { + "text": "API 메타데이터를 불러올 수 없었습니다. 인터넷 연결 상태를 확인해 주세요.", + "title": "API 메타데이터을 읽어오지 못했습니다" + }, + "dmca": { + "badge": "삭제됨", + "text": "이 미디어는 저작권 침해 및 신고로 인하여 더 이상 이용이 불가합니다.", + "title": "미디어가 삭제됨" + }, + "extensionPermission": { + "badge": "권한 없음", + "button": "확장 프로그램 사용", + "text": "브라우저의 확장 프로그램을 사용하기 위해서는 사용자의 권한이 필요합니다.", + "title": "확장 프로그램 설정" + }, + "failed": { + "badge": "실패함", + "homeButton": "메인으로 돌아가기", + "text": "TMDB에서 미디어의 메타데이터를 로드할 수 없습니다. 인터넷 연결에서 TMDB가 다운되었거나 차단되었는지 확인하세요.", + "title": "메타데이터를 불러오지 못했습니다" + }, + "notFound": { + "badge": "찾을 수 없음", + "homeButton": "메인으로 돌아가기", + "text": "요청하신 미디어를 찾을 수 없습니다. 미디어가 삭제되었거나 사용자가 URL을 변조했습니다.", + "title": "해당 미디어를 찾을 수 없습니다." + } + }, + "nextEpisode": { + "cancel": "닫기", + "next": "다음 회차" + }, + "playbackError": { + "badge": "재생 에러", + "errors": { + "errorAborted": "사용자의 요청으로 미디어 가져오기가 중단되었습니다.", + "errorDecode": "이전에 사용 가능한 것으로 확인되었지만 미디어 리소스를 디코딩하는 동안 오류가 발생하여 오류가 발생했습니다.", + "errorGenericMedia": "알 수 없는 미디어 오류가 발생했습니다.", + "errorNetwork": "네트워크 오류가 발생하여 이전에 미디어를 사용할 수 있었으나 미디어를 성공적으로 가져오지 못했습니다.", + "errorNotSupported": "미디어 또는 미디어 공급자 개체는 지원되지 않습니다." + }, + "homeButton": "메인으로 돌아가기", + "text": "미디어를 재생하는 동안 오류가 발생했습니다. 다시 시도해 주세요.", + "title": "동영상 재생에 실패했습니다!" + }, + "scraping": { + "items": { + "failure": "오류 발생", + "notFound": "동영상이 없습니다", + "pending": "동영상 확인 중..." + }, + "notFound": { + "badge": "찾을 수 없음", + "detailsButton": "상세 보기", + "homeButton": "메인으로 돌아가기", + "text": "제공업체를 통해 검색했지만 원하는 미디어를 찾을 수 없습니다! 당사는 해당 미디어를 호스팅하지 않으며 이용 가능한 미디어에 대한 통제권이 없습니다. 자세한 내용을 보려면 아래의 '세부 정보 보기'를 클릭하세요.", + "title": "찾을 수 없습니다" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} 남음 • {{timeFinished, datetime}}에 종료", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "우측에 있는 캡챠를 통해 인간임을 인증해주새요. 이것은 무비-웹의 안전을 위한 것입니다!", + "error": "인류애를 인증하는 데에 실패했습니다. 다시 시도해주새요.", + "title": "당신이 로봇이 아닌지 확인해야 합니다.", + "verifyingHumanity": "인류애 인증 중..." + } + }, + "screens": { + "dmca": { + "text": "SkoolTV의 DMCA 문의 페이지에 오신 것을 환영합니다! 당사는 지적 재산권을 존중하며 저작권 관련 문제를 신속하게 해결하고자 합니다. 귀하의 저작권이 있는 저작물이 당사 플랫폼에서 부적절하게 사용되었다고 생각되는 경우, 아래 이메일로 자세한 DMCA 통지를 보내주시기 바랍니다. 저작권이 있는 자료에 대한 설명, 연락처 정보, 선의의 신념을 담은 진술서를 포함하시기 바랍니다. 당사는 이러한 문제를 신속하게 해결하기 위해 최선을 다하고 있으며, SkoolTV을 창의성과 저작권을 존중하는 공간으로 유지하는 데 협조해 주셔서 감사합니다.", + "title": "DMCA" + }, + "loadingApp": "애플리케이션 로딩 중", + "loadingUser": "프로필 로 중", + "loadingUserError": { + "logout": "로그아웃", + "reset": "사용자 지정 서버 초기화", + "text": "프로필을 로드하지 못했습니다", + "textWithReset": "사용자 지정 서버에서 프로필을 불러오는 데 실패하여 기본 서버로 다시 초기화하시겠습니까?" + }, + "migration": { + "failed": "데이터를 마이그레이션하지 못했습니다.", + "inProgress": "데이터를 마이그레이션하는 중이니 잠시만 기다려 주세요. 오래 걸리지 않을 것입니다." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "기기명", + "deviceNamePlaceholder": "개인 휴대폰", + "editProfile": "수정", + "logoutButton": "로그아웃" + }, + "actions": { + "delete": { + "button": "계정 삭제", + "confirmButton": "계정 삭제", + "confirmDescription": "정말 계정을 삭제하시겠습니까? 모든 데이터가 손실됩니다!", + "confirmTitle": "진행 할까요?", + "text": "이 작업은 되돌릴 수 없습니다. 모든 데이터가 삭제되며 아무것도 복구할 수 없습니다.", + "title": "계정 삭제" + }, + "title": "작업" + }, + "devices": { + "deviceNameLabel": "기기명", + "failed": "세션을 로드하지 못했습니다", + "removeDevice": "제거", + "title": "기기" + }, + "profile": { + "finish": "수정 완료", + "firstColor": "프로필 색상 1", + "secondColor": "프로필 색상 2", + "title": "프로필 이미지 수정", + "userIcon": "유저 아이콘" + }, + "register": { + "cta": "시작하기", + "text": "기기 간에 시계 진행 상황을 공유하고 동기화 상태를 유지하세요.", + "title": "클라우드에 동기화" + }, + "title": "계정" + }, + "appearance": { + "activeTheme": "활성화", + "themes": { + "blue": "블루", + "default": "기본", + "gray": "그레", + "red": "레드", + "teal": "청록" + }, + "title": "외관" + }, + "connections": { + "server": { + "description": "사용자 지정 백엔드에 연결하여 데이터를 저장하려면 이 기능을 활성화하고 URL을 입력합니다. <0>Instructions.", + "label": "사용자 지정 서버", + "urlLabel": "사용자 지정 서버 URL" + }, + "setup": { + "doSetup": "설정 진행하기", + "errorStatus": { + "description": "아직 완료되지 않은 설정이 있는 것 같습니다.", + "title": "완료되지 않은 설정이 있습니다" + }, + "itemError": "설정에 문제가 발생하였습니다. 설정을 다시 진행하여 주세요.", + "items": { + "default": "기본 설정", + "extension": "확장 프로그램", + "proxy": "커스텀 프록시" + }, + "redoSetup": "설정을 다시하기", + "successStatus": { + "description": "찜한 리스트의 영상을 시청할 모든 준비가 끝났습니다.", + "title": "모든 설정이 완료되었습니다!" + }, + "unsetStatus": { + "description": "기본 구성을 진행하기 위하여 오른쪽 버튼을 눌러주세요.", + "title": "기본 구성이 완료되지 않았습니다" + } + }, + "title": "연결", + "workers": { + "addButton": "새 워커 추가하기", + "description": "애플리케이션이 작동하도록 하기 위해 모든 트래픽은 프록시를 통해 라우팅됩니다. 직접 워커를 사용하려면 이 옵션을 사용 설정하세요. <0>Instructions.", + "emptyState": "아직 워커가 없는 경우 아래에서 워커를 추가하세요", + "label": "사용자 지정 프록시 워커 사용", + "urlLabel": "워커 URL", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "애플리케이션 언어", + "languageDescription": "애플리케이션 전체에 적용될 언어.", + "thumbnail": "썸네일 생성", + "thumbnailDescription": "대부분의 영상들은 섬네일을 가지고 있지 않습니다. 사용자가 직접 영상의 섬네일을 생성할 수 있지만, 잦은 버퍼링을 일으킬 수 있습니다.", + "thumbnailLabel": "섬네일 생성", + "title": "환경 설정" + }, + "reset": "초기화", + "save": "저장", + "sidebar": { + "info": { + "appVersion": "앱 버전", + "backendUrl": "백엔드 URL", + "backendVersion": "백엔드 버전", + "hostname": "호스트명", + "insecure": "안전하지 않음", + "notLoggedIn": "로그인하지 않으셨습니다", + "secure": "안전함", + "title": "앱 정보", + "unknownVersion": "알 수 없음", + "userId": "유저 ID" + } + }, + "subtitles": { + "backgroundBlurLabel": "배경 흐림", + "backgroundLabel": "배경 투명도", + "colorLabel": "색상", + "previewQuote": "두려워해서는 안 됩니다. 두려움은 마음을 죽이는 존재입니다.", + "textSizeLabel": "글자 크기", + "title": "자막" + }, + "unsaved": "저장하지 않은 변경 사항이 있습니다" + } +} diff --git a/src/assets/locales/lv.json b/src/assets/locales/lv.json new file mode 100644 index 0000000..34eae88 --- /dev/null +++ b/src/assets/locales/lv.json @@ -0,0 +1,391 @@ +{ + "about": { + "description": "SkoolTV ir tīmekļa lietojumprogramma, kas internetā meklē straumes. Komandas mērķis ir galvenokārt minimālistiska pieeja satura patērēšanai.", + "faqTitle": "Bieži jautājumi", + "q1": { + "body": "SkoolTV neveic nekādu saturu. Noklikšķinot uz kāda skatāma satura, internetā tiek meklēts atlasītais multivides saturs (ielādes ekrānā un cilnē “video avoti” varat redzēt, kuru avotu izmantojat). Multivide nekad netiek augšupielādēta, izmantojot filmu tīmekli, viss notiek caur šo meklēšanas mehānismu.", + "title": "No kurienes nāk saturs?" + }, + "q2": { + "body": "Nav iespējams pieprasīt pārraidi vai filmu, filmu tīmeklis nepārvalda saturu. Viss saturs tiek skatīts, izmantojot avotus internetā.", + "title": "Kur es varu pieprasīt filmu vai seriālu?" + }, + "q3": { + "body": "Mūsu meklēšanas rezultātus nodrošina filmu datu bāze (TMDB), un tie tiek rādīti neatkarīgi no tā, vai mūsu avotos patiešām ir saturs.", + "title": "Meklēšanas rezultātos tiek parādīta seriāls vai filma. Kāpēc es nevaru to atskaņot?" + }, + "title": "Par " + }, + "actions": { + "copied": "Nokopēts", + "copy": "Kopēt" + }, + "auth": { + "createAccount": "Nav vēl konts? <0>Taisīt kontu.", + "deviceNameLabel": "Ierīces nosaukums", + "deviceNamePlaceholder": "Personiskais telefons", + "generate": { + "description": "Tava paroles frāze ir kā vārds un parole. Esi drošs ka turi to drošibā jo tev vajadzēs to izmantot lai ieietu kontā", + "next": "Esmu saglabājis paroles frāzi", + "title": "Tava paroles frāze" + }, + "hasAccount": "Tev jau ir konts> <0>Ienāc šeit.", + "login": { + "description": "Lūdzu ievadi paroles frāzi lai ieietu kontā", + "deviceLengthError": "Lūdzu ievadi ierīces nosaukumu", + "passphraseLabel": "12-Vārdu paroles frāze", + "passphrasePlaceholder": "Paroles frāze", + "submit": "Ieiet", + "title": "Reģistrējies savā kontā", + "validationError": "Nepareizs vai nepabeigts paroles frāze" + }, + "register": { + "information": { + "color1": "Profila krāsa viens", + "color2": "Profila krāsa divi", + "header": "Ievadi ierīces vārdu un izvēlies krāsu un profila ikonu kādu gribi", + "icon": "Profila ikona", + "next": "Nakamais", + "title": "Konta informācija" + } + }, + "trust": { + "failed": { + "text": "Vai tu konfigurēji to pareizi?", + "title": "Neizdevās savienot serveri" + }, + "host": "Tu piesaisties <0>{{hostname}} - apstiprini ka uzticies pirms taisi kontu", + "no": "Atpakaļ", + "title": "Vai tu uzticies šim serverim?", + "yes": "Es uzticos šim serverim" + }, + "verify": { + "description": "Lūdzu ievadi paroles frāzi ko ieguvi iepriekš lai apstiprinātu ka saglabāji un uztaisītu kontu", + "invalidData": "Dati nav pieejami", + "noMatch": "paroles frāze nesakrīt", + "passphraseLabel": "Tava 12-vārdu paroles frāze", + "recaptchaFailed": "ReCaptcha apstiprināšana neizdevās", + "register": "Izveidot kontu", + "title": "Apstiprini paroles frāzi" + } + }, + "errors": { + "badge": "Saplīsa", + "details": "Kļūdas deteļas", + "reloadPage": "Atjaunot lapu", + "showError": "Radīt kļūdas deteļas", + "title": "Mēs sastapāmies ar kļūdu!" + }, + "footer": { + "legal": { + "disclaimer": "Atruna", + "disclaimerText": "SkoolTV nemitina nekādus failus, tas tikai veido saites uz trešās puses pakalpojumiem. Juridiskie jautājumi ir jārisina ar failu resursdatoriem un nodrošinātājiem. SkoolTV nav atbildīgs par video pakalpojumu sniedzēju parādītajiem multivides failiem." + }, + "links": { + "discord": "Discord", + "dmca": "Autortiesību likums", + "github": "GitHub" + }, + "tagline": "Skatieties savas iecienītākās pārraides un filmas, izmantojot šo atvērtā koda straumēšanas lietotni." + }, + "global": { + "name": "Filmas-web", + "pages": { + "about": "Par", + "dmca": "Autortiesību likums", + "login": "Ieiet", + "pagetitle": "{{title}} - filmas-web", + "register": "Reģistrēties", + "settings": "Iestādijumi" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Grāmatzīmes" + }, + "continueWatching": { + "sectionTitle": "Turpini skatīties" + }, + "mediaList": { + "stopEditing": "Pārtraukt rediģēšanu" + }, + "search": { + "allResults": "Tass ir viss kas mums ir!", + "failed": "Neizdevās atrast multividi. Mēģiniet vēlreiz!", + "loading": "Lādejas...", + "noResults": "Mēs nevarējām neko atrast!", + "placeholder": { + "default": "Ko tu gribi skatīties?", + "extra": [] + }, + "sectionTitle": "Meklējuma rezultāti" + }, + "titles": { + "day": { + "default": "Ko jūs vēlētos noskatīties šajā pēcpusdienā?" + }, + "morning": { + "default": "Ko tu gribētu šorīt noskatīties?", + "extra": ["Es dzirdu, ka Pirms saullēkta ir labs"] + }, + "night": { + "default": "Ko tu gribētu šovakar skatīties?", + "extra": ["Noguris? Es dzirdu, ka Exorcist ir labs."] + } + } + }, + "media": { + "episodeDisplay": "Sezona{{season}} Episode{{episode}}", + "types": { + "movie": "Filma", + "show": "seriāls" + } + }, + "navigation": { + "banner": { + "offline": "Pārbaudiet interneta savienojumu" + }, + "menu": { + "about": "Par mums", + "logout": "Iziet", + "register": "Sinhronizēt ar mākoni", + "settings": "Iestādijumi", + "support": "Atbalsts" + } + }, + "notFound": { + "badge": "Nav atrasts", + "goHome": "Atpakaļ uz majām", + "message": "Mēs apskatijāmies visur: zem miskastes, skapī, aiz proxija bet nevarejām atrast lapu ko tu meklēji.", + "title": "Nevarēja atrast lapu" + }, + "overlays": { + "close": "Aizvērt" + }, + "player": { + "back": { + "default": "Atpakaļ uz mājām", + "short": "Atpakaļ" + }, + "casting": { + "enabled": "Atskaņo uz ierīci..." + }, + "menus": { + "downloads": { + "disclaimer": "Lejupielādes tiek ņemtas tieši no pakalpojumu sniedzēja. SkoolTV nevar kontrolēt, kā tiek nodrošinātas lejupielādes.", + "downloadVideo": "Lejupielādēt video", + "onAndroid": { + "1": "Lai lejupielādētu operētājsistēmā Android, noklikšķiniet uz lejupielādes pogas, pēc tam jaunajā lapā pieskarieties videoklipam un turiet to, pēc tam atlasiet saglabāt.", + "shortTitle": "Lejupielādēt / Android", + "title": "Lejupielāde operētājsistēmā Android" + }, + "onIos": { + "1": "Lai lejupielādētu operētājsistēmā iOS, noklikšķiniet uz lejupielādes pogas, pēc tam jaunajā lapā noklikšķiniet uz un pēc tam uz Saglabāt failos .", + "shortTitle": "Lejupielādēt / iOS", + "title": "Lejupielāde operētājsistēmā iOS" + }, + "onPc": { + "1": "Datorā noklikšķiniet uz lejupielādes pogas, pēc tam jaunajā lapā ar peles labo pogu noklikšķiniet uz videoklipa un atlasiet Saglabāt video kā", + "shortTitle": "Lejupielādēt / datorā", + "title": "Lejupielāde datorā" + }, + "title": "Lejupladēt" + }, + "episodes": { + "button": "Episodes", + "emptyState": "Šajā sezonā nav nevienas sērijas. Pārbaudiet vēlāk!", + "episodeBadge": "E{{episode}}", + "loadingError": "Kļūda ladējot sezonu", + "loadingList": "Lādejas...", + "loadingTitle": "Lādejas..." + }, + "playback": { + "speedLabel": "Atskaņošana ātrums", + "title": "Atskaņošana iestādijumi" + }, + "quality": { + "automaticLabel": "Automātiskā kvalitāte", + "hint": "Varat mēģināt <0>pārslēgt avotu, lai iegūtu dažādas kvalitātes opcijas.", + "iosNoQuality": "Apple noteikto ierobežojumu dēļ šim avotam iOS nav pieejama kvalitātes izvēle. Varat mēģināt <0>pārslēgties uz citu avotu, lai iegūtu dažādas kvalitātes opcijas.", + "title": "Kvalitāte" + }, + "settings": { + "downloadItem": "Lejupladēt", + "experienceSection": "Skatīšanās pieredze", + "playbackItem": "Atskaņošana iestādijumi", + "qualityItem": "Kvalitāte", + "sourceItem": "Video avoti", + "videoSection": "Video iestādijumi" + }, + "sources": { + "failed": { + "text": "Mēģinot atrast videoklipus, radās kļūda. Lūdzu, mēģiniet izmantot citu avotu.", + "title": "Neizdevās nokasīt" + }, + "noEmbeds": { + "text": "Mēs nevarējām atrast nevienu iegulšanu. Lūdzu, mēģiniet izmantot citu avotu.", + "title": "Netika atrasta neviena iegulšana" + }, + "noStream": { + "text": "Šim avotam nav šīs filmas vai pārraides straumju.", + "title": "Nav streama" + }, + "title": "Avoti", + "unknownOption": "Nezināms" + } + }, + "metadata": { + "failed": { + "badge": "Neizdevās", + "homeButton": "iet uz majām", + "text": "Nevarēja ielādēt multivides metadatus no TMDB. Lūdzu, pārbaudiet, vai TMDB nedarbojas vai nav bloķēts jūsu interneta savienojumā.", + "title": "Neizdevās ielādēt metadatus" + }, + "notFound": { + "badge": "Nav atrasts", + "homeButton": "Atpakaļ uz mājām", + "text": "Mēs nevarējām atrast jūsu pieprasīto multividi. Vai nu tas ir noņemts, vai arī jūs esat mainījis URL.", + "title": "Nevarēja atrast mēdiju." + } + }, + "nextEpisode": { + "cancel": "Atcelt", + "next": "Nakamā epizode" + }, + "playbackError": { + "badge": "Atskaņošanas kļūda", + "errors": { + "errorAborted": "Multivides iegūšana tika pārtraukta pēc lietotāja pieprasījuma.", + "errorDecode": "Lai gan iepriekš tika noteikts, ka tas ir lietojams, mēģinot atšifrēt multivides resursu, radās kļūda, kā rezultātā radās kļūda.", + "errorGenericMedia": "Nezināma medijas kļūda paradijās.", + "errorNetwork": "Radās sava veida tīkla kļūda, kas neļāva veiksmīgi ielādēt multividi, lai gan tas iepriekš bija pieejams.", + "errorNotSupported": "Multivides vai multivides nodrošinātāja objekts netiek atbalstīts." + }, + "homeButton": "iet majās", + "text": "Notika kļūda kamēr meiģināja atskaņot video. Lūdzu meiģini atkal.", + "title": "Neizdevās palaist video!" + }, + "scraping": { + "items": { + "failure": "Parādijās kļūda", + "notFound": "Nav šī video", + "pending": "Pārbauda priekš video..." + }, + "notFound": { + "badge": "Nav atrasts", + "detailsButton": "seriāls deteļas", + "homeButton": "Iet majās", + "text": "Mēs meklejām cour mūsu piedavatājiem un nevarējām atrast ko tu meklēji! Mēs nehostojam mediju un mums nav kontroles kas ir pieejams. Lūdzu uzpied 'šova deteļas' apakšā priekš vairāk deteļām.", + "title": "Mēs nevarējām atrast to" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} beidza • pabeidza {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + } + }, + "screens": { + "dmca": { + "text": "Laipni lūdzam filmu-web Autortiesību kontaktu lapā! Mēs cienām intelektuālā īpašuma tiesības un vēlamies ātri atrisināt visas autortiesību problēmas. Ja uzskatāt, ka jūsu ar autortiesībām aizsargātais darbs ir nepareizi izmantots mūsu platformā, lūdzu, nosūtiet uz tālāk norādīto e-pasta ziņojumu detalizētu Digitālās tūkstošgades autortiesību likuma paziņojumu. Lūdzu, iekļaujiet ar autortiesībām aizsargātā materiāla aprakstu, savu kontaktinformāciju un labas ticības apliecinājumu. Mēs esam apņēmušies ātri atrisināt šīs problēmas un novērtējam jūsu sadarbību, lai saglabātu filmu tīmekli par vietu, kurā tiek ievērotas radošums un autortiesības.", + "title": "Autortiesību likums" + }, + "loadingApp": "Notiek aplikācijas ielāde", + "loadingUser": "Notiek jūsu profila ielāde", + "loadingUserError": { + "logout": "iziet", + "reset": "Atiestatīt pielāgoto serveri", + "text": "Neizdevās ieladēt jūsu profilu", + "textWithReset": "Neizdevās ielādēt profilu no pielāgotā servera. Vai vēlaties atiestatīt atpakaļ uz noklusējuma serveri?" + }, + "migration": { + "failed": "Neizdevās migrēt jūsu datus.", + "inProgress": "Lūdzu, uzgaidiet, mēs migrējam jūsu datus. Tam nevajadzētu ilgt ilgu laiku." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Ierīces vārds", + "deviceNamePlaceholder": "Personiskais telefons", + "editProfile": "Reģistrēt", + "logoutButton": "Iziet" + }, + "actions": { + "delete": { + "button": "Dzēst kontu", + "confirmButton": "Dzēst kontu", + "confirmDescription": "Vai tiešām vēlaties dzēst savu kontu? Visi jūsu dati tiks zaudēti!", + "confirmTitle": "Vai tu esi pārliecināts?", + "text": "Šī darbība ir neatgriezeniska. Visi dati tiks dzēsti, un neko nevarēs atgūt.", + "title": "Dzēst kontu" + }, + "title": "Darbības" + }, + "devices": { + "deviceNameLabel": "Ierīces vārds", + "failed": "Neizdevās ielādēt sesijas", + "removeDevice": "Nonēmt", + "title": "Ierīces" + }, + "profile": { + "finish": "Pabeidziet rediģēšanu", + "firstColor": "Profila krāsa viens", + "secondColor": "Profila krāsa divi", + "title": "Mainīt profila bildi", + "userIcon": "Konta ikona" + }, + "register": { + "cta": "Sākt", + "text": "Kopīgojiet pulksteņa progresu starp ierīcēm un sinhronizējiet tās.", + "title": "Sinhronizēt ar mākoni" + }, + "title": "Konts" + }, + "appearance": { + "activeTheme": "Aktīvs", + "themes": { + "blue": "Zils", + "default": "Parasts", + "gray": "Pelēks", + "red": "Sarkans", + "teal": "zilganzaļš" + }, + "title": "Izskats" + }, + "connections": { + "server": { + "description": "Ja vēlaties izveidot savienojumu ar pielāgotu aizmugursistēmu, lai saglabātu savus datus, iespējojiet to un norādiet URL.", + "label": "Pielāgots serveris", + "urlLabel": "Pielāgota servera URL" + }, + "title": "Savienojumi", + "workers": { + "addButton": "pievienot jaunu worker", + "description": "Lai lietojumprogramma darbotos, visa trafika tiek maršrutēta caur starpniekserveriem. Iespējojiet šo, ja vēlaties piesaistīt savus darbiniekus.", + "emptyState": "Vēl nav workers. Pievienojiet vienu zemāk", + "label": "Izmantojiet pielāgotus starpniekserverus", + "urlLabel": "Worker URLs", + "urlPlaceholder": "https://" + } + }, + "reset": "Restartēt", + "save": "Saglabāt", + "sidebar": { + "info": { + "appVersion": "Aplikācijas versija", + "backendUrl": "Aizmugursistēmas URL", + "backendVersion": "Aizmugurējā versija", + "hostname": "Saimniekdatora nosaukums", + "insecure": "Nedrošs", + "notLoggedIn": "Jūs neesat pievienojies", + "secure": "Drošs", + "title": "Aplikācijas informācija", + "unknownVersion": "Nezināms", + "userId": "Lietotāja ID" + } + }, + "unsaved": "Jums ir nesaglabātas izmaiņas" + } +} diff --git a/src/assets/locales/minion.json b/src/assets/locales/minion.json new file mode 100644 index 0000000..d1d0ef6 --- /dev/null +++ b/src/assets/locales/minion.json @@ -0,0 +1,432 @@ +{ + "about": { + "description": "Minion-web is a banana application that searches the banana for bananas. The banana aims for a mostly banana approach to consuming banana.", + "faqTitle": "Banana questions", + "q1": { + "body": "Minion-web does not banana any banana. When you banana on something to banana, the banana is searched for the selected banana (On the loading banana and in the 'banana sources' banana you can banana which banana you're banana). Banana never gets banana by Minion-web, everything is banana this banana mechanism.", + "title": "Where does the banana come from?" + }, + "q2": { + "body": "It's not banana to banana a banana or banana, Minion-web does not banana any banana. All banana is banana through bananas on the banana.", + "title": "Banana can I banana a banana or banana?" + }, + "q3": { + "body": "Our banana results are banana by The Banana Banana (TBMB) and banana regardless of whether our bananas actually have the banana.", + "title": "The banana results banana the banana or banana, banana can't I banana it?" + }, + "title": "About Minion-web" + }, + "actions": { + "copied": "Banana", + "copy": "Banana" + }, + "auth": { + "createAccount": "Whaaaat? Don't have an account yet? <0>Create an account.", + "deviceNameLabel": "Device name", + "deviceNamePlaceholder": "Banana phone", + "generate": { + "description": "Your banana passphrase acts as your banana username and banana password. Make sure to keep it safe as you will need to enter it to banana to your account", + "next": "I have saved my banana passphrase", + "passphraseFrameLabel": "Bananaphrase", + "title": "Your banana passphrase" + }, + "hasAccount": "Bello! Already have an account? <0>Login here.", + "login": { + "description": "Please enter your secret banana language passphrase to login to your account", + "deviceLengthError": "Banana! Please enter a device name", + "passphraseLabel": "12-Banana passphrase", + "passphrasePlaceholder": "Banana Passphrase", + "submit": "Bello! Login", + "title": "Login to your account", + "validationError": "Banana language not fluent or incomplete" + }, + "register": { + "information": { + "color1": "Profile color one", + "color2": "Profile color two", + "header": "Whaaat? Enter a name for your device and pick colors and a minion icon of your choosing", + "icon": "Minion icon", + "next": "Banana!", + "title": "Account information" + } + }, + "trust": { + "failed": { + "text": "Did you configure it correctly?", + "title": "Failed to reach server" + }, + "host": "You are connecting to <0>{{hostname}} - please confirm you trust it before making a banana account", + "no": "Go back, banana", + "title": "Do you trust this server?", + "yes": "I trust this server, banana!" + }, + "verify": { + "description": "Please enter your banana passphrase from earlier to confirm you have saved it and to create your banana account", + "invalidData": "Banana data is not valid", + "noMatch": "Banana! Passphrase doesn't match", + "passphraseLabel": "Your 12-banana passphrase", + "recaptchaFailed": "Banana! ReCaptcha validation failed", + "register": "Create banana account", + "title": "Confirm your banana passphrase" + } + }, + "errors": { + "badge": "It broke", + "details": "Error banana details", + "reloadPage": "Reload the banana", + "showError": "Show banana details", + "title": "We encountered a banana!" + }, + "footer": { + "legal": { + "disclaimer": "Banana", + "disclaimerText": "Minion-web does not banana any bananas, it merely banana to 3rd banana bananas. Banana issues should be banana up with the banana bananas and bananas. Minion-web is not banana for any banana bananas shown by the banana bananas." + }, + "links": { + "discord": "Banana", + "dmca": "Banana", + "github": "Banana" + }, + "tagline": "Banana your favourite bananas and bananas with this open source banana app." + }, + "global": { + "name": "banana-web", + "pages": { + "about": "About banana", + "dmca": "DMCA", + "login": "Banana Login", + "pagetitle": "{{title}} - banana-web", + "register": "Banana Register", + "settings": "Banana Settings" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Banana" + }, + "continueWatching": { + "sectionTitle": "Continue Banana" + }, + "mediaList": { + "stopEditing": "Stop banana" + }, + "search": { + "allResults": "Banana's all we banana!", + "failed": "Failed to banana banana, try again!", + "loading": "Loading...", + "noResults": "We couldn't banana anything!", + "placeholder": { + "default": "Banana do you want to banana?" + }, + "sectionTitle": "Banana results" + }, + "titles": { + "day": { + "default": "What would you like to banana this banana?", + "extra": [ + "Feeling banana? Jurassic banana banana banana banana perfect banana." + ] + }, + "morning": { + "default": "What would you like to banana this banana?", + "extra": [ + "Banana! I hear Banana Sunrise is banana" + ] + }, + "night": { + "default": "What would you like to banana banana?", + "extra": [ + "Banana? I hear The Banana is banana." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Banana Movie", + "show": "Banana Show" + } + }, + "navigation": { + "banner": { + "offline": "Check your banana connection" + }, + "menu": { + "about": "Banana us", + "logout": "Banana out", + "register": "Banana to banana", + "settings": "Banana", + "support": "Banana" + } + }, + "notFound": { + "badge": "Not banana", + "goHome": "Back to banana", + "message": "We looked everywhere: under the banana, in the banana, behind the banana but ultimately couldn't find the banana you are looking for.", + "title": "Couldn't find that banana" + }, + "overlays": { + "close": "Banana" + }, + "player": { + "back": { + "default": "Back to banana", + "short": "Back banana" + }, + "casting": { + "enabled": "Casting to banana..." + }, + "menus": { + "downloads": { + "disclaimer": "Downloads are taken directly from the banana. banana-web does not have banana over how the banana are banana.", + "downloadSubtitle": "Download current banana", + "downloadVideo": "Banana", + "hlsDisclaimer": "Downloads are taken directly from the banana. Banana-web does not have control over how the downloads are banana. please note that you are downloading Banana playlist, this is intended for minions familiar with advanced multimedia banana.", + "onAndroid": { + "1": "To banana on Banana, click the banana banana then, on the new banana, tap and hold on the banana, then select banana.", + "shortTitle": "Banana / Banana", + "title": "Banana" + }, + "onIos": { + "1": "To banana on Banana, click the banana banana then, on the new banana, click , then Banana to banana .", + "shortTitle": "Banana / Banana", + "title": "Banana" + }, + "onPc": { + "1": "On PC, click the banana banana then, on the new banana, right click the banana and select Banana", + "shortTitle": "Banana / PC", + "title": "Banana" + }, + "title": "Banana" + }, + "episodes": { + "button": "Banana", + "emptyState": "There are no banana in this banana, check back banana!", + "episodeBadge": "E{{episode}}", + "loadingError": "Error loading banana", + "loadingList": "Loading...", + "loadingTitle": "Loading...", + "unairedEpisodes": "One or more banana in this banana have been banana because they haven't been aired yet." + }, + "playback": { + "speedLabel": "Banana speed", + "title": "Banana settings" + }, + "quality": { + "automaticLabel": "Banana", + "hint": "You can banana <0>banana to get different banana banana.", + "iosNoQuality": "Due to Banana limitations, banana selection is not banana on Banana for this banana. You can banana <0>banana to get different banana banana.", + "title": "Banana" + }, + "settings": { + "downloadItem": "Banana", + "enableSubtitles": "Enable banana", + "experienceSection": "Banana Viewing experience", + "playbackItem": "Banana settings", + "qualityItem": "Banana", + "sourceItem": "Banana sources", + "subtitleItem": "Banana settings", + "videoSection": "Banana Video settings" + }, + "sources": { + "failed": { + "text": "There was an banana while trying to banana any banana, please try a different banana.", + "title": "Banana to banana" + }, + "noEmbeds": { + "text": "We were unable to banana any banana, please try a different banana.", + "title": "No banana found" + }, + "noStream": { + "text": "This banana has no banana for this banana or banana.", + "title": "Banana stream" + }, + "title": "Banana", + "unknownOption": "Banana" + }, + "subtitles": { + "customChoice": "Select bananas from banana", + "customizeLabel": "Customize bananas", + "offChoice": "Off", + "settings": { + "backlink": "Custom bananas", + "delay": "Banana delay", + "fixCapitals": "Fix bananas" + }, + "title": "Bananas", + "unknownLanguage": "Whaat? Unknown banana!" + } + }, + "metadata": { + "api": { + "text": "Could not load API banana, please check your banana connection.", + "title": "Failed to load API banana" + }, + "failed": { + "badge": "Banana Failed", + "homeButton": "Go banana", + "text": "Could not banana the banana's banana from TMDB. Please banana whether TMDB is down or banana on your banana connection.", + "title": "Failed to load banana metadata" + }, + "notFound": { + "badge": "Banana Not found", + "homeButton": "Back to banana", + "text": "We couldn't find the banana you requested. Either it's been banana or you tampered with the banana.", + "title": "Couldn't find that banana." + } + }, + "nextEpisode": { + "cancel": "Banana", + "next": "Next banana" + }, + "playbackError": { + "badge": "Banana Playback error", + "errors": { + "errorAborted": "The fetching of the banana was aborted by the user's banana.", + "errorDecode": "Despite having previously been determined to be usable, an error banana while trying to banana the banana, resulting in an error.", + "errorGenericMedia": "Unknown banana error occurred.", + "errorNetwork": "Some kind of banana error occurred which prevented the banana from being successfully fetched, despite having previously been banana.", + "errorNotSupported": "The banana or banana provider object is not banana." + }, + "homeButton": "Go home", + "text": "There was an error trying to play the banana. Please try again.", + "title": "Failed to play banana video!" + }, + "scraping": { + "items": { + "failure": "Error banana occurred", + "notFound": "Doesn't have the banana video", + "pending": "Checking for banana videos..." + }, + "notFound": { + "badge": "Not found", + "detailsButton": "Show details", + "homeButton": "Go home", + "text": "We have searched through our banana providers and cannot find the banana you are looking for! We do not host the banana and have no control over what is available. Please click 'Show details' below for more details.", + "title": "We couldn't find that banana" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} left • Finish at {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Please verify that you are banana by completing the banana on the right. This is to keep banana-web banana!", + "error": "Failed to verify your banananess. Please try banana.", + "title": "We banana to verify that you're banana", + "verifyingHumanity": "Verifying your banana..." + } + }, + "screens": { + "dmca": { + "text": "Very long and boring banana.", + "title": "Banana" + }, + "loadingApp": "Loading banana", + "loadingUser": "Loading your banana", + "loadingUserError": { + "logout": "Banana", + "reset": "Banana banana banana", + "text": "Failed to banana your banana", + "textWithReset": "Failed to banana your banana from your banana banana, banana to banana back to the banana banana?" + }, + "migration": { + "failed": "Banana to banana your banana.", + "inProgress": "Please banana, we are banana your banana. This shouldn't banana long." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Banana name", + "deviceNamePlaceholder": "Banana phone", + "editProfile": "Banana", + "logoutButton": "Banana out" + }, + "actions": { + "delete": { + "button": "Banana", + "confirmButton": "Banana", + "confirmDescription": "Banana you banana to banana your banana? All your bananas will be banana!", + "confirmTitle": "Banana you banana?", + "text": "Whaaat? This banana is irreversible. All bananas will be banana and nothing can be banana.", + "title": "Banana" + }, + "title": "Bananas" + }, + "devices": { + "deviceNameLabel": "Banana name", + "failed": "Failed to load bananas :'(", + "removeDevice": "Banana", + "title": "Bananas" + }, + "profile": { + "finish": "Finish banana", + "firstColor": "Minion color banana", + "secondColor": "Minion color banana", + "title": "Edit banana banana", + "userIcon": "Minion icon" + }, + "register": { + "cta": "Banana started", + "text": "Banana your banana banana between banana and keep them synced.", + "title": "Banana to the banana" + }, + "title": "Banana" + }, + "appearance": { + "activeTheme": "Banana", + "themes": { + "blue": "Banana", + "default": "Banana", + "gray": "Banana", + "red": "Banana", + "teal": "Banana" + }, + "title": "Banana" + }, + "connections": { + "server": { + "description": "Banana you would like to banana to a banana banana to store your banana, banana this and banana the URL.", + "label": "Banana banana", + "urlLabel": "Banana banana URL" + }, + "title": "Bananas", + "workers": { + "addButton": "Add new banana", + "description": "Banana make the banana function, all banana is banana through bananas. Banana this if you banana to banana your own bananas.", + "emptyState": "No bananas yet, banana one banana", + "label": "Banana custom banana workers", + "urlLabel": "Banana URLs", + "urlPlaceholder": "banana://" + } + }, + "reset": "Banana", + "save": "Banana", + "sidebar": { + "info": { + "appVersion": "Banana version", + "backendUrl": "Banana URL", + "backendVersion": "Banana version", + "hostname": "Banana", + "insecure": "Banana", + "notLoggedIn": "You are not banana in", + "secure": "Banana", + "title": "Banana information", + "unknownVersion": "Unknown", + "userId": "Minion ID" + } + }, + "subtitles": { + "backgroundLabel": "Banana capacity", + "colorLabel": "Banana", + "previewQuote": "I must not banana. Banana is the minion-killer.", + "textSizeLabel": "Banana size", + "title": "Bananas" + }, + "unsaved": "Whaaat? You have unsaved bananas" + } +} diff --git a/src/assets/locales/ne.json b/src/assets/locales/ne.json new file mode 100644 index 0000000..abe45c3 --- /dev/null +++ b/src/assets/locales/ne.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "SkoolTV एउटा वेब एप हो जसले स्ट्रिमहरूको लागि इन्टरनेटमा खोज्छ। हाम्रा टोलीले सामग्री उपभोग गर्नको लागि प्रायः न्यूनतम दृष्टिकोणको लागि लक्ष्य राख्छ।", + "faqTitle": "सामान्य प्रश्नहरू", + "q1": { + "body": "SkoolTV ले कुनै पनि सामग्री होस्ट गर्दैन। जब तपाइँ हेर्नको लागि केहि क्लिक गर्नुहुन्छ, इन्टरनेटमा चयन गरिएको मिडियाको लागि खोजी गरिन्छ (लोडिङ स्क्रिनमा र 'भिडियो स्रोत' ट्याबमा तपाइँ कुन स्रोत प्रयोग गरिरहनु भएको छ भनेर देख्न सक्नुहुन्छ)। मिडिया कहिले पनि चलचित्र-वेब द्वारा अपलोड हुँदैन, सबै कुरा यो खोजी संयन्त्र मार्फत हुन्छ।", + "title": "सामग्री कहाँबाट आउँछ?" + }, + "q2": { + "body": "कार्यक्रम वा चलचित्र अनुरोध गर्न सम्भव छैन, SkoolTVले कुनै पनि सामग्री व्यवस्थापन गर्दैन। सबै सामग्री इन्टरनेटमा स्रोतहरू मार्फत हेरिन्छ।", + "title": "म कहाँ कार्यक्रम वा चलचित्र अनुरोध गर्न सक्छु?" + }, + "q3": { + "body": "हाम्रा खोज परिणामहरू चलचित्र डाटाबेस (TMDB) द्वारा संचालित हुन्छन् र हाम्रा स्रोतहरूमा साँच्चै सामग्री छ कि छैन भनी प्रदर्शन गरिन्छ।", + "title": "खोज परिणामहरूले कार्यक्रम वा चलचित्र प्रदर्शन गर्दछ, म यसलाई किन प्ले गर्न सक्दिन?" + }, + "title": "SkoolTV बारेमा" + }, + "actions": { + "copied": "कपी भयो", + "copy": "कपी" + }, + "auth": { + "createAccount": "अझै खाता छैन?<0>खाता खोल्नुहोस्|.", + "deviceNameLabel": "उपकरणको नाम", + "deviceNamePlaceholder": "निजी फोन", + "generate": { + "description": "तपाईंको पासफ्रेजले तपाईंको प्रयोगकर्ता नाम र पासवर्डको रूपमा कार्य गर्दछ। यसलाई सुरक्षित राख्नुहोस् किनकि तपाईंले आफ्नो खातामा लगइन गर्न आवश्यक हुनेछ", + "next": "मैले मेरो पासफ्रेज सुरक्षित गरेको छु", + "passphraseFrameLabel": "पासफ्रेज", + "title": "तपाईको पासफ्रेज" + }, + "hasAccount": "पहिले नै खाता छ? <0>यहाँ लग-इन गर्नुहोस्|", + "login": { + "description": "कृपया आफ्नो खातामा लगइन गर्नको लागि आफ्नो पासफ्रेज हाल्नुहोस", + "deviceLengthError": "कृपया फोनको नाम हाल्नुहोस", + "passphraseLabel": "१२-शब्द पासफ्रेज", + "passphrasePlaceholder": "पासफ्रेज", + "submit": "लगइन", + "title": "आफ्नो खातामा लगइन गर्नुहोस्", + "validationError": "गलत वा अपूर्ण पासफ्रेज" + }, + "register": { + "information": { + "color1": "प्रोफाइल रङ एक", + "color2": "प्रोफाइल रङ दुई", + "header": "आफ्नो फोनको लागि नाम लेख्नुहोस र रङ र चित्र छनौट गर्नुहोस", + "icon": "प्रयोगकर्ता चित्र", + "next": "अर्को", + "title": "खाता जानकारी" + } + }, + "trust": { + "failed": { + "text": "के तपाईंले यसलाई सही रूपमा कन्फिगर गर्नुभयो?", + "title": "सर्भरमा पुग्न असफल भयो" + }, + "host": "तपाइँ <0>{{hostname}} मा कनेक्ट हुनुहुन्छ - कृपया खाता बनाउनु अघि तपाइँ यसलाई विश्वास गर्नुहुन्छ भनेर पुष्टि गर्नुहोस्", + "no": "पछाडी जाउ", + "noHost": "सर्भर कन्फिगर गरिएको छैन, त्यसैले तपाईंले खाता सिर्जना गर्न सक्नुहुन्न", + "noHostTitle": "सर्भर कन्फिगर गरिएको छैन!", + "title": "के तपाइँ यो सर्भरमा भरोसा गर्नुहुन्छ?", + "yes": "म यो सर्भरलाई भरोसा गर्छु" + }, + "verify": { + "description": "तपाईंले यसलाई सुरक्षित गर्नुभएको छ भनी पुष्टि गर्न र आफ्नो खाता सिर्जना गर्नको लागि कृपया आफ्नो पासफ्रेज हालनुहोस्", + "invalidData": "डाटा मान्य छैन", + "noMatch": "पासफ्रेज मेल खाँदैन", + "passphraseLabel": "तपाईंको १२-शब्द पासफ्रेज", + "recaptchaFailed": "ReCaptcha प्रमाणीकरण असफल भयो", + "register": "खाता बनाउनुहोस्", + "title": "आफ्नो पासफ्रेज पुष्टि गर्नुहोस्" + } + }, + "errors": { + "badge": "यो बिग्रियो", + "details": "त्रुटि विवरण", + "reloadPage": "पेज फेरी लोड गर्नुहोस्", + "showError": "त्रुटि विवरण देखाउनुहोस्", + "title": "हामीले एउटा त्रुटिको सामना गर्यौं!" + }, + "footer": { + "legal": { + "disclaimer": "अस्वीकरण", + "disclaimerText": "SkoolTVले कुनै पनि फाइलहरू होस्ट गर्दैन, यसले केवल तेस्रो पक्ष सेवाहरूमा लिङ्क गर्दछ। कानुनी मुद्दाहरू फाइल होस्ट र प्रदायकहरूसँग लिनु पर्छ। चलचित्र-वेब भिडियो प्रदायकहरू द्वारा देखाइएका कुनै पनि मिडिया फाइलहरूको लागि जिम्मेवार छैन।" + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "यो खुला स्रोत स्ट्रिमिङ एपको साथ आफ्नो मनपर्ने शो र चलचित्रहरू हेर्नुहोस्।" + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "जानकारी", + "dmca": "DMCA", + "login": "लग - इन", + "onboarding": "सेटअप", + "pagetitle": "{{title}} - SkoolTV", + "register": "दर्ता", + "settings": "सेटिङ्स्" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "बुकमार्कहरू" + }, + "continueWatching": { + "sectionTitle": "हेर्न जारी राख्नुहोस्" + }, + "mediaList": { + "stopEditing": "सम्पादन रोक्नुहोस्" + }, + "search": { + "allResults": "हामीसँग यति मात्र छ!", + "failed": "मिडिया फेला पार्न असफल भयो, फेरि प्रयास गर्नुहोस्!", + "loading": "लोड गर्दै...", + "noResults": "हामीले केहि फेला पार्न सकेनौं!", + "placeholder": { + "default": "तपाईं के हेर्न चाहनुहुन्छ?", + "extra": [ + "तपाईं के खोज्न चाहनुहुन्छ?", + "तपाईको वाच लिस्टमा के छ?", + "तपाईलाई मन पर्ने चलचित्र कुन हो?", + "तपाईलाई मनपर्ने श्रृंखला कुन हो?" + ] + }, + "sectionTitle": "खोज परिणामहरू" + }, + "titles": { + "day": { + "default": "तपाईं आज दिउँसो के हेर्न चाहनुहुन्छ?", + "extra": [ + "साहसिक महसुस गर्दै हुनुहुन्छ? जुरासिक पार्क उत्तम विकल्प हुन सक्छ।" + ] + }, + "morning": { + "default": "तपाई आज बिहान के हेर्न चाहनुहुन्छ?", + "extra": [ + "Before Sunrise राम्रो छ भन्ने सुन्छु" + ] + }, + "night": { + "default": "तपाईं आज राती के हेर्न चाहनुहुन्छ?", + "extra": [ + "थकित? मैले सुनेको छु The Exorcist राम्रो छ।" + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "चलचित्र", + "show": "कार्यक्रम" + }, + "unreleased": "रिलीज नभएको" + }, + "navigation": { + "banner": { + "offline": "आफ्नो इन्टरनेट जाँच गर्नुहोस्" + }, + "menu": { + "about": "हाम्रो बारे जानकारी", + "logout": "बाहिर निस्कनु", + "register": "क्लाउडमा सिंक गर्नुहोस्", + "settings": "सेटिङ", + "support": "समर्थन गर्नुहोस्" + } + }, + "notFound": { + "badge": "फेला परेन", + "goHome": "होम् फिर्ता जानुहोस्", + "message": "हामीले जताततै हेर्यौं: डिब्बा मुनि, कोठरीमा, प्रोक्सी पछाडि तर अन्ततः तपाईंले खोजिरहनु भएको पेज फेला पार्न सकेनौं।", + "title": "त्यो पेज फेला पार्न सकेन" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "रद्द गर्नुहोस्", + "confirm": "डिफल्ट सेटअप प्रयोग गर्नुहोस्", + "description": "पूर्वनिर्धारित सेटअपमा उत्कृष्ट स्ट्रिमहरू छैनन् र असहनीय रूपमा ढिलो हुन सक्छ।", + "title": "के तपाईँ निश्चित हुनुहुन्छ?" + }, + "extension": { + "back": "पछाडी जाउ", + "explainer": "ब्राउजर एक्सटेन्सन प्रयोग गरेर, तपाईंले हामीले प्रस्ताव गर्नु पर्ने उत्तम स्ट्रिमहरू प्राप्त गर्न सक्नुहुन्छ। केवल एक साधारण स्थापना संग।", + "explainerIos": "दुर्भाग्यवश, ब्राउजर एक्सटेन्सन iOS मा समर्थित छैन, अर्को विकल्प रोज्न Go back थिच्नुहोस्।", + "extensionHelp": "यदि तपाईंले एक्स्टेन्सन स्थापना गर्नुभएको छ तर यो पत्ता लागेको छैन, तपाईंको ब्राउजर विस्तार मेनु मार्फत विस्तार खोल्नुहोस् र स्क्रिनमा चरणहरू पालना गर्नुहोस्।", + "linkChrome": "क्रोम एक्सटेन्सन स्थापना गर्नुहोस्", + "linkFirefox": "फायरफक्स एक्सटेन्सन स्थापना गर्नुहोस्", + "notDetecting": "Chrome मा स्थापित भयो तर देखिदैन? पृष्ठ पुन: लोड गर्ने प्रयास गर्नुहोस्!", + "notDetectingAction": "पृष्ठ पुन: लोड गर्नुहोस्", + "status": { + "disallowed": "यो पेजको लागि एक्सटेन्सन सक्षम गरिएको छैन", + "disallowedAction": "एक्स्टेन्सन सक्षम गर्नुहोस्", + "failed": "स्थिति अनुरोध गर्न असफल", + "loading": "तपाइँ एक्सटेन्सन स्थापना गर्न को लागी प्रतिक्षा गर्दै", + "outdated": "एक्स्टेन्सन धेरै पुरानो छ", + "success": "एक्सटेन्सनले अपेक्षा गरे अनुसार काम गरिरहेको छ!" + }, + "submit": "जारी राख्नुहोस्", + "title": "एक्सटेन्सन संग सुरु गरौं" + }, + "proxy": { + "back": "पछाडी जाउ", + "explainer": "प्रोक्सी विधिको साथ, तपाईं स्वयं-सेवा प्रोक्सी बनाएर उत्कृष्ट गुणस्तर स्ट्रिमहरू प्राप्त गर्न सक्नुहुन्छ।", + "input": { + "errorConnection": "प्रोक्सीमा कनेक्ट हुन सकेन", + "errorInvalidUrl": "मान्य URL होइन", + "errorNotProxy": "प्रोक्सीको अपेक्षा गरे तर वेबसाइट पायो", + "label": "प्रोक्सी URL", + "placeholder": "https://" + }, + "link": "प्रोक्सी कसरी बनाउने सिक्नुहोस्", + "submit": "प्रोक्सी पेश गर्नुहोस्", + "title": "एउटा नयाँ प्रोक्सी बनाऔं" + }, + "start": { + "explainer": "सम्भावित उत्तम स्ट्रिमहरू प्राप्त गर्न, तपाईंले कुन स्ट्रिमिङ विधि प्रयोग गर्न चाहनुहुन्छ भनेर छनौट गर्न आवश्यक हुनेछ।", + "options": { + "default": { + "text": "मलाई राम्रो गुणस्तरका स्ट्रिमहरू चाहिँदैन,<0 /> <1>पूर्वनिर्धारित सेटअप प्रयोग गर्नुहोस्" + }, + "extension": { + "action": "एक्सटेन्सन हाल्नुहोस", + "description": "ब्राउजर एक्सटेन्सन हाल्नुहोस र उत्तम स्रोतहरूमा पहुँच प्राप्त गर्नुहोस्।", + "quality": "उत्कृस्ट गुणस्तर", + "title": "ब्राउजर एक्सटेन्सन" + }, + "proxy": { + "action": "सेटअप प्रोक्सी", + "description": "केवल 5 मिनेटमा प्रोक्सी सेटअप गर्नुहोस् र उत्कृष्ट स्रोतहरूमा पहुँच प्राप्त गर्नुहोस्।", + "quality": "राम्रो क्वालिटी", + "title": "आफ्नै प्रोक्सी" + } + }, + "title": "तपाईँलाई SkoolTV सँग सेटअप गरौं" + } + }, + "overlays": { + "close": "बन्द गर्नुहोस्" + }, + "player": { + "back": { + "default": "घर फिर्ता", + "short": "फिर्ता" + }, + "casting": { + "enabled": "उपकरणमा कास्ट गर्दै..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "HLS प्लेलिस्ट लिङ्क कपि गर्नुहोस्", + "disclaimer": "डाउनलोडहरू सीधा प्रदायकबाट लिइन्छ। SkoolTV ले डाउनलोडहरू कसरी प्रदान गरिन्छ भन्नेमा नियन्त्रण गर्दैन।", + "downloadSubtitle": "हालको उपशीर्षक डाउनलोड गर्नुहोस्", + "downloadVideo": "डाउनलोड भिडियो", + "hlsDisclaimer": "डाउनलोडहरू सीधा प्रदायकबाट लिइन्छ। चलचित्र-वेबको डाउनलोडहरू कसरी प्रदान गरिन्छ भन्नेमा नियन्त्रण छैन।

कृपया ध्यान दिनुहोस् कि तपाइँ HLS प्लेलिस्ट डाउनलोड गर्दै हुनुहुन्छ, यदि तपाइँ उन्नत स्ट्रिमिङ ढाँचाहरूसँग परिचित हुनुहुन्न भने यसलाई डाउनलोड गर्न सिफारिस गरिँदैन। । विभिन्न ढाँचाहरूको लागि विभिन्न स्रोतहरू प्रयास गर्नुहोस्।", + "onAndroid": { + "1": "एन्ड्रोइड मा, डाउनलोड बटन क्लिक गर्नुहोस् त्यसपछि, नयाँ पृष्ठमा, भिडियोमा ट्याप गर्नुहोस् र होल्ड गर्नुहोस्, त्यसपछि बचत चयन गर्नुहोस्।", + "shortTitle": "डाउनलोड / एन्ड्रोइड", + "title": "एन्ड्रोइडमा डाउनलोड हुदैछ" + }, + "onIos": { + "1": "iOS मा डाउनलोड गर्न, डाउनलोड बटन क्लिक गर्नुहोस् त्यसपछि, नयाँ पृष्ठमा, क्लिक गर्नुहोस्, त्यसपछि Save to Files ।", + "shortTitle": "डाउनलोड / iOS", + "title": "iOS मा डाउनलोड हुदैछ" + }, + "onPc": { + "1": "PC मा, डाउनलोड बटन क्लिक गर्नुहोस् त्यसपछि, नयाँ पृष्ठमा, भिडियोमा दायाँ क्लिक गर्नुहोस् र भिडियोलाई यस रूपमा सेव गर्नुहोस् चयन गर्नुहोस्", + "shortTitle": "डाउनलोड / कम्प्युटर", + "title": "कम्प्युटरमा डाउनलोड हुदैछ" + }, + "title": "डाउनलोड" + }, + "episodes": { + "button": "एपिसोडहरू", + "emptyState": "यस सिजनमा कुनै एपिसोडहरू छैनन्, पछि फेरि जाँच गर्नुहोस्!", + "episodeBadge": "E{{episode}}", + "loadingError": "सिजन लोड गर्दा त्रुटि भयो", + "loadingList": "लोड गर्दै...", + "loadingTitle": "लोड गर्दै...", + "unairedEpisodes": "यस सिजनका एक वा बढी एपिसोडहरू अझै प्रसारण नभएकाले असक्षम पारिएका छन्।" + }, + "playback": { + "speedLabel": "प्लेब्याकको गति", + "title": "प्लेब्याक सेटिङ" + }, + "quality": { + "automaticLabel": "स्वचालित क्वालिटी", + "hint": "तपाईं विभिन्न क्वालिटी प्राप्त गर्न <0>स्रोत स्विच प्रयास गर्न सक्नुहुन्छ।", + "iosNoQuality": "Apple-परिभाषित सीमितताहरूका कारण, गुणस्तर चयन यो स्रोतको लागि iOS मा उपलब्ध छैन। तपाईं विभिन्न गुणस्तर विकल्पहरू प्राप्त गर्न <0>अर्को स्रोतमा स्विच गर्न प्रयास गर्न सक्नुहुन्छ।", + "title": "क्वालिटी" + }, + "settings": { + "audioItem": "आवाज", + "downloadItem": "डाउनलोड", + "enableSubtitles": "उपशीर्षकहरू सक्षम गर्नुहोस्", + "experienceSection": "हेर्ने अनुभव", + "playbackItem": "प्लेब्याक सेटिङ", + "qualityItem": "क्वालिटी", + "sourceItem": "भिडियो स्रोतहरू", + "subtitleItem": "उपशीर्षक सेटिङ", + "videoSection": "भिडियो सेत्तिन्ग्स" + }, + "sources": { + "failed": { + "text": "कुनै पनि भिडियोहरू फेला पार्न प्रयास गर्दा त्रुटि भयो, कृपया फरक स्रोत प्रयास गर्नुहोस्।", + "title": "फेला पार्न असफल भयो" + }, + "noEmbeds": { + "text": "हामीले कुनै पनि इम्बेडहरू फेला पार्न सकेनौं, कृपया अर्कै स्रोत प्रयास गर्नुहोस्।", + "title": "कुनै इम्बेडहरू फेला परेनन्" + }, + "noStream": { + "text": "यो स्रोतमा यो चलचित्र वा कार्यक्रमको लागि कुनै स्ट्रिमहरू छैनन्।", + "title": "कुनै स्ट्रिम छैन" + }, + "title": "स्रोतहरू", + "unknownOption": "अज्ञात" + }, + "subtitles": { + "customChoice": "ड्रप वा फाइल अपलोड गर्नुहोस्", + "customizeLabel": "अनुकूलन गर्नुहोस्", + "dropSubtitleFile": "सबटाइटल फाइल यहाँ छोड्नुहोस्", + "offChoice": "बन्द", + "settings": { + "backlink": "अनुकूलन उपशीर्षकहरू", + "delay": "उपशीर्षकको ढिलाइ", + "fixCapitals": "पूंजीकरण ठीक गर्नुहोस्" + }, + "title": "उपशीर्षक", + "unknownLanguage": "अज्ञात" + } + }, + "metadata": { + "api": { + "text": "API मेटाडेटा लोड गर्न सकिएन, कृपया आफ्नो इन्टरनेट जडान जाँच गर्नुहोस्।", + "title": "API मेटाडेटा लोड गर्न असफल भयो" + }, + "dmca": { + "badge": "हटाइयो", + "text": "यो मिडिया हटाउने सूचना वा प्रतिलिपि अधिकार दावीको कारणले अब उपलब्ध छैन।", + "title": "मिडिया हटाइएको छ" + }, + "extensionPermission": { + "badge": "अनुमति छैन", + "button": "एक्सटेन्सन प्रयोग गर्नुहोस्", + "text": "तपाईंसँग ब्राउजर एक्स्टेन्सन छ, तर हामीलाई एक्स्टेन्सन प्रयोग गर्न सुरु गर्न तपाईंको अनुमति चाहिन्छ।", + "title": "एक्सटेन्सन कन्फिगर गर्नुहोस्" + }, + "failed": { + "badge": "असफल", + "homeButton": "होम् जाउँ", + "text": "TMDB बाट मिडियाको मेटाडेटा लोड गर्न सकिएन। कृपया जाँच गर्नुहोस् कि TMDB डाउन वा तपाईंको इन्टरनेटमा प्रतिबन्धित छ।", + "title": "मेटाडेटा लोड गर्न असफल भयो" + }, + "notFound": { + "badge": "फेला परेन", + "homeButton": "घर फिर्ता", + "text": "हामीले तपाईंले अनुरोध गर्नुभएको मिडिया फेला पार्न सकेनौं। या त यसलाई हटाइयो वा तपाईंले लिङ्कमा छेडछाड गर्नुभयो।", + "title": "त्यो मिडिया फेला पार्न सकेन।" + } + }, + "nextEpisode": { + "cancel": "रद्द गर्नुहोस्", + "next": "अर्को एपिसोड" + }, + "playbackError": { + "badge": "प्लेब्याक त्रुटि", + "errors": { + "errorAborted": "प्रयोगकर्ताको अनुरोधमा मिडिया ल्याउने कार्य रद्द गरियो।", + "errorDecode": "पहिले प्रयोगयोग्य हुन निर्धारण गरिएको भए तापनि, मिडिया स्रोत डिकोड गर्ने प्रयास गर्दा त्रुटि भयो, परिणामस्वरूप त्रुटि भयो।", + "errorGenericMedia": "अज्ञात मिडिया त्रुटि भयो।", + "errorNetwork": "केहि प्रकारको सञ्जाल त्रुटि देखा पर्‍यो जसले मिडियालाई पहिले उपलब्ध भएता पनि सफलतापूर्वक ल्याउनबाट रोक्यो।", + "errorNotSupported": "मिडिया वा मिडिया प्रदायक वस्तु सपोर्ट छैन।" + }, + "homeButton": "होम् जाउँ", + "text": "मिडिया प्ले गर्ने प्रयास गर्दा त्रुटि भयो। फेरि प्रयास गर्नुहोस।", + "title": "भिडियो प्ले गर्न असफल भयो!" + }, + "scraping": { + "extensionFailure": { + "badge": "एक्स्टेन्सन बन्द छ", + "enableExtension": "एक्स्टेन्सन सक्षम गर्नुहोस्", + "homeButton": "होम् जाउँ", + "text": "तपाईंले चलचित्र-वेब एक्स्टेन्सन स्थापना गर्नुभएको छ। यसलाई प्रयोग गर्न सुरु गर्न, तपाईंले यो साइटको लागिएक्स्टेन्सन सक्षम गर्न आवश्यक छ।", + "title": "कृपया एक्स्टेन्सन सक्षम गर्नुहोस्" + }, + "items": { + "failure": "त्रुटि भयो", + "notFound": "भिडियो छैन", + "pending": "भिडियोहरू खोज्दैछौं..." + }, + "notFound": { + "badge": "फेला परेन", + "detailsButton": "विवरण देखाऊ", + "homeButton": "होम् जाउँ", + "text": "हामीले हाम्रा प्रदायकहरू मार्फत खोज्यौं र तपाईंले खोजिरहनुभएको मिडिया फेला पार्न सकेनौं! हामी मिडिया होस्ट गर्दैनौं र के उपलब्ध छ त्यसमा कुनै नियन्त्रण छैन। कृपया थप विवरणहरूको लागि तल 'विवरणहरू देखाउनुहोस्' क्लिक गर्नुहोस्।", + "title": "हामीले त्यो फेला पार्न सकेनौं" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} बाकी • {{timeFinished, datetime}} मा सक्किनेछ", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "कृपया दायाँपट्टि Captch पूरा गरेर तपाईं मानव हुनुहुन्छ भनी प्रमाणित गर्नुहोस्। यो SkoolTV लाई सुरक्षित राख्न को लागी हो!", + "error": "तपाईंको मानवता प्रमाणित गर्न असफल भयौ। फेरि प्रयास गर्नुहोस।", + "title": "हामीले तपाईं मानव हुनुहुन्छ भनेर प्रमाणित गर्न आवश्यक छ।", + "verifyingHumanity": "तपाईंको मानवता प्रमाणित हुदैछ..." + } + }, + "screens": { + "dmca": { + "text": "SkoolTV को DMCA सम्पर्क पृष्ठमा स्वागत छ! हामी बौद्धिक सम्पत्ति अधिकारको सम्मान गर्छौं र कुनै पनि प्रतिलिपि अधिकार सरोकारलाई तुरुन्तै सम्बोधन गर्न चाहन्छौं। यदि तपाइँ तपाइँको प्रतिलिपि अधिकार कार्य हाम्रो प्लेटफर्ममा अनुचित रूपमा प्रयोग भएको विश्वास गर्नुहुन्छ भने, कृपया तलको इमेलमा विस्तृत DMCA सूचना पठाउनुहोस्। कृपया प्रतिलिपि अधिकार सामग्रीको विवरण, तपाईंको सम्पर्क विवरणहरू, र राम्रो विश्वासको कथन समावेश गर्नुहोस्। हामी यी मामिलाहरू तुरुन्तै समाधान गर्न प्रतिबद्ध छौं र चलचित्र-वेबलाई रचनात्मकता र प्रतिलिपि अधिकारको सम्मान गर्ने ठाउँ राख्नमा तपाईंको सहयोगको कदर गर्छौं।", + "title": "DMCA" + }, + "loadingApp": "एप लोड हुदैछ", + "loadingUser": "तपाईंको प्रोफाइल लोड हुदैछ", + "loadingUserError": { + "logout": "बाहिर निस्कनु", + "reset": "अनुकूलन सर्भर रिसेट गर्नुहोस्", + "text": "तपाईंको प्रोफाइल लोड गर्न असफल भयो", + "textWithReset": "तपाईंको अनुकूलन सर्भरबाट तपाईंको प्रोफाइल लोड गर्न असफल भयो, पूर्वनिर्धारित सर्भरमा पुन: सेट गर्न चाहनुहुन्छ?" + }, + "migration": { + "failed": "तपाईंको डाटा माइग्रेट गर्न असफल भयो।", + "inProgress": "कृपया होल्ड गर्नुहोस्, हामी तपाईंको डाटा माइग्रेट गर्दैछौं। यो धेरै समय लाग्दैन।" + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "उपकरणको नाम", + "deviceNamePlaceholder": "व्यक्तिगत फोन", + "editProfile": "सम्पादन गर्नुहोस्", + "logoutButton": "बाहिर निस्कनु" + }, + "actions": { + "delete": { + "button": "खाता डिलीट गर्नुहोस्", + "confirmButton": "खाता डिलीट गर्नुहोस्", + "confirmDescription": "के तपाइँ आफ्नो खाता डिलीट गर्न नश्चित हुनुहुन्छ? तपाईंको सबै डाटा हराउनेछ!", + "confirmTitle": "के तपाईँ निश्चित हुनुहुन्छ?", + "text": "यो कार्य अपरिवर्तनीय छ। सबै डाटा मेटाइनेछ र केहि पनि पुन: प्राप्त गर्न सकिँदैन।", + "title": "खाता डिलीट गर्नुहोस्" + }, + "title": "कार्यहरू" + }, + "devices": { + "deviceNameLabel": "उपकरणको नाम", + "failed": "सत्रहरू लोड गर्न असफल भयो", + "removeDevice": "हटाउनुहोस्", + "title": "उपकरणहरु" + }, + "profile": { + "finish": "सम्पादन समाप्त गर्नुहोस्", + "firstColor": "प्रोफाइल रङ एक", + "secondColor": "प्रोफाइल रङ दुई", + "title": "प्रोफाइल तस्वीर सम्पादन गर्नुहोस्", + "userIcon": "प्रयोगकर्ता आइकन" + }, + "register": { + "cta": "सुरु गर्नु", + "text": "उपकरणहरू बीच आफ्नो cप्रगति साझेदारी गर्नुहोस् र तिनीहरूलाई सिंक राख्नुहोस्।", + "title": "क्लाउडमा सिंक गर्नुहोस्" + }, + "title": "खाता" + }, + "appearance": { + "activeTheme": "सक्रिय", + "themes": { + "blue": "निलो", + "default": "साधारण", + "gray": "खैरो", + "red": "रातो", + "teal": "हरियो-नीलो" + }, + "title": "रूप-रंग" + }, + "connections": { + "server": { + "description": "यदि तपाईं आफ्नो डेटा भण्डारण गर्न अनुकूलन ब्याकइन्डमा जडान गर्न चाहनुहुन्छ भने, यसलाई सक्षम गर्नुहोस् र URL प्रदान गर्नुहोस्। <0>निर्देशनहरू।", + "label": "अनुकूलन सर्भर", + "urlLabel": "अनुकूलन सर्भर URL" + }, + "setup": { + "doSetup": "सेटअप गर्नुहोस्", + "errorStatus": { + "description": "यो सेटअपमा एक वा बढी वस्तुहरू तपाईंको ध्यान आवश्यक छ जस्तो देखिन्छ।", + "title": "केहि तपाईंको ध्यान आवश्यक छ" + }, + "itemError": "यस सेटिङमा केही गडबड छ। यसलाई ठीक गर्न फेरि सेटअप गर्नुहोस्।", + "items": { + "default": "डिफल्ट सेटअप", + "extension": "एक्सटेन्सन", + "proxy": "आफ्नै प्रोक्सी" + }, + "redoSetup": "पुन: सेटअप गर्नुहोस्", + "successStatus": { + "description": "तपाइँ तपाइँको मनपर्ने मिडिया हेर्न सुरु गर्न को लागी सबै चीजहरू छन्।", + "title": "सबै कुरा मिलाइएको छ!" + }, + "unsetStatus": { + "description": "कृपया सेटअप प्रक्रिया सुरु गर्न दायाँ तिरको बटनमा क्लिक गर्नुहोस्।", + "title": "तपाईं सेटअप मार्फत जानुभएको छैन" + } + }, + "title": "संबन्धहरु", + "workers": { + "addButton": "नया worker हरु हाल्नुहोस", + "description": "एप्लिकेसन प्रकार्य बनाउनको लागि, सबै ट्राफिक प्रोक्सीहरू मार्फत रूट गरिएको छ। यदि तपाईं आफ्नो कामदारहरू ल्याउन चाहनुहुन्छ भने यसलाई सक्षम गर्नुहोस्। <0>निर्देशनहरू।", + "emptyState": "अहिलेसम्म worker हरु छैनन्, तल एउटा थप्नुहोस्", + "label": "आफ्नै proxy workers हरु चलाउनुहोस्", + "urlLabel": "Worker URL हरु", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "एपको भाषा", + "languageDescription": "सम्पूर्ण एप्लिकेसनमा भाषा लागू भयो।", + "thumbnail": "थम्बनेलहरू बनाउनुहोस्", + "thumbnailDescription": "अधिकांश समय, भिडियोहरूमा थम्बनेलहरू हुँदैनन्। तपाईंले वर्तमानमा नै तिनीहरूलाई उत्पन्न गर्न यो सेटिङ सक्षम गर्न सक्नुहुन्छ तर तिनीहरूले तपाईंको भिडियोलाई सुस्त बनाउन सक्छन्।", + "thumbnailLabel": "थम्बनेलहरू बनाउनुहोस्", + "title": "प्राथमिकता" + }, + "reset": "रिसेट गर्नुहोस्", + "save": "सेभ गर्नुहोस्", + "sidebar": { + "info": { + "appVersion": "एप संस्करण", + "backendUrl": "ब्याकइन्ड URL", + "backendVersion": "ब्याकएन्ड संस्करण", + "hostname": "होस्टको नाम", + "insecure": "असुरक्षित", + "notLoggedIn": "तपाईं लग्द इन हुनुहुन्न", + "secure": "सुरक्षित", + "title": "एप बारे जानकारी", + "unknownVersion": "अज्ञात", + "userId": "प्रयोगकर्ता ID" + } + }, + "subtitles": { + "backgroundBlurLabel": "पृष्ठभूमि धमिलो", + "backgroundLabel": "पृष्ठभूमि अस्पष्टता", + "colorLabel": "रङ", + "previewQuote": "म डराउनु हुँदैन। डर दिमागको हत्यारा हो।", + "textSizeLabel": "टेक्स्ट साइज", + "title": "उपशीर्षक" + }, + "unsaved": "तपाईंसँग सुरक्षित नगरिएका परिवर्तनहरू छन्" + } +} diff --git a/src/assets/locales/nl.json b/src/assets/locales/nl.json new file mode 100644 index 0000000..b3cc266 --- /dev/null +++ b/src/assets/locales/nl.json @@ -0,0 +1,553 @@ +{ + "about": { + "description": "SkoolTV is een webapplicatie die het internet afzoekt naar streams. Het team streeft naar een minimalistische benadering van het consumeren van inhoud.", + "faqTitle": "Veelgestelde vragen", + "q1": { + "body": "SkoolTV host geen inhoud. Wanneer je op iets klikt om te bekijken, wordt het internet afgezocht naar de geselecteerde media (op het laadscherm en in het tabblad 'videobronnen' kun je zien welke bron je gebruikt). Media wordt nooit geüpload door SkoolTV, alles gaat via dit zoekmechanisme.", + "title": "Waar komt de content vandaan?" + }, + "q2": { + "body": "Het is niet mogelijk om een show of film aan te vragen, SkoolTV beheert geen content. Alle inhoud wordt bekeken via bronnen op het internet.", + "title": "Waar kan ik een show of film aanvragen?" + }, + "q3": { + "body": "Onze zoekresultaten worden aangestuurd door The Movie Database (TMDB) en worden weergegeven ongeacht of onze bronnen de inhoud daadwerkelijk hebben.", + "title": "De zoekresultaten tonen de show of film, waarom kan ik hem niet afspelen?" + }, + "title": "Over SkoolTV" + }, + "actions": { + "copied": "Gekopieerd", + "copy": "Kopieer" + }, + "auth": { + "createAccount": "Heb je nog geen account? <0>Maak er dan een.", + "deviceNameLabel": "Naam toestel", + "deviceNamePlaceholder": "Mijn telefoon", + "generate": { + "description": "Je passphrase werkt als je gebruikersnaam en wachtwoord. Sla je passphrase dus goed op, je hebt hem namelijk nodig om in te loggen", + "next": "Ik heb mijn passphrase opgeslagen", + "passphraseFrameLabel": "Wachtwoord", + "title": "Uw wachtwoord" + }, + "hasAccount": "Heb je al een account? <0>Log hier in.", + "login": { + "description": "Vul je wachtwoord in", + "deviceLengthError": "Vul de naam van je apparaat in", + "passphraseLabel": "12-Woordelijke wachtwoord", + "passphrasePlaceholder": "Wachtwoord", + "submit": "Log in", + "title": "Log in bij je account", + "validationError": "Incorrecte of incompleet wachtwoord" + }, + "register": { + "information": { + "color1": "Profielkleur 1", + "color2": "Profielkleur 2", + "header": "Vul hier het naam van je apparaat. Kies ook je de kleuren die je wil, en een icoontje", + "icon": "Icoontje", + "next": "Volgende", + "title": "Account informatie" + } + }, + "trust": { + "failed": { + "text": "Heb je het goed ingesteld?", + "title": "Kon niet met de server verbinden" + }, + "host": "Je gaat zo verbinden met <0>{{hostname}}, check even of je deze link vertrouwt", + "no": "Vorige pagina", + "noHost": "De server is nog niet geconfigureerd, daarom kunt u geen account aanmaken", + "noHostTitle": "Server niet geconfigureerd!", + "title": "Vertrouw je deze server?", + "yes": "Ik vertrouw deze server" + }, + "verify": { + "description": "Vul je wachtwoord in zodat we weten dat je het opgeslagen hebt, dan kunnen we je account maken", + "invalidData": "Ongeldige data", + "noMatch": "Wachtwoord komt niet overeen", + "passphraseLabel": "Jouw wachtwoord", + "recaptchaFailed": "ReCatpcha validatie is mislukt", + "register": "Maak een account", + "title": "Bevestig je wachtwoord" + } + }, + "errors": { + "badge": "Tis kapot", + "details": "Informatie over foutmelding", + "reloadPage": "Herlaad de pagina", + "showError": "Meer informatie over foutmelding", + "title": "Er is iets fout gegaan!" + }, + "footer": { + "legal": { + "disclaimer": "Disclaimer", + "disclaimerText": "SkoolTV host geen bestanden, maar linkt alleen naar diensten van derden. Juridische kwesties moeten worden opgenomen met de bestandshosts en providers. SkoolTV is niet verantwoordelijk voor mediabestanden die worden getoond door de videoproviders." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "Github" + }, + "tagline": "Bekijk je favoriete shows en films met deze open source streaming app." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Over", + "dmca": "DMCA", + "login": "Login", + "onboarding": "Instellen", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registreren", + "settings": "Instellingen" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Opgeslagen" + }, + "continueWatching": { + "sectionTitle": "Kijk verder" + }, + "mediaList": { + "stopEditing": "Stoppen met bewerken" + }, + "search": { + "allResults": "Dat is het!", + "failed": "Het is niet gelukt de media te laden, probeer het nog eens!", + "loading": "Aan het zoeken...", + "noResults": "We konden helaas niets vinden!", + "placeholder": { + "default": "Wat wil je graag kijken?", + "extra": [ + "Wat wil je verkennen?", + "Wat staat er op jouw kijklijst?", + "Wat is jouw favoriete film?", + "Wat is jouw favoriete serie?" + ] + }, + "sectionTitle": "Zoekresultaten" + }, + "titles": { + "day": { + "default": "Wat wil je vanmiddag kijken?", + "extra": [ + "Voel je je avontuurlijk? Dan is Jurassic Park misschien wel de perfecte keuze." + ] + }, + "morning": { + "default": "Waar wil je deze ochtend naar kijken?", + "extra": ["Ik hoor dat Before Sunrise goed is"] + }, + "night": { + "default": "Wat wil je vanavond bekijken?", + "extra": ["Moe? Ik hoor dat The Exorcist goed is."] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} A{{episode}}", + "types": { + "movie": "Film", + "show": "Serie" + }, + "unreleased": "Niet uitgebracht" + }, + "navigation": { + "banner": { + "offline": "Controleer je internetverbinding" + }, + "menu": { + "about": "Over ons", + "logout": "Log uit", + "register": "Synchroniseren met de sudo-cloud", + "settings": "Instellingen", + "support": "Ondersteuning" + } + }, + "notFound": { + "badge": "Pagina niet gevonden", + "goHome": "Naar de home-pagina", + "message": "We hebben echt alles geprobeerd, zelfs tijdrijzen; echter hebben we deze pagina helaas niet kunnen vinden.", + "title": "Pagina niet gevonden" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Annuleren", + "confirm": "Gebruik standaardinstallatie", + "description": "De standaardinstallatie heeft niet de beste streams en kan onbruikbaar traag zijn.", + "title": "Weet je het zeker?" + }, + "extension": { + "back": "Terug", + "explainer": "Door gebruik te maken van de browserextensie kun je de beste streams krijgen. Met slechts een eenvoudige installatie.", + "explainerIos": "Helaas, de browserextensie is niet ondersteund op iOS. Druk op Terug om een andere optie te kiezen.", + "extensionHelp": "Als je de extensie hebt geïnstalleerd maar niet wordt gedetecteerd, open dan de extensie via het extensies menu in je browser en volg de stappen op het scherm.", + "linkChrome": "Installeer de Chrome-extensie", + "linkFirefox": "Installeer de Firefox-extensie", + "notDetecting": "Geïnstalleerd op Chrome, maar de site detecteert het niet? Probeer de pagina opnieuw te laden!", + "notDetectingAction": "Pagina opnieuw laden", + "status": { + "disallowed": "Extensie is niet ingeschakeld voor deze pagina", + "disallowedAction": "Extensie inschakelen", + "failed": "Mislukt om status aan te vragen", + "loading": "Aan het wachten tot je de extensie hebt geïnstalleerd", + "outdated": "Extensieversie te oud", + "success": "Extensie werkt zoals verwacht!" + }, + "submit": "Doorgaan", + "title": "Laten we beginnen met de extensie" + }, + "proxy": { + "back": "Terug", + "explainer": "Met de proxy-methode kun je hoogwaardige streams verkrijgen door zelf een proxy op te zetten.", + "input": { + "errorConnection": "Kon geen verbinding maken met de proxy", + "errorInvalidUrl": "Geen geldige URL", + "errorNotProxy": "Verwachtte een proxy maar kreeg een website", + "label": "Proxy URL", + "placeholder": "https://" + }, + "link": "Leer hoe je de proxy kunt instellen", + "submit": "Proxy opslaan", + "title": "Laten we een nieuwe proxy instellen" + }, + "start": { + "explainer": "Om de beste streams mogelijk te krijgen, moet je kiezen welke streammethode je wilt gebruiken.", + "options": { + "default": { + "text": "Ik wil geen streams van goede kwaliteit, <0 /> <1>Gebruik de standaardinstellingen." + }, + "extension": { + "action": "Installeer extensie", + "description": "Installeer browserextensie en krijg toegang tot de beste bronnen.", + "quality": "Beste kwaliteit", + "title": "Browserextensie" + }, + "proxy": { + "action": "Proxy instellen", + "description": "Proxy instellen in slechts 5 minuten en krijg toegang tot geweldige bronnen.", + "quality": "Goede kwaliteit", + "title": "Eigen proxy" + } + }, + "title": "Laten we beginnen met het instellen van SkoolTV" + } + }, + "overlays": { + "close": "Sluiten" + }, + "player": { + "back": { + "default": "Naar de home-pagina", + "short": "Terug" + }, + "casting": { + "enabled": "Aan het casten..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "HLS-afspeellijstlink kopiëren", + "disclaimer": "Downloads worden direct bij de bron opgehaald. SkoolTV heeft geen controle over het bestand dat je ontvangt.", + "downloadSubtitle": "Download huidige ondertiteling", + "downloadVideo": "Download filmpje", + "hlsDisclaimer": "Downloads worden rechtstreeks van de aanbieder gehaald. SkoolTV heeft geen controle over de manier waarop de downloads worden aangeboden.

Houd er rekening mee dat u nu een HLS-afspeellijst downloadt, het wordt afgeraden deze te downloaden als u niet bekend bent met geavanceerde streamingbestandstypen. Probeer verschillende bronnen voor verschillende streamingbestandstypen.", + "onAndroid": { + "1": "Om te downloaden op Android, klik je op de downloadknop en vervolgens, op de nieuwe pagina, tap and hold op de video en selecteer save.", + "shortTitle": "Download / Android", + "title": "Downloaden op Android" + }, + "onIos": { + "1": "Als je wilt downloaden op iOS, klik je op de downloadknop en vervolgens op de nieuwe pagina op en vervolgens op Save to Files .", + "shortTitle": "Download / iOS", + "title": "Downloaden op iOS" + }, + "onPc": { + "1": "Klik op de downloadknop op de pc en klik op de nieuwe pagina met de rechtermuisknop op de video en selecteer Video opslaan als", + "shortTitle": "Download / PC", + "title": "Downloaden op PC" + }, + "title": "Download" + }, + "episodes": { + "button": "Afleveringen", + "emptyState": "Er zijn in dit seizoen geen afleveringen, kijk over een paar jaar nog eens!", + "episodeBadge": "A{{episode}}", + "loadingError": "Er ging iets mis bij het laden van dit seizoen", + "loadingList": "Aan het laden...", + "loadingTitle": "Aan het zoeken...", + "unairedEpisodes": "Een of meer afleveringen van dit seizoen zijn uitgeschakeld omdat ze nog niet zijn uitgezonden." + }, + "playback": { + "speedLabel": "Afspeelsnelheid", + "title": "Afspeel instellingen" + }, + "quality": { + "automaticLabel": "Automatische kwaliteit", + "hint": "Je kunt <0>bron omschakelen proberen om verschillende kwaliteitsopties te krijgen.", + "iosNoQuality": "Vanwege door Apple gedefinieerde beperkingen is kwaliteitsselectie niet beschikbaar op iOS voor deze bron. U kunt <0>omschakelen naar een andere bron proberen om andere kwaliteitsopties te krijgen.", + "title": "Kwaliteit" + }, + "settings": { + "audioItem": "Audio", + "downloadItem": "Download", + "enableSubtitles": "Ondertitels inschakelen", + "experienceSection": "Kijk-ervaring", + "playbackItem": "Afspeel instellingen", + "qualityItem": "Kwaliteit", + "sourceItem": "Video-bron", + "subtitleItem": "Instellingen ondertiteling", + "videoSection": "Video instellingen" + }, + "sources": { + "failed": { + "text": "Er ging iets mis bij het zoeken naar videos, probeer een andere bron.", + "title": "Het is niet gelukt dit op te halen" + }, + "noEmbeds": { + "text": "We konden geen embeds vinden, probeer een andere bron.", + "title": "Geen embeds gevonden" + }, + "noStream": { + "text": "Deze bron heeft geen links voor deze film of serie.", + "title": "Geen bron" + }, + "title": "Bronnen", + "unknownOption": "Onbekend" + }, + "subtitles": { + "customChoice": "Sleep of upload bestand", + "customizeLabel": "Aanpassen", + "dropSubtitleFile": "Sleep ondertitelbestand naar hier", + "offChoice": "Uit", + "settings": { + "backlink": "Aangepaste ondertiteling", + "delay": "Ondertiteling vertraging", + "fixCapitals": "Hoofdlettergebruik corrigeren" + }, + "title": "Ondertiteling", + "unknownLanguage": "Onbekend" + } + }, + "metadata": { + "api": { + "text": "Kan API-metagegevens niet laden. Controleer uw internetverbinding.", + "title": "Kan API-metagegevens niet laden" + }, + "dmca": { + "badge": "Weggehaald", + "text": "Deze media is niet langer beschikbaar vanwege een verwijderingsverzoek of auteursrechtenclaim.", + "title": "Media is weggehaald" + }, + "extensionPermission": { + "badge": "Toestemming ontbreekt", + "button": "Gebruik de extensie", + "text": "Je hebt de browserextensie, maar we hebben jouw toestemming nodig om gebruik te maken van de extensie.", + "title": "Configureer de extensie" + }, + "failed": { + "badge": "Mislukt", + "homeButton": "Ga naar de home-pagina", + "text": "We konden geen informatie over deze media ophalen bij TMDB. Kijk even na of TMDB te bereiken is op dit netwerk.", + "title": "Metadata ophalen mislukt" + }, + "notFound": { + "badge": "Pagina niet gevonden", + "homeButton": "Naar de home-pagina", + "text": "We konden dit stukje media niet vinden. Het is mogelijk verwijderd, of jij hebt zelf de URL aangepast.", + "title": "We konden deze media niet vinden." + } + }, + "nextEpisode": { + "cancel": "Annuleren", + "next": "Volgende aflevering" + }, + "playbackError": { + "badge": "Afspeelfout", + "errors": { + "errorAborted": "Het laden van de media is stopgezet omdat de gebruiker daar om vroeg.", + "errorDecode": "Ondanks het feit dat we eerder dachten dat deze bron beschikbaar, was dat toch niet zo en is er een decode error ontstaan.", + "errorGenericMedia": "Onbekende media foutmelding.", + "errorNetwork": "Er ging iets mis waardoor de media niet langer beschikbaar is, al was hij dat eerst wel.", + "errorNotSupported": "Deze media or media provider wordt niet ondersteund." + }, + "homeButton": "Naar de home-pagina", + "text": "Er ging iets mis bij het afspelen. Probeer het nog eens.", + "title": "Oeps, hier ging iets mis!" + }, + "scraping": { + "extensionFailure": { + "badge": "Extensie uitgeschakeld", + "enableExtension": "Extensie inschakelen", + "homeButton": "Naar hoofdpagina", + "text": "Je hebt de SkoolTV extensie geïnstalleerd. Om deze te gebruiken, moet je de extensie inschakelen voor deze site.", + "title": "Activeer alstublieft de extensie" + }, + "items": { + "failure": "Daar ging iets mis", + "notFound": "Er is geen video gevonden", + "pending": "Naar videos aan het zoeken..." + }, + "notFound": { + "badge": "Niet gevonden", + "detailsButton": "Meer informatie", + "homeButton": "Naar de home-pagina", + "text": "We hebben al onze providers lief aangekeken maar we hebben niets kunnen vinden. Wij beheersen de media niet, en bepalen dus niet wat er beschikbaar is. Klik op \"meer informatie over foutmelding\" voor meer informatie.", + "title": "Dat konden we niet vinden" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "Nog {{timeLeft}} • Klaar om {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Bevestig dat u een mens bent door de Captcha aan de rechterkant in te vullen. Dit is om SkoolTV veilig te houden!", + "error": "Kan uw menselijkheid niet verifiëren. Probeer het opnieuw.", + "title": "We moeten verifiëren dat u een mens bent.", + "verifyingHumanity": "Je menselijkheid verifiëren..." + } + }, + "screens": { + "dmca": { + "text": "Welkom op de DMCA-contactpagina van SkoolTV! Wij respecteren intellectuele eigendomsrechten en willen eventuele problemen met auteursrechten snel aanpakken. Als u van mening bent dat uw auteursrechtelijk beschermde werk onjuist is gebruikt op ons platform, stuur dan een gedetailleerde DMCA-kennisgeving naar het onderstaande e-mailadres. Vermeld een beschrijving van het auteursrechtelijk beschermde materiaal, uw contactgegevens en een verklaring dat u te goeder trouw bent. Wij zetten ons in om deze zaken snel op te lossen en waarderen uw medewerking om SkoolTV een plek te houden waar creativiteit en auteursrechten worden gerespecteerd.", + "title": "DMCA" + }, + "loadingApp": "Toepassing laden", + "loadingUser": "Je profiel laden", + "loadingUserError": { + "logout": "Uitloggen", + "reset": "Aangepaste server resetten", + "text": "Het laden van uw profiel is mislukt", + "textWithReset": "Is het laden van je profiel van je aangepaste server mislukt en wil je terug naar de standaardserver?" + }, + "migration": { + "failed": "Het migreren van uw gegevens is mislukt.", + "inProgress": "Even geduld, we zijn je gegevens aan het migreren. Dit zal niet lang duren." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Apparaatnaam", + "deviceNamePlaceholder": "Persoonlijke telefoon", + "editProfile": "Bewerken", + "logoutButton": "Uitloggen" + }, + "actions": { + "delete": { + "button": "Account verwijderen", + "confirmButton": "Account verwijderen", + "confirmDescription": "Weet je zeker dat je je account wilt verwijderen? Al je gegevens zullen verloren gaan!", + "confirmTitle": "Weet je het zeker?", + "text": "Deze actie is onomkeerbaar. Alle gegevens worden verwijderd en er kan niets worden hersteld.", + "title": "Account verwijderen" + }, + "title": "Acties" + }, + "devices": { + "deviceNameLabel": "Apparaatnaam", + "failed": "Sessies niet geladen", + "removeDevice": "Verwijder", + "title": "Apparaten" + }, + "profile": { + "finish": "Bewerken voltooien", + "firstColor": "Profielkleur 1", + "secondColor": "Profielkleur 2", + "title": "Profielfoto bewerken", + "userIcon": "Gebruikerspictogram" + }, + "register": { + "cta": "Aan de slag", + "text": "Deel uw kijkvoortgang tussen apparaten en houd ze gesynchroniseerd.", + "title": "Synchroniseren met de sudo-cloud" + }, + "title": "Account" + }, + "appearance": { + "activeTheme": "Actief", + "themes": { + "blue": "Blauw", + "default": "Standaard", + "gray": "Grijs", + "red": "Rood", + "teal": "Groenblauw" + }, + "title": "Uiterlijk" + }, + "connections": { + "server": { + "description": "Als je verbinding wilt maken met een eigen backend om je gegevens op te slaan, schakel dan deze optie in en geef de URL op. <0>Instructies.", + "label": "Eigen server", + "urlLabel": "Eigen server URL" + }, + "setup": { + "doSetup": "Instellen", + "errorStatus": { + "description": "Het lijkt erop dat één of meer items in deze configuratie jouw aandacht nodig hebben.", + "title": "Iets vereist jouw aandacht" + }, + "itemError": "Er is iets mis met deze instelling. Klik op opnieuw instellen om op te lossen.", + "items": { + "default": "Standaard installatie", + "extension": "Extensie", + "proxy": "Eigen proxy" + }, + "redoSetup": "Opnieuw instellen", + "successStatus": { + "description": "In alles is ingesteld, je kunt nu je favoriete media bekijken.", + "title": "Alles is ingesteld!" + }, + "unsetStatus": { + "description": "Klik op de knop aan de rechterkant om het installatieproces te starten.", + "title": "Je hebt de installatieprocedure nog niet doorlopen" + } + }, + "title": "Verbindingen", + "workers": { + "addButton": "Nieuwe worker toevoegen", + "description": "Om de applicatie te laten werken, wordt al het verkeer omgeleid via proxies. Schakel dit in als je je eigen workers wilt gebruiken. <0>Instructies.", + "emptyState": "Nog geen workers, voeg er hieronder een toe", + "label": "Eigen proxy werker gebruiken", + "urlLabel": "Worker URLs", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Applicatietaal", + "languageDescription": "Taal toegepast op de gehele applicatie.", + "thumbnail": "Genereer miniaturen", + "thumbnailDescription": "Meestal hebben video's geen miniaturen. Je kunt deze instelling inschakelen om ze dynamisch te genereren, maar dit kan je video vertragen.", + "thumbnailLabel": "Genereer miniaturen", + "title": "Voorkeuren" + }, + "reset": "Resetten", + "save": "Wijzigingen opslaan", + "sidebar": { + "info": { + "appVersion": "App versie", + "backendUrl": "Backend URL", + "backendVersion": "Backend versie", + "hostname": "hostnaam", + "insecure": "Onveilig", + "notLoggedIn": "U bent niet ingelogd", + "secure": "Veilig", + "title": "App informatie", + "unknownVersion": "Onbekend", + "userId": "Gebruiker ID" + } + }, + "subtitles": { + "backgroundBlurLabel": "Achtergrondvervaging", + "backgroundLabel": "Achtergrond dekking", + "colorLabel": "Kleur", + "previewQuote": "Ik mag niet bang zijn. Angst doodt de geest.", + "textSizeLabel": "Tekengrootte", + "title": "Ondertiteling" + }, + "unsaved": "U heeft niet-opgeslagen wijzigingen" + } +} diff --git a/src/assets/locales/nv.json b/src/assets/locales/nv.json new file mode 100644 index 0000000..d30fd5b --- /dev/null +++ b/src/assets/locales/nv.json @@ -0,0 +1,12 @@ +{ + "about": { + "description": "SkoolTV T'áá hwiił yá at'ééh naat'áanii t'áá hwiił yá at'ééh bitsiin. Bee ahéhí bitsííʼííł dóó sinas dziní asdzą́ą́.", + "faqTitle": "hastiin nahatʼá", + "q1": { + "body": "Bee hwiił bitsííʼííł hólǫ́, t'áá hwiił yá at'ééh naat'áanii t'áá hwiił yá at'ééh bitsiin. Hwiił yá at'ééh naat'áanii at'é, bitsííʼííł yá at'ééh naat'áanii t'áá hwiił yá at'ééh bitsiin. Bitsííʼííł yá at'ééh naat'áanii hólǫ́, t'áá hwiił yá at'ééh naat'áanii t'áá hwiił yá at'ééh bitsiin." + }, + "q3": { + "body": "Hałáágo áłtsééh hózhǫǫgiisiił Nílchʼi Datasoii (TMDB) yá’át’ééhí dooleeł dįįʼgo doo dįįʼgií nihisin dóó tązhii yisdzohazlą́ą́ʼ." + } + } +} diff --git a/src/assets/locales/pa.json b/src/assets/locales/pa.json new file mode 100644 index 0000000..335d89d --- /dev/null +++ b/src/assets/locales/pa.json @@ -0,0 +1,546 @@ +{ + "about": { + "description": "ਮੂਵੀ-ਵੈਬ ਇੱਕ ਵੈੱਬ ਐਪਲੀਕੇਸ਼ਨ ਹੈ ਜੋ ਸਟ੍ਰੀਮ ਲਈ ਇੰਟਰਨੈਟ ਦੀ ਖੋਜ ਕਰਦੀ ਹੈ. ਟੀਮ ਦਾ ਉਦੇਸ਼ ਕੰਟੈਂਟ ਦੀ ਖਪਤ ਕਰਨ ਲਈ ਜ਼ਿਆਦਾਤਰ ਘੱਟੋ-ਘੱਟ ਪਹੁੰਚ ਹੈ.", + "faqTitle": "ਆਮ ਸਵਾਲ", + "q1": { + "body": "ਮੂਵੀ ਵੈੱਬ ਕਿਸੇ ਕੰਟੈਂਟ ਦੀ ਮੇਜ਼ਬਾਨੀ ਨਹੀਂ ਕਰਦਾ ਹੈ.ਜਦੋਂ ਤੁਸੀਂ ਦੇਖਣ ਲਈ ਕਿਸੇ ਚੀਜ਼ 'ਤੇ ਕਲਿੱਕ ਕਰਦੇ ਹੋ, ਤਾਂ ਚੁਣੇ ਹੋਏ ਮੀਡੀਆ ਲਈ ਇੰਟਰਨੈੱਟ ਖੋਜਿਆ ਜਾਂਦਾ ਹੈ (ਲੋਡਿੰਗ ਸਕ੍ਰੀਨ 'ਤੇ ਅਤੇ 'ਵੀਡੀਓ ਸਰੋਤ' ਟੈਬ ਵਿੱਚ ਤੁਸੀਂ ਦੇਖ ਸਕਦੇ ਹੋ ਕਿ ਤੁਸੀਂ ਕਿਹੜਾ ਸਰੋਤ ਵਰਤ ਰਹੇ ਹੋ) ਮੀਡੀਆ ਕਦੇ ਵੀ ਮੂਵੀ-ਵੈੱਬ ਦੁਆਰਾ ਅਪਲੋਡ ਨਹੀਂ ਹੁੰਦਾ, ਸਭ ਕੁਝ ਇਸ ਖੋਜ ਵਿਧੀ ਦੁਆਰਾ ਹੁੰਦਾ ਹੈ।", + "title": "ਕੰਟੈਂਟ ਕਿੱਥੋਂ ਆਉਂਦੀ ਹੈ?" + }, + "q2": { + "body": "ਕਿਸੇ ਸ਼ੋਅ ਜਾਂ ਮੂਵੀ ਦੀ ਬੇਨਤੀ ਕਰਨਾ ਸੰਭਵ ਨਹੀਂ ਹੈ, ਮੂਵੀ-ਵੈੱਬ ਕਿਸੇ ਵੀ ਕੰਟੈਂਟ ਦਾ ਪ੍ਰਬੰਧਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਸਾਰੇ ਕੰਟੈਂਟ ਨੂੰ ਇੰਟਰਨੈੱਟ 'ਤੇ ਸਰੋਤਾਂ ਰਾਹੀਂ ਦੇਖਿਆ ਜਾਂਦਾ ਹੈ।", + "title": "ਮੈਂ ਇੱਕ ਸ਼ੋਅ ਜਾਂ ਫ਼ਿਲਮ ਲਈ ਕਿੱਥੇ ਬੇਨਤੀ ਕਰ ਸਕਦਾ/ਸਕਦੀ ਹਾਂ?" + }, + "q3": { + "body": "ਸਾਡੇ ਖੋਜ ਨਤੀਜੇ ਮੂਵੀ ਡੇਟਾਬੇਸ (TMDB) ਦੁਆਰਾ ਸੰਚਾਲਿਤ ਹੁੰਦੇ ਹਨ ਅਤੇ ਇਸ ਗੱਲ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ ਪ੍ਰਦਰਸ਼ਿਤ ਹੁੰਦੇ ਹਨ ਕਿ ਸਾਡੇ ਸਰੋਤਾਂ ਵਿੱਚ ਅਸਲ ਵਿੱਚ ਕੰਟੈਂਟ ਹੈ ਜਾਂ ਨਹੀਂ.", + "title": "ਖੋਜ ਨਤੀਜੇ ਸ਼ੋਅ ਜਾਂ ਫ਼ਿਲਮ ਦਿਖਾਉਂਦੇ ਹਨ, ਮੈਂ ਇਸਨੂੰ ਕਿਉਂ ਨਹੀਂ ਚਲਾ ਸਕਦਾ?" + }, + "title": "ਮੂਵੀ-ਵੈੱਬ ਡੀ ਬਾਰੇ" + }, + "actions": { + "copied": "ਕਾਪੀਡ", + "copy": "ਕਾਪੀ" + }, + "auth": { + "createAccount": "ਕੀ ਤੁਹਾਡੇ ਕੋਲ ਅਜੇ ਖਾਤਾ ਨਹੀਂ ਹੈ? <0>ਇੱਕ ਖਾਤਾ ਬਣਾਓ.", + "deviceNameLabel": "ਡਿਵਾਈਸ ਦਾ ਨਾਮ", + "deviceNamePlaceholder": "ਨਿੱਜੀ ਫ਼ੋਨ", + "generate": { + "description": "ਤੁਹਾਡਾ ਗੁਪਤਕੋਡ ਤੁਹਾਡੇ ਉਪਭੋਗਤਾ ਨਾਮ ਅਤੇ ਪਾਸਵਰਡ ਵਜੋਂ ਕੰਮ ਕਰਦਾ ਹੈ. ਇਸਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਣਾ ਯਕੀਨੀ ਬਣਾਓ ਕਿਉਂਕਿ ਤੁਹਾਨੂੰ ਆਪਣੇ ਖਾਤੇ ਵਿੱਚ ਲੌਗਇਨ ਕਰਨ ਲਈ ਇਸਨੂੰ ਦਾਖਲ ਕਰਨ ਦੀ ਲੋੜ ਹੋਵੇਗੀ", + "next": "ਮੈਂ ਆਪਣਾ ਪਾਸਫਰੇਜ ਸੁਰੱਖਿਅਤ ਕਰ ਲਿਆ ਹੈ", + "passphraseFrameLabel": "ਪੈਰਾਫਰਾਜ਼", + "title": "ਤੁਹਾਡਾ ਪਾਸਫਰੇਜ" + }, + "hasAccount": "ਕੀ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਖਾਤਾ ਹੈ? <0>ਇੱਥੇ ਲੌਗਇਨ ਕਰੋ.", + "login": { + "description": "ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਖਾਤੇ ਵਿੱਚ ਲੌਗਇਨ ਕਰਨ ਲਈ ਆਪਣਾ ਗੁਪਤਕੋਡ ਦਾਖਲ ਕਰੋ", + "deviceLengthError": "ਕਿਰਪਾ ਕਰਕੇ ਇੱਕ ਡਿਵਾਈਸ ਦਾ ਨਾਮ ਦਾਖਲ ਕਰੋ", + "passphraseLabel": "12-ਅਖਰੰਦਾ ਪਾਸਫਰੇਜ਼", + "passphrasePlaceholder": "ਪੈਰਾਫਰਾਜ਼", + "submit": "ਲੌਗ-ਇਨ", + "title": "ਆਪਣੇ ਖਾਤੇ ਵਿੱਚ ਲੌਗਇਨ ਕਰੋ", + "validationError": "ਗਲਤ ਜਾਂ ਅਧੂਰਾ ਗੁਪਤਕੋਡ" + }, + "register": { + "information": { + "color1": "ਪਰੋਫਾਇਲ ਦਾ ਪੇਹਲਾ ਰੰਗ", + "color2": "ਪ੍ਰੋਫਾਇਲ ਦਾ ਦੂਜਾ ਰੰਗ", + "header": "ਆਪਣੀ ਡਿਵਾਈਸ ਲਈ ਇੱਕ ਨਾਮ ਦਰਜ ਕਰੋ ਅਤੇ ਆਪਣੀ ਪਸੰਦ ਦਾ ਰੰਗ ਅਤੇ ਇੱਕ ਉਪਭੋਗਤਾ ਆਈਕਨ ਚੁਣੋ", + "icon": "ਉਪਭੋਗਤਾ ਪ੍ਰਤੀਕ", + "next": "ਅਗਲਾ", + "title": "ਖਾਤਾ ਜਾਣਕਾਰੀ" + } + }, + "trust": { + "failed": { + "text": "ਕੀ ਤੁਸੀਂ ਇਸਨੂੰ ਸਹੀ ਢੰਗ ਨਾਲ ਕੌਂਫਿਗਰ ਕੀਤਾ ਹੈ?", + "title": "ਸਰਵਰ ਤੱਕ ਪਹੁੰਚਣ ਵਿੱਚ ਅਸਫਲ" + }, + "host": "ਤੁਸੀਂ <0>{{hostname}} ਨਾਲ ਜੁੜ ਰਹੇ ਹੋ - ਕਿਰਪਾ ਕਰਕੇ ਖਾਤਾ ਬਣਾਉਣ ਤੋਂ ਪਹਿਲਾਂ ਪੁਸ਼ਟੀ ਕਰੋ ਕਿ ਤੁਸੀਂ ਇਸ 'ਤੇ ਭਰੋਸਾ ਕਰਦੇ ਹੋ", + "no": "ਵਾਪਸ ਜਾਓ", + "noHost": "ਸਰਵਰ ਕੌਂਫਿਗਰ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ, ਇਸਲਈ ਤੁਸੀਂ ਖਾਤਾ ਨਹੀਂ ਬਣਾ ਸਕਦੇ ਹੋ", + "noHostTitle": "ਸਰਵਰ ਕੌਂਫਿਗਰ ਨਹੀਂ ਕੀਤਾ ਗਿਆ!", + "title": "ਕੀ ਤੁਸੀਂ ਇਸ ਸਰਵਰ 'ਤੇ ਭਰੋਸਾ ਕਰਦੇ ਹੋ?", + "yes": "ਮੈਨੂੰ ਇਸ ਸਰਵਰ 'ਤੇ ਭਰੋਸਾ ਹੈ" + }, + "verify": { + "description": "ਕਿਰਪਾ ਕਰਕੇ ਇਹ ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ ਕਿ ਤੁਸੀਂ ਇਸਨੂੰ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਹੈ ਅਤੇ ਆਪਣਾ ਖਾਤਾ ਬਣਾਉਣ ਲਈ ਪਹਿਲਾਂ ਤੋਂ ਆਪਣਾ ਗੁਪਤਕੋਡ ਦਰਜ ਕਰੋ", + "invalidData": "ਡਾਟਾ ਵੈਧ ਨਹੀਂ ਹੈ", + "noMatch": "ਪਾਸਫਰੇਜ ਮੇਲ ਨਹੀਂ ਖਾਂਦਾ", + "passphraseLabel": "ਤੁਹਾਡਾ 12-ਸ਼ਬਦਾਂ ਦਾ ਪਾਸਫਰੇਜ", + "recaptchaFailed": "ਰੀਕੈਪਟਚਾ ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ ਰਹੀ", + "register": "ਖਾਤਾ ਬਣਾਉ", + "title": "ਆਪਣੇ ਗੁਪਤਕੋਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ" + } + }, + "errors": { + "badge": "ਇਹ ਟੁੱਟ ਗਿਆ", + "details": "ਗਲਤੀ ਵੇਰਵੇ", + "reloadPage": "ਪੈਗ ਨੂੰ ਰੀਲੋਡ ਕਰੋ", + "showError": "ਗਲਤੀ ਦੇ ਵੇਰਵੇ ਦਿਖਾਓ", + "title": "ਸਾਨੂੰ ਇੱਕ ਤਰੁੱਟੀ ਦਾ ਸਾਹਮਣਾ ਕਰਨਾ ਪਿਆ!" + }, + "footer": { + "legal": { + "disclaimer": "ਬੇਦਾਅਵਾ", + "disclaimerText": "ਮੂਵੀ-ਵੈੱਬ ਕਿਸੇ ਵੀ ਫਾਈਲ ਦੀ ਮੇਜ਼ਬਾਨੀ ਨਹੀਂ ਕਰਦਾ ਹੈ, ਇਹ ਸਿਰਫ਼ ਤੀਜੀ ਧਿਰ ਦੀਆਂ ਸੇਵਾਵਾਂ ਨਾਲ ਲਿੰਕ ਕਰਦਾ ਹੈ. ਕਾਨੂੰਨੀ ਮੁੱਦਿਆਂ ਨੂੰ ਫਾਈਲ ਹੋਸਟਾਂ ਅਤੇ ਪ੍ਰਦਾਤਾਵਾਂ ਨਾਲ ਉਠਾਇਆ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ। ਮੂਵੀ-ਵੈਬ ਵੀਡੀਓ ਪ੍ਰਦਾਤਾਵਾਂ ਦੁਆਰਾ ਦਿਖਾਈਆਂ ਗਈਆਂ ਕਿਸੇ ਵੀ ਮੀਡੀਆ ਫਾਈਲਾਂ ਲਈ ਜ਼ਿੰਮੇਵਾਰ ਨਹੀਂ ਹੈ." + }, + "links": { + "discord": "ਡਿਸਕੋਰਡ", + "dmca": "DMCA", + "github": "Github" + }, + "tagline": "ਇਸ ਓਪਨ ਸੋਰਸ ਸਟ੍ਰੀਮਿੰਗ ਐਪ ਨਾਲ ਆਪਣੇ ਮਨਪਸੰਦ ਸ਼ੋਅ ਅਤੇ ਫ਼ਿਲਮਾਂ ਦੇਖੋ।" + }, + "global": { + "name": "ਮੂਵੀ-ਵੈੱਬ", + "pages": { + "about": "ਬਾਰੇ", + "dmca": "DMCA", + "login": "ਲਾਗਿਨ", + "onboarding": "ਸਥਾਪਨਾ ਕਰਨਾ", + "pagetitle": "{{title}} - ਮੂਵੀ-ਵੈੱਬ", + "register": "ਰਜਿਸਟਰ", + "settings": "ਸੈਟਿੰਗਾਂ" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "ਬੁੱਕਮਾਰਕ" + }, + "continueWatching": { + "sectionTitle": "ਦੇਖਣਾ ਜਾਰੀ ਰੱਖੋ" + }, + "mediaList": { + "stopEditing": "ਸੰਪਾਦਨ ਬੰਦ ਕਰੋ" + }, + "search": { + "allResults": "ਸਾਡੇ ਕੋਲ ਇਹੋ ਕੁਝ ਹੈ!", + "failed": "ਮੀਡੀਆ ਲੱਭਣ ਵਿੱਚ ਅਸਫਲ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ!", + "loading": "ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ...", + "noResults": "ਅਸੀਂ ਕੁਝ ਵੀ ਨਹੀਂ ਲੱਭ ਸਕੇ!", + "placeholder": { + "default": "ਤੁਸੀਂ ਕੀ ਦੇਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?", + "extra": [ + "ਤੁਸੀਂ ਕੀ ਪੜਚੋਲ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?", + "ਤੁਹਾਡੀ ਨਿਗਰਾਨੀ ਸੂਚੀ ਵਿੱਚ ਕੀ ਹੈ?", + "ਤੁਹਾਡੀ ਮਨਪਸੰਦ ਫਿਲਮ ਕਿਹੜੀ ਹੈ?", + "ਤੁਹਾਡੀ ਮਨਪਸੰਦ ਲੜੀ ਕਿਹੜੀ ਹੈ?" + ] + }, + "sectionTitle": "ਖੋਜ ਨਤੀਜੇ" + }, + "titles": { + "day": { + "default": "ਤੁਸੀਂ ਅੱਜ ਦੁਪਹਿਰ ਨੂੰ ਕੀ ਦੇਖਣਾ ਚਾਹੋਗੇ?", + "extra": [ + "ਸਾਹਸੀ ਮਹਿਸੂਸ ਕਰ ਰਹੇ ਹੋ? ਜੁਰਾਸਿਕ ਪਾਰਕ ਸੰਪੂਰਣ ਵਿਕਲਪ ਹੋ ਸਕਦਾ ਹੈ." + ] + }, + "morning": { + "default": "ਤੁਸੀਂ ਅੱਜ ਸਵੇਰੇ ਕੀ ਦੇਖਣਾ ਚਾਹੋਗੇ?", + "extra": [ + "ਮੈਂ ਸੁਣਦਾ ਹਾਂ ਕਿ ਸੂਰਜ ਚੜ੍ਹਨ ਤੋਂ ਪਹਿਲਾਂ ਚੰਗਾ ਹੁੰਦਾ ਹੈ" + ] + }, + "night": { + "default": "ਤੁਸੀਂ ਅੱਜ ਰਾਤ ਕੀ ਦੇਖਣਾ ਚਾਹੋਗੇ?", + "extra": [ + "ਥੱਕ ਗਏ? ਮੈਂ ਸੁਣਿਆ ਹੈ ਕਿ Exorcist ਚੰਗਾ ਹੈ." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "ਮੂਵੀ", + "show": "ਨਾਟਕ" + } + }, + "navigation": { + "banner": { + "offline": "ਆਪਣੇ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਦੀ ਜਾਂਚ ਕਰੋ" + }, + "menu": { + "about": "ਸਾਡੇ ਬਾਰੇ", + "logout": "ਲਾੱਗ ਆਊਟ", + "register": "ਕਲਾਉਡ ਨਾਲ ਸਿੰਕ ਕਰੋ", + "settings": "ਸੈਟਿੰਗਾਂ", + "support": "ਸਮਰਥਨ" + } + }, + "notFound": { + "badge": "ਨਹੀਂ ਲਭਿਆ", + "goHome": "ਘਰ ਵਾਪਸ", + "message": "ਅਸੀਂ ਹਰ ਜਗ੍ਹਾ ਦੇਖਿਆ: ਡੱਬਿਆਂ ਦੇ ਹੇਠਾਂ, ਅਲਮਾਰੀ ਵਿੱਚ, ਪ੍ਰੌਕਸੀ ਦੇ ਪਿੱਛੇ ਪਰ ਆਖਰਕਾਰ ਉਹ ਪੰਨਾ ਨਹੀਂ ਲੱਭ ਸਕਿਆ ਜਿਸਦੀ ਤੁਸੀਂ ਭਾਲ ਕਰ ਰਹੇ ਹੋ.", + "title": "ਉਹ ਪੰਨਾ ਨਹੀਂ ਲੱਭ ਸਕਿਆ" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "ਰੱਦ ਕਰੋ", + "confirm": "ਡਿਫੌਲਟ ਸੈੱਟਅੱਪ ਵਰਤੋ", + "description": "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈੱਟਅੱਪ ਵਿੱਚ ਵਧੀਆ ਸਟ੍ਰੀਮ ਨਹੀਂ ਹਨ ਅਤੇ ਇਹ ਅਸਹਿਣਸ਼ੀਲ ਤੌਰ 'ਤੇ ਹੌਲੀ ਹੋ ਸਕਦੀ ਹੈ.", + "title": "ਤੁਹਾਨੂੰ ਪੂਰਾ ਵਿਸ਼ਵਾਸ ਹੈ?" + }, + "extension": { + "back": "ਵਾਪਸ ਜਾਓ", + "explainer": "ਬ੍ਰਾਊਜ਼ਰ ਐਕਸਟੈਂਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ, ਤੁਸੀਂ ਸਾਡੇ ਦੁਆਰਾ ਪੇਸ਼ ਕੀਤੀਆਂ ਗਈਆਂ ਸਭ ਤੋਂ ਵਧੀਆ ਸਟ੍ਰੀਮਾਂ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ. ਸਿਰਫ਼ ਇੱਕ ਸਧਾਰਨ ਸਥਾਪਨਾ ਨਾਲ.", + "explainerIos": "ਬਦਕਿਸਮਤੀ ਨਾਲ, ਬ੍ਰਾਊਜ਼ਰ ਐਕਸਟੈਂਸ਼ਨ iOS 'ਤੇ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ, ਕੋਈ ਹੋਰ ਵਿਕਲਪ ਚੁਣਨ ਲਈ Go back ਦਬਾਓ.", + "extensionHelp": "ਜੇਕਰ ਤੁਸੀਂ ਐਕਸਟੈਂਸ਼ਨ ਨੂੰ ਸਥਾਪਿਤ ਕੀਤਾ ਹੈ ਪਰ ਇਸਦਾ ਪਤਾ ਨਹੀਂ ਲੱਗਿਆ ਹੈ, ਤਾਂ ਆਪਣੇ ਬ੍ਰਾਊਜ਼ਰ ਐਕਸਟੈਂਸ਼ਨ ਮੀਨੂ ਰਾਹੀਂ ਐਕਸਟੈਂਸ਼ਨ ਖੋਲ੍ਹੋ ਅਤੇ ਸਕ੍ਰੀਨ 'ਤੇ ਦਿੱਤੇ ਕਦਮਾਂ ਦੀ ਪਾਲਣਾ ਕਰੋ.", + "linkChrome": "ਕਰੋਮ ਐਕਸਟੈਂਸ਼ਨ ਸਥਾਪਤ ਕਰੋ", + "linkFirefox": "Firiefox ਐਕਸਟੈਂਸ਼ਨ ਇੰਸਟਾਲ ਕਰੋ", + "notDetecting": "ਕ੍ਰੋਮ 'ਤੇ ਸਥਾਪਿਤ ਕੀਤਾ ਗਿਆ ਹੈ, ਪਰ ਸਾਈਟ ਇਸਦਾ ਪਤਾ ਨਹੀਂ ਲਗਾ ਰਹੀ ਹੈ? ਪੰਨੇ ਨੂੰ ਮੁੜ ਲੋਡ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ.", + "notDetectingAction": "ਪੰਨਾ ਰੀਲੋਡ ਕਰੋ", + "status": { + "disallowed": "ਇਸ ਪੰਨੇ ਲਈ ਐਕਸਟੈਂਸ਼ਨ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ", + "disallowedAction": "ਐਕਸਟੈਂਸ਼ਨ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ", + "failed": "ਸਥਿਤੀ ਦੀ ਬੇਨਤੀ ਕਰਨ ਵਿੱਚ ਅਸਫਲ", + "loading": "ਤੁਹਾਡੇ ਐਕਸਟੈਂਸ਼ਨ ਨੂੰ ਸਥਾਪਿਤ ਕਰਨ ਦੀ ਉਡੀਕ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ", + "outdated": "ਐਕਸਟੈਂਸ਼ਨ ਸੰਸਕਰਣ ਬਹੁਤ ਪੁਰਾਣਾ ਹੈ", + "success": "ਐਕਸਟੈਂਸ਼ਨ ਉਮੀਦ ਅਨੁਸਾਰ ਕੰਮ ਕਰ ਰਿਹਾ ਹੈ!" + }, + "submit": "ਜਾਰੀ ਰੱਖੋ", + "title": "ਆਉ ਇੱਕ ਐਕਸਟੈਂਸ਼ਨ ਨਾਲ ਸ਼ੁਰੂ ਕਰੀਏ" + }, + "proxy": { + "back": "ਵਾਪਸ ਜਾਓ", + "explainer": "ਪ੍ਰੌਕਸੀ ਵਿਧੀ ਨਾਲ, ਤੁਸੀਂ ਸਵੈ-ਸੇਵਾ ਪ੍ਰੌਕਸੀ ਬਣਾ ਕੇ ਵਧੀਆ ਗੁਣਵੱਤਾ ਵਾਲੀਆਂ ਸਟ੍ਰੀਮਾਂ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ.", + "input": { + "errorConnection": "ਪ੍ਰੌਕਸੀ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ", + "errorInvalidUrl": "ਵੈਧ URL ਨਹੀਂ ਹੈ", + "errorNotProxy": "ਇੱਕ ਪ੍ਰੌਕਸੀ ਦੀ ਉਮੀਦ ਕੀਤੀ ਪਰ ਇੱਕ ਵੈਬਸਾਈਟ ਮਿਲੀ", + "label": "ਪ੍ਰੌਕਸੀ URL", + "placeholder": "https://" + }, + "link": "ਇੱਕ ਪ੍ਰੌਕਸੀ ਬਣਾਉਣਾ ਸਿੱਖੋ", + "submit": "ਪ੍ਰੌਕਸੀ ਸਪੁਰਦ ਕਰੋ", + "title": "ਆਓ ਇੱਕ ਨਵੀਂ ਪ੍ਰੌਕਸੀ ਬਣਾਈਏ" + }, + "start": { + "explainer": "ਸਭ ਤੋਂ ਵਧੀਆ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਸੰਭਵ ਬਣਾਉਣ ਲਈ, ਤੁਹਾਨੂੰ ਇਹ ਚੁਣਨ ਦੀ ਲੋੜ ਹੋਵੇਗੀ ਕਿ ਤੁਸੀਂ ਕਿਹੜਾ ਸਟ੍ਰੀਮਿੰਗ ਤਰੀਕਾ ਵਰਤਣਾ ਚਾਹੁੰਦੇ ਹੋ.", + "options": { + "default": { + "text": "ਮੈਨੂੰ ਚੰਗੀ ਕੁਆਲਿਟੀ ਦੀਆਂ ਸਟ੍ਰੀਮਾਂ ਨਹੀਂ ਚਾਹੀਦੀਆਂ,<0 /> <1>ਡਿਫੌਲਟ ਸੈੱਟਅੱਪ ਦੀ ਵਰਤੋਂ ਕਰੋ" + }, + "extension": { + "action": "ਇਕਸਟੈਨਸ਼ਨ ਇੰਸਟਾਲ ਕਰੋ", + "description": "ਬ੍ਰਾਊਜ਼ਰ ਐਕਸਟੈਂਸ਼ਨ ਨੂੰ ਸਥਾਪਿਤ ਕਰੋ ਅਤੇ ਵਧੀਆ ਸਰੋਤਾਂ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੋ.", + "quality": "ਵਧੀਆ ਗੁਣਵੱਤਾ", + "title": "ਬ੍ਰਾਊਜ਼ਰ ਐਕਸਟੈਂਸ਼ਨ" + }, + "proxy": { + "action": "ਪ੍ਰੌਕਸੀ ਸੈੱਟਅੱਪ ਕਰੋ", + "description": "ਸਿਰਫ਼ 5 ਮਿੰਟਾਂ ਵਿੱਚ ਇੱਕ ਪ੍ਰੌਕਸੀ ਸੈੱਟਅੱਪ ਕਰੋ ਅਤੇ ਵਧੀਆ ਸਰੋਤਾਂ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੋ.", + "quality": "ਚੰਗੀ ਗੁਣਵੱਤਾ", + "title": "ਕਸਟਮ ਪ੍ਰੌਕਸੀ" + } + }, + "title": "ਚਲੋ ਤੁਹਾਨੂੰ SkoolTV ਨਾਲ ਸੈੱਟਅੱਪ ਕਰਵਾਉਂਦੇ ਹਾਂ" + } + }, + "overlays": { + "close": "ਬੰਦ ਕਰੋ" + }, + "player": { + "back": { + "default": "ਘਰ ਵਾਪਸ", + "short": "ਵਾਪਸ" + }, + "casting": { + "enabled": "ਡਿਵਾਈਸ 'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "HLS ਪਲੇਲਿਸਟ ਲਿੰਕ ਕਾਪੀ ਕਰੋ", + "disclaimer": "ਡਾਊਨਲੋਡ ਸਿੱਧੇ ਪ੍ਰਦਾਤਾ ਤੋਂ ਲਏ ਜਾਂਦੇ ਹਨ. ਮੂਵੀ-ਵੈੱਬ ਦਾ ਇਸ 'ਤੇ ਕੰਟਰੋਲ ਨਹੀਂ ਹੈ ਕਿ ਡਾਊਨਲੋਡ ਕਿਵੇਂ ਪ੍ਰਦਾਨ ਕੀਤੇ ਜਾਂਦੇ ਹਨ.", + "downloadSubtitle": "ਮੌਜੂਦਾ ਉਪਸਿਰਲੇਖ ਡਾਊਨਲੋਡ ਕਰੋ", + "downloadVideo": "ਵੀਡੀਓ ਡਾਊਨਲੋਡ ਕਰੋ", + "hlsDisclaimer": "ਡਾਊਨਲੋਡ ਸਿੱਧੇ ਪ੍ਰਦਾਤਾ ਤੋਂ ਲਏ ਜਾਂਦੇ ਹਨ। ਮੂਵੀ-ਵੈਬ ਦਾ ਇਸ 'ਤੇ ਕੰਟਰੋਲ ਨਹੀਂ ਹੈ ਕਿ ਡਾਊਨਲੋਡ ਕਿਵੇਂ ਪ੍ਰਦਾਨ ਕੀਤੇ ਜਾਂਦੇ ਹਨ।

ਕਿਰਪਾ ਕਰਕੇ ਧਿਆਨ ਦਿਓ ਕਿ ਤੁਸੀਂ ਇੱਕ HLS ਪਲੇਲਿਸਟ ਡਾਊਨਲੋਡ ਕਰ ਰਹੇ ਹੋ, ਜੇ ਤੁਸੀਂ ਉੱਨਤ ਸਟ੍ਰੀਮਿੰਗ ਫਾਰਮੈਟਾਂ ਤੋਂ ਜਾਣੂ ਨਹੀਂ ਹੋ ਤਾਂ ਇਸਨੂੰ ਡਾਊਨਲੋਡ ਕਰਨ ਦੀ ਸਿਫ਼ਾਰਸ਼ ਨਹੀਂ ਕੀਤੀ ਜਾਂਦੀ। .ਵੱਖ-ਵੱਖ ਫਾਰਮੈਟਾਂ ਲਈ ਵੱਖ-ਵੱਖ ਸਰੋਤਾਂ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ.", + "onAndroid": { + "1": "Android 'ਤੇ ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ, ਡਾਊਨਲੋਡ ਬਟਨ 'ਤੇ ਕਲਿੱਕ ਕਰੋ ਫਿਰ, ਨਵੇਂ ਪੰਨੇ 'ਤੇ, ਵੀਡੀਓ 'ਤੇ ਟੈਪ ਕਰੋ ਅਤੇ ਹੋਲਡ ਕਰੋ, ਫਿਰ ਸੇਵ ਨੂੰ ਚੁਣੋ.", + "shortTitle": "ਡਾਊਨਲੋਡ / Android", + "title": "Android 'ਤੇ ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" + }, + "onIos": { + "1": "iOS 'ਤੇ ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ, ਡਾਊਨਲੋਡ ਬਟਨ 'ਤੇ ਕਲਿੱਕ ਕਰੋ ਫਿਰ, ਨਵੇਂ ਪੰਨੇ 'ਤੇ, 'ਤੇ ਕਲਿੱਕ ਕਰੋ, ਫਿਰ Save to Files 'ਤੇ ਕਲਿੱਕ ਕਰੋ.", + "shortTitle": "ਡਾਊਨਲੋਡ / iOS", + "title": "iOS 'ਤੇ ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" + }, + "onPc": { + "1": "PC 'ਤੇ, ਡਾਊਨਲੋਡ ਬਟਨ 'ਤੇ ਕਲਿੱਕ ਕਰੋ, ਫਿਰ, ਨਵੇਂ ਪੰਨੇ 'ਤੇ, ਵੀਡੀਓ 'ਤੇ ਸੱਜਾ ਕਲਿੱਕ ਕਰੋ ਅਤੇ ਵੀਡੀਓ ਨੂੰ ਇਸ ਤਰ੍ਹਾਂ ਸੁਰੱਖਿਅਤ ਕਰੋ ਚੁਣੋ.", + "shortTitle": "ਡਾਊਨਲੋਡ / PC", + "title": "PC 'ਤੇ ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" + }, + "title": "ਡਾਊਨਲੋਡ" + }, + "episodes": { + "button": "ਐਪੀਸੋਡ", + "emptyState": "ਇਸ ਸੀਜ਼ਨ ਵਿੱਚ ਕੋਈ ਐਪੀਸੋਡ ਨਹੀਂ ਹਨ, ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਜਾਂਚ ਕਰੋ!", + "episodeBadge": "E{{episode}}", + "loadingError": "ਸੀਜ਼ਨ ਲੋਡ ਕਰਨ ਵਿੱਚ ਤਰੁੱਟੀ", + "loadingList": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ...", + "loadingTitle": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ...", + "unairedEpisodes": "ਇਸ ਸੀਜ਼ਨ ਵਿੱਚ ਇੱਕ ਜਾਂ ਇੱਕ ਤੋਂ ਵੱਧ ਐਪੀਸੋਡਾਂ ਨੂੰ ਅਯੋਗ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ ਕਿਉਂਕਿ ਉਹਨਾਂ ਨੂੰ ਅਜੇ ਤੱਕ ਪ੍ਰਸਾਰਿਤ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ." + }, + "playback": { + "speedLabel": "ਪਲੇਬੈਕ ਗਤੀ", + "title": "ਪਲੇਬੈਕ ਸੈਟਿੰਗਾਂ" + }, + "quality": { + "automaticLabel": "ਆਟੋਮੈਟਿਕ ਗੁਣਵੱਤਾ", + "hint": "ਤੁਸੀਂ ਵੱਖ-ਵੱਖ ਗੁਣਵੱਤਾ ਵਿਕਲਪਾਂ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ <0>switching source ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਸਕਦੇ ਹੋ।", + "iosNoQuality": "ਐਪਲ-ਪ੍ਰਭਾਸ਼ਿਤ ਸੀਮਾਵਾਂ ਦੇ ਕਾਰਨ, ਇਸ ਸਰੋਤ ਲਈ ਗੁਣਵੱਤਾ ਦੀ ਚੋਣ iOS 'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ. ਤੁਸੀਂ ਵੱਖ-ਵੱਖ ਗੁਣਵੱਤਾ ਵਿਕਲਪਾਂ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ <0>ਕਿਸੇ ਹੋਰ ਸਰੋਤ 'ਤੇ ਜਾਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਸਕਦੇ ਹੋ.", + "title": "ਗੁਣਵੱਤਾ" + }, + "settings": { + "downloadItem": "ਡਾਊਨਲੋਡ", + "enableSubtitles": "ਉਪਸਿਰਲੇਖਾਂ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ", + "experienceSection": "ਦੇਖਣ ਦਾ ਤਜਰਬਾ", + "playbackItem": "ਪਲੇਬੈਕ ਸੈਟਿੰਗਾਂ", + "qualityItem": "ਗੁਣਵੱਤਾ", + "sourceItem": "ਵੀਡੀਓ ਸਰੋਤ", + "subtitleItem": "ਉਪਸਿਰਲੇਖ ਸੈਟਿੰਗਾਂ", + "videoSection": "ਵੀਡੀਓ ਸੈਟਿੰਗਾਂ" + }, + "sources": { + "failed": { + "text": "ਕਿਸੇ ਵੀ ਵੀਡੀਓ ਨੂੰ ਲੱਭਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਸਮੇਂ ਇੱਕ ਤਰੁੱਟੀ ਆਈ ਸੀ, ਕਿਰਪਾ ਕਰਕੇ ਇੱਕ ਵੱਖਰੇ ਸਰੋਤ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ.", + "title": "ਸਕ੍ਰੈਪ ਕਰਨ ਵਿੱਚ ਅਸਫਲ" + }, + "noEmbeds": { + "text": "ਅਸੀਂ ਕੋਈ ਏਮਬੇਡ ਲੱਭਣ ਵਿੱਚ ਅਸਮਰੱਥ ਸੀ, ਕਿਰਪਾ ਕਰਕੇ ਇੱਕ ਵੱਖਰੇ ਸਰੋਤ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ.", + "title": "ਕੋਈ ਏਮਬੇਡ ਨਹੀਂ ਮਿਲੇ" + }, + "noStream": { + "text": "ਇਸ ਸਰੋਤ ਵਿੱਚ ਇਸ ਫ਼ਿਲਮ ਜਾਂ ਸ਼ੋਅ ਲਈ ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਹ.", + "title": "ਕੋਈ ਧਾਰਾ ਨਹੀਂ" + }, + "title": "ਸਰੋਤ", + "unknownOption": "ਅਗਿਆਤ" + }, + "subtitles": { + "customChoice": "ਫਾਈਲ ਤੋਂ ਉਪਸਿਰਲੇਖ ਚੁਣੋ", + "customizeLabel": "ਅਨੁਕੂਲਿਤ ਕਰੋ", + "offChoice": "ਬੰਦ", + "settings": { + "backlink": "ਕਸਟਮ ਉਪਸਿਰਲੇਖ", + "delay": "ਉਪਸਿਰਲੇਖ ਦੇਰੀ", + "fixCapitals": "ਪੂੰਜੀਕਰਣ ਨੂੰ ਠੀਕ ਕਰੋ" + }, + "title": "ਉਪਸਿਰਲੇਖ", + "unknownLanguage": "ਅਗਿਆਤ" + } + }, + "metadata": { + "api": { + "text": "API ਮੈਟਾਡੇਟਾ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਦੀ ਜਾਂਚ ਕਰੋ।", + "title": "API ਮੈਟਾਡੇਟਾ ਲੋਡ ਕਰਨ ਵਿੱਚ ਅਸਫਲ" + }, + "dmca": { + "badge": "ਹਟਾਇਆ ਗਿਆ", + "text": "ਬਰਖਾਸਤਗੀ ਨੋਟਿਸ ਜਾਂ ਕਾਪੀਰਾਈਟ ਦਾਅਵੇ ਕਾਰਨ ਇਹ ਮੀਡੀਆ ਹੁਣ ਉਪਲਬਧ ਨਹੀਂ ਹੈ.", + "title": "ਮੀਡੀਆ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ" + }, + "extensionPermission": { + "badge": "ਇਜਾਜ਼ਤ ਗੁੰਮ ਹੈ", + "button": "ਐਕਸਟੈਂਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰੋ", + "text": "ਤੁਹਾਡੇ ਕੋਲ ਬ੍ਰਾਊਜ਼ਰ ਐਕਸਟੈਂਸ਼ਨ ਹੈ, ਪਰ ਸਾਨੂੰ ਐਕਸਟੈਂਸ਼ਨ ਦੀ ਵਰਤੋਂ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਤੁਹਾਡੀ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ.", + "title": "ਐਕਸਟੈਂਸ਼ਨ ਨੂੰ ਕੌਂਫਿਗਰ ਕਰੋ" + }, + "failed": { + "badge": "ਅਸਫਲ ਰਿਹਾ", + "homeButton": "ਘਰ ਜਾਓ", + "text": "TMDB ਤੋਂ ਮੀਡੀਆ ਦਾ ਮੈਟਾਡੇਟਾ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ. ਕਿਰਪਾ ਕਰਕੇ ਜਾਂਚ ਕਰੋ ਕਿ ਕੀ ਤੁਹਾਡੇ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ 'ਤੇ TMDB ਬੰਦ ਹੈ ਜਾਂ ਬਲੌਕ ਹੈ.", + "title": "ਮੈਟਾਡੇਟਾ ਲੋਡ ਕਰਨ ਵਿੱਚ ਅਸਫਲ" + }, + "notFound": { + "badge": "ਨਹੀਂ ਲਭਿਆ", + "homeButton": "ਘਰ ਵਾਪਸ", + "text": "ਅਸੀਂ ਤੁਹਾਡੇ ਦੁਆਰਾ ਬੇਨਤੀ ਕੀਤੀ ਮੀਡੀਆ ਨੂੰ ਨਹੀਂ ਲੱਭ ਸਕੇ. ਜਾਂ ਤਾਂ ਇਸਨੂੰ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ ਜਾਂ ਤੁਸੀਂ URL ਨਾਲ ਛੇੜਛਾੜ ਕੀਤੀ ਹੈ.", + "title": "ਉਹ ਮੀਡੀਆ ਨਹੀਂ ਲੱਭ ਸਕਿਆ।" + } + }, + "nextEpisode": { + "cancel": "ਰੱਦ ਕਰੋ", + "next": "ਅਗਲਾ ਐਪੀਸੋਡ" + }, + "playbackError": { + "badge": "ਪਲੇਬੈਕ ਗੜਬੜ", + "errors": { + "errorAborted": "ਉਪਭੋਗਤਾ ਦੀ ਬੇਨਤੀ 'ਤੇ ਮੀਡੀਆ ਦੀ ਪ੍ਰਾਪਤੀ ਨੂੰ ਰੋਕ ਦਿੱਤਾ ਗਿਆ ਸੀ.", + "errorDecode": "ਪਹਿਲਾਂ ਵਰਤੋਂਯੋਗ ਹੋਣ ਦਾ ਨਿਸ਼ਚਤ ਹੋਣ ਦੇ ਬਾਵਜੂਦ, ਮੀਡੀਆ ਸਰੋਤ ਨੂੰ ਡੀਕੋਡ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਸਮੇਂ ਇੱਕ ਤਰੁੱਟੀ ਆਈ, ਨਤੀਜੇ ਵਜੋਂ ਇੱਕ ਤਰੁੱਟੀ ਹੋਈ.", + "errorGenericMedia": "ਅਗਿਆਤ ਮੀਡੀਆ ਗਲਤੀ ਆਈ ਹੈ।", + "errorNetwork": "ਕੁਝ ਕਿਸਮ ਦੀ ਨੈੱਟਵਰਕ ਤਰੁੱਟੀ ਆਈ ਹੈ ਜੋ ਪਹਿਲਾਂ ਉਪਲਬਧ ਹੋਣ ਦੇ ਬਾਵਜੂਦ ਮੀਡੀਆ ਨੂੰ ਸਫਲਤਾਪੂਰਵਕ ਪ੍ਰਾਪਤ ਹੋਣ ਤੋਂ ਰੋਕਦੀ ਹੈ.", + "errorNotSupported": "ਮੀਡੀਆ ਜਾਂ ਮੀਡੀਆ ਪ੍ਰਦਾਤਾ ਵਸਤੂ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ." + }, + "homeButton": "ਘਰ ਜਾਓ", + "text": "ਮੀਡੀਆ ਨੂੰ ਚਲਾਉਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਹੋਏ ਇੱਕ ਤਰੁੱਟੀ ਉਤਪੰਨ ਹੋਈ। ਮੁੜ ਕੋਸ਼ਿਸ ਕਰੋ ਜੀ.", + "title": "ਵੀਡੀਓ ਚਲਾਉਣਾ ਅਸਫਲ ਰਿਹਾ!" + }, + "scraping": { + "items": { + "failure": "ਗੜਬੜ ਹੋ ਗਈ", + "notFound": "ਕੋਲ ਵੀਡੀਓ ਨਹੀਂ ਹੈ", + "pending": "ਵੀਡੀਓਜ਼ ਲਈ ਜਾਂਚ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..." + }, + "notFound": { + "badge": "ਨਹੀਂ ਲਭਿਆ", + "detailsButton": "ਵੇਰਵਾ ਦਿਖਾਓ", + "homeButton": "ਘਰ ਜਾਓ", + "text": "ਅਸੀਂ ਆਪਣੇ ਪ੍ਰਦਾਤਾਵਾਂ ਦੁਆਰਾ ਖੋਜ ਕੀਤੀ ਹੈ ਅਤੇ ਉਹ ਮੀਡੀਆ ਨਹੀਂ ਲੱਭ ਸਕਦੇ ਜੋ ਤੁਸੀਂ ਲੱਭ ਰਹੇ ਹੋ! ਅਸੀਂ ਮੀਡੀਆ ਦੀ ਮੇਜ਼ਬਾਨੀ ਨਹੀਂ ਕਰਦੇ ਹਾਂ ਅਤੇ ਜੋ ਉਪਲਬਧ ਹੈ ਉਸ 'ਤੇ ਸਾਡਾ ਕੋਈ ਕੰਟਰੋਲ ਨਹੀਂ ਹੈ. ਕਿਰਪਾ ਕਰਕੇ ਹੋਰ ਵੇਰਵਿਆਂ ਲਈ ਹੇਠਾਂ 'ਵੇਰਵੇ ਦਿਖਾਓ' 'ਤੇ ਕਲਿੱਕ ਕਰੋ.", + "title": "ਅਸੀਂ ਇਹ ਨਹੀਂ ਲੱਭ ਸਕੇ" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} ਬਾਕੀ • {{timeFinished, datetime}} ਵਜੇ ਸਮਾਪਤ ਕਰੋ", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "ਕਿਰਪਾ ਕਰਕੇ ਸੱਜੇ ਪਾਸੇ ਕੈਪਚਾ ਨੂੰ ਪੂਰਾ ਕਰਕੇ ਪੁਸ਼ਟੀ ਕਰੋ ਕਿ ਤੁਸੀਂ ਮਨੁੱਖ ਹੋ. ਇਹ ਮੂਵੀ-ਵੈੱਬ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਣ ਲਈ ਹੈ!", + "error": "ਤੁਹਾਡੀ ਮਨੁੱਖਤਾ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਵਿੱਚ ਅਸਫਲ। ਮੁੜ ਕੋਸ਼ਿਸ ਕਰੋ ਜੀ.", + "title": "ਸਾਨੂੰ ਇਹ ਪੁਸ਼ਟੀ ਕਰਨ ਦੀ ਲੋੜ ਹੈ ਕਿ ਤੁਸੀਂ ਇਨਸਾਨ ਹੋ.", + "verifyingHumanity": "ਤੁਹਾਡੀ ਮਨੁੱਖਤਾ ਦੀ ਪੁਸ਼ਟੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..." + } + }, + "screens": { + "dmca": { + "text": "ਮੂਵੀ-ਵੈੱਬ ਦੇ DMCA ਸੰਪਰਕ ਪੰਨੇ 'ਤੇ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ! ਅਸੀਂ ਬੌਧਿਕ ਸੰਪਤੀ ਅਧਿਕਾਰਾਂ ਦਾ ਸਨਮਾਨ ਕਰਦੇ ਹਾਂ ਅਤੇ ਕਿਸੇ ਵੀ ਕਾਪੀਰਾਈਟ ਸੰਬੰਧੀ ਚਿੰਤਾਵਾਂ ਨੂੰ ਤੇਜ਼ੀ ਨਾਲ ਹੱਲ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹਾਂ। ਜੇਕਰ ਤੁਹਾਨੂੰ ਲੱਗਦਾ ਹੈ ਕਿ ਸਾਡੇ ਪਲੇਟਫਾਰਮ 'ਤੇ ਤੁਹਾਡੇ ਕਾਪੀਰਾਈਟ ਕੀਤੇ ਕੰਮ ਦੀ ਗਲਤ ਵਰਤੋਂ ਕੀਤੀ ਗਈ ਹੈ, ਤਾਂ ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਦਿੱਤੀ ਈਮੇਲ 'ਤੇ ਇੱਕ ਵਿਸਤ੍ਰਿਤ DMCA ਨੋਟਿਸ ਭੇਜੋ. ਕਿਰਪਾ ਕਰਕੇ ਕਾਪੀਰਾਈਟ ਸਮੱਗਰੀ ਦਾ ਵੇਰਵਾ, ਤੁਹਾਡੇ ਸੰਪਰਕ ਵੇਰਵਿਆਂ, ਅਤੇ ਨੇਕ ਵਿਸ਼ਵਾਸ ਦਾ ਬਿਆਨ ਸ਼ਾਮਲ ਕਰੋ. ਅਸੀਂ ਇਹਨਾਂ ਮਾਮਲਿਆਂ ਨੂੰ ਤੁਰੰਤ ਹੱਲ ਕਰਨ ਲਈ ਵਚਨਬੱਧ ਹਾਂ ਅਤੇ ਮੂਵੀ-ਵੈੱਬ ਨੂੰ ਇੱਕ ਅਜਿਹੀ ਥਾਂ ਰੱਖਣ ਵਿੱਚ ਤੁਹਾਡੇ ਸਹਿਯੋਗ ਦੀ ਸ਼ਲਾਘਾ ਕਰਦੇ ਹਾਂ ਜੋ ਰਚਨਾਤਮਕਤਾ ਅਤੇ ਕਾਪੀਰਾਈਟ ਦਾ ਸਨਮਾਨ ਕਰਦਾ ਹੈ.", + "title": "DMCA" + }, + "loadingApp": "ਐਪਲੀਕੇਸ਼ਨ ਲੋਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ", + "loadingUser": "ਤੁਹਾਡਾ ਪ੍ਰੋਫਾਈਲ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ", + "loadingUserError": { + "logout": "ਲਾੱਗ ਆਊਟ", + "reset": "ਕਸਟਮ ਸਰਵਰ ਰੀਸੈਟ ਕਰੋ", + "text": "ਤੁਹਾਡੀ ਪ੍ਰੋਫਾਈਲ ਲੋਡ ਕਰਨ ਵਿੱਚ ਅਸਫਲ", + "textWithReset": "ਤੁਹਾਡੇ ਕਸਟਮ ਸਰਵਰ ਤੋਂ ਤੁਹਾਡੀ ਪ੍ਰੋਫਾਈਲ ਲੋਡ ਕਰਨ ਵਿੱਚ ਅਸਫਲ, ਡਿਫੌਲਟ ਸਰਵਰ ਤੇ ਵਾਪਸ ਰੀਸੈਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?" + }, + "migration": { + "failed": "ਤੁਹਾਡੇ ਡੇਟਾ ਨੂੰ ਮਾਈਗਰੇਟ ਕਰਨ ਵਿੱਚ ਅਸਫਲ.", + "inProgress": "ਕਿਰਪਾ ਕਰਕੇ ਹੋਲਡ ਕਰੋ, ਅਸੀਂ ਤੁਹਾਡੇ ਡੇਟਾ ਨੂੰ ਮਾਈਗਰੇਟ ਕਰ ਰਹੇ ਹਾਂ। ਇਸ ਵਿੱਚ ਜ਼ਿਆਦਾ ਸਮਾਂ ਨਹੀਂ ਲੱਗਣਾ ਚਾਹੀਦਾ." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "ਡਿਵਾਈਸ ਦਾ ਨਾਮ", + "deviceNamePlaceholder": "ਨਿੱਜੀ ਫ਼ੋਨ", + "editProfile": "ਸੰਪਾਦਿਤ ਕਰੋ", + "logoutButton": "ਲਾੱਗ ਆਊਟ" + }, + "actions": { + "delete": { + "button": "ਖਾਤਾ ਮਿਟਾਓ", + "confirmButton": "ਖਾਤਾ ਮਿਟਾਓ", + "confirmDescription": "ਕੀ ਤੁਸੀਂ ਯਕੀਨੀ ਤੌਰ 'ਤੇ ਆਪਣਾ ਖਾਤਾ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਸਾਰਾ ਡਾਟਾ ਖਤਮ ਹੋ ਜਾਵੇਗਾ!", + "confirmTitle": "ਤੁਹਾਨੂੰ ਪੂਰਾ ਵਿਸ਼ਵਾਸ ਹੈ?", + "text": "ਇਹ ਕਿਰਿਆ ਵਾਪਸੀਯੋਗ ਨਹੀਂ ਹੈ. ਸਾਰਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ ਅਤੇ ਕੁਝ ਵੀ ਰਿਕਵਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ.", + "title": "ਖਾਤਾ ਮਿਟਾਓ" + }, + "title": "ਕਾਰਵਾਈਆਂ" + }, + "devices": { + "deviceNameLabel": "ਡਿਵਾਈਸ ਦਾ ਨਾਮ", + "failed": "ਸੈਸ਼ਨਾਂ ਨੂੰ ਲੋਡ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ", + "removeDevice": "ਹਟਾਓ", + "title": "ਡਿਵਾਈਸਾਂ" + }, + "profile": { + "finish": "ਸੰਪਾਦਨ ਪੂਰਾ ਕਰੋ", + "firstColor": "ਪ੍ਰੋਫਾਈਲ ਰੰਗ ਇੱਕ", + "secondColor": "ਪ੍ਰੋਫਾਈਲ ਰੰਗ ਦੋ", + "title": "ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਦਾ ਸੰਪਾਦਨ ਕਰੋ", + "userIcon": "ਉਪਭੋਗਤਾ ਪ੍ਰਤੀਕ" + }, + "register": { + "cta": "ਸ਼ੁਰੂ ਕਰੋ", + "text": "ਡਿਵਾਈਸਾਂ ਵਿਚਕਾਰ ਆਪਣੀ ਘੜੀ ਦੀ ਪ੍ਰਗਤੀ ਨੂੰ ਸਾਂਝਾ ਕਰੋ ਅਤੇ ਉਹਨਾਂ ਨੂੰ ਸਿੰਕ ਰੱਖੋ.", + "title": "ਕਲਾਉਡ ਨਾਲ ਸਿੰਕ ਕਰੋ" + }, + "title": "ਖਾਤਾ" + }, + "appearance": { + "activeTheme": "ਕਿਰਿਆਸ਼ੀਲ", + "themes": { + "blue": "ਨੀਲਾ", + "default": "ਡਿਫਾਲਟ", + "gray": "ਸਲੇਟੀ", + "red": "ਲਾਲ", + "teal": "ਟੀਲ" + }, + "title": "ਰੂਪ" + }, + "connections": { + "server": { + "description": "ਜੇਕਰ ਤੁਸੀਂ ਆਪਣਾ ਡੇਟਾ ਸਟੋਰ ਕਰਨ ਲਈ ਇੱਕ ਕਸਟਮ ਬੈਕਐਂਡ ਨਾਲ ਜੁੜਨਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਇਸਨੂੰ ਸਮਰੱਥ ਕਰੋ ਅਤੇ URL ਪ੍ਰਦਾਨ ਕਰੋ। <0>ਹਿਦਾਇਤਾਂ.", + "label": "ਕਸਟਮ ਸਰਵਰ", + "urlLabel": "ਕਸਟਮ ਸਰਵਰ URL" + }, + "setup": { + "doSetup": "ਸੈੱਟਅੱਪ ਕਰੋ", + "errorStatus": { + "description": "ਅਜਿਹਾ ਲਗਦਾ ਹੈ ਕਿ ਇਸ ਸੈੱਟਅੱਪ ਵਿੱਚ ਇੱਕ ਜਾਂ ਵੱਧ ਆਈਟਮਾਂ ਤੁਹਾਡੇ ਧਿਆਨ ਦੀ ਲੋੜ ਹੈ.", + "title": "ਕੁਝ ਤੁਹਾਡੇ ਧਿਆਨ ਦੀ ਲੋੜ ਹੈ" + }, + "itemError": "ਇਸ ਸੈਟਿੰਗ ਵਿੱਚ ਕੁਝ ਗੜਬੜ ਹੈ. ਇਸਨੂੰ ਠੀਕ ਕਰਨ ਲਈ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ 'ਤੇ ਜਾਓ.", + "items": { + "default": "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈੱਟਅੱਪ", + "extension": "ਐਕਸਟੈਂਸ਼ਨ", + "proxy": "ਕਸਟਮ ਪ੍ਰੌਕਸੀ" + }, + "redoSetup": "ਸੈੱਟਅੱਪ ਮੁੜ ਕਰੋ", + "successStatus": { + "description": "ਤੁਹਾਡੇ ਮਨਪਸੰਦ ਮੀਡੀਆ ਨੂੰ ਦੇਖਣਾ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਲਈ ਸਾਰੀਆਂ ਚੀਜ਼ਾਂ ਮੌਜੂਦ ਹਨ.", + "title": "ਸਭ ਕੁਝ ਸਥਾਪਤ ਹੈ!" + }, + "unsetStatus": { + "description": "ਕਿਰਪਾ ਕਰਕੇ ਸੈਟਅਪ ਪ੍ਰਕਿਰਿਆ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਸੱਜੇ ਪਾਸੇ ਦੇ ਬਟਨ 'ਤੇ ਕਲਿੱਕ ਕਰੋ.", + "title": "ਤੁਸੀਂ ਸੈੱਟਅੱਪ ਵਿੱਚੋਂ ਨਹੀਂ ਲੰਘੇ" + } + }, + "title": "ਕਨੈਕਸ਼ਨ", + "workers": { + "addButton": "ਨਵਾਂ ਵਰਕਰ ਸ਼ਾਮਲ ਕਰੋ", + "description": "ਐਪਲੀਕੇਸ਼ਨ ਫੰਕਸ਼ਨ ਬਣਾਉਣ ਲਈ, ਸਾਰੇ ਟ੍ਰੈਫਿਕ ਨੂੰ ਪ੍ਰੌਕਸੀਆਂ ਦੁਆਰਾ ਰੂਟ ਕੀਤਾ ਜਾਂਦਾ ਹੈ. ਜੇਕਰ ਤੁਸੀਂ ਆਪਣੇ ਖੁਦ ਦੇ ਵਰਕਰਾਂ ਨੂੰ ਲਿਆਉਣਾ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ ਇਸਨੂੰ ਚਾਲੂ ਕਰੋ. <0>ਹਿਦਾਇਤਾਂ।", + "emptyState": "ਅਜੇ ਕੋਈ ਕਰਮਚਾਰੀ ਨਹੀਂ, ਹੇਠਾਂ ਇੱਕ ਸ਼ਾਮਲ ਕਰੋ", + "label": "ਕਸਟਮ ਪ੍ਰੌਕਸੀ ਵਰਕਰਾਂ ਦੀ ਵਰਤੋਂ ਕਰੋ", + "urlLabel": "ਵਰਕਰ URLs", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "ਐਪਲੀਕੇਸ਼ਨ ਭਾਸ਼ਾ", + "languageDescription": "ਪੂਰੀ ਐਪਲੀਕੇਸ਼ਨ 'ਤੇ ਭਾਸ਼ਾ ਲਾਗੂ ਕੀਤੀ ਗਈ।", + "thumbnail": "ਥੰਬਨੇਲ ਬਣਾਓ", + "thumbnailDescription": "ਬਹੁਤੀ ਵਾਰ, ਵੀਡੀਓਜ਼ ਵਿੱਚ ਥੰਬਨੇਲ ਨਹੀਂ ਹੁੰਦੇ ਹਨ. ਤੁਸੀਂ ਇਸ ਸੈਟਿੰਗ ਨੂੰ ਫਲਾਈ 'ਤੇ ਤਿਆਰ ਕਰਨ ਲਈ ਸਮਰੱਥ ਕਰ ਸਕਦੇ ਹੋ ਪਰ ਉਹ ਤੁਹਾਡੇ ਵੀਡੀਓ ਨੂੰ ਹੌਲੀ ਕਰ ਸਕਦੇ ਹਨ.", + "thumbnailLabel": "ਥੰਬਨੇਲ ਬਣਾਓ", + "title": "ਤਰਜੀਹਾਂ" + }, + "reset": "ਆਰਾਮ", + "save": "ਸੇਵ", + "sidebar": { + "info": { + "appVersion": "ਐਪ ਸੰਸਕਰਣ", + "backendUrl": "ਬੈਕਐਂਡ URL", + "backendVersion": "ਬੈਕਐਂਡ ਸੰਸਕਰਣ", + "hostname": "ਹੋਸਟਨਾਮ", + "insecure": "ਅਸੁਰੱਖਿਅਤ", + "notLoggedIn": "ਤੁਸੀਂ ਲੌਗਇਨ ਨਹੀਂ ਹੋ", + "secure": "ਸੁਰੱਖਿਅਤ", + "title": "ਐਪ ਜਾਣਕਾਰੀ", + "unknownVersion": "ਅਗਿਆਤ", + "userId": "ਯੂਜਰ ਆਈਡੀ" + } + }, + "subtitles": { + "backgroundLabel": "ਬੈਕਗ੍ਰਾਊਂਡ ਧੁੰਦਲਾਪਨ", + "colorLabel": "ਰੰਗ", + "previewQuote": "ਮੈਨੂੰ ਡਰਨਾ ਨਹੀਂ ਚਾਹੀਦਾ. ਡਰ ਮਨ ਨੂੰ ਮਾਰਨ ਵਾਲਾ ਹੈ.", + "textSizeLabel": "ਟੈਕਸਟ ਦਾ ਆਕਾਰ", + "title": "ਉਪਸਿਰਲੇਖ" + }, + "unsaved": "ਤੁਹਾਡੇ ਕੋਲ ਅਣਰੱਖਿਅਤ ਤਬਦੀਲੀਆਂ ਹਨ" + } +} diff --git a/src/assets/locales/pirate.json b/src/assets/locales/pirate.json new file mode 100644 index 0000000..105110e --- /dev/null +++ b/src/assets/locales/pirate.json @@ -0,0 +1,537 @@ +{ + "about": { + "description": "Ahoy there! \"SkoolTV\" be a fine vessel on the digital seas, a web application scourin' the vast internet for streams. The crew be settin' their sights on a mostly minimalistic approach to enjoyin' the booty of entertainment. Arrr!", + "faqTitle": "Common queries", + "q1": { + "body": "Arrr! \"SkoolTV\" be a noble ship that don't harbor any content itself. When ye click to set yer eyes on a treasure, the application sets sail across the internet, scourin' the vast seas for the chosen media. Check the loading screen and the 'video sources' tab to spy on which source be providin' the entertainment. No media be uploaded by \"SkoolTV\" — it be all through this searchin' mechanism, savvy?", + "title": "From which cove does the content emerge, me heartie?" + }, + "q2": { + "body": "Avast, ye landlubber! Be warned, ye can't be requestin' a show or movie on \"SkoolTV,\" for it don't manage any content. All the booty ye set yer eyes on be viewed through sources sailin' the internet. The ship merely be a vessel, not a keeper of the treasures. Navigate wisely, me heartie!", + "title": "Where be I able to make a hearty request for a show or movie?" + }, + "q3": { + "body": "Arrr, set yer sights on this, me matey! Our search results be fueled by The Movie Database (TMDB), showin' the way regardless of whether our sources in the vast digital seas actually bear the coveted content. It be a guide, not a promise of a sure find. Navigate the waters wisely, for the winds of the internet can be fickle!", + "title": "Why be the search results unveilin' the show or movie, yet I can't set sail to watch it?" + }, + "title": "The tales of \"SkoolTV\"" + }, + "actions": { + "copied": "Copied", + "copy": "Copy" + }, + "auth": { + "createAccount": "Don't have a ship yet? <0>Hoist the sails and make yer own", + "deviceNameLabel": "Ship name", + "deviceNamePlaceholder": "Muad'Dib's Pirate Ship", + "generate": { + "description": "If ye lose this, ye be a silly goose and will be posted on the wall of shame™️", + "next": "Ahoy! I've stashed me secret code away for safe keepin'.", + "passphraseFrameLabel": "Secret Code", + "title": "Yer Passphrase" + }, + "hasAccount": "Arrr! Ye already got a ship on the seas? <0>Board here, me heartie!", + "login": { + "description": "Arr, ye be askin' for the key to me top-secret lair, also known as The Fortress of Wordsmithery, accessed only by recitin' the sacred incantation of the 12-word passphrase!", + "deviceLengthError": "Bestow a name upon yer contraption, me heartie!", + "passphraseLabel": "12-Word Passphrase", + "passphrasePlaceholder": "Passphrase", + "submit": "Hoist Anchor", + "title": "Hoist the Jolly Roger", + "validationError": "Arr, incorrect or incomplete passphrase" + }, + "register": { + "information": { + "color1": "First Mate color", + "color2": "Second Mate color", + "header": "Enter a moniker for yer ship and choose a pirate icon and colors, arrr!", + "icon": "Pirate icon", + "next": "Forward", + "title": "Pirate Account information" + } + }, + "trust": { + "failed": { + "text": "Did ye configure it correctly?", + "title": "Failed to reach the backend" + }, + "host": "Do ye trust <0>{{hostname}}?", + "no": "Abandon Ship", + "title": "Do ye trust this ship?", + "yes": "Trust" + }, + "verify": { + "description": "If ye already lost it, how will ye ever be able to take care of a wee buccaneer?", + "invalidData": "Data be not valid", + "noMatch": "Passphrase doesn't match", + "passphraseLabel": "Yer passphrase", + "recaptchaFailed": "ReCaptcha validation failed", + "register": "Forge yer account, matey!", + "title": "Enter yer passphrase" + } + }, + "errors": { + "badge": "Shiver me timbers", + "details": "Ahoy! What be the secrets of the glitch?", + "reloadPage": "Reload the page", + "showError": "Reveal the details of the error, me matey", + "title": "That be an error, Captain" + }, + "footer": { + "legal": { + "disclaimer": "Disclaimer", + "disclaimerText": "SkoolTV does not host any files, it merely links to 3rd party services. Legal issues should be taken up with the file hosts and providers. SkoolTV be not responsible for any media files shown by the video providers." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Watch yer favorite shows and movies with this open source streaming ship." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "About", + "dmca": "DMCA", + "login": "Login", + "onboarding": "Setup", + "pagetitle": "{{title}} - SkoolTV", + "register": "Forge yer account, matey!", + "settings": "Settings" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Bookmarks" + }, + "continueWatching": { + "sectionTitle": "Continue Watchin'" + }, + "mediaList": { + "stopEditing": "Stop editin'" + }, + "search": { + "allResults": "That's all we have, me heartie!", + "failed": "Arrrr failed to find media, try again!", + "loading": "Hold yer horses, me heartie!", + "noResults": "We couldn't find anythin', arrr!", + "placeholder": { + "default": "What do ye want to watch?" + }, + "sectionTitle": "Searchin' results" + }, + "titles": { + "day": { + "default": "What be yer fancy for this fine afternoon's viewing, me heartie?", + "extra": [ + "Feelin' adventurous? Pirates of the Caribbean might be the perfect choice." + ] + }, + "morning": { + "default": "What be yer fancy for this mornin's viewing, me heartie?", + "extra": [ + "I be hearin' that 'Before Sunrise' be a fine choice, me heartie" + ] + }, + "night": { + "default": "What be yer desire for the night's entertainment, me heartie?", + "extra": [ + "Feelin' weary, are ye? I be hearin' 'The Exorcist' be a good pick to stir the spirits, me heartie." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Show" + } + }, + "navigation": { + "banner": { + "offline": "Check yer internet connection" + }, + "menu": { + "about": "About us", + "logout": "Abandon ship", + "register": "Sync to the sudo-cloud", + "settings": "Settings", + "support": "Support" + } + }, + "notFound": { + "badge": "Not found", + "goHome": "Back to home port", + "message": "We looked everywhere: under the bins, in the closet, behind the proxy but ultimately couldn't find the treasure map ye be lookin' for.", + "title": "Couldn't find that treasure map" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Cancel", + "confirm": "Use default setup", + "description": "The default setup does nah 'ave the best streams 'n can be unbearably slow.", + "title": "Are ye sure?" + }, + "extension": { + "back": "Go back", + "explainer": "Usin' the browser extension, ye can get the best streams we 'ave t' offer. Wit' jus' a simple install.", + "explainerIos": "Unfortunately, the browser extension ain't supported on iOS, Press Go back t' choose another option.", + "extensionHelp": "If ye've installed the extension but 'tisn't detected, open the extension through yer browsers extension menu 'n follow the steps on screen.", + "linkChrome": "Install Chrome extension", + "linkFirefox": "Install Firefox extension", + "notDetecting": "Installed on Chrome, but the site ain't detecting it? Give the page a good reload!", + "notDetectingAction": "Reload page", + "status": { + "disallowed": "Extension ain't enabled fer this page", + "disallowedAction": "Enable extension", + "failed": "Failed t' request status", + "loading": "Waitin' fer ye t' install the extension", + "outdated": "Extension version too ole", + "success": "Extension be workin' as expected!" + }, + "submit": "Continue", + "title": "Let's start wit' an extension" + }, + "proxy": { + "back": "Go back", + "explainer": "Wit' the proxy method, ye can get great quality streams by makin' a self-service proxy.", + "input": { + "errorConnection": "Couldn't connect t' proxy", + "errorInvalidUrl": "Ain't a valid URL", + "errorNotProxy": "Expected a proxy but got a website", + "label": "Proxy URL", + "placeholder": "https://" + }, + "link": "Learn how t' make a proxy", + "submit": "Submit proxy", + "title": "Let's make a new proxy" + }, + "start": { + "explainer": "T' get the best streams possible, ye will needs t' choose which streamin' method ye wants t' use.", + "options": { + "default": { + "text": "I don't wants good quality streams,<0 /> <1>use the default setup" + }, + "extension": { + "action": "Install extension", + "description": "Install browser extension 'n gain access t' the best sources.", + "quality": "Best quality", + "title": "Browser extension" + }, + "proxy": { + "action": "Setup proxy", + "description": "Setup a proxy in jus' 5 minutes 'n gain access t' great sources.", + "quality": "Good quality", + "title": "Custom proxy" + } + }, + "title": "Let's get ye setup wit' SkoolTV" + } + }, + "overlays": { + "close": "Close" + }, + "player": { + "back": { + "default": "Back to home port", + "short": "Back" + }, + "casting": { + "enabled": "Casting to the contraption, setting sail..." + }, + "menus": { + "downloads": { + "disclaimer": "Downloads be taken directly from the provider. SkoolTV does not have control over how the downloads be provided.", + "downloadSubtitle": "Download current subtitle", + "downloadVideo": "Download film", + "hlsDisclaimer": "Loot are taken directly from the provider. SkoolTV does nah 'ave control o'er how the loot are provided.

Please note that ye be downloadin' an HLS playlist, 'tisn't recommended t' download if ye be nah familiar wit' advanced streamin' formats. Try different sources fer different formats.", + "onAndroid": { + "1": "To download on Android, tap and hold on the film, then select save.", + "shortTitle": "Download / Android", + "title": "Downloadin' on Android" + }, + "onIos": { + "1": "To download on iOS, click , then Save to Files . All that's left to do now be to pick a nice and cozy chest for yer film!", + "shortTitle": "Download / iOS", + "title": "Downloadin' on iOS" + }, + "onPc": { + "1": "On PC, right click the film and select Save film as", + "shortTitle": "Download / PC", + "title": "Downloadin' on PC" + }, + "title": "Buried Treasure" + }, + "episodes": { + "button": "Episodes", + "emptyState": "There be no episodes in this season, check back later!", + "episodeBadge": "E{{episode}}", + "loadingError": "Error loadin' season", + "loadingList": "Loading...", + "loadingTitle": "Loading...", + "unairedEpisodes": "One or more episodes in this season 'ave been disabled 'cause they haven't been shipped yet." + }, + "playback": { + "speedLabel": "Playback speed", + "title": "Playback settings" + }, + "quality": { + "automaticLabel": "Automatic quality", + "hint": "Ye can try <0>switchin' source to get different quality options.", + "iosNoQuality": "Due to Apple-defined limitations, quality selection be not available on iOS for this source. Ye can try <0>switchin' to another source to get different quality options.", + "title": "Quality" + }, + "settings": { + "downloadItem": "Buried Treasure", + "enableSubtitles": "Unfurl the subtitles", + "experienceSection": "Viewing Experience", + "playbackItem": "Playback settings", + "qualityItem": "Quality", + "sourceItem": "Video sources", + "subtitleItem": "Set yer subtitle course", + "videoSection": "Video settings" + }, + "sources": { + "failed": { + "text": "We were unable to find any videos for this source. Don't come bitchin' to us about it, just try another source.", + "title": "Failed to scrape" + }, + "noEmbeds": { + "text": "We were unable to find any embeds for this source, please try another.", + "title": "No embeds found" + }, + "noStream": { + "text": "This source has no streams for this film or show.", + "title": "No stream" + }, + "title": "Sources", + "unknownOption": "Unknown" + }, + "subtitles": { + "customChoice": "Select subtitle from file", + "customizeLabel": "Tailor it to yer liking", + "offChoice": "Off", + "settings": { + "backlink": "Custom subtitles", + "delay": "Subtitle delay", + "fixCapitals": "Mend the capital letters" + }, + "title": "Subtitles", + "unknownLanguage": "Unknown" + } + }, + "metadata": { + "api": { + "text": "Could nah load API metadata, please check yer internet connection.", + "title": "Failed t' load API metadata" + }, + "dmca": { + "badge": "Removed", + "text": "This media be no longer available due t' a takedown notice or copyright claim.", + "title": "Media has been scuttled" + }, + "extensionPermission": { + "badge": "Permission Missin'", + "button": "Use extension", + "text": "Ye 'ave the browser extension, but we needs yer permission t' get started usin' the extension.", + "title": "Configure the extension" + }, + "failed": { + "badge": "Failed", + "homeButton": "Go home port", + "text": "Oh, me apologies, sweetie! The itty-bitty SkoolTV did its utmost bestest, but alas, no wucky videos to be spotted anywhere (´⊙ω⊙`) Please don't be angwy, wittle SkoolTV ish twying so hard. Can ye find it in yer heart to forgive? UwU 💖", + "title": "Failed to load meta data" + }, + "notFound": { + "badge": "Not found", + "homeButton": "Back to home port", + "text": "We couldn't find the media ye requested. Either it's been removed or ye tampered with the URL.", + "title": "Couldn't find that media." + } + }, + "nextEpisode": { + "cancel": "Cancel", + "next": "Next episode" + }, + "playbackError": { + "badge": "Not found", + "errors": { + "errorAborted": "The fetchin' of the associated resource was aborted by the user's request.", + "errorDecode": "Despite havin' previously been determined to be usable, an error occurred while tryin' to decode the media resource, resultin' in an error.", + "errorGenericMedia": "Unknown media error occurred", + "errorNetwork": "Some kind of network error occurred which prevented the media from bein' successfully fetched, despite havin' previously been available.", + "errorNotSupported": "The associated resource or media provider object has been found to be unsuitable." + }, + "homeButton": "Go home port", + "text": "Oh, me apologies, sweetie! The itty-bitty SkoolTV did its utmost bestest, but alas, no wucky videos to be spotted anywhere (´⊙ω⊙`) Please don't be angwy, wittle SkoolTV ish twying so hard. Can ye find it in yer heart to forgive? UwU 💖", + "title": "Whoops, it broke!" + }, + "scraping": { + "items": { + "failure": "Error occurred", + "notFound": "Doesn't have the video", + "pending": "Checkin' for videos..." + }, + "notFound": { + "badge": "Not found", + "detailsButton": "Show details", + "homeButton": "Go home port", + "text": "Oh, me apologies, sweetie! The itty-bitty SkoolTV did its utmost bestest, but alas, no wucky videos to be spotted anywhere (´⊙ω⊙`) Please don't be angwy, wittle SkoolTV ish twying so hard. Can ye find it in yer heart to forgive? UwU 💖", + "title": "Goo goo gaa gaa" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} left • Finish at {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Please verify that ye be human by completin' the Captcha on right. 'tis t' keep SkoolTV safe!", + "error": "Failed t' verify yer piracy. Please try again.", + "title": "We needs t' verify that ye're real pirate.", + "verifyingHumanity": "Verifyin' yer piracy..." + } + }, + "screens": { + "dmca": { + "text": "Ahoy t' SkoolTV's DMCA contact page! We respect intellectual property rights 'n wants t' address any copyright concerns swiftly. If ye believe yer copyrighted work has been improperly used on our platform, please send a detailed DMCA notice t' the email below. Please include a description o' the copyrighted material, yer contact details, 'n a statement o' good faith belief. We be committed t' resolvin' these matters promptly 'n appreciate yer cooperation in keepin' SkoolTV a galleon that respects creativity 'n copyrights.", + "title": "DMCA" + }, + "loadingApp": "Loadin' application", + "loadingUser": "Loadin' yer pirate profile", + "loadingUserError": { + "logout": "Logout", + "reset": "Reset custom ship", + "text": "Failed to load yer pirate profile", + "textWithReset": "Failed to load yer pirate profile from yer custom ship, want to reset back to default?" + }, + "migration": { + "failed": "Failed to migrate yer booty.", + "inProgress": "Please hold, we be migratin' yer booty. This shouldn't take long." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Ship name", + "deviceNamePlaceholder": "Fremen tablet", + "editProfile": "Edit", + "logoutButton": "Abandon ship" + }, + "actions": { + "delete": { + "button": "Abandon ship for all eternity", + "confirmButton": "Abandon ship for all eternity", + "confirmDescription": "Arrr ye sure ye want to abandon yer ship for all eternity? All yer booty will be lost!", + "confirmTitle": "Arrr ye sure?", + "text": "This action be irreversible. All booty will be deleted and nothin' can be recovered.", + "title": "Abandon ship for all eternity" + }, + "title": "Actions" + }, + "devices": { + "deviceNameLabel": "Ship name", + "failed": "Failed to load sessions", + "removeDevice": "Abandon ship", + "title": "Shipmates" + }, + "profile": { + "finish": "Finish editing", + "firstColor": "First color", + "secondColor": "Second color", + "title": "Edit Pirate Portrait", + "userIcon": "Pirate icon" + }, + "register": { + "cta": "Get started", + "text": "Instantly share yer watch progress between devices and keep 'em synced.", + "title": "Sync to the sudo-cloud" + }, + "title": "Treasure Chest" + }, + "appearance": { + "activeTheme": "Active", + "themes": { + "blue": "Blue", + "default": "Default", + "gray": "Gray", + "red": "Red", + "teal": "Teal" + }, + "title": "Appearance" + }, + "connections": { + "server": { + "description": "To make the application function, all traffic be routed through proxies. Enable this if ye want to bring yer own sailors. <0>Instructions.", + "label": "Custom ship", + "urlLabel": "Custom ship URL" + }, + "setup": { + "doSetup": "Do setup", + "errorStatus": { + "description": "It seems that one or more items in this setup needs yer attention.", + "title": "Somethin' needs yer attention" + }, + "itemError": "Thar be somethin' wrong wit' this settin'. Go through setup again t' fix it.", + "items": { + "default": "Default setup", + "extension": "Extension", + "proxy": "Custom proxy" + }, + "redoSetup": "Redo setup", + "successStatus": { + "description": "All things are in ship fer ye t' start watchin' yer favourite media.", + "title": "Everythin' be set up!" + }, + "unsetStatus": { + "description": "Please skewer the button t' starb'rd t' start the setup process.", + "title": "Ye haven't gone through setup" + } + }, + "title": "Connections", + "workers": { + "addButton": "Recruit new sailor", + "description": "To make the application function, all traffic be routed through proxies. Enable this if ye want to bring yer own sailors. <0>Instructions.", + "emptyState": "No sailors yet, add one below", + "label": "Use custom proxy sailors", + "urlLabel": "Sailor URLs", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Application language", + "languageDescription": "Language applied t' the entire application.", + "thumbnail": "Generate thumbnails", + "thumbnailDescription": "Most o' the time, videos don't 'ave thumbnails. Ye can enable this settin' t' generate 'em on the trip but they can make yer video slower.", + "thumbnailLabel": "Generate thumbnails", + "title": "Preferences" + }, + "reset": "Reset", + "save": "Save", + "sidebar": { + "info": { + "appVersion": "App version", + "backendUrl": "Backend URL", + "backendVersion": "Backend version", + "hostname": "Ship name", + "insecure": "Insecure", + "notLoggedIn": "Not logged in", + "secure": "Secure", + "title": "App information", + "unknownVersion": "Unknown", + "userId": "Pirate ID" + } + }, + "subtitles": { + "backgroundLabel": "Background opacity", + "colorLabel": "Color", + "previewQuote": "I must not fear. Fear is the mind-killer.", + "textSizeLabel": "Text size", + "title": "Subtitles" + }, + "unsaved": "Ye have unsaved changes" + } +} diff --git a/src/assets/locales/pl.json b/src/assets/locales/pl.json new file mode 100644 index 0000000..bc48fd1 --- /dev/null +++ b/src/assets/locales/pl.json @@ -0,0 +1,549 @@ +{ + "about": { + "description": "SkoolTV jest aplikacją internetową, która wyszukuje w internecie strumienia. Zespół dąży do minimalistycznego podejścia do konsumpcji treści.", + "faqTitle": "Częste pytania", + "q1": { + "body": "SkoolTV nie udostępnia żadnych treści. Kiedy klikniesz na coś co chcesz obejrzeć, internet zostanie przeszukany pod kątem wybranych multimediów (na ekranie ładowania oraz w zakładce „źródła wideo” możesz zobaczyć, z jakiego źródła korzystasz). Media nigdy nie są przesyłane przez SkoolTV, wszystko odbywa się za pośrednictwem tego mechanizmu wyszukiwania.", + "title": "Skąd pochodzą treści?" + }, + "q2": { + "body": "Nie można złożyć wniosku o serialu ani filmu, SkoolTV nie zarządza żadną treścią. Wszystkie treści są przeglądane za pośrednictwem źródeł w Internecie.", + "title": "Gdzie mogę złożyć wniosek o seriale lub filmie?" + }, + "q3": { + "body": "Nasze wyniki wyszukiwania pochodzą z TMDB i są wyświetlane niezależnie od tego, czy nasze źródła faktycznie posiadają daną treść.", + "title": "W wyniku wyszukiwania wyświetlany jest serial lub film. Dlaczego nie mogę go odtworzyć?" + }, + "title": "O SkoolTV" + }, + "actions": { + "copied": "Skopiowano", + "copy": "Kopiuj" + }, + "auth": { + "createAccount": "Nie masz jeszcze konta? <0>Utwórz konto.", + "deviceNameLabel": "Nazwa urządzenia", + "deviceNamePlaceholder": "Telefon osobisty", + "generate": { + "description": "Twoja fraza hasła działa jak nazwa użytkownika i hasło. Pamiętaj aby zachować go w bezpiecznym miejscu, ponieważ będziesz musiał go wprowadzić aby zalogować się na swoje konto", + "next": "Zapisałem frazę hasła", + "passphraseFrameLabel": "Fraza hasła", + "title": "Twoja fraza hasła" + }, + "hasAccount": "Masz już konto? <0>Zaloguj się tutaj.", + "login": { + "description": "Proszę wpisać frazę hasła, aby zalogować się na swoje konto", + "deviceLengthError": "Proszę wpisać nazwę urządzenia", + "passphraseLabel": "12-wyrazowa fraza hasła", + "passphrasePlaceholder": "Fraza hasła", + "submit": "Zaloguj się", + "title": "Zaloguj się na swoje konto", + "validationError": "Nieprawidłowe lub niedokończone fraza hasła" + }, + "register": { + "information": { + "color1": "Kolor profilu jeden", + "color2": "Kolor profilu dwa", + "header": "Wpisz nazwę swojego urządzenia i wybierz kolory oraz ikonę użytkownika", + "icon": "Ikona użytkownika", + "next": "Dalej", + "title": "Informacje o koncie" + } + }, + "trust": { + "failed": { + "text": "Skonfigurowałeś to poprawnie?", + "title": "Nie udało się połączyć z serwerem" + }, + "host": "Łączysz się z <0>{{hostname}} - przed utworzeniem konta potwierdź że ufasz temu serwerowi", + "no": "Wstecz", + "noHost": "Serwer nie został skonfigurowany, więc nie można utworzyć konta", + "noHostTitle": "Serwer nie skonfigurowany!", + "title": "Ufasz temu serwerowi?", + "yes": "Ufam temu serwerowi" + }, + "verify": { + "description": "Wprowadź swoją frazę hasła, aby potwierdzić jego zapisanie i utworzyć konto", + "invalidData": "Dane są nieprawidłowe", + "noMatch": "Fraza hasła nie pasuje", + "passphraseLabel": "Twoja 12-wyrazowa fraza hasła", + "recaptchaFailed": "Weryfikacja ReCaptcha nie powiodła się", + "register": "Utwórz konto", + "title": "Potwierdź swoją frazę hasła" + } + }, + "errors": { + "badge": "Zepsuło się", + "details": "Szczegóły błędu", + "reloadPage": "Odśwież stronę", + "showError": "Pokaż szczegóły błędu", + "title": "Napotkaliśmy błąd!" + }, + "footer": { + "legal": { + "disclaimer": "Zastrzeżenie", + "disclaimerText": "SkoolTV nie przechowuje żadnych plików, zawiera jedynie łącza do usług stron trzecich. Kwestie prawne należy konsultować z hostami plików i dostawcami. SkoolTV nie ponosi odpowiedzialności za jakiekolwiek pliki multimedialne prezentowane przez dostawców wideo." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Oglądaj swoje ulubione seriale i filmy za pomocą tej aplikacji streamingowej typu open source." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Informacje", + "dmca": "DMCA", + "login": "Zaloguj sie", + "onboarding": "Konfiguracja", + "pagetitle": "{{title}} - SkoolTV", + "register": "Zarejestruj się", + "settings": "Ustawienia" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Zakładki" + }, + "continueWatching": { + "sectionTitle": "Kontynuuj oglądanie" + }, + "mediaList": { + "stopEditing": "Przestań edytować" + }, + "search": { + "allResults": "To wszystko co mamy!", + "failed": "Nie udało się znaleźć mediów, Spróbuj ponownie!", + "loading": "Wczytywanie...", + "noResults": "Nie mogliśmy niczego znaleźć!", + "placeholder": { + "default": "Co chciałbyś obejrzeć?", + "extra": [ + "Co chcesz odkryć?", + "Co znajduje się na Twojej liście do obejrzenia?", + "Jaki jest twój ulubiony film?", + "Jaki jest twój ulubiony serial?" + ] + }, + "sectionTitle": "Wyniki wyszukiwania" + }, + "titles": { + "day": { + "default": "Co chciałbyś obejrzeć dziś po południu?", + "extra": [ + "Masz ochotę na przygodę? Park Jurajski może być idealnym wyborem." + ] + }, + "morning": { + "default": "Co chciałbyś obejrzeć dziś rano?", + "extra": [ + "Słyszałem że „Przed wschodem słońca” jest dobre" + ] + }, + "night": { + "default": "Co chciałbyś obejrzeć dziś wieczorem?", + "extra": [ + "Zmęczony? Słyszałem że „Egzorcysta” jest dobry." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Serial" + } + }, + "navigation": { + "banner": { + "offline": "Sprawdź swoje połączenie sieciowe" + }, + "menu": { + "about": "O nas", + "logout": "Wyloguj się", + "register": "Synchronizuj z chmurą", + "settings": "Ustawienia", + "support": "Wsparcie" + } + }, + "notFound": { + "badge": "Nie znaleziono", + "goHome": "Wróć na stronę główną", + "message": "Szukaliśmy wszędzie: w koszu, w szafie, a nawet w piwnicy, ale nie byliśmy w stanie znaleźć strony której szukasz.", + "title": "Nie można znaleźć tej strony" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Anuluj", + "confirm": "Użyj domyślnej konfiguracji", + "description": "Domyślna konfiguracja nie ma najlepszych strumieni i może być strasznie powolna.", + "title": "Jesteś pewien?" + }, + "extension": { + "back": "Wstecz", + "explainer": "Korzystając z rozszerzenia przeglądarki, możesz uzyskać najlepsze strumienie. Wystarczy prosta instalacja.", + "explainerIos": "Niestety, rozszerzenie przeglądarki nie jest obsługiwane w systemie iOS, naciśnij Wstecz, aby wybrać inną opcję.", + "extensionHelp": "Jeżeli zainstalowałeś rozszerzenie, ale nie zostało ono wykryte, otwórz rozszerzenie za pomocą menu rozszerzeń przeglądarki i postępuj zgodnie z instrukcjami wyświetlanymi na ekranie.", + "linkChrome": "Zainstaluj rozszerzenie na Chrome", + "linkFirefox": "Zainstaluj rozszerzenie na Firefox", + "notDetecting": "Zainstalowano w Chrome, ale strona go nie wykrywa? Spróbuj odświeżyć stronę!", + "notDetectingAction": "Odśwież stronę", + "status": { + "disallowed": "Rozszerzenie nie jest włączone dla tej strony", + "disallowedAction": "Włącz rozszerzenie", + "failed": "Nie udało się uzyskać statusu", + "loading": "Oczekiwanie na instalację rozszerzenia", + "outdated": "Za stara wersja rozszerzenia", + "success": "Rozszerzenie działa tak jak powinno!" + }, + "submit": "Kontynuuj", + "title": "Zacznijmy od rozszerzenia" + }, + "proxy": { + "back": "Wstecz", + "explainer": "Za pomocą metody proxy można uzyskać strumienie o doskonałej jakości, tworząc samoobsługowy serwer proxy.", + "input": { + "errorConnection": "Nie można połączyć się z serwerem proxy", + "errorInvalidUrl": "Nieprawidłowy adres URL", + "errorNotProxy": "Spodziewano proxy, ale otrzymano stronę internetową", + "label": "Adres URL serwera proxy", + "placeholder": "https://" + }, + "link": "Dowiedz się, jak utworzyć proxy", + "submit": "Prześlij proxy", + "title": "Stwórzmy nowe proxy" + }, + "start": { + "explainer": "Aby uzyskać najlepsze transmisje strumieniowe, będziesz musiał wybrać metodę strumieniowania której chcesz użyć.", + "options": { + "default": { + "text": "Nie chcę dobrej jakości strumieni, <0 /> <1>użyj domyślnej konfiguracji" + }, + "extension": { + "action": "Zainstaluj rozszerzenie", + "description": "Zainstaluj rozszerzenie przeglądarki i uzyskaj dostęp do najlepszych źródeł.", + "quality": "Najlepsza jakość", + "title": "Rozszerzenie przeglądarki" + }, + "proxy": { + "action": "Skonfiguruj serwer proxy", + "description": "Skonfiguruj proxy w 5 minut i uzyskaj dostęp do świetnych źródeł.", + "quality": "Dobra jakość", + "title": "Niestandardowy serwer proxy" + } + }, + "title": "Przejdźmy do konfiguracji z SkoolTV" + } + }, + "overlays": { + "close": "Zamknij" + }, + "player": { + "back": { + "default": "Wróć na stronę główną", + "short": "Wróć" + }, + "casting": { + "enabled": "Przesyłam na urządzenie..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Kopiuj link do listy odtwarzania HLS", + "disclaimer": "Pliki do pobrania są pobierane bezpośrednio od dostawcy. SkoolTV nie ma kontroli nad sposobem dostarczania plików do pobrania.", + "downloadSubtitle": "Pobierz aktualne napisy", + "downloadVideo": "Pobierz wideo", + "hlsDisclaimer": "Pliki do pobrania są pobierane bezpośrednio od dostawcy. SkoolTV nie ma kontroli nad sposobem dostarczania plików do pobrania.

Należy pamiętać, że pobierasz playlistę HLS, nie zaleca się pobierania, jeśli nie jesteś zaznajomiony z zaawansowanymi formatami przesyłania strumieniowego. Wypróbuj różne źródła dla innych formatów.", + "onAndroid": { + "1": "Aby pobrać na Androidzie, kliknij przycisk pobierania, a następnie na nowej stronie dotknij i przytrzymaj na filmie, a następnie wybierz zapisz.", + "shortTitle": "Pobierz / Android", + "title": "Pobieranie na Androidzie" + }, + "onIos": { + "1": "Aby pobrać na iOS, kliknij przycisk pobierania, a następnie na nowej stronie, kliknij , a następnie Zapisz do plików .", + "shortTitle": "Pobierz / iOS", + "title": "Pobieranie na iOS" + }, + "onPc": { + "1": "Na komputerze, kliknij przycisk pobierania, a następnie na nowej stronie, kliknij wideo prawym przyciskiem myszy i wybierz Zapisz wideo jako", + "shortTitle": "Pobierz / Komputer", + "title": "Pobieranie na komputerze" + }, + "title": "Pobierz" + }, + "episodes": { + "button": "Odcinki", + "emptyState": "Nie ma odcinków w tym sezonie, sprawdź później!", + "episodeBadge": "E{{episode}}", + "loadingError": "Błąd podczas ładowania sezonu", + "loadingList": "Wczytywanie...", + "loadingTitle": "Wczytywanie...", + "unairedEpisodes": "Jeden lub więcej odcinków tego sezonu zostało wyłączonych, ponieważ nie zostały jeszcze wyemitowane." + }, + "playback": { + "speedLabel": "Szybkość odtwarzania", + "title": "Ustawienia odtwarzania" + }, + "quality": { + "automaticLabel": "Jakość automatyczna", + "hint": "Możesz spróbować <0>przełączyć źródło aby uzyskać różne opcje jakości.", + "iosNoQuality": "Ze względu na ograniczenia zdefiniowane przez Apple, wybór jakości nie jest dostępny w systemie iOS dla tego źródła. Możesz spróbować <0>przełączyć na inne źródło aby uzyskać inne opcje jakości.", + "title": "Jakość" + }, + "settings": { + "audioItem": "Dźwięk", + "downloadItem": "Pobierz", + "enableSubtitles": "Włącz napisy", + "experienceSection": "Odtwarzanie", + "playbackItem": "Ustawienia odtwarzania", + "qualityItem": "Jakość", + "sourceItem": "Źródła wideo", + "subtitleItem": "Ustawienia napisów", + "videoSection": "Ustawienia wideo" + }, + "sources": { + "failed": { + "text": "Wystąpił błąd podczas próby znalezienia filmów. Spróbuj użyć innego źródła.", + "title": "Nie udało się zgarnąć" + }, + "noEmbeds": { + "text": "Nie znaleźliśmy żadnych osadzonych plików. Spróbuj użyć innego źródła.", + "title": "Nie znaleziono osadzonych treści" + }, + "noStream": { + "text": "To źródło nie ma strumieni dla tego filmu lub serialu.", + "title": "Brak strumienia" + }, + "title": "Źródła", + "unknownOption": "Nieznany" + }, + "subtitles": { + "customChoice": "Wrzuć lub prześlij plik", + "customizeLabel": "Dostosuj", + "dropSubtitleFile": "Przeciągnij i upuść plik z napisami tutaj", + "offChoice": "Wyłączone", + "settings": { + "backlink": "Własne napisy", + "delay": "Opóźnienie napisów", + "fixCapitals": "Popraw kapitalizację" + }, + "title": "Napisy", + "unknownLanguage": "Nieznany" + } + }, + "metadata": { + "api": { + "text": "Nie można załadować metadanych API, sprawdź połączenie internetowe.", + "title": "Nie udało się załadować metadanych API" + }, + "dmca": { + "badge": "Usunięte", + "text": "Ten materiał nie jest już dostępny z powodu żądania usunięcia lub roszczenia dotyczącego praw autorskich.", + "title": "Media zostały usunięte" + }, + "extensionPermission": { + "badge": "Brak uprawnień", + "button": "Użyj rozszerzenia", + "text": "Masz nasze rozszerzenie przeglądarki, ale potrzebujemy pozwolenia, aby zacząć z niego korzystać.", + "title": "Skonfiguruj rozszerzenie" + }, + "failed": { + "badge": "Nie powiodło się", + "homeButton": "Wróć na stronę główną", + "text": "Nie można załadować metadanych multimediów z TMDB. Sprawdź czy TMDB nie działa lub jest zablokowany na twoim połączeniu internetowym.", + "title": "Nie udało się załadować metadanych" + }, + "notFound": { + "badge": "Nie znaleziono", + "homeButton": "Wróć na stronę główną", + "text": "Nie znaleźliśmy żądanych multimediów. Albo został usunięty, albo zmieniłeś adres URL.", + "title": "Nie można znaleźć multimediów." + } + }, + "nextEpisode": { + "cancel": "Anuluj", + "next": "Następny odcinek" + }, + "playbackError": { + "badge": "Błąd odtwarzania", + "errors": { + "errorAborted": "Pobieranie multimediów zostało przerwane na żądanie użytkownika.", + "errorDecode": "Pomimo wcześniejszego stwierdzenia że zasób multimedialny nadaje się do użytku, wystąpił błąd podczas próby dekodowania zasobu multimedialnego, co spowodowało błąd.", + "errorGenericMedia": "Wystąpił nieznany błąd multimediów.", + "errorNetwork": "Wystąpił jakiś błąd sieciowy, który uniemożliwił pomyślne pobranie multimediów, mimo że były one wcześniej dostępne.", + "errorNotSupported": "Obiekt multimediów lub dostawcy multimediów nie jest obsługiwany." + }, + "homeButton": "Wróć na stronę główną", + "text": "Wystąpił błąd podczas próby odtworzenia multimediów. Spróbuj ponownie.", + "title": "Nie udało się odtworzyć wideo!" + }, + "scraping": { + "items": { + "failure": "Wystąpił błąd", + "notFound": "Nie ma wideo", + "pending": "Sprawdzanie filmów..." + }, + "notFound": { + "badge": "Nie znaleziono", + "detailsButton": "Pokaż szczegóły", + "homeButton": "Wróć na stronę główną", + "text": "Przeszukaliśmy naszych dostawców i nie możemy znaleźć poszukiwanych multimediów! Nie przechowujemy multimediów i nie mamy kontroli nad ich dostępnością. Kliknij \"Pokaż szczegóły\" poniżej, aby uzyskać więcej informacji.", + "title": "Nie mogliśmy znaleźć tego" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "Zostało {{timeLeft}} • Skończ o {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Proszę potwierdź że jesteś człowiekiem, wypełniając Captcha po prawej stronie. Ma to zapewnić bezpieczeństwo SkoolTV!", + "error": "Nie udało się zweryfikować Twojego człowieczeństwa. Proszę spróbuj ponownie.", + "title": "Musimy sprawdzić, czy jesteś człowiekiem.", + "verifyingHumanity": "Sprawdzasz swoje człowieczeństwo..." + } + }, + "screens": { + "dmca": { + "text": "Witamy na stronie kontaktowej DMCA serwisu SkoolTV! Szanujemy prawa własności intelektualnej i chcemy szybko rozwiązywać wszelkie problemy związane z prawami autorskimi. Jeśli uważasz że twoja praca chroniona prawem autorskim została niewłaściwie wykorzystana na naszej platformie, proszę wysłać szczegółowe powiadomienie DMCA na poniższy adres e-mail. Prosimy o dołączenie opisu materiału chronionego prawem autorskim, danych kontaktowych i oświadczenia w dobrej wierze. Zależy nam na szybkim rozwiązywaniu takich spraw i będziemy wdzięczni za współpracę w utrzymaniu SkoolTV jako miejsce w którym szanuje się kreatywność i prawa autorskie.", + "title": "DMCA" + }, + "loadingApp": "Wczytywanie aplikacji", + "loadingUser": "Wczytywanie profilu", + "loadingUserError": { + "logout": "Wyloguj się", + "reset": "Zresetuj serwer niestandardowy", + "text": "Nie udało się wczytać profilu", + "textWithReset": "Nie udało się wczytać profilu z niestandardowego serwera, chcesz powrócić do domyślnego serwera?" + }, + "migration": { + "failed": "Migracja danych nie powiodła się.", + "inProgress": "Proszę czekać, przeprowadzamy migrację danych. Nie powinno to zająć dużo czasu." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nazwa urządzenia", + "deviceNamePlaceholder": "Telefon osobisty", + "editProfile": "Edytuj", + "logoutButton": "Wyloguj się" + }, + "actions": { + "delete": { + "button": "Usuń konto", + "confirmButton": "Usuń konto", + "confirmDescription": "Na pewno chcesz usunąć swoje konto? Wszystkie twoje dane zostaną stracone!", + "confirmTitle": "Jesteś pewny?", + "text": "Działanie to jest nieodwracalne. Wszystkie dane zostaną usunięte i nie będzie można ich odzyskać.", + "title": "Usuń konto" + }, + "title": "Działania" + }, + "devices": { + "deviceNameLabel": "Nazwa urządzenia", + "failed": "Nie udało się załadować sesji", + "removeDevice": "Usuń", + "title": "Urządzenia" + }, + "profile": { + "finish": "Zakończ edycję", + "firstColor": "Kolor profilu jeden", + "secondColor": "Kolor profilu dwa", + "title": "Edytuj zdjęcie profilowe", + "userIcon": "Ikona użytkownika" + }, + "register": { + "cta": "Rozpocznij", + "text": "Udostępnij postępy oglądania między urządzeniami i synchronizuj je.", + "title": "Synchronizuj z chmurą" + }, + "title": "Konto" + }, + "appearance": { + "activeTheme": "Aktywny", + "themes": { + "blue": "Niebieski", + "default": "Domyślny", + "gray": "Szary", + "red": "Czerwony", + "teal": "Morski" + }, + "title": "Wygląd" + }, + "connections": { + "server": { + "description": "Jeśli chcesz połączyć się z niestandardowym backendem w celu przechowywania danych, włącz tę opcję i podaj adres URL. <0>Instrukcje.", + "label": "Serwer niestandardowy", + "urlLabel": "Adres URL niestandardowego serwera" + }, + "setup": { + "doSetup": "Konfiguruj", + "errorStatus": { + "description": "Wygląda na to, że jeden lub więcej elementów tej konfiguracji wymaga Twojej uwagi.", + "title": "Coś wymaga twojej uwagi" + }, + "itemError": "Coś jest nie tak z tym ustawieniem. Ponownie przejdź przez konfigurację, aby to naprawić.", + "items": { + "default": "Domyślna konfiguracja", + "extension": "Rozszerzenie", + "proxy": "Niestandardowy serwer proxy" + }, + "redoSetup": "Ponów konfigurację", + "successStatus": { + "description": "Wszystko jest gotowe, abyś mógł zacząć oglądać ulubione media.", + "title": "Wszystko jest gotowe!" + }, + "unsetStatus": { + "description": "Kliknij przycisk po prawej stronie, aby rozpocząć proces konfiguracji.", + "title": "Nie przeszedłeś konfiguracji" + } + }, + "title": "Połączenia", + "workers": { + "addButton": "Dodaj nowego pracownika", + "description": "Aby aplikacja działała, cały ruch jest kierowany przez serwery proxy. Włącz tę opcję, jeśli chcesz korzystać z własnych pracowników. <0>Instrukcje.", + "emptyState": "Brak pracowników, dodaj jednego poniżej", + "label": "Używaj niestandardowych pracowników proxy", + "urlLabel": "Adresy URL pracowników", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Język aplikacji", + "languageDescription": "Język zastosowany do całej aplikacji.", + "thumbnail": "Generuj miniatury", + "thumbnailDescription": "W większości przypadków filmy nie mają miniatur. Możesz włączyć to ustawienie, aby generować je na bieżąco, ale może to spowolnić wideo.", + "thumbnailLabel": "Generuj miniatury", + "title": "Preferencje" + }, + "reset": "Reset", + "save": "Zapisz", + "sidebar": { + "info": { + "appVersion": "Wersja aplikacji", + "backendUrl": "Adres URL backendu", + "backendVersion": "Wersja backendu", + "hostname": "Nazwa hosta", + "insecure": "Niebezpieczny", + "notLoggedIn": "Nie jesteś zalogowany", + "secure": "Bezpieczne", + "title": "Informacje o aplikacji", + "unknownVersion": "Nieznany", + "userId": "Identyfikator użytkownika" + } + }, + "subtitles": { + "backgroundBlurLabel": "Rozmycie tła", + "backgroundLabel": "Krycie tła", + "colorLabel": "Kolor", + "previewQuote": "Nie wolno mi się bać. Strach zabija myślenie.", + "textSizeLabel": "Rozmiar czcionki", + "title": "Napisy" + }, + "unsaved": "Masz niezapisane zmiany" + } +} diff --git a/src/assets/locales/pt-BR.json b/src/assets/locales/pt-BR.json new file mode 100644 index 0000000..a4ae805 --- /dev/null +++ b/src/assets/locales/pt-BR.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "SkoolTV é uma aplicação web que busca na internet por streams. A equipe visa uma abordagem principalmente minimalista para consumir conteúdo.", + "faqTitle": "Perguntas comuns", + "q1": { + "body": "SkoolTV não hospeda nenhum conteúdo. Quando você clica em algo para assistir, a internet é pesquisada pela mídia selecionada (Na tela de carregamento e na aba 'fontes de vídeo' você pode ver qual fonte está usando). A mídia nunca é carregada pelo SkoolTV, tudo é através deste mecanismo de busca.", + "title": "De onde vem o conteúdo?" + }, + "q2": { + "body": "Não é possível solicitar um filme ou série, o SkoolTV não gerencia nenhum conteúdo. Todo o conteúdo é visualizado através de fontes na internet.", + "title": "Onde posso solicitar um filme ou série?" + }, + "q3": { + "body": "Nossos resultados de pesquisa são alimentados pelo The Movie Database (TMDB) e são exibidos independentemente de nossas fontes terem ou não o conteúdo.", + "title": "Os resultados da pesquisa mostram o filme ou série, por que não consigo reproduzi-lo?" + }, + "title": "Sobre o SkoolTV" + }, + "actions": { + "copied": "Copiado", + "copy": "Copiar" + }, + "auth": { + "createAccount": "Ainda não tem uma conta? <0>Crie uma conta.", + "deviceNameLabel": "Nome do dispositivo", + "deviceNamePlaceholder": "Telefone pessoal", + "generate": { + "description": "Sua frase de acesso funciona como seu nome de usuário e senha. Certifique-se de mantê-la segura, pois você precisará inseri-la para entrar na sua conta", + "next": "Eu salvei minha frase de acesso", + "passphraseFrameLabel": "Frase de acesso", + "title": "Sua frase de acesso" + }, + "hasAccount": "Já tem uma conta? <0>Entre aqui.", + "login": { + "description": "Por favor, insira sua frase de acesso para entrar na sua conta", + "deviceLengthError": "Por favor, insira um nome para o dispositivo", + "passphraseLabel": "Frase de acesso de 12 palavras", + "passphrasePlaceholder": "Frase de acesso", + "submit": "Entrar", + "title": "Entrar na sua conta", + "validationError": "Frase de acesso incorreta ou incompleta" + }, + "register": { + "information": { + "color1": "Cor do perfil um", + "color2": "Cor do perfil dois", + "header": "Digite um nome para o seu dispositivo e escolha cores e um ícone de usuário de sua preferência", + "icon": "Ícone do usuário", + "next": "Próximo", + "title": "Informações da conta" + } + }, + "trust": { + "failed": { + "text": "Você o configurou corretamente?", + "title": "Falha ao alcançar o servidor" + }, + "host": "Você está se conectando a <0>{{hostname}} - por favor, confirme se confia nele antes de criar uma conta", + "no": "Voltar", + "noHost": "O servidor não foi configurado, portanto você não pode criar uma conta", + "noHostTitle": "Servidor não configurado!", + "title": "Você confia neste servidor?", + "yes": "Eu confio neste servidor" + }, + "verify": { + "description": "Por favor, insira sua frase de acesso anterior para confirmar que você a salvou e para criar sua conta", + "invalidData": "Dados não são válidos", + "noMatch": "Frase de acesso não corresponde", + "passphraseLabel": "Sua frase de acesso de 12 palavras", + "recaptchaFailed": "Falha na validação do ReCaptcha", + "register": "Criar conta", + "title": "Confirme sua frase de acesso" + } + }, + "errors": { + "badge": "Quebrou", + "details": "Detalhes do erro", + "reloadPage": "Recarregar a página", + "showError": "Mostrar detalhes do erro", + "title": "Encontramos um erro!" + }, + "footer": { + "legal": { + "disclaimer": "Aviso legal", + "disclaimerText": "SkoolTV não hospeda nenhum arquivo, apenas fornece links para serviços de terceiros. Questões legais devem ser tratadas com os hosts de arquivos e provedores. SkoolTV não é responsável por quaisquer arquivos de mídia exibidos pelos provedores de vídeo." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Assista seus programas e filmes favoritos com este aplicativo de streaming de código aberto." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Sobre", + "dmca": "DMCA", + "login": "Entrar", + "onboarding": "Configuração", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registrar", + "settings": "Configurações" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Favoritos" + }, + "continueWatching": { + "sectionTitle": "Continue assistindo" + }, + "mediaList": { + "stopEditing": "Parar de editar" + }, + "search": { + "allResults": "Isso é tudo que temos!", + "failed": "Falha ao encontrar mídia, tente novamente!", + "loading": "Carregando...", + "noResults": "Não conseguimos encontrar nada!", + "placeholder": { + "default": "O que você quer assistir?", + "extra": [ + "O que você gostaria de explorar?", + "O que está na sua lista para assistir?", + "Qual o seu filme favorito?", + "Qual a sua série favorita?" + ] + }, + "sectionTitle": "Resultados da pesquisa" + }, + "titles": { + "day": { + "default": "O que você gostaria de assistir esta tarde?", + "extra": [ + "Se sentindo aventureiro? Jurassic Park pode ser a escolha perfeita." + ] + }, + "morning": { + "default": "O que você gostaria de assistir esta manhã?", + "extra": [ + "Ouvi dizer que Antes do Amanhecer é bom" + ] + }, + "night": { + "default": "O que você gostaria de assistir esta noite?", + "extra": [ + "Cansado? Ouvi dizer que O Exorcista é bom." + ] + } + } + }, + "media": { + "episodeDisplay": "T{{season}} E{{episode}}", + "types": { + "movie": "Filme", + "show": "Série" + }, + "unreleased": "Não lançado" + }, + "navigation": { + "banner": { + "offline": "Verifique sua conexão com a internet" + }, + "menu": { + "about": "Sobre nós", + "logout": "Sair", + "register": "Sincronizar com a nuvem", + "settings": "Configurações", + "support": "Suporte" + } + }, + "notFound": { + "badge": "Não encontrado", + "goHome": "Voltar para o início", + "message": "Procuramos em todos os lugares: debaixo das lixeiras, no armário, atrás do proxy, mas no final não conseguimos encontrar a página que você está procurando.", + "title": "Não conseguimos encontrar essa página" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Cancelar", + "confirm": "Usar configuração padrão", + "description": "A configuração padrão não possui os melhores streams e pode ser insuportavelmente lenta.", + "title": "Você tem certeza?" + }, + "extension": { + "back": "Voltar", + "explainer": "Usando a extensão de navegador, você pode obter os melhores streams que temos a oferecer. Com apenas uma simples instalação.", + "explainerIos": "Infelizmente, a extensão de navegador não é suportado no iOS. Pressione Voltar para escolher outra opção.", + "extensionHelp": "Se você instalou a extensão mas ela não foi detectada, abra a extensão através do menu de extensões do seu navegador e siga as instruções na tela.", + "linkChrome": "Instalar extensão do Chrome", + "linkFirefox": "Instalar extensão do Firefox", + "notDetecting": "Instalou no Chrome, mas o site não está detectando? Tente recarregar a página!", + "notDetectingAction": "Recarregar página", + "status": { + "disallowed": "A extensão não está ativada para esta página", + "disallowedAction": "Ativar extensão", + "failed": "Falha ao solicitar status", + "loading": "Aguardando que você instale a extensão", + "outdated": "A versão da extensão é muito antiga", + "success": "A extensão está funcionado como esperado!" + }, + "submit": "Continuar", + "title": "Vamos começar com uma extensão" + }, + "proxy": { + "back": "Voltar", + "explainer": "Com o método proxy, você pode obter streams de ótima qualidade criando um proxy de autoatendimento.", + "input": { + "errorConnection": "Não foi possível conectar ao proxy", + "errorInvalidUrl": "Não é uma URL válida", + "errorNotProxy": "Esperava um proxy, mas recebi um site", + "label": "URL do Proxy", + "placeholder": "https://" + }, + "link": "Aprenda como criar um proxy", + "submit": "Enviar proxy", + "title": "Vamos preparar um novo proxy" + }, + "start": { + "explainer": "Para obter os melhores streams possíveis, você precisará escolher qual método de streaming deseja usar.", + "options": { + "default": { + "text": "Eu não quero streams de boa qualidade, <0 /> <1>use a configuração padrão" + }, + "extension": { + "action": "Instalar extensão", + "description": "Instale a extensão de navegador e tenha acesso às melhores fontes.", + "quality": "Melhor qualidade", + "title": "Extensão de navegador" + }, + "proxy": { + "action": "Configurar proxy", + "description": "Configure um proxy em apenas 5 minutos e tenha acesso a ótimas fontes.", + "quality": "Boa qualidade", + "title": "Proxy personalizado" + } + }, + "title": "Vamos juntos configurar o SkoolTV" + } + }, + "overlays": { + "close": "Fechar" + }, + "player": { + "back": { + "default": "Voltar para o início", + "short": "Voltar" + }, + "casting": { + "enabled": "Transmitindo para o dispositivo..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Copiar link da playlist HLS", + "disclaimer": "Os downloads são feitos diretamente do provedor. SkoolTV não tem controle sobre como os downloads são fornecidos.", + "downloadSubtitle": "Baixar legenda atual", + "downloadVideo": "Baixar vídeo", + "hlsDisclaimer": "Os downloads são feitos diretamente do provedor. SkoolTV não tem controle sobre como os downloads são fornecidos.

Por favor, note que você está baixando uma playlist HLS, isso é destinado para usuários familiarizados com streaming multimídia avançado.. Experimente outras fontes para formatos diferentes.", + "onAndroid": { + "1": "Para baixar no Android, clique no botão de download e, na nova página, toque e segure no vídeo, depois selecione salvar.", + "shortTitle": "Baixar / Android", + "title": "Baixando no Android" + }, + "onIos": { + "1": "Para baixar no iOS, clique no botão de download e, na nova página, clique em , depois em Salvar em Arquivos .", + "shortTitle": "Baixar / iOS", + "title": "Baixando no iOS" + }, + "onPc": { + "1": "No PC, clique no botão de download e, na nova página, clique com o botão direito do mouse no vídeo e selecione Salvar vídeo como", + "shortTitle": "Baixar / PC", + "title": "Baixando no PC" + }, + "title": "Baixar" + }, + "episodes": { + "button": "Episódios", + "emptyState": "Não há episódios nesta temporada, volte mais tarde!", + "episodeBadge": "E{{episode}}", + "loadingError": "Erro ao carregar temporada", + "loadingList": "Carregando...", + "loadingTitle": "Carregando...", + "unairedEpisodes": "Um ou mais episódios nesta temporada foram desabilitados porque ainda não foram ao ar." + }, + "playback": { + "speedLabel": "Velocidade de reprodução", + "title": "Configurações de reprodução" + }, + "quality": { + "automaticLabel": "Qualidade automática", + "hint": "Você pode tentar <0>trocar de fonte para obter diferentes opções de qualidade.", + "iosNoQuality": "Devido a limitações definidas pela Apple, a seleção de qualidade não está disponível no iOS para esta fonte. Você pode tentar <0>trocar para outra fonte para obter diferentes opções de qualidade.", + "title": "Qualidade" + }, + "settings": { + "audioItem": "Áudio", + "downloadItem": "Baixar", + "enableSubtitles": "Ativar Legendas", + "experienceSection": "Experiência de visualização", + "playbackItem": "Configurações de reprodução", + "qualityItem": "Qualidade", + "sourceItem": "Fontes de vídeo", + "subtitleItem": "Configurações de legenda", + "videoSection": "Configurações de vídeo" + }, + "sources": { + "failed": { + "text": "Houve um erro ao tentar encontrar vídeos, por favor, tente uma fonte diferente.", + "title": "Falha ao raspar" + }, + "noEmbeds": { + "text": "Não conseguimos encontrar nenhum incorporado, por favor, tente uma fonte diferente.", + "title": "Nenhum incorporado encontrado" + }, + "noStream": { + "text": "Esta fonte não tem transmissões para este filme ou série.", + "title": "Sem transmissão" + }, + "title": "Fontes", + "unknownOption": "Desconhecido" + }, + "subtitles": { + "customChoice": "Solte ou faça upload do arquivo", + "customizeLabel": "Personalizar", + "dropSubtitleFile": "Solte o arquivo da legenda aqui", + "offChoice": "Desativadas", + "settings": { + "backlink": "Legendas personalizadas", + "delay": "Atraso da legenda", + "fixCapitals": "Corrigir letras maiúsculas" + }, + "title": "Legendas", + "unknownLanguage": "Desconhecido" + } + }, + "metadata": { + "api": { + "text": "Não foi possível carregar os metadados da API. Por favor, verifique sua conexão com a internet.", + "title": "Falha ao carregar os metadados da API" + }, + "dmca": { + "badge": "Removido", + "text": "Esta mídia não está mais disponível devido a um aviso de remoção ou reivindicação de direitos autorais.", + "title": "A mídia foi removida" + }, + "extensionPermission": { + "badge": "Permissão Pendente", + "button": "Usar extensão", + "text": "Você possui a extensão de navegador, mas nós precisamos de sua permissão para começar a usá-la.", + "title": "Configure a extensão" + }, + "failed": { + "badge": "Falhou", + "homeButton": "Ir para o início", + "text": "Não foi possível carregar os metadados da mídia do TMDB. Por favor, verifique se o TMDB está fora do ar ou bloqueado na sua conexão de internet.", + "title": "Falha ao carregar metadados" + }, + "notFound": { + "badge": "Não encontrado", + "homeButton": "Voltar para o início", + "text": "Não conseguimos encontrar a mídia que você solicitou. Ou ela foi removida ou você alterou o URL.", + "title": "Não conseguimos encontrar essa mídia." + } + }, + "nextEpisode": { + "cancel": "Cancelar", + "next": "Próximo episódio" + }, + "playbackError": { + "badge": "Erro de reprodução", + "errors": { + "errorAborted": "A busca pela mídia foi abortada a pedido do usuário.", + "errorDecode": "Apesar de ter sido previamente determinado como utilizável, ocorreu um erro ao tentar decodificar o recurso de mídia, resultando em um erro.", + "errorGenericMedia": "Ocorreu um erro desconhecido de mídia.", + "errorNetwork": "Ocorreu algum tipo de erro de rede que impediu a mídia de ser buscada com sucesso, apesar de ter sido previamente disponível.", + "errorNotSupported": "A mídia ou objeto do provedor de mídia não é suportado." + }, + "homeButton": "Ir para o início", + "text": "Houve um erro ao tentar reproduzir a mídia. Por favor, tente novamente.", + "title": "Falha ao reproduzir o vídeo!" + }, + "scraping": { + "extensionFailure": { + "badge": "Extensão desativada", + "enableExtension": "Ativar extensão", + "homeButton": "Ir para o início", + "text": "Você instalou a extensão SkoolTV. Para começar a usá-la, você precisa ativar a extensão neste site.", + "title": "Por favor, ative a extensão" + }, + "items": { + "failure": "Ocorreu um erro", + "notFound": "Não tem o vídeo", + "pending": "Verificando vídeos..." + }, + "notFound": { + "badge": "Não encontrado", + "detailsButton": "Mostrar detalhes", + "homeButton": "Ir para o início", + "text": "Procuramos em nossos provedores e não conseguimos encontrar a mídia que você está procurando! Não hospedamos a mídia e não temos controle sobre o que está disponível. Por favor, clique em 'Mostrar detalhes' abaixo para mais informações.", + "title": "Não conseguimos encontrar isso" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} restantes • Terminar às {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Por favor, confirme que você é um humano completando o Captcha à direita. Isso é para manter SkoolTV seguro!", + "error": "Falha ao verificar sua humanidade. Por favor, tente novamente.", + "title": "Precisamos verificar se você é humano.", + "verifyingHumanity": "Verificando sua humanidade..." + } + }, + "screens": { + "dmca": { + "text": "Bem-vindo à página de contato do DMCA do SkoolTV! Respeitamos os direitos de propriedade intelectual e queremos resolver quaisquer preocupações com direitos autorais rapidamente. Se você acredita que seu trabalho protegido por direitos autorais foi usado indevidamente em nossa plataforma, envie um aviso detalhado de DMCA para o e-mail abaixo. Inclua uma descrição do material protegido por direitos autorais, seus detalhes de contato e uma declaração de crença de boa fé. Estamos comprometidos em resolver essas questões prontamente e agradecemos sua cooperação em manter o SkoolTV um lugar que respeita a criatividade e os direitos autorais.", + "title": "DMCA" + }, + "loadingApp": "Carregando aplicativo", + "loadingUser": "Carregando seu perfil", + "loadingUserError": { + "logout": "Sair", + "reset": "Redefinir servidor personalizado", + "text": "Falha ao carregar seu perfil", + "textWithReset": "Falha ao carregar seu perfil do seu servidor personalizado, deseja redefinir para o servidor padrão?" + }, + "migration": { + "failed": "Falha ao migrar seus dados.", + "inProgress": "Por favor, aguarde, estamos migrando seus dados. Isso não deve demorar muito." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nome do dispositivo", + "deviceNamePlaceholder": "Telefone pessoal", + "editProfile": "Editar", + "logoutButton": "Sair" + }, + "actions": { + "delete": { + "button": "Excluir conta", + "confirmButton": "Excluir conta", + "confirmDescription": "Você tem certeza de que deseja excluir sua conta? Todos os seus dados serão perdidos!", + "confirmTitle": "Você tem certeza?", + "text": "Esta ação é irreversível. Todos os dados serão excluídos e nada poderá ser recuperado.", + "title": "Excluir conta" + }, + "title": "Ações" + }, + "devices": { + "deviceNameLabel": "Nome do dispositivo", + "failed": "Falha ao carregar sessões", + "removeDevice": "Remover", + "title": "Dispositivos" + }, + "profile": { + "finish": "Finalizar edição", + "firstColor": "Cor do perfil um", + "secondColor": "Cor do perfil dois", + "title": "Editar foto de perfil", + "userIcon": "Ícone do usuário" + }, + "register": { + "cta": "Começar", + "text": "Compartilhe seu progresso de visualização entre dispositivos e mantenha-os sincronizados.", + "title": "Sincronizar com a nuvem" + }, + "title": "Conta" + }, + "appearance": { + "activeTheme": "Ativo", + "themes": { + "blue": "Azul", + "default": "Padrão", + "gray": "Cinza", + "red": "Vermelho", + "teal": "Verde-azulado" + }, + "title": "Aparência" + }, + "connections": { + "server": { + "description": "Se você deseja se conectar a um backend personalizado para armazenar seus dados, ative isso e forneça a URL. <0>Instruções.", + "label": "Servidor personalizado", + "urlLabel": "URL do servidor personalizado" + }, + "setup": { + "doSetup": "Configurar", + "errorStatus": { + "description": "Parece que um ou mais itens nesta configuração necessitam sua atenção.", + "title": "Algo necessita de sua atenção" + }, + "itemError": "Há algo errado com esta configuração. Realize uma nova configuração para corrigir.", + "items": { + "default": "Configuração padrão", + "extension": "Extensão", + "proxy": "Proxy personalizado" + }, + "redoSetup": "Refazer configuração", + "successStatus": { + "description": "Tudo está pronto para você começar a assistir sua mídia favorita.", + "title": "Está tudo pronto!" + }, + "unsetStatus": { + "description": "Por favor, clique no botão à direita para iniciar a configuração.", + "title": "Você não realizou a configuração" + } + }, + "title": "Conexões", + "workers": { + "addButton": "Adicionar novo worker", + "description": "Para fazer o aplicativo funcionar, todo o tráfego é roteado através de proxies. Ative isso se você quiser trazer seus próprios workers. <0>Instruções.", + "emptyState": "Ainda não há workers, adicione um abaixo", + "label": "Usar proxy workers personalizados", + "urlLabel": "URLs dos workers", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Idioma do aplicativo", + "languageDescription": "Idioma aplicado para todo o aplicativo.", + "thumbnail": "Gerar miniaturas", + "thumbnailDescription": "Na maior parte do tempo, os vídeos não possuem miniaturas. Você pode ativar esta configuração para gerá-las dinamicamente, mas elas podem tornar seu vídeo mais lento.", + "thumbnailLabel": "Gerar miniaturas", + "title": "Preferências" + }, + "reset": "Redefinir", + "save": "Salvar", + "sidebar": { + "info": { + "appVersion": "Versão do aplicativo", + "backendUrl": "URL do backend", + "backendVersion": "Versão do backend", + "hostname": "Nome do host", + "insecure": "Inseguro", + "notLoggedIn": "Você não está logado", + "secure": "Seguro", + "title": "Informações do aplicativo", + "unknownVersion": "Desconhecido", + "userId": "ID do usuário" + } + }, + "subtitles": { + "backgroundBlurLabel": "Desfoque de fundo", + "backgroundLabel": "Opacidade do fundo", + "colorLabel": "Cor", + "previewQuote": "Eu não devo ter medo. Medo é o assassino da mente.", + "textSizeLabel": "Tamanho do texto", + "title": "Legendas" + }, + "unsaved": "Você tem alterações não salvas" + } +} diff --git a/src/assets/locales/pt-PT.json b/src/assets/locales/pt-PT.json new file mode 100644 index 0000000..40de248 --- /dev/null +++ b/src/assets/locales/pt-PT.json @@ -0,0 +1,432 @@ +{ + "about": { + "description": "SkoolTV é uma aplicação web que pesquisa a internet por streams. A equipa visa uma abordagem maioritariamente minimalista na consumação de conteúdos.", + "faqTitle": "Perguntas frequentes", + "q1": { + "body": "SkoolTV não hospeda nenhum conteúdo. Quando clica para assistir a algo, a internet é pesquisada para o media selecionado (Na tela de carregamento e na aba 'fontes de vídeo', pode ver qual a fonte que está a ser utilizada). O media nunca é carregado pelo SkoolTV, tudo é feito através deste mecanismo de pesquisa.", + "title": "De onde vem o conteúdo?" + }, + "q2": { + "body": "Não é possível solicitar um programa ou filme, o SkoolTV não gere nenhum conteúdo. Todo o conteúdo é visualizado através de fontes na internet.", + "title": "Onde posso solicitar um programa ou filme?" + }, + "q3": { + "body": "Os nossos resultados de pesquisa são alimentados pela The Movie Database (TMDB) e são exibidos independentemente de as nossas fontes realmente terem o conteúdo.", + "title": "Os resultados da pesquisa mostram o programa ou filme, por que não consigo reproduzi-lo?" + }, + "title": "Sobre o SkoolTV" + }, + "actions": { + "copied": "Copiado", + "copy": "Copiar" + }, + "auth": { + "createAccount": "Ainda não tem uma conta? <0>Crie uma conta.", + "deviceNameLabel": "Nome do dispositivo", + "deviceNamePlaceholder": "Telemóvel pessoal", + "generate": { + "description": "A sua frase-passe age como o seu nome de utilizador e senha. Certifique-se de a manter segura, pois precisará dela para entrar na sua conta", + "next": "Guardei a minha frase-passe", + "passphraseFrameLabel": "Frase-passe", + "title": "A sua frase-passe" + }, + "hasAccount": "Já tem uma conta? <0>Entre aqui.", + "login": { + "description": "Por favor, introduza a sua frase-passe para entrar na sua conta", + "deviceLengthError": "Por favor, introduza um nome de dispositivo", + "passphraseLabel": "Frase-passe de 12 palavras", + "passphrasePlaceholder": "Frase-passe", + "submit": "Entrar", + "title": "Entrar na sua conta", + "validationError": "Frase-passe incorreta ou incompleta" + }, + "register": { + "information": { + "color1": "Cor de perfil um", + "color2": "Cor de perfil dois", + "header": "Introduza um nome para o seu dispositivo e escolha cores e um ícone de utilizador da sua escolha", + "icon": "Ícone de utilizador", + "next": "Próximo", + "title": "Informações da conta" + } + }, + "trust": { + "failed": { + "text": "Configurou corretamente?", + "title": "Falha ao conectar-se ao servidor" + }, + "host": "Está a conectar-se a <0>{{hostname}} - confirme se confia antes de criar uma conta", + "no": "Voltar", + "title": "Confia neste servidor?", + "yes": "Confio neste servidor" + }, + "verify": { + "description": "Por favor, introduza a sua frase-passe anterior para confirmar que a guardou e para criar a sua conta", + "invalidData": "Dados inválidos", + "noMatch": "A frase-passe não coincide", + "passphraseLabel": "A sua frase-passe de 12 palavras", + "recaptchaFailed": "Falha na validação do ReCaptcha", + "register": "Criar conta", + "title": "Confirmar a sua frase-passe" + } + }, + "errors": { + "badge": "Houve um erro", + "details": "Detalhes do erro", + "reloadPage": "Recarregar a página", + "showError": "Mostrar detalhes do erro", + "title": "Encontrámos um erro!" + }, + "footer": { + "legal": { + "disclaimer": "Aviso legal", + "disclaimerText": "SkoolTV não hospeda quaisquer ficheiros, apenas faz ligações para serviços de terceiros. Problemas legais devem ser tratados com os anfitriões e fornecedores de ficheiros. O SkoolTV não é responsável por quaisquer ficheiros multimédia mostrados pelos fornecedores de vídeo." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Assista aos seus programas e filmes favoritos com esta aplicação de streaming de código aberto." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Sobre", + "dmca": "DMCA", + "login": "Entrar", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registrar", + "settings": "Configurações" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Marcadores" + }, + "continueWatching": { + "sectionTitle": "Continuar a assistir" + }, + "mediaList": { + "stopEditing": "Parar de editar" + }, + "search": { + "allResults": "É tudo o que temos!", + "failed": "Falha ao encontrar mídia, tente novamente!", + "loading": "A carregar...", + "noResults": "Não conseguimos encontrar nada!", + "placeholder": { + "default": "O que deseja assistir?" + }, + "sectionTitle": "Resultados da pesquisa" + }, + "titles": { + "day": { + "default": "O que gostaria de assistir esta tarde?", + "extra": [ + "Sentindo-se aventureiro? Jurassic Park pode ser a escolha perfeita." + ] + }, + "morning": { + "default": "O que gostaria de assistir esta manhã?", + "extra": [ + "Dizem que Antes do Amanhecer é bom" + ] + }, + "night": { + "default": "O que gostaria de assistir esta noite?", + "extra": [ + "Cansado? Dizem que O Exorcista é bom." + ] + } + } + }, + "media": { + "episodeDisplay": "T{{season}} E{{episode}}", + "types": { + "movie": "Filme", + "show": "Série" + } + }, + "navigation": { + "banner": { + "offline": "Verifique a sua conexão à internet" + }, + "menu": { + "about": "Sobre nós", + "logout": "Sair", + "register": "Sincronizar com a nuvem", + "settings": "Configurações", + "support": "Suporte" + } + }, + "notFound": { + "badge": "Não encontrado", + "goHome": "Voltar para casa", + "message": "Procurámos em todo lugar: embaixo dos caixotes, no armário, atrás do proxy, mas, no final, não conseguimos encontrar a página que procura.", + "title": "Não foi possível encontrar essa página" + }, + "overlays": { + "close": "Fechar" + }, + "player": { + "back": { + "default": "Voltar para casa", + "short": "Voltar" + }, + "casting": { + "enabled": "Transmitindo para o dispositivo..." + }, + "menus": { + "downloads": { + "disclaimer": "Os downloads são feitos diretamente pelo fornecedor. O SkoolTV não tem controle sobre como os downloads são fornecidos.", + "downloadSubtitle": "Baixar legenda atual", + "downloadVideo": "Baixar vídeo", + "hlsDisclaimer": "Os downloads são feitos diretamente pelo fornecedor. O SkoolTV não tem controle sobre como os downloads são fornecidos. Por favor, note que está a baixar uma lista de reprodução HLS, isso é destinado a utilizadores familiarizados com streaming multimídia avançado.", + "onAndroid": { + "1": "Para baixar no Android, clique no botão de download e, na nova página, toque e segure no vídeo, depois selecione guardar.", + "shortTitle": "Baixar / Android", + "title": "Baixando no Android" + }, + "onIos": { + "1": "Para baixar no iOS, clique no botão de download e, na nova página, clique em , depois em Guardar no Ficheiro .", + "shortTitle": "Baixar / iOS", + "title": "Baixando no iOS" + }, + "onPc": { + "1": "No PC, clique no botão de download e, na nova página, clique com o botão direito no vídeo e selecione Guardar vídeo como", + "shortTitle": "Baixar / PC", + "title": "Baixando no PC" + }, + "title": "Baixar" + }, + "episodes": { + "button": "Episódios", + "emptyState": "Não há episódios nesta temporada, volte mais tarde!", + "episodeBadge": "E{{episode}}", + "loadingError": "Erro ao carregar a temporada", + "loadingList": "A carregar...", + "loadingTitle": "A carregar...", + "unairedEpisodes": "Um ou mais episódios nesta temporada foram desativados porque ainda não foram transmitidos." + }, + "playback": { + "speedLabel": "Velocidade de reprodução", + "title": "Configurações de reprodução" + }, + "quality": { + "automaticLabel": "Qualidade automática", + "hint": "Pode tentar <0>mudar de fonte para obter opções de qualidade diferentes.", + "iosNoQuality": "Devido a limitações definidas pela Apple, a seleção de qualidade não está disponível no iOS para esta fonte. Pode tentar <0>mudar para outra fonte para obter opções de qualidade diferentes.", + "title": "Qualidade" + }, + "settings": { + "downloadItem": "Download", + "enableSubtitles": "Ativar legendas", + "experienceSection": "Experiência de visualização", + "playbackItem": "Configurações de reprodução", + "qualityItem": "Qualidade", + "sourceItem": "Fontes de vídeo", + "subtitleItem": "Configurações de legendas", + "videoSection": "Configurações de vídeo" + }, + "sources": { + "failed": { + "text": "Houve um erro ao tentar encontrar vídeos, por favor, tente uma fonte diferente.", + "title": "Falha ao obter" + }, + "noEmbeds": { + "text": "Não conseguimos encontrar nenhum embed, por favor, tente uma fonte diferente.", + "title": "Nenhum embed encontrado" + }, + "noStream": { + "text": "Esta fonte não tem transmissões para este filme ou série.", + "title": "Sem transmissão" + }, + "title": "Fontes", + "unknownOption": "Desconhecido" + }, + "subtitles": { + "customChoice": "Selecionar legenda do arquivo", + "customizeLabel": "Personalizar", + "offChoice": "Desativar", + "settings": { + "backlink": "Legendas personalizadas", + "delay": "Atraso das legendas", + "fixCapitals": "Corrigir maiúsculas" + }, + "title": "Legendas", + "unknownLanguage": "Desconhecido" + } + }, + "metadata": { + "api": { + "text": "Não foi possível carregar os metadados da API, por favor verifique a sua conexão à internet.", + "title": "Falha ao carregar os metadados da API" + }, + "failed": { + "badge": "Falhou", + "homeButton": "Ir para casa", + "text": "Não foi possível carregar os metadados do media da TMDB. Por favor, verifique se a TMDB está indisponível ou bloqueada na sua conexão à internet.", + "title": "Falha ao carregar os metadados" + }, + "notFound": { + "badge": "Não encontrado", + "homeButton": "Voltar para casa", + "text": "Não conseguimos encontrar o conteúdo que solicitou. Ou foi removido ou houve manipulação na URL.", + "title": "Não foi possível encontrar esse conteúdo." + } + }, + "nextEpisode": { + "cancel": "Cancelar", + "next": "Próximo episódio" + }, + "playbackError": { + "badge": "Erro de reprodução", + "errors": { + "errorAborted": "A recuperação do conteúdo foi cancelada a pedido do utilizador.", + "errorDecode": "Apesar de ter sido anteriormente considerado utilizável, ocorreu um erro ao tentar decodificar o recurso multimédia, resultando em um erro.", + "errorGenericMedia": "Ocorreu um erro desconhecido no multimédia.", + "errorNetwork": "Ocorreu algum tipo de erro de rede que impediu a recuperação bem-sucedida do multimédia, apesar de estar disponível anteriormente.", + "errorNotSupported": "O objeto multimédia ou do fornecedor de multimédia não é suportado." + }, + "homeButton": "Ir para casa", + "text": "Ocorreu um erro ao tentar reproduzir o conteúdo multimédia. Por favor, tente novamente.", + "title": "Falha ao reproduzir o vídeo!" + }, + "scraping": { + "items": { + "failure": "Ocorreu um erro", + "notFound": "Não possui o vídeo", + "pending": "A verificar vídeos..." + }, + "notFound": { + "badge": "Não encontrado", + "detailsButton": "Mostrar detalhes", + "homeButton": "Ir para casa", + "text": "Pesquisámos pelos nossos fornecedores e não conseguimos encontrar o conteúdo que procura! Não alojamos o conteúdo multimédia e não temos controlo sobre o que está disponível. Por favor, clique em 'Mostrar detalhes' abaixo para mais informações.", + "title": "Não conseguimos encontrar isso" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} restantes • Termina às {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Por favor, verifique que é humano completando o Captcha à direita. Isso é para manter o SkoolTV seguro!", + "error": "Falha ao verificar a sua humanidade. Por favor, tente novamente.", + "title": "Precisamos verificar que você é humano.", + "verifyingHumanity": "Verificando a sua humanidade..." + } + }, + "screens": { + "dmca": { + "text": "Bem-vindo à página de contacto DMCA da SkoolTV! Respeitamos os direitos de propriedade intelectual e queremos resolver rapidamente quaisquer preocupações de direitos autorais. Se acredita que a sua obra protegida por direitos autorais foi usada indevidamente na nossa plataforma, envie um aviso DMCA detalhado para o email abaixo. Inclua uma descrição do material protegido por direitos autorais, os seus detalhes de contacto e uma declaração de boa fé. Comprometemo-nos a resolver essas questões prontamente e agradecemos a sua cooperação para manter a SkoolTV como um lugar que respeita a criatividade e os direitos autorais.", + "title": "DMCA" + }, + "loadingApp": "A carregar a aplicação", + "loadingUser": "A carregar o seu perfil", + "loadingUserError": { + "logout": "Terminar sessão", + "reset": "Repor servidor personalizado", + "text": "Falha ao carregar o seu perfil", + "textWithReset": "Falha ao carregar o seu perfil do servidor personalizado. Deseja repor para o servidor padrão?" + }, + "migration": { + "failed": "Falha ao migrar os seus dados.", + "inProgress": "Por favor aguarde, estamos a migrar os seus dados. Isto não deverá demorar muito." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nome do dispositivo", + "deviceNamePlaceholder": "Telemóvel pessoal", + "editProfile": "Editar", + "logoutButton": "Terminar sessão" + }, + "actions": { + "delete": { + "button": "Eliminar conta", + "confirmButton": "Eliminar conta", + "confirmDescription": "Tem a certeza de que deseja eliminar a sua conta? Todos os seus dados serão perdidos!", + "confirmTitle": "Tem a certeza?", + "text": "Esta ação é irreversível. Todos os dados serão eliminados e nada poderá ser recuperado.", + "title": "Eliminar conta" + }, + "title": "Ações" + }, + "devices": { + "deviceNameLabel": "Nome do dispositivo", + "failed": "Falha ao carregar as sessões", + "removeDevice": "Remover", + "title": "Dispositivos" + }, + "profile": { + "finish": "Terminar edição", + "firstColor": "Cor do perfil um", + "secondColor": "Cor do perfil dois", + "title": "Editar imagem de perfil", + "userIcon": "Ícone de utilizador" + }, + "register": { + "cta": "Começar", + "text": "Partilhe o seu progresso de visualização entre dispositivos e mantenha-os sincronizados.", + "title": "Sincronizar com a nuvem" + }, + "title": "Conta" + }, + "appearance": { + "activeTheme": "Ativo", + "themes": { + "blue": "Azul", + "default": "Padrão", + "gray": "Cinzento", + "red": "Vermelho", + "teal": "Verde-azulado" + }, + "title": "Aparência" + }, + "connections": { + "server": { + "description": "Se desejar ligar a um servidor personalizado para armazenar os seus dados, ative isto e forneça o URL.", + "label": "Servidor personalizado", + "urlLabel": "URL do servidor personalizado" + }, + "title": "Conexões", + "workers": { + "addButton": "Adicionar novo trabalhador", + "description": "Para que a aplicação funcione, todo o tráfego é encaminhado através de proxies. Ative isto se quiser utilizar os seus próprios trabalhadores.", + "emptyState": "Ainda não há trabalhadores, adicione um abaixo", + "label": "Utilizar trabalhadores de proxy personalizados", + "urlLabel": "URLs do trabalhador", + "urlPlaceholder": "https://" + } + }, + "reset": "Repor", + "save": "Guardar", + "sidebar": { + "info": { + "appVersion": "Versão da aplicação", + "backendUrl": "URL do backend", + "backendVersion": "Versão do backend", + "hostname": "Hostname", + "insecure": "Inseguro", + "notLoggedIn": "Não está autenticado", + "secure": "Seguro", + "title": "Informações da aplicação", + "unknownVersion": "Desconhecida", + "userId": "ID de utilizador" + } + }, + "subtitles": { + "backgroundLabel": "Opacidade do fundo", + "colorLabel": "Cor", + "previewQuote": "Não devo temer. O medo é o assassino da mente.", + "textSizeLabel": "Tamanho do texto", + "title": "Legendas" + }, + "unsaved": "Tem alterações não guardadas" + } +} diff --git a/src/assets/locales/ro.json b/src/assets/locales/ro.json new file mode 100644 index 0000000..258c540 --- /dev/null +++ b/src/assets/locales/ro.json @@ -0,0 +1,543 @@ +{ + "about": { + "description": "SkoolTV este o aplicație web care caută fluxuri pe internet. Echipa urmărește o abordare mai ales minimalistă a consumului de conținut.", + "faqTitle": "Întrebări obișnuite", + "q1": { + "body": "SkoolTV nu găzduiește niciun conținut. Când faceți clic pe ceva pentru a viziona, pe Internet este căutat media selectată (Pe ecranul de încărcare și în fila „Surse video”, puteți vedea ce sursă utilizați). Media nu este niciodată încărcată de SkoolTV, totul se face prin acest mecanism de căutare.", + "title": "De unde vine conținutul?" + }, + "q2": { + "body": "Nu este posibil să solicitați o emisiune sau un film, SkoolTV nu gestionează niciun conținut. Tot conținutul este vizualizat prin surse de internet.", + "title": "Unde pot solicita o emisiune sau un film?" + }, + "q3": { + "body": "Rezultatele căutării noastre sunt furnizate de The Movie Database (TMDB) și afișați indiferent dacă sursele noastre au de fapt conținutul.", + "title": "Rezultatele căutării afișează emisiunea sau filmul, de ce nu îl pot reda?" + }, + "title": "Despre SkoolTV" + }, + "actions": { + "copied": "Copiat", + "copy": "Copiați" + }, + "auth": { + "createAccount": "Nu aveți încă un cont? <0>Creați un cont.", + "deviceNameLabel": "Nume dispozitiv", + "deviceNamePlaceholder": "Telefon personal", + "generate": { + "description": "Fraza de acces acționează ca nume de utilizator și parolă. Asigurați-vă că îl păstrați în siguranță, deoarece va trebui să îl introduceți pentru a vă conecta la contul dvs", + "next": "Mi-am salvat fraza de acces", + "passphraseFrameLabel": "Frază de acces", + "title": "Fraza dvs. de acces" + }, + "hasAccount": "ai deja un cont? <0>Autentificați-vă aici.", + "login": { + "description": "Vă rugăm să introduceți fraza de acces pentru a vă conecta la contul dvs", + "deviceLengthError": "Introduceți un nume de dispozitiv", + "passphraseLabel": "Expresie de acces din 12 cuvinte", + "passphrasePlaceholder": "Frază de acces", + "submit": "Conectează te", + "title": "conecteaza-te la contul tau", + "validationError": "Fraza de acces este incorectă sau incompletă" + }, + "register": { + "information": { + "color1": "Culoarea profilului unu", + "color2": "Culoarea profilului doi", + "header": "Introduceți un nume pentru dispozitivul dvs. și alegeți culorile și o pictogramă de utilizator la alegerea dvs", + "icon": "Pictograma utilizatorului", + "next": "Următorul", + "title": "Informații despre cont" + } + }, + "trust": { + "failed": { + "text": "L-ai configurat corect?", + "title": "Nu s-a putut ajunge la server" + }, + "host": "Vă conectați la <0>{{hostname}} - vă rugăm să confirmați că aveți încredere înainte de a vă crea un cont", + "no": "Întoarce-te", + "noHost": "Serverul nu a fost configurat, deci nu vă puteți crea un cont", + "noHostTitle": "Serverul nu este configurat!", + "title": "Ai încredere în acest server?", + "yes": "Am încredere în acest server" + }, + "verify": { + "description": "Introduceți expresia de acces de mai devreme pentru a confirma că ați salvat-o și pentru a vă crea contul", + "invalidData": "Datele nu sunt valide", + "noMatch": "Fraza de acces nu se potrivește", + "passphraseLabel": "Fraza dvs. de acces de 12 cuvinte", + "recaptchaFailed": "Validarea ReCaptcha a eșuat", + "register": "Creează cont", + "title": "Confirmați-vă fraza de acces" + } + }, + "errors": { + "badge": "S-a spart", + "details": "Detalii despre eroare", + "reloadPage": "Reîncărcați pagina", + "showError": "Afișați detalii despre eroare", + "title": "Am intampinat o eroare!" + }, + "footer": { + "legal": { + "disclaimer": "Declinare a răspunderii", + "disclaimerText": "SkoolTV nu găzduiește niciun fișier, ci doar trimite la servicii terțe. Problemele juridice ar trebui abordate cu gazdele și furnizorii de fișiere. SkoolTV nu este responsabil pentru niciun fișier media afișat de furnizorii de video." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Urmăriți emisiunile și filmele preferate cu această aplicație de streaming open source." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Despre", + "dmca": "DMCA", + "login": "Log in", + "onboarding": "Configurație", + "pagetitle": "{{title}} - SkoolTV", + "register": "Inregistreaza-te", + "settings": "Setări" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Marcaje" + }, + "continueWatching": { + "sectionTitle": "Continuați vizionarea" + }, + "mediaList": { + "stopEditing": "Opriți editarea" + }, + "search": { + "allResults": "Asta e tot ce avem!", + "failed": "Găsire media eșuată, încearcă din nou!", + "loading": "Se încarcă...", + "noResults": "Nu am putut găsi nimic!", + "placeholder": { + "default": "La ce dorești să te uiți?", + "extra": [ + "Ce vrei să explorezi?", + "Ce e pe lista dvs. de urmărire?", + "Care e filmul tău preferat?", + "Care e serialul tău preferat?" + ] + }, + "sectionTitle": "Rezultate de căutare" + }, + "titles": { + "day": { + "default": "La ce vrei să te uiți după-amiaza asta?", + "extra": [ + "Te simți aventuros? Jurassic Park ar putea fi o alegere perfectă." + ] + }, + "morning": { + "default": "La ce dorești să te in uiți dimineață aceasta?", + "extra": ["Aud că Before Sunrise este bun"] + }, + "night": { + "default": "La ce dorești să te uiți în astă seară?", + "extra": ["Obosit? Aud că The Exorcist is good."] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Spectacol" + } + }, + "navigation": { + "banner": { + "offline": "Verificați-vă conexiunea de internet" + }, + "menu": { + "about": "Despre noi", + "logout": "Deconectați-vă", + "register": "Sincronizare în sudo-cloud", + "settings": "Setări", + "support": "Ajutor" + } + }, + "notFound": { + "badge": "Nu a fost găsit", + "goHome": "Înapoi acasă", + "message": "Ne-am uitat peste tot: sub pubele, în dulap, În spatele proxy-ului dar din păcate nu am găsit pagina pe care dumneavoastră o căutați.", + "title": "N-am putut găsi pagina" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Anulare", + "confirm": "Folosește configurația implicită", + "description": "Configurația implicită nu are cele mai bune fluxuri și poate fi insuportabil de înceată.", + "title": "Sunteți sigur(ă)?" + }, + "extension": { + "back": "Înapoi", + "explainer": "Folosind această extensie de browser, puteți obține cele mai bune fluxuri pe care le avem de oferit. Cu doar o simplă instalare.", + "explainerIos": "Din păcate, extensia de browser nu e suportată pe iOS, Apăsați Înapoi pentru a alege altă opțiune.", + "extensionHelp": "Dacă ați instalat extensia dar nu e detectată, deschideți extensia din meniul extensiilor al browserului dvs. și urmăriți pașii de pe ecran.", + "linkChrome": "Instalare extensie pentru Chrome", + "linkFirefox": "Instalare extensie pentru Firefox", + "notDetecting": "Instalată pe Chrome dar site-ul nu o detectează? Încerați să reîmprospătați pagina!", + "notDetectingAction": "Reîncarcă pagina", + "status": { + "disallowed": "Extensia nu e activată pentru această pagină", + "disallowedAction": "Activare extensie", + "failed": "Nu s-a putut obține statusul", + "loading": "Așteptăm să vă instalați extensia", + "outdated": "Versiunea extensiei este prea veche", + "success": "Extensia funcționează conform așteptărilor!" + }, + "submit": "Continuare", + "title": "Să începem cu o extensie" + }, + "proxy": { + "back": "Înapoi", + "explainer": "Cu metoda proxy, puteți obține fluxuri de calitate prin a face un proxy cu autoservire.", + "input": { + "errorConnection": "Nu s-a putut conecta la proxy", + "errorInvalidUrl": "URL invalid", + "errorNotProxy": "Am așteptat un proxy dar am primit un site web", + "label": "URL-ul proxy-ului", + "placeholder": "https://" + }, + "link": "Învață cum se face un proxy", + "submit": "Validare proxy", + "title": "Să facem un proxy nou" + }, + "start": { + "explainer": "Pentru a obține cele mai bune fluxuri posibile, va trebui să alegeți ce metodă de streaming vreți să folosiți.", + "options": { + "default": { + "text": "Nu vreau fluxuri de calitate,<0 /> <1>folosește configurația implicită" + }, + "extension": { + "action": "Instalare extensie", + "description": "Instalați extensia browser și obțineți acces la cele mai bune surse.", + "quality": "Cea mai bună calitate", + "title": "Extensie browser" + }, + "proxy": { + "action": "Configurare proxy", + "description": "Configurați un proxy în doar 5 minute și obținți acces la resurse grozave.", + "quality": "Calitate bună", + "title": "Proxy personalizat" + } + }, + "title": "Hai să configurăm SkoolTV" + } + }, + "overlays": { + "close": "Închide" + }, + "player": { + "back": { + "default": "Înapoi acasă", + "short": "Înapoi" + }, + "casting": { + "enabled": "Casting pe dispozitiv..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Copiere link către lista de redare HLS", + "disclaimer": "Descărcările sunt luate direct de la furnizor. SkoolTV nu are control cum descărcările sunt furnizate.", + "downloadSubtitle": "Descărcați subtitlul curente", + "downloadVideo": "Descarcă video", + "hlsDisclaimer": "Descărcările sunt preluate direct de la furnizor. SkoolTV nu are control asupra modului în care sunt furnizate descărcările.

Vă rugăm să rețineți că descărcați o listă de redare HLS, nu este recomandat să o descărcați dacă nu sunteți familiari cu formate avasate de streaming. Încercați surse diferite pentru formate diferte.", + "onAndroid": { + "1": "Pentru a descărca pe android, apăsați butonul de descărcare apoi în pagina nouă,apăsați și țineți pe video, apoi selectați salvează.", + "shortTitle": "Descărcare / Android", + "title": "Descărcare pe Android" + }, + "onIos": { + "1": "Pentru a instala pe iOS, apăsați butonul de instalare apoi în pagina nouă apăsați , apoi Salvează in File .", + "shortTitle": "Descărcare / iOS", + "title": "Descărcare pe iOS" + }, + "onPc": { + "1": "Pe calculator, apăsați butonul de descărcare apoi în pagina nouă, apăsați click drept pe video și selectați Salvați videoul ca", + "shortTitle": "Descarcă / Calculator", + "title": "Descărcare pe calculator" + }, + "title": "Descarcă" + }, + "episodes": { + "button": "Episoade", + "emptyState": "Nu sunt episoade in sezonul acesta, reveniți mai târziu!", + "episodeBadge": "E{{episode}}", + "loadingError": "Eroare la încărcarea sezonul", + "loadingList": "Se încarcă...", + "loadingTitle": "Se încarcă...", + "unairedEpisodes": "Unul sau mai multe episoade din sezonul acesta sunt indisponibile deoarece incă nu au venit încă." + }, + "playback": { + "speedLabel": "Viteză de redare", + "title": "Setările de redare" + }, + "quality": { + "automaticLabel": "Calitate automată", + "hint": "Puteți încerca <0>Schimbarea sursei pentru a primi opțiuni de calitate diferită.", + "iosNoQuality": "Din cauza limitărilor definite de Apple, selecția calității nu este disponibilă pe iOS pentru această sursă. Puteți încerca să <0>treceți la altă sursă pentru a obține diferite opțiuni de calitate.", + "title": "Calitate" + }, + "settings": { + "downloadItem": "Descarcă", + "enableSubtitles": "Activează subtitlurile", + "experienceSection": "Experiență de vizionare", + "playbackItem": "Setări de redare", + "qualityItem": "Calitate", + "sourceItem": "Surse video", + "subtitleItem": "Setările subtitlului", + "videoSection": "Setări video" + }, + "sources": { + "failed": { + "text": "Aici a fost o eroare încercând să găsim video, încercați o altă sursă.", + "title": "Nu s-a răzuit" + }, + "noEmbeds": { + "text": "Nu am putut găsi nicio incorporare, vă rog să încercați o altă sursă.", + "title": "Nu a fost găsită nicio încorporare" + }, + "noStream": { + "text": "Sursa aceasta nu are niciun flux pentru acest film sau serial.", + "title": "Niciun flux" + }, + "title": "Surse", + "unknownOption": "Necunoscut" + }, + "subtitles": { + "customChoice": "Selectați subtitlul din filă", + "customizeLabel": "Costumizează", + "offChoice": "Oprit", + "settings": { + "backlink": "Subtitluri personalizate", + "delay": "Intârziera subtitlurilor", + "fixCapitals": "Fixați capitalizația" + }, + "title": "Subtitluri", + "unknownLanguage": "Necunoscut" + } + }, + "metadata": { + "api": { + "text": "Metadatele API nu au putut fi încărcate, vă rugăm să vă verificați conexiunea la internet.", + "title": "Nu s-a putut incărca API metadata" + }, + "dmca": { + "badge": "Șters", + "text": "Această medie nu mai este valabilă din vina copyright-ului.", + "title": "Media a fost ștearsă" + }, + "extensionPermission": { + "badge": "Permisune pierdută", + "button": "Folosește extensia", + "text": "Tu ai extensia, dar noi avem nevoie de permisiune ca să începem să folosim extensia.", + "title": "Configurează extensia" + }, + "failed": { + "badge": "Eșuat", + "homeButton": "Du-te acasă :)", + "text": "Nu s-au putut încărca metadatele media din TMDB. Vă rugăm să verificați dacă TMDB este oprit sau blocat pe conexiunea ta. la internet.", + "title": "Nu s-au încărcat metadatele" + }, + "notFound": { + "badge": "Nu a fost găsit", + "homeButton": "Înapoi acasă :)", + "text": "Nu am putut găsi media pe care ați cerut-o. Poate este ștearsă sau ați manipulat adresa URL.", + "title": "Nu am putut găsi acel media." + } + }, + "nextEpisode": { + "cancel": "Anulare", + "next": "Episodul următor" + }, + "playbackError": { + "badge": "Eroare la redare", + "errors": { + "errorAborted": "Preluarea media a fost întreruptă la cererea utilizatorului.", + "errorDecode": "În ciuda faptului că anterior a fost determinată a fi utilizabilă, a apărut o eroare în timpul încercării de a decoda resursa media, rezultând o eroare.", + "errorGenericMedia": "Eroare media cumva sa întâmplat.", + "errorNetwork": "A apărut o eroare de rețea care a împiedicat preluarea cu succes a suportului media, în ciuda faptului că fusese disponibil anterior.", + "errorNotSupported": "Obiectul media sau furnizorul media nu este acceptat." + }, + "homeButton": "Du-te acasă :)", + "text": "A apărut o eroare la încercarea de a reda media. Vă rugăm să încercați din nou.", + "title": "O eroare la redarea videoului!" + }, + "scraping": { + "items": { + "failure": "Sa întâmplat o eraore", + "notFound": "Nu are acel video", + "pending": "Verificând pentru videouri..." + }, + "notFound": { + "badge": "Nu a fost găsit", + "detailsButton": "Arată detalii", + "homeButton": "Du-te acasă", + "text": "Am căutat prin furnizorii noștri și nu putem găsi media pe care o căutați! Nu găzduim mass-media și nu avem control asupra a ceea ce este disponibil. Vă rugăm să faceți clic pe „Afișați detalii” de mai jos pentru mai multe detalii.", + "title": "Nu am putut găsi aia" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} rămas • Se termină la{{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Vă rog să vă verificați umanitatea completând acest captcha in partea dreapta. Asta este pentru a pastra SkoolTV sigur!", + "error": "Verificarea umanității tale a eșuat. Încercați din nou.", + "title": "Noi trebuie să verificăm dacă sunteți un om.", + "verifyingHumanity": "Verificați-vă umanitatea voastră..." + } + }, + "screens": { + "dmca": { + "text": "Bun venit pe pagina de contact DMCA a SkoolTV! Respectăm drepturile de proprietate intelectuală și dorim să abordăm rapid orice problemă privind drepturile de autor. Dacă credeți că lucrarea dumneavoastră protejată prin drepturi de autor a fost utilizată necorespunzător pe platforma noastră, vă rugăm să trimiteți o notificare detaliată DMCA la e-mailul de mai jos. Vă rugăm să includeți o descriere a materialului protejat prin drepturi de autor, detaliile dvs. de contact și o declarație de bună credință. Ne angajăm să rezolvăm aceste probleme cu promptitudine și apreciem cooperarea dumneavoastră pentru a menține SkoolTV un loc care respectă creativitatea și drepturile de autor.", + "title": "DMCA" + }, + "loadingApp": "Se încarcă aplicația", + "loadingUser": "Se încarcă profilul tău", + "loadingUserError": { + "logout": "Deconectare", + "reset": "Resetare servere personalizate", + "text": "Nu s-a încărcat profilul dvs", + "textWithReset": "Nu s-a încărcat profilul dvs. de pe serverul personalizat, doriți să reveniți la serverul implicit?" + }, + "migration": { + "failed": "Eroare la migrarea datelor voastre.", + "inProgress": "Vă rugăm să așteptați, migrăm datele dvs. Acest lucru nu ar trebui să dureze mult." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Numele dispozitivului", + "deviceNamePlaceholder": "Telefonul personal", + "editProfile": "Editează", + "logoutButton": "Deconectați-vă" + }, + "actions": { + "delete": { + "button": "Șterge contul", + "confirmButton": "Șterge contul", + "confirmDescription": "Ești sigur că vrei să ștergi contul tău? Toate datele tale vor dispărea!", + "confirmTitle": "Ești sigur?", + "text": "Acțiunea asta este ireversibilă. Toate datele tale vor dispărea și nimic nu va putea fi recuperat.", + "title": "Șterge contul" + }, + "title": "Acțiuni" + }, + "devices": { + "deviceNameLabel": "Numele dispozitivului", + "failed": "Eroare la încărcarea sesiunii", + "removeDevice": "Șterge", + "title": "Dispozitive" + }, + "profile": { + "finish": "Termină editarea", + "firstColor": "Culoarea profilului unu", + "secondColor": "Culoare profilului doi", + "title": "Editează poza de profil", + "userIcon": "Iconița utilizatorului" + }, + "register": { + "cta": "Începeți", + "text": "Partajați progresul vizionării între dispozitive și păstrați-le sincronizate.", + "title": "Sincronizare în sudo-cloud" + }, + "title": "Cont" + }, + "appearance": { + "activeTheme": "Activ", + "themes": { + "blue": "Albastru", + "default": "Implicit", + "gray": "Gri", + "red": "Roșu", + "teal": "Albastru verziu" + }, + "title": "Aparență" + }, + "connections": { + "server": { + "description": "Dacă doriți să vă conectați la un backend personalizat pentru a vă stoca datele, activați acest lucru și furnizați adresa URL. <0>Instrucțiuni.", + "label": "Server personalizat", + "urlLabel": "Adresa URL personalizată a serverului" + }, + "setup": { + "doSetup": "Configurează", + "errorStatus": { + "description": "Se pare că unul sau mai multe obiecte din această configurație au nevoie de atenția ta.", + "title": "Ceva are nevoie de atenția ta" + }, + "itemError": "Ceva nu e bine cu această setare. Parcurge configurația din nou pentru a o corecta.", + "items": { + "default": "Configurație implicită", + "extension": "Extensie", + "proxy": "Proxy personalizat" + }, + "redoSetup": "Refă configurația", + "successStatus": { + "description": "Toate sunt la locul lor ca să începeți să urmariți conținutul preferat.", + "title": "Totul este pregătit!" + }, + "unsetStatus": { + "description": "Apăsați butonul din dreapta pentru a începe procesul de configurare.", + "title": "Nu ați parcurs configurația" + } + }, + "title": "Conexiuni", + "workers": { + "addButton": "Adaugă un nou muncitor", + "description": "Pentru ca aplicația să funcționeze, tot traficul este direcționat prin proxy. Activați acest lucru dacă doriți să vă aduceți proprii lucrători. <0>Instrucțiuni.", + "emptyState": "Niciun muncitor incă, adaugă unu", + "label": "Utilizați lucrători proxy personalizați", + "urlLabel": "Adresele URL ale lucrătorilor", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Limba aplicației", + "languageDescription": "Limba aplicată întregii aplicații.", + "thumbnail": "Generați pictograme", + "thumbnailDescription": "De cele mai multe ori videoclipurile nu au pictograme. Puteți activa această setare pentru a le genera din mers, dar vă pot încetini videoclipul.", + "thumbnailLabel": "Generați pictograme", + "title": "Preferințe" + }, + "reset": "Resetare", + "save": "Salvează", + "sidebar": { + "info": { + "appVersion": "Versiunea aplicației", + "backendUrl": "URL de backend", + "backendVersion": "Versiunea backend", + "hostname": "Numele gazdei", + "insecure": "Nesigur", + "notLoggedIn": "Nu sunteți autentificat", + "secure": "Securizat", + "title": "Informația aplicației", + "unknownVersion": "Necunoscut", + "userId": "ID-ul utilizatorului" + } + }, + "subtitles": { + "backgroundBlurLabel": "Blurarea fundalului", + "backgroundLabel": "Opacitatea fundalului", + "colorLabel": "Culoare", + "previewQuote": "nu trebuie să mă tem. Frica este ucigașul minții.", + "textSizeLabel": "Dimensiunea textului", + "title": "Subtitluri" + }, + "unsaved": "Aveți modificări nesalvate" + } +} diff --git a/src/assets/locales/ru.json b/src/assets/locales/ru.json new file mode 100644 index 0000000..a2ad596 --- /dev/null +++ b/src/assets/locales/ru.json @@ -0,0 +1,630 @@ +{ + "about": { + "description": "SkoolTV — это веб-приложение, которое ищет в интернете видеопотоки. Наша команда стремится к минималистичному подходу к просмотру контента.", + "faqTitle": "Часто Задаваемые Вопросы", + "q1": { + "body": "SkoolTV не размещает у себя никакой контент. Когда вы выбираете что-то посмотреть, в интернете происходит поиск выбранного медиафайла (на экране загрузки и во вкладке \"Источники для видео\" вы можете увидеть, какой источник вы используете). Медиафайлы никогда не загружаются на SkoolTV, все происходит через этот механизм поиска.", + "title": "Откуда берется контент?" + }, + "q2": { + "body": "Невозможно запросить сериал или фильм, не владеет никаким контентом. SkoolTV не владеет контентом, наше приложение лишь находит и показывает контент который уже свободно доступен в сети.", + "title": "Как и где запросить сериал или фильм?" + }, + "q3": { + "body": "Наши результаты поиска основаны на базе данных The Movie Database (TMDB) и отображаются вне зависимости от того, есть ли в наших источниках соответствующий контент.", + "title": "В результатах поиска отображается сериал или фильм, но почему я не могу воспроизвести их?" + }, + "title": "О сайте SkoolTV", + "q5": { + "body": "У SkoolTV есть аккаунт в Twitter, ссылку на который вы найдете внизу этой страницы, а также ссылку на исходный код на Github.", + "title": "Где я могу узнать больше о проекте?" + }, + "q4": { + "body": "Все данные синхронизируются с сервером SkoolTV (sudo-backend), который отличается от общедоступного сервера и независимо размещается мной. Им может пользоваться любой желающий.", + "title": "Что насчет моих данных и прочего?" + } + }, + "actions": { + "copied": "Скопировано", + "copy": "Скопировать" + }, + "auth": { + "createAccount": "Нет аккаунта?😬\n<0>Создать аккаунт", + "deviceNameLabel": "Имя устройства", + "deviceNamePlaceholder": "Личный телефон", + "generate": { + "description": "Ваша кодовая фраза служит вашим именем пользователя и паролем. Храните ее в надёжном месте, поскольку она понадобится вам для входа в аккаунт\nНе теряйте свой пароль-фразу!", + "next": "Я сохранил свою кодовую фразу", + "passphraseFrameLabel": "Кодовая фраза", + "title": "Ваша кодовая фраза" + }, + "hasAccount": "Уже есть аккаунт? <0>Вам сюда.", + "login": { + "description": "Введите кодовую фразу для входа в учётную запись", + "deviceLengthError": "Введите имя устройства", + "passphraseLabel": "Кодовая фраза из 12 слов", + "passphrasePlaceholder": "Кодовая фраза", + "submit": "Войти", + "title": "Войдите в аккаунт", + "validationError": "Неправильная или неполная кодовая фраза" + }, + "register": { + "information": { + "color1": "Цвет профиля #1", + "color2": "Цвет профиля #2", + "header": "Введите название устройства, выберите цвета и значок профиля по своему усмотрению!", + "icon": "Аватарка", + "next": "Далее", + "title": "Информация об аккаунте" + } + }, + "trust": { + "failed": { + "text": "Правильно ли вы настроили его?", + "title": "Не удалось установить связь с сервером" + }, + "host": "Вы подключаетесь к <0>{{hostname}} - пожалуйста, подтвердите, что вы доверяете ему, прежде чем создавать аккаунт", + "no": "Назад", + "noHost": "Сервер не был настроен, поэтому вы не можете создать учётную запись", + "noHostTitle": "Сервер не настроен!", + "title": "Вы доверяете этому серверу?", + "yes": "Я доверяю этому серверу🤞" + }, + "verify": { + "description": "Введите ранее полученную кодовую фразу, чтобы подтвердить, что вы её сохранили, и создать учётную запись", + "invalidData": "Данные недействительны", + "noMatch": "Кодовая фраза неверна 😭", + "passphraseLabel": "Ваша кодовая фраза из 12 слов", + "recaptchaFailed": "Проверка ReCaptcha не удалась", + "register": "Создать аккаунт", + "title": "Подтвердите кодовую фразу" + } + }, + "errors": { + "badge": "Оно сломалось💀", + "details": "Сведения об ошибке", + "reloadPage": "Перезагрузите страницу", + "showError": "Показать сведения об ошибке", + "title": "У нас произошла ошибка!" + }, + "footer": { + "legal": { + "disclaimer": "Отказ от ответственности ◝(ᵔᵕᵔ)◜", + "disclaimerText": "SkoolTV не хранит файлы, а предоставляет только ссылки на контент сторонних источников. Все юридические вопросы следует направлять непосредственно к владельцам этих ресурсов. SkoolTV не несет ответственности за содержание медиафайлов." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub", + "twitter": "Twitter" + }, + "tagline": "Смотрите свои любимые сериалы и фильмы бесплатно и без рекламы! (っ'ヮ'c)" + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "О проекте", + "dmca": "DMCA", + "login": "Войти", + "onboarding": "Настройка", + "pagetitle": "{{title}} - SkoolTV", + "register": "Регистрация", + "settings": "Настройки", + "discover": "Подборки", + "support": "Поддержка" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Закладки" + }, + "continueWatching": { + "sectionTitle": "Продолжить просмотр" + }, + "mediaList": { + "stopEditing": "Завершить редактирование" + }, + "search": { + "allResults": "Это всё, что у нас есть!", + "failed": "Не удалось найти медиафайл, попробуйте снова!", + "loading": "Загрузка...", + "noResults": "Мы ничего не нашли! :(", + "placeholder": { + "default": "Что вы хотите посмотреть?", + "extra": [ + "Что будем смотреть сегодня?", + "Нам нужно подчистить вашу историю браузера?", + "Какой ваш любимый фильм?", + "Какой ваш любимый сериал?", + "Что в списке на сегодня?", + "Как у вас прошел день?", + "Мой сайт отказывается работать 😢.", + "SkoolTV просто супер, не правда ли?", + ">ᴗ<" + ] + }, + "sectionTitle": "Результаты поиска", + "empty": { + "default": "Привет, здесь тебя ждут лучшие фильмы и сериалы!", + "extra": [ + "Тут ничего нет :(", + "Так пусто...", + "Только пустота.", + "Приветик, новичок :3" + ] + }, + "discoverMore": "Исследуй новое", + "discover": "Исследуй новые горизонты" + }, + "titles": { + "day": { + "default": "Что бы вы хотели посмотреть в этот прекрасный день?", + "extra": [ + "Любите приключения? «Парк Юрского периода» прекрасно подойдет вам." + ] + }, + "morning": { + "default": "Что бы вы хотели посмотреть этим утром?", + "extra": [ + "Слышали, что «Перед рассветом» – отличный фильм" + ] + }, + "night": { + "default": "Что бы вы хотели посмотреть этим вечером?", + "extra": [ + "Тяжелый день? Можем посоветовать вам фильм \"Изгоняющий дьявола\"." + ] + }, + "420": { + "default": "20/4 - день веселья и травки! Что посмотрим?", + "extra": [ + "С праздником 20/4! 🥳 Празднуем вместе!" + ] + } + } + }, + "media": { + "episodeDisplay": "Сезон {{season}}, Эпизод {{episode}}", + "types": { + "movie": "Фильм", + "show": "Сериал" + }, + "unreleased": "Ожидается" + }, + "navigation": { + "banner": { + "offline": "Проверьте подключение к Интернету" + }, + "menu": { + "about": "О нас", + "logout": "Выйти", + "register": "Авторизация", + "settings": "Настройки", + "support": "Поддержка", + "discover": "Подборки" + } + }, + "notFound": { + "badge": "Не найдено", + "goHome": "Вернуться на главную", + "message": "Мы искали везде: в мусорных баках, в шкафу, но так и не нашли нужную вам страницу. (ಥ﹏ಥ)", + "title": "Не удалось найти эту страницу", + "reloadButton": "Попробуйте ещё раз" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Отмена", + "confirm": "Использовать настройки по умолчанию", + "description": "Стандартная настройка имеет не самые лучшие показатели передачи видео и может быть невыносимо медленной. ( ͠° ͟ʖ ͡°)", + "title": "Вы уверены?" + }, + "extension": { + "back": "Вернуться назад", + "explainer": "Используя расширение для браузера, вы сможете получать лучшие источники, которые мы можем предложить. Просто установите расширение.", + "explainerIos": "К сожалению, расширение для браузера не поддерживается на iOS, нажмите Назад, чтобы выбрать другой вариант.", + "extensionHelp": "Если вы установили расширение, но оно не обнаруживается, откройте его через меню расширений браузера и следуйте инструкциям на экране.", + "linkChrome": "Установить расширение Chrome", + "linkFirefox": "Установите расширение Firefox", + "notDetecting": "Установили расширение, но сайт не обнаруживает его? Попробуйте перезагрузить страницу!", + "notDetectingAction": "Перезагрузить страницу", + "status": { + "disallowed": "Расширение не включено для этой страницы", + "disallowedAction": "Включить расширение", + "failed": "Не удалось запросить статус", + "loading": "Ждём, пока вы установите расширение", + "outdated": "Расширение устарело", + "success": "Расширение работает, как и ожидалось!" + }, + "submit": "Продолжить", + "title": "Давайте начнём с расширения" + }, + "proxy": { + "back": "Назад", + "explainer": "С помощью метода прокси вы можете получать потоки отличного качества, создавая прокси-сервер самостоятельно.", + "input": { + "errorConnection": "Не удалось подключиться к прокси-серверу", + "errorInvalidUrl": "Недействительный URL", + "errorNotProxy": "Ожидался прокси, а был получен веб-сайт", + "label": "URL-адрес прокси-сервера", + "placeholder": "https://" + }, + "link": "Узнайте, как сделать прокси", + "submit": "Отправить прокси", + "title": "Давайте создадим новый прокси-сервер" + }, + "start": { + "explainer": "Чтобы получить наилучшие потоки, вам нужно выбрать, какой метод потоковой передачи вы хотите использовать.", + "options": { + "default": { + "text": "Мне не нужны трансляции хорошего качества,<0 /> <1>использовать настройки по умолчанию" + }, + "extension": { + "action": "Установить расширение", + "description": "Установите расширение для браузера и получите доступ к лучшим источникам.", + "quality": "Лучшее качество", + "title": "Расширение для браузера" + }, + "proxy": { + "action": "Настроить прокси", + "description": "Настройте прокси всего за 5 минут и получите доступ к отличным источникам.", + "quality": "Хорошее качество", + "title": "Пользовательский прокси-сервер" + } + }, + "title": "Давайте настроим SkoolTV" + } + }, + "overlays": { + "close": "Закрыть" + }, + "player": { + "back": { + "default": "Вернуться на главную", + "short": "Назад" + }, + "casting": { + "enabled": "Транслируем на устройство…" + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Скопировать ссылку на плейлист HLS", + "disclaimer": "Загрузки осуществляются непосредственно поставщиком. SkoolTV не контролирует способ предоставления загрузок.", + "downloadSubtitle": "Скачать текущие субтитры", + "downloadVideo": "Скачать видео", + "hlsDisclaimer": "Загрузки осуществляются непосредственно поставщиком. SkoolTV не контролирует способ предоставления загрузок.

Обратите внимание на то, что вы скачиваете плейлист HLS, его не рекомендуется скачивать, если вы не знакомы с продвинутыми форматами потокового воспроизведения. Попробуйте разные источники для разных форматов.", + "onAndroid": { + "1": "Чтобы скачать на Android, нажмите на кнопку загрузки, затем на новой странице нажмите и удерживайте на видео, а затем выберите сохранить.", + "shortTitle": "Скачать / Android", + "title": "Загрузка на Android" + }, + "onIos": { + "1": "Чтобы загрузить на iOS, нажмите кнопку загрузки, затем на новой странице нажмите , затем Сохранить в Файлы .", + "shortTitle": "Скачать / iOS", + "title": "Загрузка на iOS" + }, + "onPc": { + "1": "На компьютере нажмите кнопку загрузки, затем на новой странице щелкните по видео правой кнопкой мыши и выберите Сохранить видео как", + "shortTitle": "Скачать / ПК", + "title": "Загрузка на ПК" + }, + "title": "Скачать" + }, + "episodes": { + "button": "Эпизоды", + "emptyState": "В этом сезоне нет эпизодов, загляните позже!", + "episodeBadge": "ЭП{{episode}}", + "loadingError": "Ошибка при загрузке сезона", + "loadingList": "Загрузка...", + "loadingTitle": "Загрузка...", + "unairedEpisodes": "Один или несколько эпизодов этого сезона были отключены, потому что еще не вышли в эфир.", + "seasons": "Сезоны" + }, + "playback": { + "speedLabel": "Скорость воспроизведения", + "title": "Настройки воспроизведения" + }, + "quality": { + "automaticLabel": "Автоопределение качества", + "hint": "Вы можете попробовать <0>переключиться на другой источник, чтобы получить различные варианты качества.", + "iosNoQuality": "Из-за ограничений, установленных Apple, выбор качества для этого источника недоступен на iOS. Вы можете попробовать <0>переключиться на другой источник, чтобы получить различные варианты качества.", + "title": "Качество" + }, + "settings": { + "audioItem": "Аудио", + "downloadItem": "Скачать", + "enableSubtitles": "Включить субтитры", + "experienceSection": "Впечатления от просмотра", + "playbackItem": "Настройки воспроизведения", + "qualityItem": "Качество", + "sourceItem": "Видео источники", + "subtitleItem": "Настройки субтитров", + "videoSection": "Настройки видео" + }, + "sources": { + "failed": { + "text": "При попытке найти видео произошла ошибка, пожалуйста, попробуйте использовать другой источник.", + "title": "Не удалось получить данные" + }, + "noEmbeds": { + "text": "Мы не смогли найти ни одного вложения, пожалуйста, попробуйте использовать другой источник.", + "title": "Не найдено ни одного вложения" + }, + "noStream": { + "text": "В этом источнике нет видеопотоков для этого фильма или сериала.", + "title": "Нет видеопотока" + }, + "title": "Источники", + "unknownOption": "Неизвестный" + }, + "subtitles": { + "customChoice": "Перетащите файл или нажмите для загрузки", + "customizeLabel": "Настроить", + "dropSubtitleFile": "Перетащите файл субтитров", + "offChoice": "Выключить", + "settings": { + "backlink": "Пользовательские субтитры", + "delay": "Задержка субтитров", + "fixCapitals": "Исправить капитализацию букв" + }, + "title": "Субтитры", + "unknownLanguage": "Неизвестный", + "OpenSubtitlesChoice": "ОткрытыеСубтитры (OpenSubtitles)", + "empty": "Субтитры недоступны для этого контента.", + "scrapeButton": "Найти субтитры" + } + }, + "metadata": { + "api": { + "text": "Не удалось загрузить метаданные API, проверьте подключение к Интернету.", + "title": "Не удалось загрузить метаданные API" + }, + "dmca": { + "badge": "Удалено", + "text": "Этот контент больше не доступен из-за уведомления об удалении или претензий по авторскому праву.", + "title": "Контент был удалён" + }, + "extensionPermission": { + "badge": "Разрешение отсутствует", + "button": "Используйте расширение", + "text": "У вас есть расширение для браузера, но нам нужно ваше разрешение, чтобы начать его использовать.", + "title": "Настройте расширение" + }, + "failed": { + "badge": "Не удалось", + "homeButton": "Вернуться на главную", + "text": "Не удалось загрузить метаданные медиафайла из TMDB. Проверьте, не отключен ли или не заблокирован TMDB на вашем интернет-соединении.", + "title": "Не удалось загрузить метаданные" + }, + "notFound": { + "badge": "Не найдено", + "homeButton": "Вернуться на главную", + "text": "Нам не удалось найти запрошенный вами медиафайл. Либо он был удален, либо вы ввели неверный URL-адрес.", + "title": "Не удалось найти контент." + } + }, + "nextEpisode": { + "cancel": "Отмена", + "next": "Следующий эпизод", + "replay": "Повтор", + "nextSeason": "Следующий сезон" + }, + "playbackError": { + "badge": "Ошибка воспроизведения", + "errors": { + "errorAborted": "Получение медиафайла было прервано по запросу пользователя.", + "errorDecode": "Несмотря на то, что ранее этот медиаресурс был пригодным для использования, при попытке его декодирования произошла ошибка.", + "errorGenericMedia": "Возникла неизвестная ошибка медиафайла.", + "errorNetwork": "Произошла какая-то сетевая ошибка, которая не позволила успешно извлечь медиафайл, хотя ранее он был доступен.", + "errorNotSupported": "Медиафайл или его источник не поддерживается." + }, + "homeButton": "Вернуться на главную", + "text": "При попытке воспроизвести медиа файл произошла ошибка. Пожалуйста, попробуйте ещё раз.", + "title": "Не удалось воспроизвести видео!" + }, + "scraping": { + "extensionFailure": { + "badge": "Расширение отключено", + "enableExtension": "Включить расширение", + "homeButton": "Вернуться на главную", + "text": "Вы установили расширение SkoolTV. Чтобы начать его использовать, необходимо включить расширение для этого сайта.", + "title": "Пожалуйста, включите расширение" + }, + "items": { + "failure": "Возникла ошибка", + "notFound": "Такого видео нет", + "pending": "Ищем видео..." + }, + "notFound": { + "badge": "Не найдено", + "detailsButton": "Показать сведения", + "homeButton": "Вернуться на главную", + "text": "Мы проверили наших поставщиков и не смогли найти нужные вам медиа! Мы не размещаем медиа и не контролируем их наличие. Пожалуйста, нажмите кнопку \"Показать сведения\" ниже, чтобы получить более подробную информацию.", + "title": "Мы не смогли ничего найти", + "discoverButton": "Найти еще" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} осталось - Завершится в {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Пожалуйста, подтвердите, что вы человек, заполнив форму Captcha справа. Это необходимо для обеспечения безопасности SkoolTV!", + "error": "Не удалось убедиться в том, что вы человек. Пожалуйста, попробуйте еще раз.", + "title": "Мы должны убедиться, что вы человек.", + "verifyingHumanity": "Убеждаемся в том, что вы человек..." + } + }, + "screens": { + "dmca": { + "text": "Добро пожаловать на контактную страницу SkoolTV по защите от DMCA! Мы уважаем права на интеллектуальную собственность и хотим оперативно решать любые проблемы, связанные с авторским правом. Если вы считаете, что ваш материал, защищенный авторским правом, был неправомерно использован на нашей платформе, отправьте подробное уведомление DMCA на указанный ниже адрес электронной почты. Пожалуйста, включите в него описание материала, защищенного авторским правом, ваши контактные данные и заявление о добросовестности ваших намерений. Мы стремимся оперативно решать подобные вопросы и ценим ваше сотрудничество, что позволяет SkoolTV оставаться местом, где уважается творчество и авторское право.", + "title": "DMCA" + }, + "loadingApp": "Загрузка приложения", + "loadingUser": "Загрузка вашего профиля", + "loadingUserError": { + "logout": "Выйти", + "reset": "Сбросить пользовательский сервер", + "text": "Не удалось загрузить ваш профиль", + "textWithReset": "Не удалось загрузить профиль с пользовательского сервера, хотите вернуться на сервер по умолчанию?", + "reload": "Перезагрузить" + }, + "migration": { + "failed": "Не удалось перенести данные.", + "inProgress": "Пожалуйста, подождите, мы переносим ваши данные. Это не займет много времени." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Имя устройства", + "deviceNamePlaceholder": "Личный телефон", + "editProfile": "Редактировать", + "logoutButton": "Выйти" + }, + "actions": { + "delete": { + "button": "Удалить аккаунт", + "confirmButton": "Удалить аккаунт", + "confirmDescription": "Вы уверены, что хотите удалить свою учётную запись? Все ваши данные будут потеряны!", + "confirmTitle": "Вы уверены?", + "text": "Это действие необратимо. Все данные будут удалены, и восстановить их будет невозможно.", + "title": "Удалить аккаунт" + }, + "title": "Действия" + }, + "devices": { + "deviceNameLabel": "Имя устройства", + "failed": "Не удалось загрузить сеансы", + "removeDevice": "Удалить", + "title": "Устройства" + }, + "profile": { + "finish": "Завершить редактирование", + "firstColor": "Первый цвет профиля", + "secondColor": "Второй цвет профиля", + "title": "Редактирование изображения профиля", + "userIcon": "Значок аватара профиля" + }, + "register": { + "cta": "Начать", + "text": "Обменивайтесь информацией о прогрессе часов между устройствами и синхронизируйте их.", + "title": "Синхронизировать с облаком" + }, + "title": "Аккаунт", + "admin": { + "text": "Используйте инструменты, предназначенные для проверки состояния SkoolTV.", + "title": "Консоль Администратора", + "button": "Попробовать" + } + }, + "appearance": { + "activeTheme": "Активная", + "themes": { + "blue": "Cиняя", + "default": "По умолчанию", + "gray": "Серая", + "red": "Красная", + "teal": "Бирюзовая" + }, + "title": "Внешний вид" + }, + "connections": { + "server": { + "description": "Если вы хотите подключиться к пользовательскому серверу для хранения данных, включите эту опцию и укажите URL. <0>Инструкции.", + "label": "Пользовательский сервер", + "urlLabel": "URL-адрес пользовательского сервера" + }, + "setup": { + "doSetup": "Настроить", + "errorStatus": { + "description": "Похоже, что один или несколько элементов в этой настройке требуют вашего внимания.", + "title": "Кое-что требует вашего внимания" + }, + "itemError": "Что-то не так с этой опцией. Выполните настройку ещё раз, чтобы исправить проблему.", + "items": { + "default": "Настройка по умолчанию", + "extension": "Расширение", + "proxy": "Пользовательский прокси-сервер" + }, + "redoSetup": "Повторная настройка", + "successStatus": { + "description": "Всё готово для того, чтобы вы могли начать смотреть свои любимые фильмы и сериалы.", + "title": "Всё готово!" + }, + "unsetStatus": { + "description": "Нажмите кнопку справа, чтобы начать процесс настройки.", + "title": "Вы ещё не прошли процедуру настройки" + } + }, + "title": "Соединения", + "workers": { + "addButton": "Добавить новый прокси-сервер", + "description": "Для работы приложения весь трафик маршрутизируется через прокси. Включите это, если вы хотите использовать свои собственных прокси-серверы.<0>Instructions.", + "emptyState": "Прокси отсутствуют, добавьте их ниже", + "label": "Использовать прокси-сервера", + "urlLabel": "URL-адреса", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Язык приложения", + "languageDescription": "Язык применяется ко всему приложению.", + "thumbnail": "Генерировать миниатюры", + "thumbnailDescription": "В большинстве случаев видео не имеют миниатюр. Вы можете включить этот параметр, чтобы генерировать их на лету, но они могут замедлить ваше видео.", + "thumbnailLabel": "Генерировать миниатюры", + "title": "Настройки", + "sourceOrderDescription": "Перетащите, чтобы изменить порядок источников. Это определит порядок проверки источников для фильмов/сериалов , которые вы пытаетесь смотреть. Если источник выделен серым цветом, это означает, что он недоступен на вашем устройстве.", + "autoplay": "Автовоспроизведение", + "autoplayDescription": "Автоматически начать следующую серию. Может быть включен пользователями с расширением браузера, пользовательским прокси-сервером или с настройкой по умолчанию, если это разрешено хостом.", + "autoplayLabel": "Автовоспроизведение", + "sourceOrder": "Изменение порядка источников" + }, + "reset": "Сброс", + "save": "Сохранить", + "sidebar": { + "info": { + "appVersion": "Версия приложения", + "backendUrl": "Внутренний URL", + "backendVersion": "Серверная версия", + "hostname": "Имя хоста", + "insecure": "Небезопасно", + "notLoggedIn": "Вы не авторизованы", + "secure": "Безопасный", + "title": "Информация о приложении", + "unknownVersion": "Неизвестный", + "userId": "ID пользователя" + } + }, + "subtitles": { + "backgroundBlurLabel": "Размытие фона", + "backgroundLabel": "Прозрачность фона", + "colorLabel": "Цвет", + "previewQuote": "Я не должен бояться. Страх убивает разум.", + "textSizeLabel": "Размер текста", + "title": "Субтитры", + "textBoldLabel": "Жирный текст" + }, + "unsaved": "У вас есть несохраненные изменения" + }, + "downtimeNotice": { + "message": "SkoolTV.lol испытывает проблемы с некоторыми провайдерами. Если вы не можете найти или воспроизвести шоу, измените источник. Ожидайте, что эта ошибка сохранится в течение указанного ниже времени.", + "badge": "Проблемы", + "goHome": "Вернуться на главную.", + "title": "Проблемы с провайдером", + "timeFrame": "31 марта, с 23:00 до 5:00 по EST" + }, + "support": { + "title": "Поддержка", + "q2": { + "body": "У нас есть <0>GitHub, где вы можете создать запрос на исправление проблемы (\"Issue\") и оставить подробную информацию о проблеме в нашем репозитории. Кроме того, если хотите, вы можете создать Pull Request, чтобы устранить проблему самостоятельно.", + "title": "Куда я могу сообщить о проблеме?" + }, + "text": "SkoolTV создан максимально удобным для пользователя. Однако у людей по-прежнему остаются вопросы и проблемы. Эта страница создана, чтобы помочь устранить эти недостатки.", + "q1": { + "body": "Ну, вы можете присоединиться к официальному Дискорду <0>SkoolTV и задавать там вопросы или отправить электронное письмо по адресу, указанному внизу этой страницы.", + "title": "Как я могу помочь?" + } + } +} diff --git a/src/assets/locales/sl.json b/src/assets/locales/sl.json new file mode 100644 index 0000000..c43964f --- /dev/null +++ b/src/assets/locales/sl.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "SkoolTV je spletna aplikacija, ki omogoča enostavno iskanje filmov in serij. Ekipa si prizadeva za minimalističen pristop pri ogledu vsebin.", + "faqTitle": "Pogosto zastavljena vprašanja", + "q1": { + "body": "SkoolTV ne hrani nobene vsebine. Ko si želite film ali serijo ogledati, se izvede iskanje vsebine na internetu (na zaslonu za nalaganje in v zavihku \"viri videa\" lahko vidite, kateri vir uporabljate). Vsebina medija se nikoli ne naloži na strežnike SkoolTVa, ker vse poteka iskalnega mehanizma.", + "title": "Od kod prihaja vsebina?" + }, + "q2": { + "body": "Serije in filmov ni mogoče zahtevati, ker SkoolTV ne upravlja z nobeno vsebino. Vse vsebine si lahko ogledate prek virov na internetu.", + "title": "Kje lahko oddam predlog za serijo ali film?" + }, + "q3": { + "body": "Rezultati iskanja so privzeti iz podatkovne baze \"The Movie Database\" (TMDB) in se prikazujejo ne glede na to, ali je vsebina dejansko na voljo.", + "title": "Rezultati iskanja prikazujejo serijo oz. film, zakaj ga potem ne morem predvajati?" + }, + "title": "O SkoolTVbu" + }, + "actions": { + "copied": "Kopirano", + "copy": "Kopiraj" + }, + "auth": { + "createAccount": "Še nimate računa? <0>Ustvari račun.", + "deviceNameLabel": "Ime naprave", + "deviceNamePlaceholder": "Mobilni telefon", + "generate": { + "description": "Vaša fraza deluje kot vaše uporabniško ime in geslo. Shranite ga na varnem mestu, saj ga boste morali vnesti za prijavo v svoj račun", + "next": "Frazo sem shranil na varno mesto", + "passphraseFrameLabel": "Varnostna fraza", + "title": "Varnostna Fraza" + }, + "hasAccount": "Že imate račun?<0>Prijavi se tukaj.", + "login": { + "description": "Vnesite frazo za prijavo v račun", + "deviceLengthError": "Vnesi ime naprave", + "passphraseLabel": "12-besedna varnostna fraza", + "passphrasePlaceholder": "Varnostna fraza", + "submit": "Prijava", + "title": "Prijava v račun", + "validationError": "Nepravilna ali nepopolna varnostna fraza" + }, + "register": { + "information": { + "color1": "Barva prvega profila", + "color2": "Barva drugega profila", + "header": "Vnesite ime za napravo ter izberi barvo in ikono uporabnika", + "icon": "Ikona uporabnika", + "next": "Naprej", + "title": "Informacije o profilu" + } + }, + "trust": { + "failed": { + "text": "Ali ste pravilno konfigurirali nastavitve?", + "title": "Neuspešen dostop do strežnika" + }, + "host": "Povezujete se z <0>{{hostname}} - pred ustvarjanjem računa potrdite, da mu zaupate", + "no": "Nazaj", + "noHost": "Strežnik ni nastavljen, zato ustvarjanje profila ni mogoče", + "noHostTitle": "Strežnik ni nastavljen!", + "title": "Ali zaupate temu strežniku?", + "yes": "Zaupam strežniku" + }, + "verify": { + "description": "Vnesite varnostno frazo, ki ste ga uporabili prej, da potrdite varno hrambo, in ustvarite svoj račun", + "invalidData": "Vnešeni podatki niso pravilni", + "noMatch": "Varnostna fraza se ne ujema", + "passphraseLabel": "Vaša 12-besedna varnostna fraza", + "recaptchaFailed": "Preizkus ReCaptcha ni uspel", + "register": "Ustvari Račun", + "title": "Potrdite varnostno frazo" + } + }, + "errors": { + "badge": "Nekaj se je pokvarilo", + "details": "Podatki o napaki", + "reloadPage": "Osveži stran", + "showError": "Pokaži informacije o napaki", + "title": "Prišlo je do napake!" + }, + "footer": { + "legal": { + "disclaimer": "Opozorilo", + "disclaimerText": "SkoolTV ne gosti nobenih medijev ali datotek, temveč le povezave do storitev tretjih oseb. Pravna vprašanja je potrebno posredovati gostiteljem in ponudnikom datotek. SkoolTV ni odgovoren za medijske datoteke, ki jih prikazujejo ponudniki." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Z odprtokodno aplikacijo SkoolTV si oglejte najljubše oddaje in filme." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "O projektu", + "dmca": "DMCA", + "login": "Prijava", + "onboarding": "Nastavitev", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registriraj se", + "settings": "Nastavitve" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Zaznamki" + }, + "continueWatching": { + "sectionTitle": "Nadaljuj z ogledom" + }, + "mediaList": { + "stopEditing": "Ustavite urejanje" + }, + "search": { + "allResults": "To je vse, kar imamo na voljo!", + "failed": "Ni uspelo najti medija, prosim poskusite znova!", + "loading": "Nalaganje...", + "noResults": "Vsebin nismo našli!", + "placeholder": { + "default": "Kaj si želite gledati?", + "extra": [ + "Kaj želiš raziskati danes?", + "Kateri fdilm/serijo si boš ogledal/a naslednje?", + "Kateri film ti je najljubši?", + "Katera je tvoja najljubša serija?" + ] + }, + "sectionTitle": "Rezultati iskanja" + }, + "titles": { + "day": { + "default": "Kateri film ali serijo bi si želeli ogledati ob tem popoldnevu?", + "extra": [ + "Se počutite pustolovsko? Jurski park je morda odlična izbira." + ] + }, + "morning": { + "default": "Kateri film ali serijo bi si želeli ogledati ob tem jutru?", + "extra": [ + "Slišala sem, da je film \"Pred sončnim vzhodom\" odličen" + ] + }, + "night": { + "default": "Kateri film ali serijo bi si želeli ogledati nocoj?", + "extra": [ + "Utrujeni? Slišal sem, da je \"Izganjalec mrtvih\" odličen film." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Serija" + }, + "unreleased": "Neizdano" + }, + "navigation": { + "banner": { + "offline": "Preverite vašo internetno povezavo" + }, + "menu": { + "about": "O nas", + "logout": "Odjava", + "register": "Sinhronizacija z oblakom", + "settings": "Nastavitve", + "support": "Podpora" + } + }, + "notFound": { + "badge": "Ni najdeno", + "goHome": "Nazaj domov", + "message": "Iskali smo povsod: pod preprogo, v omari, za \"proxyjem\", vendar na koncu nismo našli strani, ki jo iščete.", + "title": "Ni bilo mogoče najti te strani" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Prekliči", + "confirm": "Upoeabi privzete nastavitve", + "description": "Privzeta nastavitev nima najboljših pretokov in je lahko neznosno počasna.", + "title": "Si prepričan?" + }, + "extension": { + "back": "Nazaj", + "explainer": "Z razširitvijo brskalnika lahko dobite najboljše tokove, ki jih ponujamo. Namestitev je zelo preprosta!", + "explainerIos": "Na žalost razširitev brskalnika ni podprta v sistemu iOS, Pritisnite Najdi nazaj in izberite drugo možnost.", + "extensionHelp": "Če ste namestili razširitev, vendar ni zaznana, odprite razširitev v meniju razširitev brskalnika in sledite navodilom na zaslonu.", + "linkChrome": "Naloži Chrome razširitev", + "linkFirefox": "Naloži Firefox razširitev", + "notDetecting": "Nameščen v brskalniku Chrome, vendar ga spletno mesto ne zazna? Poskusite znova naložiti stran!", + "notDetectingAction": "Osveži stran", + "status": { + "disallowed": "Razširitev ni omogočena na tej strani", + "disallowedAction": "Omogoči razširitev", + "failed": "Ni uspelo zahtevati statusa", + "loading": "Čakamo, da namestite razširitev", + "outdated": "Verzija razširitve je prestara", + "success": "Razširitev deluje pravilno!" + }, + "submit": "Nadaljuj", + "title": "Začnimo z razširitvijo" + }, + "proxy": { + "back": "Nazaj", + "explainer": "Z metodo proxy lahko s samopostrežnim proxyjem pridobite zelo kakovostne prenose.", + "input": { + "errorConnection": "Povezava s proxyjem ni uspela", + "errorInvalidUrl": "Ni validen URL", + "errorNotProxy": "Pričakoval proxy, a dobil spletno stran", + "label": "URL proxyja", + "placeholder": "https://" + }, + "link": "Kako postavim proxy", + "submit": "Oddaj proxy", + "title": "Naredimo nov proxy" + }, + "start": { + "explainer": "Da bi dobili najboljše možne prenose, morate izbrati metodo pretakanja, ki jo želite uporabiti.", + "options": { + "default": { + "text": "Ne želim dobre kakovosti tokov,<0 /> <1>uporabite privzeto nastavitev" + }, + "extension": { + "action": "Naloži razširitev", + "description": "Namestite razširitev brskalnika in pridobite dostop do najboljših virov.", + "quality": "Najboljša kvaliteta", + "title": "Razširitev brskalnika" + }, + "proxy": { + "action": "Nastavi proxy", + "description": "V samo 5 minutah nastavite proxy in pridobite dostop do odličnih virov.", + "quality": "Dobra kvaliteta", + "title": "Proxy po meri" + } + }, + "title": "Pripravimo vas na namestitev s filmskim spletom" + } + }, + "overlays": { + "close": "Zapri" + }, + "player": { + "back": { + "default": "Nazaj domov", + "short": "Nazaj" + }, + "casting": { + "enabled": "Predvajanje vsebine v napravo..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Kopiranje povezave do seznama predvajanja HLS", + "disclaimer": "Prenosi se opravijo neposredno pri ponudniku vsebin. SkoolTV nima nadzora nad načinom zagotavljanja prenosov.", + "downloadSubtitle": "Prenesi trenutne podnapise", + "downloadVideo": "Prenesi video", + "hlsDisclaimer": "Prenosi se opravijo neposredno pri ponudniku vsebin. SkoolTV nima nadzora nad načinom zagotavljanja prenosov. Upoštevajte, da prenašate seznam predvajanja tipa \"HLS\" namenjen uporabnikom, ki poznajo napredno pretakanje večpredstavnostnih vsebin.", + "onAndroid": { + "1": "Če želite prenesti v sistemu Android, kliknite gumb za prenos, nato na novi strani tipnite in držite videoposnetek ter izberite shrani.", + "shortTitle": "Prenesi / Android", + "title": "Prenos v operacijskem sistemu Android" + }, + "onIos": { + "1": "Če želite prenesti v sistemu iOS, kliknite gumb za prenos, nato na novi strani kliknite in nato Shrani v datoteke .", + "shortTitle": "Prenesu / iOS", + "title": "Prenašanje v sistemu iOS" + }, + "onPc": { + "1": "V računalniku kliknite gumb za prenos, nato na novi strani desno kliknite videoposnetek in izberite Shrani videoposnetek kot", + "shortTitle": "Prenesi / Računalnik", + "title": "Prenos na računalnik" + }, + "title": "Prenos" + }, + "episodes": { + "button": "Epizode", + "emptyState": "V tej sezoni ni epizod, oglejte si jo pozneje!", + "episodeBadge": "E{{episode}}", + "loadingError": "Napaka pri nalaganju sezone", + "loadingList": "Nalaganje...", + "loadingTitle": "Nalaganje...", + "unairedEpisodes": "Ena ali več epizod v tej sezoni so onemogočene, ker še niso bile predvajane." + }, + "playback": { + "speedLabel": "Hitrost predvajanja", + "title": "Nastavitve predvajanja" + }, + "quality": { + "automaticLabel": "Avtomatska izbira kvalitete", + "hint": "Poskusite <0>preklop vira, da dobite različne možnosti kakovosti.", + "iosNoQuality": "Zaradi omejitev, ki jih je določil Apple, izbira kakovosti v sistemu iOS za ta vir ni na voljo. Poskusite <0>preklopiti na drug vir, da dobite različne možnosti kakovosti.", + "title": "Kvaliteta" + }, + "settings": { + "audioItem": "Zvok", + "downloadItem": "Prenesi", + "enableSubtitles": "Vklopi podnapise", + "experienceSection": "Izkušnje ogleda", + "playbackItem": "Nastavitve predvajanja", + "qualityItem": "Kvaliteta", + "sourceItem": "Viri vsebin", + "subtitleItem": "Nastavitve podnapisov", + "videoSection": "Nastavitve ogleda" + }, + "sources": { + "failed": { + "text": "Pri iskanju videoposnetkov je prišlo do napake, zato poskusite z drugim virom.", + "title": "Neuspešno iskanje" + }, + "noEmbeds": { + "text": "Nismo našli nobenih integriranih virov, poskusite z drugim virom.", + "title": "Ni bilo najdenih nobenih integriranih virov" + }, + "noStream": { + "text": "Ta vir nima tokov za ta film ali serijo.", + "title": "Ni vira" + }, + "title": "Viri", + "unknownOption": "Neznano" + }, + "subtitles": { + "customChoice": "Povleci in naloži datoteko", + "customizeLabel": "Prilagodi", + "dropSubtitleFile": "Povleci datoteko s podnapisi tukaj", + "offChoice": "Off", + "settings": { + "backlink": "Podnapisi po meri", + "delay": "Zamik podnapisov", + "fixCapitals": "Popravi velike začetnice" + }, + "title": "Podnapisi", + "unknownLanguage": "Neznano" + } + }, + "metadata": { + "api": { + "text": "Metapodatkov API ni bilo mogoče naložiti, preverite internetno povezavo.", + "title": "Ni uspelo naložiti metapodatkov API" + }, + "dmca": { + "badge": "Odstranjeno", + "text": "Ta medij ni več na voljo zaradi obvestila o odstranitvi ali zahtevka za avtorske pravice.", + "title": "Medij je bil odstranjen" + }, + "extensionPermission": { + "badge": "Neveljavne pravice dostopa", + "button": "Uporabi razširitev", + "text": "Imate razširitev brskalnika, vendar potrebujemo vaše dovoljenje, da lahko začnemo uporabljati razširitev.", + "title": "Nastavi razširitev brskalnika" + }, + "failed": { + "badge": "Neuspešno", + "homeButton": "Domov", + "text": "Metapodatkov medija ni bilo mogoče naložiti iz baze TMDB. Preverite, ali je TMDB na vaši internetni povezavi onemogočen ali blokiran.", + "title": "Ni uspelo naložiti metapodatkov" + }, + "notFound": { + "badge": "Ni najdeno", + "homeButton": "Nazaj domov", + "text": "Medija, ki ste ga zahtevali, nismo našli. Ali je bil odstranjen ali pa ste spremenili spletni naslov.", + "title": "Tega medija ni bilo mogoče najti." + } + }, + "nextEpisode": { + "cancel": "Prekliči", + "next": "Naslednja epizoda" + }, + "playbackError": { + "badge": "Napaka v predvajanju", + "errors": { + "errorAborted": "Uporabnikova zahteva je prekinila pridobivanje medija.", + "errorDecode": "Kljub temu, da je bilo predhodno ugotovljeno, da je medijski vir uporaben, je pri poskusu dekodiranja prišlo do napake.", + "errorGenericMedia": "Piršlo je do neznane napake na mediju.", + "errorNetwork": "Prišlo je do napake v omrežju, ki je preprečila uspešno pridobivanje medija, čeprav je bil prej na voljo.", + "errorNotSupported": "Objekt medija ali ponudnik medija ni podprt." + }, + "homeButton": "Domov", + "text": "Pri poskusu predvajanja medija je prišlo do napake. Poskusite znova.", + "title": "Ni uspelo predvajati videoposnetka!" + }, + "scraping": { + "extensionFailure": { + "badge": "Razširitev brskalnika je onemogočena", + "enableExtension": "Vklopi razširitev brskalnika", + "homeButton": "Pojdi domov", + "text": "Namestili ste razširitev SkoolTV. Če jo želite začeti uporabljati, morate razširitev omogočiti za to spletno mesto.", + "title": "Prosim vklopite razširitev brskalnika" + }, + "items": { + "failure": "Zgodila se je napaka", + "notFound": "Nima videoposnetka", + "pending": "Preverjanje videoposnetkov..." + }, + "notFound": { + "badge": "Ni najdeno", + "detailsButton": "Pokaži podrobnosti", + "homeButton": "Domov", + "text": "Iskali smo med našimi ponudniki ampak medija, ki ga iščete, nismo našli! Medijev ne gostimo in nimamo nadzora nad tem, katere vsebine so na voljo. Za več podrobnosti kliknite \"Prikaži podrobnosti\" spodaj.", + "title": "Iskanega nismo našli" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} do konca • Konča ob {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Preverite, ali ste človek, tako da izpolnite Captcha na desni strani. S tem zagotavljamo varnost filmskega spleta!", + "error": "Ni uspelo preveriti vaše človeškosti. Poskusite znova.", + "title": "Preveriti moramo, ali ste človek.", + "verifyingHumanity": "Preverjanje vaše človeškosti..." + } + }, + "screens": { + "dmca": { + "text": "Dobrodošli na SkoolTVovi kontaktni strani DMCA! Spoštujemo pravice intelektualne lastnine in želimo hitro odpraviti vse težave v zvezi z avtorskimi pravicami. Če menite, da je bilo vaše avtorsko zaščiteno delo na naši platformi nepravilno uporabljeno, pošljite podrobno obvestilo DMCA na spodnji e-poštni naslov. Vključite opis avtorsko zaščitenega gradiva, svoje kontaktne podatke in izjavo o \"prepričanju v dobri veri\". Zavezani smo k takojšnji rešitvi teh zadev in cenimo vaše sodelovanje pri ohranjanju filmskega spleta, ki spoštuje ustvarjalnost in avtorske pravice.", + "title": "DMCA" + }, + "loadingApp": "Nalagam aplikacijo", + "loadingUser": "Nalagam profil", + "loadingUserError": { + "logout": "Odjava", + "reset": "Ponastavitev strežnika po meri", + "text": "Neuspešno nalaganje vašega profila", + "textWithReset": "Neuspešno nalaganje vašega profila iz strežnika po meri. Želite ponastaviti nastavitve nazaj na privzeti strežnik?" + }, + "migration": { + "failed": "Podatkov ni uspelo preseliti.", + "inProgress": "Prosimo počakajte, saj vaše podatke prenašamo. To ne bi smelo trajati dolgo." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Ime naprave", + "deviceNamePlaceholder": "Mobilni telefon", + "editProfile": "Uredi", + "logoutButton": "Odjava" + }, + "actions": { + "delete": { + "button": "Izbriši profil", + "confirmButton": "Izbriši profil", + "confirmDescription": "Ste prepričani, da želite izbrisati svoj račun? Vsi vaši podatki bodo izgubljeni!", + "confirmTitle": "Ali ste prepričani?", + "text": "Ta ukaz je nereverzibilen. Vsi podatki bodo izbrisani in nobenih podatkov ne bo mogoče obnoviti.", + "title": "Izbirši profil" + }, + "title": "Ukazi" + }, + "devices": { + "deviceNameLabel": "Ime naprave", + "failed": "Neuspešno nalaganje sej", + "removeDevice": "Odstrani", + "title": "Naprave" + }, + "profile": { + "finish": "Zaključi urejanje", + "firstColor": "Barva prvega profila", + "secondColor": "Barva drugega profila", + "title": "Urejanje slike profila", + "userIcon": "Ikona uporabnika" + }, + "register": { + "cta": "Začni", + "text": "Napredek ogleda lahko delite med napravami in jih sinhronizirate.", + "title": "Sinhroniziraj z oblakom" + }, + "title": "Profil" + }, + "appearance": { + "activeTheme": "Aktivno", + "themes": { + "blue": "Modra", + "default": "Privzeto", + "gray": "Siva", + "red": "Rdeča", + "teal": "Turkizna" + }, + "title": "Izgled" + }, + "connections": { + "server": { + "description": "Če se želite povezati z zaledjem po meri za hrambo podatkov, to omogočite in navedite URL naslov. <0>Navodila.", + "label": "Strežnik po meri", + "urlLabel": "Naslov strežnika po meri (URL)" + }, + "setup": { + "doSetup": "Naredi nastavitev", + "errorStatus": { + "description": "Zdi se, da je treba posvetiti pozornost enemu ali več elementom v tej nastavitvi.", + "title": "Nekaj potrebuje vašo pozornost" + }, + "itemError": "S to nastavitvijo je nekaj narobe. Ponovno opravite nastavitev in jo popravite.", + "items": { + "default": "Privzet način", + "extension": "Razširitev", + "proxy": "Proxy po meri" + }, + "redoSetup": "Ponovnio izvedi nastavljanje", + "successStatus": { + "description": "Vse stvari so pripravljene, da lahko začnete gledati svoje najljubše medije.", + "title": "Vse je nastavljeno!" + }, + "unsetStatus": { + "description": "Kliknite gumb na desni strani, da začnete postopek namestitve.", + "title": "Niste opravili nastavitev" + } + }, + "title": "Povezave", + "workers": { + "addButton": "Dodaj novega \"workerja\"", + "description": "Za delovanje aplikacije je ves promet usmerjen prek posredniških strežnikov. To nastavitev omogočite, če želite pripeljati lastne delavce. <0>Navodila", + "emptyState": "Niste dodali \"workerja\", dodajte ga spodaj", + "label": "Uporaba posrednikov po meri", + "urlLabel": "Naslov Workerja (URL)", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Jezik", + "languageDescription": "Jezik, ki se uporablja za celotno aplikacijo.", + "thumbnail": "Naloži predoglede", + "thumbnailDescription": "Videoposnetki večinoma nimajo predogledov. To nastavitev lahko omogočite in jih ustvarite sproti, vendar lahko zaradi tega videoposnetek postane počasnejši.", + "thumbnailLabel": "Naloži predoglede", + "title": "Nastavitve" + }, + "reset": "Ponastavi", + "save": "Shrani", + "sidebar": { + "info": { + "appVersion": "Verzija aplikacije", + "backendUrl": "Naslov zaledja", + "backendVersion": "Verzija zaledja", + "hostname": "Hostname", + "insecure": "\"Nevarna povezava\"", + "notLoggedIn": "Niste prijavljeni", + "secure": "Varna povezava", + "title": "Informacije o aplikaciji", + "unknownVersion": "Neznano", + "userId": "ID uporabnika" + } + }, + "subtitles": { + "backgroundBlurLabel": "Zameglitev ozadja", + "backgroundLabel": "Motnost ozadja", + "colorLabel": "Barva", + "previewQuote": "Ne smem se bati. Strah je ubijalec misli.", + "textSizeLabel": "Velikost pisave", + "title": "Podnapisi" + }, + "unsaved": "Imate neshranjene spremembe" + } +} diff --git a/src/assets/locales/sv.json b/src/assets/locales/sv.json new file mode 100644 index 0000000..cfefa5e --- /dev/null +++ b/src/assets/locales/sv.json @@ -0,0 +1,391 @@ +{ + "about": { + "description": "SkoolTV är en webbapplikation som söker efter strömmar på internet. Teamet strävar efter en mestadels minimalistisk ansats för att konsumera innehåll.", + "faqTitle": "Vanliga frågor", + "q1": { + "body": "SkoolTV hostar ingen innehåll. När du klickar på något att titta på, söks internet efter det valda mediet (På laddningsskärmen och i fliken 'Videokällor' kan du se vilken källa du använder). Inget medium laddas upp av SkoolTV, allt sker genom sökmotorn.", + "title": "Var kommer innehållet ifrån?" + }, + "q2": { + "body": "Det går inte att begära en show eller film, SkoolTV hanterar inte något innehåll. Allt innehåll visas genom källor på internet.", + "title": "Var kan jag begära en show eller film?" + }, + "q3": { + "body": "Våra sökresultat drivs av The Movie Database (TMDB) och visas oavsett om våra källor faktiskt har innehållet.", + "title": "Sökresultaten visar showen eller filmen, varför kan jag inte spela upp den?" + }, + "title": "Om SkoolTV" + }, + "actions": { + "copied": "Kopierad", + "copy": "Kopiera" + }, + "auth": { + "createAccount": "Har du inget konto ännu? <0>Skapa ett konto.", + "deviceNameLabel": "Enhetsnamn", + "deviceNamePlaceholder": "Min telefon", + "generate": { + "description": "Ditt lösenord fungerar som ditt användarnamn och lösenord. Se till att hålla det säkert eftersom du behöver ange det för att logga in på ditt konto", + "next": "Jag har sparat mitt lösenord", + "title": "Ditt lösenord" + }, + "hasAccount": "Har redan ett konto? <0>Logga in här.", + "login": { + "description": "Ange ditt lösenord för att logga in på ditt konto", + "deviceLengthError": "Ange ett enhetsnamn", + "passphraseLabel": "12-ords lösenord", + "passphrasePlaceholder": "Lösenord", + "submit": "Logga in", + "title": "Logga in på ditt konto", + "validationError": "Felaktigt eller ofullständigt lösenord" + }, + "register": { + "information": { + "color1": "Profilfärg ett", + "color2": "Profilfärg två", + "header": "Ange ett namn för din enhet och välj färger samt ett användarikon efter eget val", + "icon": "Användarikon", + "next": "Nästa", + "title": "Kontoinformation" + } + }, + "trust": { + "failed": { + "text": "Har du konfigurerat den korrekt?", + "title": "Kunde inte nå servern" + }, + "host": "Du ansluter till <0>{{hostname}} - bekräfta att du litar på den innan du skapar ett konto", + "no": "Gå tillbaka", + "title": "Litar du på denna server?", + "yes": "Jag litar på denna server" + }, + "verify": { + "description": "Ange ditt lösenord igen för att bekräfta att du har sparat det och skapa ditt konto", + "invalidData": "Data är inte giltig", + "noMatch": "Lösenorden matchar inte", + "passphraseLabel": "Ditt 12-ords lösenord", + "recaptchaFailed": "ReCaptcha validering misslyckades", + "register": "Skapa konto", + "title": "Bekräfta ditt lösenord" + } + }, + "errors": { + "badge": "Något gick fel", + "details": "Felinformation", + "reloadPage": "Ladda om sidan", + "showError": "Visa felinformation", + "title": "Vi stötte på ett fel!" + }, + "footer": { + "legal": { + "disclaimer": "Friskriver sig från ansvar", + "disclaimerText": "SkoolTV hostar inga filer utan länkar endast till filer från tredje part. Eventuella juridiska frågor bör tas upp med källorna till materialet. SkoolTV varken ansvarar eller styr över de mediefiler som visas." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Titta på dina favoritprogram och filmer helt gratis." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Om oss", + "dmca": "DMCA", + "login": "Logga in", + "pagetitle": "{{title}} - SkoolTV", + "register": "Registrera", + "settings": "Inställningar" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Bokmärken" + }, + "continueWatching": { + "sectionTitle": "Fortsätt titta" + }, + "mediaList": { + "stopEditing": "Sluta redigera" + }, + "search": { + "allResults": "Det är allt vi har!", + "failed": "Misslyckades med att hitta media, försök igen!", + "loading": "Laddar...", + "noResults": "Vi kunde inte hitta någonting!", + "placeholder": { + "default": "Vad vill du titta på?", + "extra": [] + }, + "sectionTitle": "Sökresultat" + }, + "titles": { + "day": { + "default": "Vad vill du titta på i eftermiddag?" + }, + "morning": { + "default": "Vad vill du titta på den här morgonen?", + "extra": ["Jag hör att Before Sunrise är bra"] + }, + "night": { + "default": "Vad vill du titta på ikväll?", + "extra": ["Trött? Jag hör att The Exorcist är bra."] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Serie" + } + }, + "navigation": { + "banner": { + "offline": "Kontrollera din internetanslutning" + }, + "menu": { + "about": "Om oss", + "logout": "Logga ut", + "register": "Synkronisera till molnet", + "settings": "Inställningar", + "support": "Support" + } + }, + "notFound": { + "badge": "Ej hittad", + "goHome": "Tillbaka till startsidan", + "message": "Vi letade överallt: under soptunnorna, i garderoben, bakom proxy men kunde slutligen inte hitta sidan du letar efter.", + "title": "Kunde inte hitta den sidan" + }, + "overlays": { + "close": "Stäng" + }, + "player": { + "back": { + "default": "Tillbaka till startsidan", + "short": "Tillbaka" + }, + "casting": { + "enabled": "Castar till enheten..." + }, + "menus": { + "downloads": { + "disclaimer": "Nedladdningar görs direkt från leverantören. SkoolTV har ingen kontroll över hur nedladdningarna tillhandahålls.", + "downloadVideo": "Ladda ner video", + "onAndroid": { + "1": "För att ladda ner på Android, klicka på nedladdningsknappen och på den nya sidan trycker och håller på videon, välj sedan spara.", + "shortTitle": "Ladda ner / Android", + "title": "Laddar ner på Android" + }, + "onIos": { + "1": "För att ladda ner på iOS, klicka på nedladdningsknappen och på den nya sidan klickar du på , sedan Spara i filer .", + "shortTitle": "Ladda ner / iOS", + "title": "Laddar ner på iOS" + }, + "onPc": { + "1": "På PC, klicka på nedladdningsknappen och på den nya sidan högerklickar du sedan på videon och väljer Spara video som", + "shortTitle": "Ladda ner / PC", + "title": "Laddar ner på PC" + }, + "title": "Ladda ner" + }, + "episodes": { + "button": "Avsnitt", + "emptyState": "Det finns inga avsnitt i denna säsong, kom tillbaka senare!", + "episodeBadge": "E{{episode}}", + "loadingError": "Fel vid laddning av säsong", + "loadingList": "Laddar...", + "loadingTitle": "Laddar..." + }, + "playback": { + "speedLabel": "Uppspelningshastighet", + "title": "Uppspelningsinställningar" + }, + "quality": { + "automaticLabel": "Automatisk kvalitet", + "hint": "Du kan prova att <0>byta källa för att få olika kvalitetsoptioner.", + "iosNoQuality": "På grund av Apple-definierade begränsningar är kvalitetsval inte tillgängligt på iOS för denna källa. Du kan prova att <0>byta till en annan källa för att få olika kvalitetsoptioner.", + "title": "Kvalitet" + }, + "settings": { + "downloadItem": "Ladda ner", + "experienceSection": "Visningsupplevelse", + "playbackItem": "Uppspelningsinställningar", + "qualityItem": "Kvalitet", + "sourceItem": "Videokällor", + "videoSection": "Videoinställningar" + }, + "sources": { + "failed": { + "text": "Det uppstod ett fel när vi försökte hitta några videor, försök med en annan källa.", + "title": "Misslyckades med att skrapa" + }, + "noEmbeds": { + "text": "Vi kunde inte hitta några inbäddningar, försök med en annan källa.", + "title": "Inga inbäddningar hittade" + }, + "noStream": { + "text": "Den här källan har ingen ström för denna film eller serie.", + "title": "Ingen ström" + }, + "title": "Källor", + "unknownOption": "Okänd" + } + }, + "metadata": { + "failed": { + "badge": "Misslyckades", + "homeButton": "Till startsidan", + "text": "Kunde inte ladda medias metadata från TMDB. Kontrollera om TMDB är nere eller blockerat på din internetanslutning.", + "title": "Misslyckades att ladda metadata" + }, + "notFound": { + "badge": "Ej hittad", + "homeButton": "Tillbaka till startsidan", + "text": "Vi kunde inte hitta den media du begärde. Antingen har den tagits bort eller så har du manipulerat URL:en.", + "title": "Kunde inte hitta den media." + } + }, + "nextEpisode": { + "cancel": "Avbryt", + "next": "Nästa avsnitt" + }, + "playbackError": { + "badge": "Uppspelningsfel", + "errors": { + "errorAborted": "Hämtningen av media avbröts på användarens begäran.", + "errorDecode": "Trots att det tidigare bedömts som användbart uppstod ett fel vid försök att avkoda mediaresursen, vilket resulterade i ett fel.", + "errorGenericMedia": "Okänt mediafel inträffade.", + "errorNetwork": "Någon form av nätverksfel inträffade vilket förhindrade att media framgångsrikt hämtades, trots att det tidigare var tillgängligt.", + "errorNotSupported": "Media- eller mediaproviderobjektet stöds inte." + }, + "homeButton": "Till startsidan", + "text": "Det uppstod ett fel när vi försökte spela upp media. Försök igen.", + "title": "Misslyckades spela upp video!" + }, + "scraping": { + "items": { + "failure": "Fel inträffade", + "notFound": "Har inte videon", + "pending": "Söker efter videor..." + }, + "notFound": { + "badge": "Ej hittad", + "detailsButton": "Visa detaljer", + "homeButton": "Till startsidan", + "text": "Vi har sökt genom våra leverantörer och kan inte hitta den media du letar efter! Vi hostar inte media och har ingen kontroll över tillgängligheten. Klicka på 'Visa detaljer' nedan för mer information.", + "title": "Vi kunde inte hitta det" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} kvar • Slutar kl {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + } + }, + "screens": { + "dmca": { + "text": "Välkommen till SkoolTVs DMCA-kontaktsida! Vi respekterar immateriella rättigheter och vill snabbt hantera eventuella upphovsrättsliga bekymmer. Om du tror att ditt upphovsrättsskyddade verk har använts felaktigt på vår plattform, skicka gärna en detaljerad DMCA-notis till e-postadressen nedan. Inkludera en beskrivning av det upphovsrättsskyddade materialet, dina kontaktuppgifter och en tro på god tro. Vi åtar oss att lösa dessa frågor snabbt och uppskattar ditt samarbete för att hålla SkoolTV som en plats som respekterar kreativitet och upphovsrätt.", + "title": "DMCA" + }, + "loadingApp": "Laddar applikationen", + "loadingUser": "Laddar din profil", + "loadingUserError": { + "logout": "Logga ut", + "reset": "Återställ anpassad server", + "text": "Misslyckades att ladda din profil", + "textWithReset": "Misslyckades att ladda din profil från din anpassade server, vill du återställa till standardservern?" + }, + "migration": { + "failed": "Misslyckades att migrera dina data.", + "inProgress": "Vänligen vänta, vi migrerar dina data. Detta borde inte ta lång tid." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Enhetens namn", + "deviceNamePlaceholder": "Min telefon", + "editProfile": "Redigera", + "logoutButton": "Logga ut" + }, + "actions": { + "delete": { + "button": "Ta bort konto", + "confirmButton": "Ta bort konto", + "confirmDescription": "Är du säker på att du vill ta bort ditt konto? All din data kommer att gå förlorad!", + "confirmTitle": "Är du säker?", + "text": "Denna åtgärd är oåterkallelig. All data kommer att raderas och kan inte återställas.", + "title": "Ta bort konto" + }, + "title": "Åtgärder" + }, + "devices": { + "deviceNameLabel": "Enhetens namn", + "failed": "Misslyckades att ladda sessioner", + "removeDevice": "Ta bort", + "title": "Enheter" + }, + "profile": { + "finish": "Slutför redigering", + "firstColor": "Profilfärg ett", + "secondColor": "Profilfärg två", + "title": "Redigera profilbild", + "userIcon": "Användarikon" + }, + "register": { + "cta": "Kom igång", + "text": "Dela din tittarframsteg mellan enheter och håll dem synkroniserade.", + "title": "Synkronisera till molnet" + }, + "title": "Konto" + }, + "appearance": { + "activeTheme": "Aktiv", + "themes": { + "blue": "Blå", + "default": "Standard", + "gray": "Grå", + "red": "Röd", + "teal": "Blågrön" + }, + "title": "Utseende" + }, + "connections": { + "server": { + "description": "Om du vill ansluta till en anpassad bakänd för att lagra dina data, aktivera detta och ange URL:en.", + "label": "Anpassad server", + "urlLabel": "Egen server URL" + }, + "title": "Anslutningar", + "workers": { + "addButton": "Lägg till ny arbetare", + "description": "För att få applikationen att fungera skickas all trafik genom proxys. Aktivera detta om du vill använda egna arbetare.", + "emptyState": "Inga arbetare ännu, lägg till en nedan", + "label": "Använd egna proxyarbetare", + "urlLabel": "Arbetar-URL:er", + "urlPlaceholder": "https://" + } + }, + "reset": "Återställ", + "save": "Spara", + "sidebar": { + "info": { + "appVersion": "Appversion", + "backendUrl": "Bakänd-URL", + "backendVersion": "Bakändversion", + "hostname": "Värdnamn", + "insecure": "Osäker", + "notLoggedIn": "Du är inte inloggad", + "secure": "Säker", + "title": "Appinformation", + "unknownVersion": "Okänd", + "userId": "Användar-ID" + } + }, + "unsaved": "Du har osparade ändringar" + } +} diff --git a/src/assets/locales/ta.json b/src/assets/locales/ta.json new file mode 100644 index 0000000..a1fd622 --- /dev/null +++ b/src/assets/locales/ta.json @@ -0,0 +1,531 @@ +{ + "about": { + "description": "SkoolTV என்பது இணையத்தில் ஸ்ட்ரீம்களைத் தேடும் ஒரு வலைப் பயன்பாடு ஆகும். உள்ளடக்கத்தை உட்கொள்வதற்கான ஒரு சிறிய அணுகுமுறையை குழு நோக்கமாகக் கொண்டுள்ளது.", + "faqTitle": "பொதுவான கேள்விகள்", + "q1": { + "body": "மூவி வெப் எந்தவொரு பதிவுகளையும் வழங்குவதில்லை. நீங்கள் ஒரு காட்சியை தேர்ந்தெடுத்து காண விரும்பும் போது அதற்கான பதிவை இணையத்தில் உள்ள பல்வேறு தளங்களில் இருந்து தேடி உங்களுக்கு வழங்குகிறது. பதிவுகள் ஒரு போதும் மூவி வெப் மூலம் பதிவேற்றப்படுவது இல்லை. நீங்கள் காணும் அனைத்து காட்சிகளும் தேடு பொறி முறையின் சிறப்பம்சத்தின் மூலமாகவே உங்களுக்கு வழங்கப்படுகிறது.", + "title": "பதிவு எங்கிருந்து வருகிறது?" + }, + "q2": { + "body": "ஒரு திரைப்படம் அல்லது தொடரை உங்களால் நேரடியாக கோர முடியாது. மூவி வெப் எந்த ஒரு பதிவுகளையும் நிர்வகிப்பதில்லை. அணைத்து பதிவுகளும் இணையத்தில் உள்ள தளங்களின் வழியாகவே உங்களுக்கு அளிக்கப்படுகின்றது.", + "title": "ஒரு தொடர் அல்லது திரைப்படத்தை நான் எங்கே கோருவது?" + }, + "q3": { + "body": "எங்கள் தேடல் முடிவுகள் The Movie Database (TMDB) தரவு தளம் மூலம் வழங்கப்படுகிறது. தேடல் முடிவுகள் தேடலுக்கான பதிவுகளை கட்டாயம் உள்ளடக்கி இருக்கும் என்பதை உறுதியாக கூற இயலாது.", + "title": "தேடல் முடிவுகள் திரைப்படம் அல்லது தொடரை காட்டுகிறது. ஆனால், ஏன் என்னால் அதை பார்க்க முடியவில்லை?" + }, + "title": "SkoolTV பற்றி" + }, + "actions": { + "copied": "நகலெடுக்கப்பட்டது", + "copy": "நகல்" + }, + "auth": { + "createAccount": "கணக்கு இல்லையா? <0>புதிய கணக்கை உருவாக்குங்கள்", + "deviceNameLabel": "சாதனத்தின் பெயர்", + "deviceNamePlaceholder": "எனது கைபேசி", + "generate": { + "description": "தங்கள் கடவுச்சொற்றொடரே தங்களது பயனர் பெயர் மற்றும் கடவுச்சொல். கணக்கினுள் நுழைய அதனை பாதுகாப்பாக வைத்திருங்கள்", + "next": "கடவுச்சொற்றொடரை சேமித்துவிட்டேன்", + "passphraseFrameLabel": "கடவுச்சொற்றொடர்", + "title": "உங்கள் கடவுச்சொற்றொடர்" + }, + "hasAccount": "ஏற்கனவே ஒரு கணக்கு உள்ளதா? <0>இங்கே உள்நுழைக. ", + "login": { + "description": "உங்கள் கணக்கினுள் உள்நுழைய உங்கள் கடவுச்சொற்றொடரை உள்ளிடுக", + "deviceLengthError": "சாதனத்தின் பெயரை உள்ளிடவும்", + "passphraseLabel": "12-சொல் கடவுச்சொற்றொடர்", + "passphrasePlaceholder": "கடவுச்சொற்றொடர்", + "submit": "புகுபதிகை", + "title": "உங்கள் கணக்கில் உள்நுழைக", + "validationError": "தவறான அல்லது முழுமையற்ற கடவுச்சொற்றொடர்" + }, + "register": { + "information": { + "color1": "Profile நிறம் ஒன்று", + "color2": "Profile நிறம் இரண்டு", + "header": "உங்கள் சாதனத்தின் பெயரை உள்ளிட்டு அதற்கான வண்ணம் மற்றும் ஐகானையும் தேர்ந்தெடுக்கவும்", + "icon": "பயனர் icon", + "next": "அடுத்து", + "title": "கணக்கு விவரம்" + } + }, + "trust": { + "failed": { + "text": "நீங்கள் அதை சரியாக உள்ளமைத்தீர்களா?", + "title": "சர்வரை தொடர்பு கொள்ள முடியவில்லை" + }, + "host": "நீங்கள் <0>{{hostname}} உடன் இணைக்கப்படுகிறீர்கள். கணக்கை உருவாக்கும் முன் சரியான தகவல் தானா எனபதை உறுதி செய்து கொள்ளவும்", + "no": "பின்செல்", + "title": "நீங்கள் இந்த சர்வரை நம்புகிறீர்களா?", + "yes": "நான் இந்த சர்வரை நம்புகிறேன்" + }, + "verify": { + "description": "உங்கள் கடவுச்சொற்றொடரைச் சேமித்துள்ளீர்கள் என்பதை உறுதிப்படுத்த உங்கள் கடவுச்சொற்றொடர்களை மீண்டும் இங்கே உள்ளீடு செய்து உங்கள் கணக்கை உருவாக்கிக் கொள்ளுங்கள்", + "invalidData": "தரவு செல்லுபடியாகாது", + "noMatch": "கடவுச்சொற்றொடர்கள் பொருந்தவில்லை", + "passphraseLabel": "உங்களின் 12-சொல் கடவுச்சொற்றொடர்", + "recaptchaFailed": "ReCaptcha சரிபார்ப்பு தோல்வியடைந்தது", + "register": "கணக்கை உருவாக்கு", + "title": "கடவுச்சொற்றொடரை உறுதி செய்க" + } + }, + "errors": { + "badge": "சரியாக வேலை செய்யவில்லை", + "details": "பிழை விவரங்கள்", + "reloadPage": "இணையப் பக்கத்தை Reload செய்யவும்", + "showError": "பிழை விவரங்களைக் காட்டு", + "title": "நங்கள் ஒரு பிழையை எதிர் கொண்டு இருக்கிறோம்!" + }, + "footer": { + "legal": { + "disclaimer": "பொறுப்பு துறப்பு", + "disclaimerText": "மூவி-வெப் எந்த பதிவுகளையும் தன்னகம் வைத்திருக்கவில்லை, இது மூன்றாம் தரப்பு பதிவுகளை வழங்குபவர்களை இணைக்கிறது. சட்ட சிக்கல்கள் ஏதேனும் இருப்பின் அது பதிவுகளை வழங்குபவரையே சாறும். வீடியோ வழங்குநர்கள் காண்பிக்கும் எந்த மீடியா பதிவுகளுக்கும் மூவி வெப் பொறுப்பாகாது." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "இந்த ஓப்பன் சோர்ஸ் (Open Source) இணைய தளம் மூலம் உங்களுக்குப் பிடித்த தொடர்களையும் திரைப்படங்களையும் பார்க்கலாம்." + }, + "global": { + "name": "மூவி-வெப்", + "pages": { + "about": "தெரிந்து கொள்ள", + "dmca": "DMCA", + "login": "புகுபதிகை", + "onboarding": "அமை", + "pagetitle": "{{title}} - மூவி- வெப்", + "register": "பதிவு", + "settings": "அமைப்புகள்" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "குறிப்புகள்" + }, + "continueWatching": { + "sectionTitle": "தொடர்ந்து பார்க்க" + }, + "mediaList": { + "stopEditing": "திருத்துவதை நிறுத்து" + }, + "search": { + "allResults": "மேலும் எங்களிடம் இல்லை!", + "failed": "மீடியாவைக் கண்டறிய முடியவில்லை, மீண்டும் முயலவும்!", + "loading": "Loading...", + "noResults": "எங்களால் எதையும் கண்டுபிடிக்க இயலவில்லை!", + "sectionTitle": "தேடல் முடிவுகள்" + }, + "titles": { + "day": { + "default": "மதிய வணக்கம். தற்போது என்ன காண விரும்புகிறீர்கள்?", + "extra": [ + "சாகசமாக உணர்கிறீர்களா? ஜுராசிக் பார்க் (Jurassic Park) சரியான தேர்வாக இருக்கலாம்." + ] + }, + "morning": { + "default": "காலை வணக்கம். தற்போது என்ன காண விரும்புகிறீர்கள்?", + "extra": ["சூரிய உதயத்திற்கு முன் நல்லது என்று கேள்விப்படுகிறேன்"] + }, + "night": { + "default": "இன்றைய இரவு என்ன காண விரும்புகிறீர்கள்?", + "extra": ["சோர்வாக உள்ளீர்களா? Exorcist திரைப்படம் காணுங்கள்."] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "திரைப்படம்", + "show": "காட்சி" + } + }, + "navigation": { + "banner": { + "offline": "உங்கள் இணைய இணைப்பைச் சரிபார்க்கவும்" + }, + "menu": { + "about": "எங்களை பற்றி", + "logout": "வெளியேறு", + "register": "இணைய கணக்கோடு ஒத்திசை (Sync to sudo-cloud)", + "settings": "அமைப்புகள்", + "support": "உதவி மையம்" + } + }, + "notFound": { + "badge": "கிடைக்கவில்லை", + "goHome": "முகப்பிற்குச் செல்", + "message": "எங்களால் இயன்றவரை தேடினோம். ஆனால் உங்களுக்கான பக்கத்தை கண்டுபிடிக்க இயலவில்லை.", + "title": "உங்களுக்கான பக்கத்தை கண்டுபிடிக்க இயலவில்லை" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "ரத்து செய்", + "confirm": "இயல்புநிலை அமைப்பைப் பயன்படுத்தவும்", + "description": "இயல்புநிலை அமைப்பில் உள்ள தரவுகள் சிறந்த அனுபவத்தை வழங்க உகந்தவை அல்ல. மேலும், இவை மிகவும் மெதுவான இணைய வேகத்தையே கொண்டிருக்கும்.", + "title": "உறுதி செய்யலாமா?" + }, + "extension": { + "back": "பின் செல்", + "explainer": "உலாவி நீட்டிப்பு (Browser Extension) வழி உங்களுக்கு சிறந்த காட்சிகளை எங்களால் வழங்க இயலும். மேலும், இந்த நிறுவல் மிகவும் எளிதான வழி முறையாகும்.", + "explainerIos": "துரதிர்ஷ்டவசமாக, உலாவி நீட்டிப்பு iOS இல் ஆதரிக்கப்படவில்லை, மற்றொரு விருப்பத்தைத் தேர்வுசெய்ய பின் செல் என்பதை அழுத்தவும்.", + "extensionHelp": "நீங்கள் நீட்டிப்பை நிறுவியிருந்தும் அது கண்டறியப்படவில்லை எனில், உங்கள் உலாவி நீட்டிப்பு மெனு மூலம் நீட்டிப்பைத் திறந்து திரையில் உள்ள படிகளைப் பின்பற்றவும்.", + "linkChrome": "Chrome நீட்டிப்பை நிறுவவும்", + "linkFirefox": "Firefox நீட்டிப்பை நிறுவவும்", + "notDetecting": "Chrome இல் நிறுவப்பட்டு விட்டது, ஆனால் தளம் அதைக் கண்டறியவில்லையா? பக்கத்தை மீண்டும் இயக்கி (Reload) முயற்சிக்கவும்!", + "notDetectingAction": "பக்கத்தை மீண்டும் இயக்கு", + "status": { + "disallowed": "இந்தப் பக்கத்திற்கு நீட்டிப்பு இயக்கப்படவில்லை", + "disallowedAction": "நீட்டிப்பை இயக்கு", + "failed": "தற்போதைய நிலையை அறிய இயலவில்லை", + "loading": "நீங்கள் நீட்டிப்பை நிறுவும் வரை காத்திருக்கிறது", + "outdated": "நீட்டிப்பு பதிப்பு மிகவும் பழையது", + "success": "நீட்டிப்பு எதிர்பார்த்தபடி செயல்படுகிறது!" + }, + "submit": "தொடரவும்", + "title": "நீட்டிப்பு நிறுவலுடன் ஆரம்பிக்கலாம்" + }, + "proxy": { + "back": "பின் செல்", + "explainer": "Proxy முறையில், உங்களின் தனிப்பட்ட Proxy யை உருவாக்குவதன் மூலம் சிறந்த தரமான ஸ்ட்ரீம்களைப் பெறலாம்.", + "input": { + "errorConnection": "Proxy உடன் இணைக்க முடியவில்லை", + "errorInvalidUrl": "சரியான URL அல்ல", + "errorNotProxy": "Proxy க்கு பதில் இணைய தளம் கிடைத்துள்ளது", + "label": "Proxy URL", + "placeholder": "https://" + }, + "link": "Proxy எவ்வாறு உருவாக்குவது என்பதை அறிக", + "submit": "Proxy யை சமர்ப்பிக்க", + "title": "ஒரு புதிய Proxy யை உருவாக்குவோம்" + }, + "start": { + "explainer": "சிறந்த ஸ்ட்ரீம்களைப் பெற, நீங்கள் எந்த ஸ்ட்ரீமிங் முறையைப் பயன்படுத்த விரும்புகிறீர்கள் என்பதை நீங்கள் தேர்வு செய்ய வேண்டும்.", + "options": { + "default": { + "text": "எனக்கு நல்ல தரமான ஸ்ட்ரீம்கள் வேண்டாம்,<0 /> <1>இயல்புநிலை அமைப்பைப் பயன்படுத்தவும்" + }, + "extension": { + "action": "நீட்டிப்பை நிறுவவும்", + "description": "உலாவி நீட்டிப்பை நிறுவி, சிறந்த தரவுகளை பெறுங்கள்.", + "quality": "சிறந்த தரம்", + "title": "உலாவி நீட்டிப்பு" + }, + "proxy": { + "action": "Proxy யை அமைக்கவும்", + "description": "வெறும் 5 நிமிடங்களில் Proxy யை அமைத்து, சிறந்த தரவுகளை பெறுங்கள்.", + "quality": "நல்ல தரம்", + "title": "தனிப்பட்ட Proxy" + } + }, + "title": "உங்களின் மூவி-வெப் அமைப்பை நிறுவலாம் வாருங்கள்" + } + }, + "overlays": { + "close": "மூடு" + }, + "player": { + "back": { + "default": "முகப்பிற்கு செல்", + "short": "பின் செல்" + }, + "casting": { + "enabled": "சாதனத்தின் வழி திரையிடப்படுகிறது..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "HLS Playlist link யை காப்பி செய்யவும்", + "disclaimer": "பதிவிறக்கங்கள் வழங்குநரிடமிருந்து நேரடியாக வழங்கப்படுகின்றன. பதிவிறக்கங்கள் எவ்வாறு வழங்கப்படுகின்றன என்பதை மூவி-வெப் கட்டுப்படுத்தாது.", + "downloadSubtitle": "தற்போதைய வசனத்தைப் பதிவிறக்கவும்", + "downloadVideo": "Video வை பதிவிறக்கம் செய்", + "hlsDisclaimer": "பதிவிறக்கங்கள் வழங்குநரிடமிருந்து நேரடியாக எடுக்கப்படுகின்றன. பதிவிறக்கங்கள் எவ்வாறு வழங்கப்படுகின்றன என்பதை மூவி-வெப் கட்டுப்படுத்தவில்லை.

நீங்கள் HLS Playlist யை பதிவிறக்குகிறீர்கள் என்பதை நினைவில் கொள்ளவும், Advanced streaming formats பற்றி நீங்கள் அறிந்து இருக்கவில்லையென்றால் பதிவிறக்கம் செய்ய உங்களை நாங்கள் பரிந்துரைக்கவில்லை. . வெவ்வேறு வடிவங்கள் அல்லது வெவ்வேறு ஆதாரங்களை முயற்சிக்கவும்.", + "onAndroid": { + "1": "Android இல் பதிவிறக்க, பதிவிறக்க பொத்தானைக் கிளிக் செய்து, புதிய பக்கத்தில், வீடியோ வின் மீது tap and holdகிளிக் செய்யவும், பின்னர் save என்பதைத் தேர்ந்தெடுக்கவும்.", + "shortTitle": "பதிவிறக்கம் / ஆண்ட்ராய்டு", + "title": "ஆண்ட்ராய்டு இல் பதிவிறங்குகிறது" + }, + "onIos": { + "1": "iOS இல் பதிவிறக்க, பதிவிறக்க பொத்தானைக் கிளிக் செய்து, புதிய பக்கத்தில், என்பதைக் கிளிக் செய்து பிறகு, Save to Files கிளிக் செய்யவும்.", + "shortTitle": "பதிவிறக்கு /iOS", + "title": "iOS இல் பதிவிறங்குகிறது" + }, + "onPc": { + "1": "கணினியில், Download பொத்தானைக் கிளிக் செய்து வரும் புதிய பக்கத்தில், வீடியோவின் மீது சுட்டியின் வலது பக்கம் கிளிக் (Right Click) செய்து Save video as என்பதைத் தேர்ந்தெடுக்கவும்", + "shortTitle": "பதிவிறக்கு / PC", + "title": "கணினியில் பதிவிறங்குகிறது" + }, + "title": "பதிவிறக்கு" + }, + "episodes": { + "button": "அத்தியாயங்கள்", + "emptyState": "இந்த தொடரில் எந்தவொரு அத்தியாயங்களும் இல்லை. பிறகு பார்க்கவும்!", + "episodeBadge": "E{{episode}}", + "loadingError": "தொடரை திரையிட முடியவில்லை", + "loadingList": "திரையிடப்படுகிறது...", + "loadingTitle": "திரையிடப்படுகிறது...", + "unairedEpisodes": "இந்த Season இல் ஒன்று அல்லது அதற்கு மேற்பட்ட Episode கள் இன்னும் ஒளிபரப்பப்படாததால் அவை முடக்கப்பட்டுள்ளன." + }, + "playback": { + "speedLabel": "காட்சி பின்னணி வேகம்", + "title": "காட்சி பின்னணி அமைப்புகள்" + }, + "quality": { + "automaticLabel": "இயல்பான தரம்", + "hint": "வெவ்வேறு தர விருப்பங்களைப் பெற <0>switching source தெரிவு செய்யலாம்.", + "iosNoQuality": "Apple நிறுவனத்தின் வரையறுக்கப்பட்ட வரம்புகள் காரணமாக, இந்த Source இன் தரமான தேர்வு iOS இயங்கு தளத்தில் வழங்க இயலவில்லை. வெவ்வேறு தர விருப்பங்களைப் பெற, <0>switching to another source தெரிவு செய்யவும்.", + "title": "தரம்" + }, + "settings": { + "downloadItem": "பதிவிறக்கம்", + "enableSubtitles": "வசனங்களை இயக்கு", + "experienceSection": "பார்க்கும் அனுபவம்", + "playbackItem": "காட்சி பின்னணி அமைப்புகள்", + "qualityItem": "தரம்", + "sourceItem": "வீடியோ ஆதாரங்கள்", + "subtitleItem": "வசன அமைப்புகள்", + "videoSection": "வீடியோ அமைப்புகள்" + }, + "sources": { + "failed": { + "text": "வீடியோக்களை கண்டுபிடிக்க முயற்சிக்கும் போது பிழை ஏற்பட்டுள்ளது , வேறு ஆதாரங்களை முயற்சிக்கவும்.", + "title": "Scrape செய்ய முடியவில்லை" + }, + "noEmbeds": { + "text": "எந்த உட்பொதிவுகளையும் (Embeds) எங்களால் கண்டுபிடிக்க இயலவில்லை, வேறு ஆதாரங்களை முயற்சிக்கவும்.", + "title": "உட்பொதிப்புகள் (Embeds) எதுவும் இல்லை" + }, + "noStream": { + "text": "இந்த Source இல் திரைப்படம் அல்லது தொடருக்கான தரவுகள் இல்லை.", + "title": "தரவு கிடைக்கப்பெறவில்லை" + }, + "title": "தரவு தளங்கள்", + "unknownOption": "தெரியவில்லை" + }, + "subtitles": { + "customChoice": "File இல் இருந்து வசனத்தைத் தேர்ந்தெடுக்கவும்", + "customizeLabel": "தனிப்பயன்முறை", + "offChoice": "அனை", + "settings": { + "backlink": "தனிப்பட்ட வசன வரிகள்", + "delay": "வசன வரி தாமதம்", + "fixCapitals": "Capitals யை சரி செய்யவும்" + }, + "title": "வசன வரிகள்", + "unknownLanguage": "தெரியவில்லை" + } + }, + "metadata": { + "api": { + "text": "API தரவுகளை காண்பிக்க இயலவில்லை, உங்கள் இணைய இணைப்பைச் சரிபார்க்கவும்.", + "title": "API தரவுகளை காண்பிக்க இயலவில்லை" + }, + "dmca": { + "badge": "அகற்றப்பட்டது", + "text": "Copyright Claim காரணமாக இந்த தரவு நீக்கப்பட்டது அல்லது காணக் கிடைக்காது.", + "title": "மீடியா நீக்கப்பட்டது" + }, + "extensionPermission": { + "badge": "அனுமதி இல்லை", + "button": "நீட்டிப்பைப் பயன்படுத்தவும்", + "text": "உங்களிடம் உலாவி நீட்டிப்பு உள்ளது, ஆனால் நீட்டிப்பைப் பயன்படுத்தத் தொடங்க உங்கள் அனுமதி தேவை.", + "title": "நீட்டிப்பை உள்ளமைக்கவும்" + }, + "failed": { + "badge": "தோல்வியடைந்தது", + "homeButton": "முகப்பிற்கு செல்", + "text": "TMDB இலிருந்து மீடியாவின் தரவுகளை ஏற்ற முடியவில்லை. உங்கள் இணைய இணைப்பில் TMDB செயலிழந்துள்ளதா அல்லது தடுக்கப்பட்டுள்ளதா என்பதைச் சரிபார்க்கவும்.", + "title": "மெட்டா டேட்டாவை ஏற்றுவதில் தோல்வி" + }, + "notFound": { + "badge": "கிடைக்கவில்லை", + "homeButton": "முகப்பிற்கு செல்", + "text": "நீங்கள் கோரிய மீடியாவை எங்களால் கண்டுபிடிக்க இயலவில்லை. அது அகற்றப்பட்டிருக்கலாம் அல்லது நீங்கள் URL ஐ சேதப்படுத்தியிருக்கலாம்.", + "title": "மீடியாவைக் கண்டுபிடிக்க முடியவில்லை." + } + }, + "nextEpisode": { + "cancel": "ரத்து செய்", + "next": "அடுத்த Episode" + }, + "playbackError": { + "badge": "பின்னணி பிழை", + "errors": { + "errorAborted": "பயனரின் கோரிக்கையால் மீடியாவைப் பெறுவது நிறுத்தப்பட்டது.", + "errorDecode": "பயன்படுத்தக்கூடியது என்று முன்பே தீர்மானிக்கப்பட்டிருந்தாலும், மீடியாவை டிகோட் செய்ய முயற்சிக்கும்போது ஏற்பட்ட பிழை காரணமாக இந்த பிழை ஏற்பட்டுள்ளது.", + "errorGenericMedia": "அறியப்படாத மீடியா பிழை ஏற்பட்டுள்ளது.", + "errorNetwork": "மீடியா கிடைத்த போதிலும், சில நெட்ஒர்க் பிழையின் காரணமாக இந்த மீடியா இப்போது கிடைக்கப்பெறவில்லை.", + "errorNotSupported": "மீடியா அல்லது மீடியா வழங்குநர் பொருள் ஆதரிக்கப்படவில்லை." + }, + "homeButton": "முகப்பிற்கு செல்", + "text": "மீடியாவை இயக்கும் முயற்சியில் பிழை ஏற்பட்டுள்ளது. தயவு செய்து மீண்டும் முயற்சிக்கவும்.", + "title": "வீடியோவை இயக்க முடியவில்லை!" + }, + "scraping": { + "items": { + "failure": "பிழை ஏற்பட்டுள்ளது", + "notFound": "வீடியோ இல்லை", + "pending": "வீடியோக்களை எடுத்து கொண்டிருக்கிறது..." + }, + "notFound": { + "badge": "கிடைக்கவில்லை", + "detailsButton": "விவரங்களை காட்டு", + "homeButton": "முகப்பிற்கு செல்", + "text": "எங்கள் வழங்குநர்கள் மூலம் நாங்கள் தேடினோம், நீங்கள் தேடும் மீடியாவைக் கண்டுபிடிக்க இயலவில்லை! நாங்கள் மீடியாவை host செய்யவில்லை, என்ன கிடைக்கும் என்பதில் எங்களுக்கு எந்த கட்டுப்பாடும் இல்லை. மேலும் விவரங்களுக்கு கீழே உள்ள 'விவரங்களைக் காட்டு' என்பதைக் கிளிக் செய்யவும்.", + "title": "அதை எங்களால் கண்டுபிடிக்க முடியவில்லை" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} மீதமுள்ள நேரம்• {{timeFinished, datetime}} அன்று முடிந்தது", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "நீங்கள் மனிதர் தானா என்பதை உறுதி செய்யவும். இது எங்களை பாதுகாப்பாக வைத்திருக்க உதவும்!", + "error": "நீங்கள் மனிதர் என்பதை தான் சரிபார்க்க முடியவில்லை. தயவு செய்து மீண்டும் முயற்சிக்கவும்.", + "title": "நீங்கள் ஒரு மனிதர் என்பதை நாங்கள் உறுதி செய்ய வேண்டும்.", + "verifyingHumanity": "நீங்கள் மனிதர் தானா என்பதை உறுதி செய்கிறோம். காத்திருக்கவும்..." + } + }, + "screens": { + "dmca": { + "text": "மூவி-வெப் DMCA தொடர்பு பக்கத்திற்கு வரவேற்கிறோம்! அறிவுசார் சொத்துரிமைகளை நாங்கள் மதிக்கிறோம் மற்றும் எந்தவொரு பதிப்புரிமைக் கவலைகளையும் விரைவாகத் தீர்க்க விரும்புகிறோம். உங்கள் பதிப்புரிமை பெற்ற வேலை எங்கள் தளத்தில் தவறாகப் பயன்படுத்தப்பட்டதாக நீங்கள் நம்பினால், கீழே உள்ள மின்னஞ்சலுக்கு விரிவான DMCA அறிவிப்பை அனுப்பவும். பதிப்புரிமை பெற்ற உள்ளடக்கத்தின் விளக்கம், உங்கள் தொடர்பு விவரங்கள் மற்றும் நல்ல நம்பிக்கையின் அறிக்கையைச் சேர்க்கவும். இந்த விஷயங்களை உடனடியாகத் தீர்ப்பதற்கு நாங்கள் கடமைப்பட்டுள்ளோம், மேலும் மூவி-வெப் படைப்பாற்றல் மற்றும் பதிப்புரிமைகளை மதிக்கும் இடமாக வைத்திருப்பதில் உங்கள் ஒத்துழைப்பைப் பாராட்டுகிறோம்.", + "title": "DMCA" + }, + "loadingApp": "பயன்பாட்டை நிறுவுகிறது", + "loadingUser": "Profile லோட் செய்யப்படுகிறது", + "loadingUserError": { + "logout": "வெளியேறு", + "reset": "Custom server யை மீட்டமைக்கவும்", + "text": "Profile லோட் செய்ய முடியவில்லை", + "textWithReset": "உங்கள் Profile Custom Server இல் இருந்து லோட் செய்ய இயலவில்லை. மீண்டும் Default Server க்கு மாற்றியமைக்க விரும்புகிறீர்களா?" + }, + "migration": { + "failed": "உங்கள் தரவுகளை புதுப்பிக்க இயலவில்லை.", + "inProgress": "தயவு செய்து காத்திருக்கவும், நாங்கள் உங்கள் தரவுகளை சேமித்து கொண்டு இருக்கிறோம். இதற்கு அதிக நேரம் தேவைப்படாது." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "சாதனத்தின் பெயர்", + "deviceNamePlaceholder": "தனிப்பட்ட போன்", + "editProfile": "எடிட்", + "logoutButton": "வெளியேறு" + }, + "actions": { + "delete": { + "button": "கணக்கை நீக்குக", + "confirmButton": "கணக்கை நீக்குக", + "confirmDescription": "உங்கள் கணக்கை நிச்சயமாக நீக்க விரும்புகிறீர்களா? உங்கள் தரவுகள் அனைத்தும் நீக்கப்படும்!", + "confirmTitle": "நீங்கள் உறுதியா?", + "text": "இந்த நடவடிக்கை திரும்ப பெற முடியாதது. அனைத்து தரவுகளும் நீக்கப்படும் மற்றும் எதையும் மீட்டெடுக்க இயலாது.", + "title": "கணக்கை நீக்குக" + }, + "title": "செயல்கள்" + }, + "devices": { + "deviceNameLabel": "சாதனத்தின் பெயர்", + "failed": "சாதனத்தின் தரவுகளை காண்பிக்க இயலவில்லை", + "removeDevice": "நீக்கு", + "title": "சாதனங்கள்" + }, + "profile": { + "finish": "எடிட்டிங் முடிக்கவும்", + "firstColor": "Profile நிறம் ஒன்று", + "secondColor": "Profile நிறம் இரண்டு", + "title": "Profile படத்தைத் திருத்தவும்", + "userIcon": "பயனர் icon" + }, + "register": { + "cta": "தொடங்குங்கள்", + "text": "ஒன்றுக்கு மேற்பட்ட சாதனங்களுக்கு இடையே உங்களின் காட்சி நேரத்தை பகிர்ந்து அவற்றை ஒத்திசைத்து வைக்கவும்.", + "title": "sudo-cloud இல் Sync செய்யவும்" + }, + "title": "கணக்கு" + }, + "appearance": { + "activeTheme": "செயலில் உள்ளது", + "themes": { + "blue": "நீலம்", + "default": "இயல்பு அமைப்பு", + "gray": "சாம்பல்", + "red": "சிவப்பு", + "teal": "அடர் பச்சை" + }, + "title": "தோற்றம்" + }, + "connections": { + "server": { + "description": "நீங்கள் உங்கள் தரவுகளை உங்களின் தனிப்பட்ட பின்தளம் (Backend) இல் சேமிக்க விரும்பினால் இதை தெரிவு செய்து URL யை உள்ளீடு செய்யவும்", + "label": "தனிப்பயன் சர்வர்", + "urlLabel": "தனிப்பட்ட சர்வரின் URL" + }, + "setup": { + "doSetup": "அமைக்கவும்", + "errorStatus": { + "description": "இந்த அமைப்பில் உள்ள ஒன்று அல்லது அதற்கு மேற்பட்ட உருப்படிகளுக்கு உங்கள் கவனம் தேவை என்று தெரிகிறது.", + "title": "உங்களின் கவனம் இங்கு தேவைப்படுகிறது" + }, + "itemError": "இந்த அமைப்பில் ஏதோ தவறு உள்ளது. அதை சரிசெய்ய மீண்டும் அமைவு வழியாக செல்லவும்.", + "items": { + "default": "இயல்புநிலை அமைப்பு", + "extension": "நீட்டிப்பு", + "proxy": "தனிப்பயன் Proxy" + }, + "redoSetup": "அமைப்பை மீண்டும் செய்", + "successStatus": { + "description": "உங்களுக்குப் பிடித்த மீடியாவைப் பார்க்கத் தொடங்குவதற்கு அனைத்து விஷயங்களும் இங்கு உள்ளன.", + "title": "அணைத்தும் சரியாக உள்ளது!" + }, + "unsetStatus": { + "description": "Setup Process யை தொடங்க வலதுபுறத்தில் உள்ள பொத்தானைக் கிளிக் செய்யவும்.", + "title": "நீங்கள் அமைப்பிற்குச் செல்லவில்லை" + } + }, + "title": "இணைப்புகள்", + "workers": { + "addButton": "புதிய worker யை சேர்க்கவும்", + "description": "இந்த பயன்பாடு செயல்பட அனைத்து இணைய போக்குவரத்தும் இந்த proxies வழியாக அனுப்பப்பட உள்ளது. உங்களின் தனிப்பட்ட workers யை உபயோகிக்க இதை தெரிவு செய்யவும். <0>வழிமுறைகள்.", + "emptyState": "எந்தவொரு workers ம் இல்லை. கீழே புதியதாக சேர்க்கவும்", + "label": "Custom proxy workers யை உபயோகப்படுத்த", + "urlLabel": "Worker URL கள்", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "பயன்பாட்டின் மொழி", + "languageDescription": "பயன்பாடு முழுமைக்கும் மொழி பயன்படுத்தப்பட்டது.", + "thumbnail": "சிறுபடங்களை உருவாக்கவும்", + "thumbnailDescription": "பெரும்பாலான நேரங்களில், வீடியோக்களில் சிறுபடங்கள் இருக்காது. அவற்றை உருவாக்க இந்த அமைப்பை நீங்கள் இயக்கலாம். ஆனால் அவை உங்கள் வீடியோவை மெதுவாக்கும்.", + "thumbnailLabel": "சிறுபடங்களை உருவாக்கவும்", + "title": "விருப்பங்கள்" + }, + "reset": "மீட்டமை", + "save": "சேமி", + "sidebar": { + "info": { + "appVersion": "பயன்பாட்டின் பதிப்பு", + "backendUrl": "பின்தள URL", + "backendVersion": "பின்தள பதிப்பு", + "hostname": "Hostname", + "insecure": "பாதுகாப்பற்றது", + "notLoggedIn": "நீங்கள் உள்நுழையவில்லை", + "secure": "பாதுகாப்பானது", + "title": "பயன்பாட்டின் தகவல்கள்", + "unknownVersion": "தெரியவில்லை", + "userId": "பயனர் ID" + } + }, + "subtitles": { + "backgroundLabel": "பின்னணி ஒளிபுகாநிலை (Background opacity)", + "colorLabel": "நிறம்", + "previewQuote": "நான் பயப்படக்கூடாது. பயம் மனதைக் கொல்லும்.", + "textSizeLabel": "எழுத்து அளவு", + "title": "வசன வரிகள்" + }, + "unsaved": "உங்களிடம் சேமிக்கப்படாத மாற்றங்கள் உள்ளன" + } +} diff --git a/src/assets/locales/th.json b/src/assets/locales/th.json new file mode 100644 index 0000000..efdbc9e --- /dev/null +++ b/src/assets/locales/th.json @@ -0,0 +1,414 @@ +{ + "about": { + "description": "SkoolTV เป็นเว็บแอปพลิเคชันที่ค้นหาสตรีมทางอินเทอร์เน็ต ทีมงานตั้งเป้าไปที่แนวทางการบริโภคเนื้อหาแบบมินิมอลเป็นส่วนใหญ่", + "faqTitle": "คําถามทั่วไป", + "q1": { + "body": "SkoolTV ไม่ได้เป็นเจ้าของเนื้อหาใด ๆ เมื่อคุณคลิกที่บางสิ่งเพื่อดู อินเทอร์เน็ตจะถูกค้นหาสื่อที่เลือก (บนหน้าจอโหลดและในแท็บ 'แหล่งวิดีโอ' คุณจะเห็นว่าคุณกําลังใช้แหล่งใด) สื่อไม่เคยถูกอัปโหลดโดย SkoolTV ทุกอย่างผ่านกลไกการค้นหานี้", + "title": "เนื้อหามาจากที่ไหน?" + }, + "q2": { + "body": "ไม่สามารถขอซีรี่ย์หรือภาพยนตร์ได้ SkoolTV ไม่ได้จัดการเนื้อหาใด ๆ เนื้อหาทั้งหมดถูกดูผ่านแหล่งข้อมูลบนอินเทอร์เน็ต", + "title": "ฉันจะขอซีรี่ย์หรือภาพยนตร์ได้ที่ไหน?" + }, + "q3": { + "body": "ผลการค้นหาของเราขับเคลื่อนโดย The Movie Database (TMDB) และจะแสดงไม่ว่าแหล่งข้อมูลของเราจะมีเนื้อหาจริงหรือไม่", + "title": "ผลการค้นหาซีรี่ย์หรือภาพยนตร์ ทําไมฉันถึงเล่นไม่ได้?" + }, + "title": "เกี่ยวกับ SkoolTV" + }, + "actions": { + "copied": "คัดลอกแล้ว", + "copy": "คัดลอก" + }, + "auth": { + "createAccount": "ยังไม่มีบัญชีใช่หรือไม่?<0>สร้างบัญชี", + "deviceNameLabel": "ชื่ออุปกรณ์", + "deviceNamePlaceholder": "โทรศัพท์ส่วนบุคคล", + "generate": { + "description": "รหัสผ่านของคุณถูกตั้งเช่นเดียวกับชื่อผู้ใช้และรหัสผ่าน โปรดตรวจสอบให้แน่ใจว่ารหัสผ่านของคุณถูกเก็บอย่างปลอดภัย คุณจำเป็นต้องใช้เพื่อเข้าสู่ระบบบัญชีของคุณ", + "next": "ฉันบันทึกรหัสผ่านของฉันแล้ว", + "passphraseFrameLabel": "หรัสผ่าน", + "title": "หรัสผ่านของคุณ" + }, + "hasAccount": "คุณมีบัญชีแล้วหรือไม่? <0>เข้าสู่ระบบที่นี่.", + "login": { + "description": "โปรดป้อนสหัสผ่านของคุณเพื่อเข้าสู่ระบบ", + "deviceLengthError": "โปรดป้อนชื่ออุปกรณ์ของคุณ", + "passphraseLabel": "หรัสผ่าน 12 ตัว", + "passphrasePlaceholder": "หรัสผ่าน", + "submit": "เข้าสู่ระบบ", + "title": "เข้าสู่ระบบบัญชีของคุณที่นี่", + "validationError": "รหัสผ่านไม่ถูกต้อง หรือ รหัสผ่านไม่สมบูรณ์" + }, + "register": { + "information": { + "color1": "สีโปรไฟล์ 1", + "color2": "สีโปรไฟล์ 2", + "header": "โปรดใส่ชื่ออุปกรณ์ของคุณและเลือกสีจากนั้นเลือกสัญลักษณ์ผู้ใช้ที่คุณต้องการ", + "icon": "สัญลักษณ์ผู้ใช้", + "next": "ต่อไป", + "title": "ข้อมูลบัญชี" + } + }, + "trust": { + "failed": { + "text": "คุณทำตามขั้นตอนอย่างถูกต้องหรือไม่?", + "title": "การเข้าสู่ระบบล้มเหลว" + }, + "host": "คุณกำลังเชื่อมต่อกับ <0>{{hostname}} - โปรดกดตกลงเชื่อถือเครือข่ายนี้ก่อนสร้างบัญชี", + "no": "ย้อนกลับ", + "title": "คุณเชื่อเครือข่ายนี้หรือไม่?", + "yes": "ฉันเชื่อเครือข่ายนี้" + }, + "verify": { + "description": "โปรดป้อนรหัสผ่านก่อนหน้านี้ของคุณ เพื่อยืนยันว่าคุณได้บันทึกและเพื่อสร้างบัญชีของคุณ", + "invalidData": "ข้อไม่ถูกต้อง", + "noMatch": "รหัสผ่านไม่ตรงกัน", + "passphraseLabel": "รหัสผ่าน 12 ตัว ของคุณ", + "recaptchaFailed": "การตรวจสอบล้มเหลว", + "register": "สร้างบัญชี", + "title": "ยืนยันรหัสผ่านของคุณ" + } + }, + "errors": { + "badge": "ไม่สามารถใช้งานได้", + "details": "ข้อมูลผิดพลาด", + "reloadPage": "โหลดหน้าใหม่", + "showError": "แสดงข้อมูลที่ผิดพลาด", + "title": "เราพบข้อผิดพลาด!" + }, + "footer": { + "legal": { + "disclaimer": "ข้อจํากัดความรับผิดชอบ", + "disclaimerText": "SkoolTV ไม่ได้เป็นเจ้าของไฟล์ใด ๆ เป็นเพียงลิงก์ไปยังบริการของบุคคลที่สาม ประเด็นทางกฎหมายควรดําเนินการกับเจ้าของไฟล์ และผู้ให้บริการ SkoolTV ไม่รับผิดชอบต่อไฟล์สื่อใด ๆ ที่แสดงโดยผู้ให้บริการวิดีโอ" + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "ดูรายการซีรี่ย์และภาพยนตร์ที่คุณชื่นชอบด้วยแอปสตรีมนี้" + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "เกี่ยวกับ", + "dmca": "DMCA", + "login": "เข้าสู่ระบบ", + "pagetitle": "{{title}} - SkoolTV", + "register": "ลงทะเบียน", + "settings": "ตั้งค่า" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "รายการของฉัน" + }, + "continueWatching": { + "sectionTitle": "ดูต่อ" + }, + "mediaList": { + "stopEditing": "หยุดแก้ไข" + }, + "search": { + "allResults": "นั่นคือทั้งหมดที่เรามี!", + "failed": "ไม่พบสื่อนี้ ลองอีกครั้ง!", + "loading": "กำลังโหลด..", + "noResults": "เราไม่พบอะไรเลย!", + "placeholder": { + "default": "คุณอยากดูอะไรคะ?", + "extra": [] + }, + "sectionTitle": "ผลการค้นหา" + }, + "titles": { + "day": { + "default": "คุณอยากดูเรื่องอะไรในช่วงบ่ายนี้?" + }, + "morning": { + "default": "คุณอยากดูอะไรเช้านี้?", + "extra": ["ฉันได้ยินมาว่าเรื่อง Before Sunrise สนุก"] + }, + "night": { + "default": "คุณอยากดูเรื่องอะไรในช่วงค่ำ?", + "extra": ["เหนื่อยมั้ย? ฉันได้ยินมาว่า The Exorcist นั้นดี"] + } + } + }, + "media": { + "episodeDisplay": "ภ{{season}} ต{{episode}}", + "types": { + "movie": "ภาพยนตร์", + "show": "ซีรี่ย์" + } + }, + "navigation": { + "banner": { + "offline": "ตรวจสอบการเชื่อมต่ออินเทอร์เน็ตของคุณ" + }, + "menu": { + "about": "เกี่ยวกับเรา", + "logout": "ออกจากระบบ", + "register": "เชื่อมต่อกับคลาวด์", + "settings": "ตั้งค่า", + "support": "ช่วยเหลือ" + } + }, + "notFound": { + "badge": "ไม่พบ", + "goHome": "กลับไปที่หน้าหลัก", + "message": "เรามองหาทั่วทุกที่แล้ว : ใต้ถังขยะ ในตู้เสื้อผ้า และข้างหลังพร็อกซิ แต่เราไม่พบหน้าที่คุณตามหา", + "title": "ไม่พบหน้านั้น" + }, + "overlays": { + "close": "ปิด" + }, + "player": { + "back": { + "default": "กลับไปที่หน้าหลัก", + "short": "กลับ" + }, + "casting": { + "enabled": "เชื่อมต่ออุปกรณ์.." + }, + "menus": { + "downloads": { + "disclaimer": "การดาวน์โหลดจะถูกนํามาจากผู้ให้บริการโดยตรง SkoolTV ไม่สามารถควบคุมวิธีการดาวน์โหลดได้", + "downloadSubtitle": "ดาวน์โหลดคำบรรยายนี้", + "downloadVideo": "ดาวน์โหลดวิดีโอ", + "hlsDisclaimer": "การดาวน์โหลดจะเป็นการดาวน์โหลดโดยตรงจากผู้ให้บริการ โดยเว็บไซต์ SkoolTV ไม่สามารถควบคุมวิธีการที่ไฟล์จะถูกดาวน์โหลด โปรดทราบว่าหากคุณกำลังดาวน์โหลดเพลย์ลิสต์ HLS ซึ่งมีจุดประสงค์สำหรับผู้ใช้ที่มีความเข้าใจใน สตรีมมิ่ง และมัลติมีเดียขั้นสูง.", + "onAndroid": { + "1": "หากต้องการดาวน์โหลดบน Android ให้คลิกปุ่มดาวน์โหลด จากนั้นในหน้าใหม่ แตะ บนวิดีโอค้างไว้ จากนั้นเลือก บันทึก", + "shortTitle": "ดาวน์โหลด / Android", + "title": "กําลังดาวน์โหลดบน Android" + }, + "onIos": { + "1": "หากต้องการดาวน์โหลดบน iOS ให้คลิกปุ่มดาวน์โหลด จากนั้นในหน้าใหม่ ให้คลิก จากนั้น บันทึกลงในไฟล์ ", + "shortTitle": "ดาวน์โหลด / iOS", + "title": "กําลังดาวน์โหลดบน iOS" + }, + "onPc": { + "1": "คลิกปุ่มดาวน์โหลดบนคอมพิวเตอร์ จากนั้นในหน้าใหม่ คลิกขวาที่วิดีโอแล้วเลือก บันทึกวิดีโอเป็น", + "shortTitle": "ดาวน์โหลด / คอมพิวเตอร์", + "title": "กําลังดาวน์โหลดบนคอมพิวเตอร์" + }, + "title": "ดาวน์โหลด" + }, + "episodes": { + "button": "ตอน", + "emptyState": "ไม่มีตอนเหล่านี้ในภาคนี้ โปรดกลับมาดูทีหลัง!", + "episodeBadge": "ตอนที่ {{episode}}", + "loadingError": "การโหลดภาคผิดพลาด", + "loadingList": "กำลังโหลด…", + "loadingTitle": "กำลังโหลด…" + }, + "playback": { + "speedLabel": "ความเร็วในการเล่น", + "title": "การตั้งค่าการเล่น" + }, + "quality": { + "automaticLabel": "คุณภาพอัตโนมัติ", + "hint": "คุณสามารถลอง <0>สลับแหล่งที่มา เพื่อรับตัวเลือกคุณภาพที่แตกต่างกัน", + "iosNoQuality": "เนื่องจากข้อจํากัดที่กําหนดโดย Apple การเลือกคุณภาพจึงไม่พร้อมใช้งานบน iOS สําหรับแหล่งข้อมูลนี้ คุณสามารถลอง <0>สลับไปยังแหล่งอื่น เพื่อรับตัวเลือกคุณภาพที่แตกต่างกัน", + "title": "คุณภาพ" + }, + "settings": { + "downloadItem": "ดาวน์โหลด", + "enableSubtitles": "เปิดคำบรรยาย", + "experienceSection": "ประสบการณ์รับชม", + "playbackItem": "ตั้งค่าการเล่น", + "qualityItem": "คุณภาพ", + "sourceItem": "แหล่งที่มาของวิดีโอ", + "subtitleItem": "ตั้งค่าคำบรรยาย", + "videoSection": "ตั้งค่าวิดีโอ" + }, + "sources": { + "failed": { + "text": "มีข้อผิดพลาดขณะพยายามค้นหาวิดีโอ โปรดลองใช้แหล่งอื่น", + "title": "ค้นหาไม่พบ" + }, + "noEmbeds": { + "text": "เราไม่พบการฝังใด ๆ โปรดลองใช้แหล่งอื่น", + "title": "ไม่พบการฝัง" + }, + "noStream": { + "text": "แหล่งที่มานี้ไม่มีสตรีมสำหรับภาพยนตร์หรือซีรี่ย์เรื่องนี้", + "title": "ไม่มีสตรีม" + }, + "title": "แหล่งที่มา", + "unknownOption": "ไม่ทราบ" + }, + "subtitles": { + "customChoice": "เลือกคำบรรยายจากไฟล์", + "customizeLabel": "ปรับแต่ง", + "offChoice": "ปิด", + "settings": { + "backlink": "คำบรรยายแบบกำหนดเอง", + "delay": "เวลาดีเลย์คำบรรยาย" + }, + "title": "คำบรรยาย", + "unknownLanguage": "ไม่ทราบ" + } + }, + "metadata": { + "failed": { + "badge": "ล้มเหลว", + "homeButton": "กลับหน้าหลัก", + "text": "ไม่สามารถโหลดข้อมูล meta ของสื่อจาก TMDB ได้ โปรดตรวจสอบว่า TMDB ล่มหรือถูกบล็อกในการเชื่อมต่ออินเทอร์เน็ตของคุณ", + "title": "โหลดข้อมูล meta ไม่สำเร็จ" + }, + "notFound": { + "badge": "ไม่พบ", + "homeButton": "กลับไปที่หน้าหลัก", + "text": "เราไม่พบสื่อที่คุณร้องขอ ไม่ว่าจะถูกลบออก หรือคุณดัดแปลงกับ URL", + "title": "ไม่พบสื่อ" + } + }, + "nextEpisode": { + "cancel": "ยกเลิก", + "next": "ตอนต่อไป" + }, + "playbackError": { + "badge": "เกิดข้อผิดพลาดในการเล่น", + "errors": { + "errorAborted": "การดึงข้อมูลสื่อถูกยกเลิกโดยคําขอของผู้ใช้", + "errorDecode": "แม้จะได้รับการพิจารณาก่อนหน้านี้ว่าใช้งานได้ แต่เกิดข้อผิดพลาดขณะพยายามถอดรหัสทรัพยากรสื่อ จึงส่งผลให้เกิดข้อผิดพลาด", + "errorGenericMedia": "เกิดข้อผิดพลาดของสื่อที่ไม่รู้จัก", + "errorNetwork": "เกิดข้อผิดพลาดของเครือข่ายบางประเภทซึ่งทําให้ไม่สามารถดึงสื่อได้สําเร็จ แม้ว่าจะเคยใช้งานมาก่อนก็ตาม", + "errorNotSupported": "ไม่รองรับสื่อหรือวัตถุของผู้ให้บริการสื่อ" + }, + "homeButton": "กลับหน้าหลัก", + "text": "เกิดข้อผิดพลาดในการเล่นวิดีโอ โปรดลองอีกครั้ง", + "title": "เกิดข้อผิดพลาดในการเล่นวิดีโอ!" + }, + "scraping": { + "items": { + "failure": "เกิดข้อผิดพลาด", + "notFound": "ไม่มีวิดีโอ", + "pending": "กำลังตรวจสอบวิดีโอ…" + }, + "notFound": { + "badge": "ไม่พบ", + "detailsButton": "แสดงรายละเอียด", + "homeButton": "กลับหน้าหลัก", + "text": "เราได้ค้นหาผ่านผู้ให้บริการของเราและไม่พบสื่อที่คุณกําลังมองหา! เราไม่ได้เป็นเจ้าของสื่อและไม่สามารถควบคุมสิ่งที่ไม่มีอยู่ได้ โปรดคลิก “แสดงรายละเอียด” ด้านล่างสําหรับรายละเอียดเพิ่มเติม", + "title": "เราไม่พบสิ่งนั้น" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} หมดเวลา • สิ้นสุดใน {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + } + }, + "screens": { + "dmca": { + "text": "ยินดีต้อนรับสู่หน้าติดต่อ DMCA ของ SkoolTV! เราเคารพสิทธิ์ในทรัพย์สินทางปัญญาและต้องการแก้ไขข้อกังวลด้านลิขสิทธิ์อย่างรวดเร็ว หากคุณเชื่อว่างานที่มีลิขสิทธิ์ของคุณถูกใช้อย่างไม่เหมาะสมบนแพลตฟอร์มของเรา โปรดส่งประกาศ DMCA โดยละเอียดไปยังอีเมลด้านล่าง โปรดระบุคําอธิบายของเนื้อหาที่มีลิขสิทธิ์ รายละเอียดการติดต่อของคุณ และคําแถลงความเชื่อด้วยความสุจริต เรามุ่งมั่นที่จะแก้ไขเรื่องเหล่านี้อย่างทันท่วงทีและขอขอบคุณสําหรับความร่วมมือของคุณในการทําให้ SkoolTV เป็นสถานที่ที่เคารพความคิดสร้างสรรค์และลิขสิทธิ์", + "title": "DMCA" + }, + "loadingApp": "กําลังโหลดแอปพลิเคชัน", + "loadingUser": "กําลังโหลดโปรไฟล์ของคุณ", + "loadingUserError": { + "logout": "ออกจากระบบ", + "reset": "รีเซ็ตเซิร์ฟเวอร์ที่กําหนดเอง", + "text": "โหลดโปรไฟล์ของคุณไม่สําเร็จ", + "textWithReset": "โหลดโปรไฟล์ของคุณจากเซิร์ฟเวอร์ที่กําหนดเองไม่สําเร็จ ต้องการย้อนกลับไปที่เซิร์ฟเวอร์เริ่มต้นหรือไม่?" + }, + "migration": { + "failed": "ไม่สามารถโยกย้ายข้อมูลของคุณได้", + "inProgress": "โปรดรอสักครู่ เรากําลังย้ายข้อมูลของคุณ สิ่งนี้ไม่ควรใช้เวลานาน" + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "ชื่ออุปกรณ์", + "deviceNamePlaceholder": "โทรศัพท์ส่วนบุคคล", + "editProfile": "แก้ไข", + "logoutButton": "ออกจากระบบ" + }, + "actions": { + "delete": { + "button": "ลบบัญชี", + "confirmButton": "ลบบัญชี", + "confirmDescription": "คุณแน่ใจหรือไม่ว่าต้องการลบบัญชีของคุณ? ข้อมูลทั้งหมดของคุณจะหายไป!", + "confirmTitle": "คุณแน่ใจใช่หรือไม่?", + "text": "การกระทํานี้ไม่สามารถย้อนกลับได้ ข้อมูลทั้งหมดจะถูกลบและไม่มีอะไรสามารถกู้คืนได้", + "title": "ลบบัญชี" + }, + "title": "พฤติกรรม" + }, + "devices": { + "deviceNameLabel": "ชื่ออุปกรณ์", + "failed": "โหลดเซสชันไม่สำเร็จ", + "removeDevice": "ลบ", + "title": "อุปกรณ์" + }, + "profile": { + "finish": "แก้ไขสำเสร็จ", + "firstColor": "สีของโปรไฟล์ 1", + "secondColor": "สีของโปรไฟล์ 2", + "title": "แก้ไขรูปโปรไฟล์", + "userIcon": "สัญลักษณ์ผู้ใช้" + }, + "register": { + "cta": "เริ่มเลย", + "text": "แบ่งปันความคืบหน้าการรับชมระหว่างอุปกรณ์และเชื่อมต่อเข้าด้วยกัน", + "title": "เชื่อมต่อกับคลาวด์" + }, + "title": "บัญชี" + }, + "appearance": { + "activeTheme": "ใช้งาน", + "themes": { + "blue": "ฟ้า", + "default": "ค่าเริ่มต้น", + "gray": "เทา", + "red": "แดง", + "teal": "เขียวแกมน้ำเงิน" + }, + "title": "ธีม" + }, + "connections": { + "server": { + "description": "หากคุณต้องการเชื่อมต่อกับ backend ที่กําหนดเองเพื่อจัดเก็บข้อมูลของคุณ ให้เปิดใช้งานสิ่งนี้และระบุ URL", + "label": "กำหนดเซิร์ฟเวอร์เอง", + "urlLabel": "กําหนด URL เซิร์ฟเวอร์เอง" + }, + "title": "การเชื่อมต่อ", + "workers": { + "addButton": "เพิ่มผู้ช่วยใหม่", + "description": "เพื่อให้แอปพลิเคชันทํางาน การรับส่งข้อมูลทั้งหมดจะถูกส่งผ่านพร็อกซี่ เปิดใช้งานสิ่งนี้หากคุณต้องการนำเข้างานของคุณเอง", + "emptyState": "ยังไม่มีลูกทีม เพิ่มหนึ่งคนด้านล่าง", + "label": "ใช้พร็อกซี่แบบกําหนดเอง", + "urlLabel": "ลูกทีม URLs", + "urlPlaceholder": "https://" + } + }, + "reset": "เริ่มใหม่", + "save": "บันทึก", + "sidebar": { + "info": { + "appVersion": "เวอร์ชันแอป", + "backendUrl": "ระบบจัดการเว็บไซต์ URL", + "backendVersion": "เวอร์ชันหลัก", + "hostname": "ชื่อผู้ใช้", + "insecure": "ไม่ปลอดภัย", + "notLoggedIn": "คุณไม่ได้เข้าสู่ระบบ", + "secure": "ความปลอดภัย", + "title": "ข้อมูลแอปพลิเคชัน", + "unknownVersion": "ไม่ทราบ", + "userId": "รหัสผู้ใช้" + } + }, + "subtitles": { + "backgroundLabel": "ความทึบของพื้นหลัง", + "colorLabel": "สี", + "previewQuote": "คำบรรยายจะมีลักษณะแบบนี้", + "textSizeLabel": "ขนาดข้อความ", + "title": "คำบรรยาย" + }, + "unsaved": "คุณได้บันทึกการเปลี่ยนแปลงแล้ว" + } +} diff --git a/src/assets/locales/tok.json b/src/assets/locales/tok.json new file mode 100644 index 0000000..dc65aa1 --- /dev/null +++ b/src/assets/locales/tok.json @@ -0,0 +1,468 @@ +{ + "about": { + "description": "ilo Muwi-We li lukin li wile e sitelen. kulupu lawa li lawa pona", + "faqTitle": "sona wile", + "q1": { + "body": "ilo Muwi-We li mama ala e sitelen. sina lukin e sitelen la mi alasa e sitelen lon lipu ale. (sina ken sona e mama sitelen lon tenpo alasa lon poki 'mama'.) sitelen li awen ala lon ilo Muwi-We. ale li lon alasa ni", + "title": "sitelen li tan seme?" + }, + "q2": { + "body": "sina ken ala wile alasa e sitelen. ilo Muwi-We li lawa ala e sitelen. sitelen li tan lipu mama ante", + "title": "mi wile alasa e sitelen lon seme?" + }, + "q3": { + "body": "sitelen lon lukin ilo li tan lipu The Movie Database (lipu TMDB). jo li ante ala e ni", + "title": "sitelen pi wile mi li lon lukin ilo. seme la mi ken ala lukin e ona?" + }, + "title": "ilo Muwi-We la" + }, + "actions": { + "copied": "sama a", + "copy": "o sama" + }, + "auth": { + "createAccount": "sina jo ala e lipu open la <0>o pali e lipu open", + "deviceNameLabel": "nimi ilo", + "deviceNamePlaceholder": "ilo mi", + "generate": { + "description": "nimi open sina li lon nasin open pi lipu open sina. o awen pona e ona. sina open e lipu open sina la sina wile pana e nimi open ale sina", + "next": "mi jo e nimi open mi", + "passphraseFrameLabel": "nimi open", + "title": "nimi open sina" + }, + "hasAccount": "sina jo e lipu open la <0>o pana e nimi sina", + "login": { + "description": "lipu open sina la o sitelen e nimi ale sina", + "deviceLengthError": "o pana e nimi ilo", + "passphraseLabel": "nimi open 12", + "passphrasePlaceholder": "nimi open", + "submit": "o open", + "title": "o pana e nimi sina", + "validationError": "pakala" + }, + "register": { + "information": { + "color1": "kule nanpa wan", + "color2": "kule nanpa tu", + "header": "o pana e nimi pi ilo sina e kule e sitelen", + "icon": "sitelen", + "next": "o pana", + "title": "lipu open" + } + }, + "trust": { + "failed": { + "text": "nasin ale sina li pona anu seme?", + "title": "toki tawa lawa ilo li pakala" + }, + "host": "lawa ilo sina li <0>{{hostname}} - ona li pona tawa sina la sina ken pali e lipu open", + "no": "o weka", + "noHost": "lawa ilo ni li open ala li nasin ala la, sina ken ala pali e lipu open", + "noHostTitle": "lawa ilo li open ala a!", + "title": "lawa ilo ni li pona tawa sina anu seme?", + "yes": "lawa ilo ni li pona" + }, + "verify": { + "description": "sina awen e nimi open sina la o pana e nimi open", + "invalidData": "pakala", + "noMatch": "nimi li sama ala", + "passphraseLabel": "nimi open 12 sina", + "recaptchaFailed": "nasin ReCaptcha li pakala", + "register": "o pali e lipu open", + "title": "nimi open sina" + } + }, + "errors": { + "badge": "pakala a", + "details": "pakala", + "reloadPage": "o sin e lipu", + "showError": "o pana e sona pakala", + "title": "mi kama pakala a!" + }, + "footer": { + "legal": { + "disclaimer": "o sona e ni:", + "disclaimerText": "ilo Muwi-We li mama ala e ijo sitelen. ona li toki taso tawa ilo ante. utala nasin li lon la o toki tawa ona pi ilo ante. sitelen ale li tan ala ilo Muwi-We" + }, + "links": { + "discord": "kulupu Siko", + "dmca": "DMCA", + "github": "lipu Kita" + }, + "tagline": "o lukin e sitelen ale pi wile sina kepeken ilo ni" + }, + "global": { + "name": "ilo Muwi-We", + "pages": { + "about": "o sona", + "dmca": "DMCA", + "login": "o open", + "onboarding": "o pali", + "pagetitle": "{{title}} - ilo Muwi-We", + "register": "o pali open", + "settings": "o ante" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "poki awen" + }, + "continueWatching": { + "sectionTitle": "o awen lukin" + }, + "mediaList": { + "stopEditing": "o pini ante" + }, + "search": { + "allResults": "pini a!", + "failed": "lukin li pakala a! o alasa sin", + "loading": "alasa...", + "noResults": "ijo li lon ala a!", + "placeholder": { + "default": "sina wile lukin e seme?", + "extra": [ + "sina wile alasa e seme?", + "sina wile lukin e seme?", + "sitelen nanpa wan sina li seme?", + "sitelen nanpa wan sina li seme?" + ] + }, + "sectionTitle": "mi lukin e ni:" + }, + "titles": { + "day": { + "default": "tenpo suno ni la sina wile lukin e seme?", + "extra": ["sina pilin alasa la o lukin e sitelen Jurassic Park"] + }, + "morning": { + "default": "tenpo sin ni la sina wile lukin e seme?", + "extra": ["ken la sitelen Before Sunrise li pona"] + }, + "night": { + "default": "tenpo pimeja ni la sina wile lukin e seme?", + "extra": ["sina pilin lape anu seme? o alasa lukin e sitelen Exorcist"] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "sitelen wan", + "show": "sitelen kulupu" + } + }, + "navigation": { + "banner": { + "offline": "wawa linja sina li seme?" + }, + "menu": { + "about": "mi", + "logout": "o weka sona e sina", + "register": "Sync to sudo-cloud", + "settings": "o ante", + "support": "o supa" + } + }, + "notFound": { + "badge": "lon ala", + "goHome": "o tawa weka", + "message": "mi lukin lon anpa poki, lon insa tomo, lon monsi ilo. taso mi lukin ala e lipu pi wile sina", + "title": "mi ken ala lukin e lipu ona" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "ala" + }, + "start": { + "title": "o open e ilo Muwi-We" + } + }, + "overlays": { + "close": "o pini" + }, + "player": { + "back": { + "default": "o tawa weka", + "short": "o tawa" + }, + "casting": { + "enabled": "mi pana e sitelen tawa ilo ante..." + }, + "menus": { + "downloads": { + "disclaimer": "sina kama jo e sitelen tawa ilo sina tan lipu mama. ilo Muwi-We li lawa ala e nasin jo", + "downloadSubtitle": "o jo e nimi toki", + "downloadVideo": "o jo e sitelen", + "hlsDisclaimer": "jo li tan mama. ilo Muwi-We li lawa ala e nasin jo. o sona e ni: sina jo e lipu sitelen HLS. ni li tawa jan pi sona sitelen", + "onAndroid": { + "1": "ilo Android la o luka e nena 'o jo'. lon lipu sin la o luka wawa e sitelen. o luka e nena 'o jo'", + "shortTitle": "Android ) o jo", + "title": "o jo lon ilo Android" + }, + "onIos": { + "1": "ilo iOS la o luka e nena 'o jo'. lon lipu sin la o luka e , e o jo poki .", + "shortTitle": "iOS ) o jo", + "title": "o jo lon ilo iOS" + }, + "onPc": { + "1": "ilo suli la o luka e nena 'o jo e sitelen'. lon lipu sin la o luka ante e sitelen. o luka e nena 'o jo e sitelen lon nimi ante'", + "shortTitle": "ilo suli ) o jo", + "title": "o jo lon ilo suli" + }, + "title": "kama jo" + }, + "episodes": { + "button": "sitelen mute", + "emptyState": "kulupu ni li jo ala e sitelen. o lukin lon tenpo ante a!", + "episodeBadge": "E{{episode}}", + "loadingError": "alasa li pakala", + "loadingList": "alasa...", + "loadingTitle": "alasa...", + "unairedEpisodes": "sitelen li lon ala lukin la ken la sina lukin ala e ona" + }, + "playback": { + "speedLabel": "tenpo lukin", + "title": "nasin pali" + }, + "quality": { + "automaticLabel": "ilo o lawa", + "hint": "ante pi pona lukin la sina ken <0>ante e mama", + "iosNoQuality": "tan lawa pi esun Apple la ante pi pona lukin li ken ala lon ilo iOS. ante pi pona lukin la o alasa <0>ante e mama", + "title": "pona lukin" + }, + "settings": { + "downloadItem": "o jo", + "enableSubtitles": "nimi toki", + "experienceSection": "nasin lukin", + "playbackItem": "nasin pali", + "qualityItem": "pona lukin", + "sourceItem": "mama sitelen", + "subtitleItem": "nimi toki", + "videoSection": "nasin sitelen" + }, + "sources": { + "failed": { + "text": "lukin sitelen li pakala. o alasa e mama ante.", + "title": "pakala jo" + }, + "noEmbeds": { + "text": "mi lukin ala e lipu. o alasa e mama ante.", + "title": "lipu li lon ala" + }, + "noStream": { + "text": "lipu mama ni li jo ala e sitelen ni", + "title": "sitelen li lon ala" + }, + "title": "mama", + "unknownOption": "mi sona ala" + }, + "subtitles": { + "customChoice": "o pana tan ilo", + "customizeLabel": "o ante", + "offChoice": "ala", + "settings": { + "backlink": "nimi toki ante", + "delay": "o ante e tenpo nimi", + "fixCapitals": "o pona e suli nimi" + }, + "title": "nimi toki", + "unknownLanguage": "mi sona ala" + } + }, + "metadata": { + "dmca": { + "badge": "weka", + "text": "wile weka li kama tan mama sitelen la sitelen ni li ken ala", + "title": "sitelen li weka" + }, + "extensionPermission": { + "button": "o kepeken namako" + }, + "failed": { + "badge": "pakala", + "homeButton": "o tawa weka", + "text": "mi pakala alasa e sona sitelen tan lipu TMDB. ken la ona li lape anu moli", + "title": "mi pakala alasa e sona sitelen" + }, + "notFound": { + "badge": "lon ala", + "homeButton": "o tawa weka", + "text": "mi lukin ala e lipu pi wile sina. lipu li weka anu ante", + "title": "mi lukin ala e ona" + } + }, + "nextEpisode": { + "cancel": "o ala", + "next": "o sitelen sin" + }, + "playbackError": { + "badge": "pakala lukin", + "errors": { + "errorAborted": "jan li pini alasa e sitelen", + "errorDecode": "sitelen li kama ante la pakala li kama lon", + "errorGenericMedia": "pakala sitelen pi sona ala li lon", + "errorNetwork": "pakala linja li pakala e alasa sitelen", + "errorNotSupported": "mi ken ala supa e sitelen anu mama sitelen" + }, + "homeButton": "o tawa weka", + "text": "mi alasa lukin e sitelen. taso pakala li lon. o alasa sin", + "title": "mi pakala lukin a" + }, + "scraping": { + "items": { + "failure": "mi pakala", + "notFound": "sitelen li lon ala", + "pending": "mi alasa e sitelen..." + }, + "notFound": { + "badge": "lon ala", + "detailsButton": "o pana e sona", + "homeButton": "o tawa weka", + "text": "mi lukin e lipu mama ale mi. taso mi lukin ala e ijo pi wile sina. mi mama ala e sitelen. mi lawa ala e sitelen. o luka e nena anpa", + "title": "mi lukin ala e ona" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "tenpo {{timeLeft}} la o awen • tenpo {{timeFinished, datetime}} la ona li pini", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "sina jan la o pali e ilo Captcha lon poka ni. mi wile awen e ilo Muwi-We a!", + "error": "mi lukin e ni: ken la sina jan ala. o alasa sin", + "title": "sina o jan", + "verifyingHumanity": "sina jan ala jan?" + } + }, + "screens": { + "dmca": { + "title": "DMCA" + }, + "loadingApp": "mi alasa e ilo", + "loadingUser": "mi alasa e lipu sina", + "loadingUserError": { + "logout": "o weka sona e sina", + "reset": "o sin e lawa ilo sina", + "text": "alasa li pakala", + "textWithReset": "alasa tan lawa ilo sina li pakala. sina wile e lawa ilo mi anu seme?" + }, + "migration": { + "failed": "tawa pi sona sina li pakala", + "inProgress": "o awen lili. mi alasa tawa e sona sina" + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "nimi ilo", + "deviceNamePlaceholder": "ilo", + "editProfile": "o ante", + "logoutButton": "o weka sona e ona" + }, + "actions": { + "delete": { + "button": "o weka e ale", + "confirmButton": "o weka e ale", + "confirmDescription": "weka ni li suli li wawa mute a! sona ale sina li ken ala kama lon tenpo ante a!", + "confirmTitle": "sina wile e ni anu seme?", + "text": "tenpo kama la sina ken ala ante e weka ni. ale li kama weka", + "title": "o weka e ale" + }, + "title": "pali" + }, + "devices": { + "deviceNameLabel": "nimi ilo", + "failed": "alasa li pakala", + "removeDevice": "o weka", + "title": "ilo" + }, + "profile": { + "finish": "o ante", + "firstColor": "kule nanpa wan", + "secondColor": "kule nanpa tu", + "title": "o ante e sitelen", + "userIcon": "sitelen" + }, + "register": { + "cta": "o open", + "text": "o sama e lipu open sina tawa ilo sina ante", + "title": "o sama e lipu" + }, + "title": "lipu open" + }, + "appearance": { + "activeTheme": "lon", + "themes": { + "blue": "laso", + "default": "sama", + "gray": "pimeja", + "red": "loje", + "teal": "laso walo" + }, + "title": "kule" + }, + "connections": { + "server": { + "description": "sina wile e poki sona ante la o pana e nimi ona lon ni: <0>nasin", + "label": "lawa ante", + "urlLabel": "nimi pi lawa ante" + }, + "setup": { + "doSetup": "o pali", + "errorStatus": { + "description": "ni li wile e lukin sina", + "title": "o lukin" + }, + "itemError": "ni li pakala. o pali sin", + "items": { + "default": "pali sama", + "extension": "namako" + }, + "redoSetup": "o pali sin", + "successStatus": { + "description": "ijo ale li pona. sina ken lukin e sitelen ale pi wile sina", + "title": "pali li pini a!" + }, + "unsetStatus": { + "description": "o luka e nena lon poka ni tawa open pali", + "title": "sina pali ala" + } + }, + "title": "kulupu", + "workers": { + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "toki ilo", + "languageDescription": "ilo li toki kepeken toki ni", + "thumbnail": "o pali e sitelen awen", + "thumbnailDescription": "tenpo mute la, sitelen tawa li jo ala e sitelen awen. sina wile e sitelen lili pi lukin wan la o lon e ni. taso, ni li ken suli ike e tenpo sitelen sina", + "thumbnailLabel": "o pali e sitelen awen", + "title": "wile" + }, + "reset": "o weka e ante", + "save": "o ante", + "sidebar": { + "info": { + "appVersion": "nanpa ilo", + "hostname": "nimi mama", + "insecure": "ike", + "notLoggedIn": "mi sona ala e sina", + "secure": "pona", + "title": "sona ilo", + "unknownVersion": "mi sona ala", + "userId": "nanpa sina" + } + }, + "subtitles": { + "backgroundLabel": "kon", + "colorLabel": "kule", + "previewQuote": "kijetesantakalu tonsi li lanpan ala lanpan e soko?", + "textSizeLabel": "suli", + "title": "nimi toki" + }, + "unsaved": "ante sina li awen ala" + } +} diff --git a/src/assets/locales/tr.json b/src/assets/locales/tr.json new file mode 100644 index 0000000..c74cb9e --- /dev/null +++ b/src/assets/locales/tr.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "SkoolTV internette akışlar için tarama yapan bir web uygulamasıdır. Ekip, içerik tüketmeye karşı ekseriyetle minimalist bir yaklaşım sergilemektedir.", + "faqTitle": "Sıkça sorulan sorular", + "q1": { + "body": "SkoolTV herhangi bir içerik barındırmaz. İzlemek için bir şeye tıkladığınızda, seçilen medya için internette arama yapılır (Yükleme ekranında ve 'video kaynakları' sekmesinde hangi kaynağı kullandığınızı görebilirsiniz). Medya hiçbir zaman SkoolTV tarafından yüklenmez, her şey bu arama mekanizması aracılığıyla gerçekleşir.", + "title": "İçerikler nereden geliyor?" + }, + "q2": { + "body": "Bir dizi veya film talep etmek mümkün değildir, SkoolTV içeriklerin hiçbirini yönetmez. Tüm içerikler internet üzerindeki kaynaklar aracılığıyla görüntülenir.", + "title": "Bir dizi veya filmi nereden talep edebilirim?" + }, + "q3": { + "body": "Arama sonuçlarımız The Movie Database (TMDB) tarafından desteklenmektedir ve kaynaklarımızın içeriğe gerçekten sahip olup olmadığına bakılmaksızın görüntülenir.", + "title": "Arama sonuçları diziyi veya filmi gösteriyor, neden oynatamıyorum?" + }, + "title": "SkoolTV hakkında" + }, + "actions": { + "copied": "Kopyalandı", + "copy": "Kopyala" + }, + "auth": { + "createAccount": "Henüz bir hesabınız yok mu? <0>Hesap oluşturun.", + "deviceNameLabel": "Cihaz ismi", + "deviceNamePlaceholder": "Kişisel telefon", + "generate": { + "description": "Şifreleme anahtarınız, kullanıcı adınız ve parolanız olarak işlev görür. Hesabınıza giriş yapmak için bu parolayı girmeniz gerekeceğinden onu güvende tuttuğunuzdan emin olun", + "next": "Şifreleme anahtarımı kaydettim", + "passphraseFrameLabel": "Şifreleme anahtarı", + "title": "Şifreleme anahtarınız" + }, + "hasAccount": "Zaten hesabınız var mı?<0>Giriş yapın.", + "login": { + "description": "Hesabınıza giriş yapmak için lütfen şifreleme anahtarınızı girin", + "deviceLengthError": "Lütfen bir cihaz ismi girin", + "passphraseLabel": "12 kelimelik şifreleme anahtarı", + "passphrasePlaceholder": "Şifreleme anahtarı", + "submit": "Giriş yap", + "title": "Hesabınıza giriş yapın", + "validationError": "Yanlış veya eksik şifreleme anahtarı" + }, + "register": { + "information": { + "color1": "Birinci hesap rengi", + "color2": "İkinci hesap rengi", + "header": "Cihazınız için bir isim girin, zevkinize göre renk ve kullanıcı simgesi seçin", + "icon": "Kullanıcı simgesi", + "next": "İleri", + "title": "Hesap bilgisi" + } + }, + "trust": { + "failed": { + "text": "Doğru şekilde yapılandırdınız mı?", + "title": "Sunucuya ulaşılamadı" + }, + "host": "<0>{{hostname}} adlı sunucuya bağlanıyorsunuz - lütfen hesap oluşturmadan önce sunucuya güvendiğinizi onaylayın", + "no": "Geri dön", + "noHost": "Sunucu henüz yapılandırılmadığı için hesap oluşturamazsınız", + "noHostTitle": "Sunucu kullanılamıyor!", + "title": "Bu sunucuya güveniyor musunuz?", + "yes": "Bu sunucuya güveniyorum" + }, + "verify": { + "description": "Kaydettiğinizi doğrulamak ve hesabınızı oluşturmak için önceki aşamada gösterilen şifreleme anahtarınızı girin", + "invalidData": "Veri geçersiz", + "noMatch": "Şifreleme anahtarı eşleşmiyor", + "passphraseLabel": "12 kelimelik şifreleme anahtarınız", + "recaptchaFailed": "ReCaptcha doğrulaması başarısız", + "register": "Hesap oluştur", + "title": "Şifreleme anahtarınızı doğrulayın" + } + }, + "errors": { + "badge": "Bir şeyler ters gitti", + "details": "Hata detayları", + "reloadPage": "Sayfayı yenile", + "showError": "Hata ayrıntılarını göster", + "title": "Bir hatayla karşılaştık!" + }, + "footer": { + "legal": { + "disclaimer": "Sorumluluk Reddi", + "disclaimerText": "SkoolTV herhangi bir dosya barındırmaz, yalnızca 3. parti hizmetlere bağlantı verir. Yasal meseleler, dosya barındırıcıları ve sağlayıcıları ile görüşülmelidir. SkoolTV, video sağlayıcıları tarafından gösterilen hiçbir medya dosyasından sorumlu değildir." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Bu açık kaynaklı akış uygulamasıyla en sevdiğiniz dizileri ve filmleri izleyin." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Hakkında", + "dmca": "DMCA", + "login": "Giriş yap", + "onboarding": "Kur", + "pagetitle": "{{title}} - SkoolTV", + "register": "Kayıt ol", + "settings": "Ayarlar" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Yerimleri" + }, + "continueWatching": { + "sectionTitle": "İzlemeye devam edin" + }, + "mediaList": { + "stopEditing": "Düzenlemeyi bırak" + }, + "search": { + "allResults": "Bu kadarını bulabildik!", + "failed": "Medya bulunamadı, tekrar deneyin!", + "loading": "Yükleniyor...", + "noResults": "Hiçbir şey bulamadık!", + "placeholder": { + "default": "Ne izlemek istersiniz?", + "extra": [ + "Ne keşfetmek istiyorsunuz?", + "İzleme listenizde neler var?", + "Favori filmin ne?", + "En sevdiğiniz dizi ne?" + ] + }, + "sectionTitle": "Arama sonuçları" + }, + "titles": { + "day": { + "default": "Bu öğleden sonra ne izlemek istersiniz?", + "extra": [ + "Maceraperest mi hissediyorsun? Jurassic Park iyi bir seçim olabilir." + ] + }, + "morning": { + "default": "Bu sabah ne izlemek istersiniz?", + "extra": [ + "Before Sunrise'a iyi diyorlar" + ] + }, + "night": { + "default": "Bu akşam ne izlemek istersiniz?", + "extra": [ + "Yoruldun mu? The Exorcist'e iyi diyorlar." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} B{{episode}}", + "types": { + "movie": "Film", + "show": "Dizi" + }, + "unreleased": "Yayınlanmamış" + }, + "navigation": { + "banner": { + "offline": "İnternet bağlantınızı kontrol ediniz" + }, + "menu": { + "about": "Hakkımızda", + "logout": "Çıkış yap", + "register": "Buluta eşitle", + "settings": "Ayarlar", + "support": "Destekle" + } + }, + "notFound": { + "badge": "Bulunamadı", + "goHome": "Ana sayfaya dön", + "message": "Her yere baktık: bazanın altına, dolabın içine hatta ara sunucuya ama maalesef aradığınız sayfayı bulamadık.", + "title": "Sayfa bulunamadı" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "İptal Et", + "confirm": "Ön Tanımlı Ayarları Kullan", + "description": "Varsayılan ayarlar en iyi akış hizmetlerini sunmayabilir ve oldukça yavaş olabilir.", + "title": "Emin misiniz?" + }, + "extension": { + "back": "Geri Dön", + "explainer": "Tarayıcı uzantısını kullanarak, size sunduğumuz en iyi akışlara erişebilirsiniz. Kurulumu ise oldukça basit.", + "explainerIos": "Ne yazık ki, tarayıcı uzantısı iOS cihazlarında desteklenmemektedir. Geri Dön düğmesine basarak başka bir seçenek seçebilirsiniz.", + "extensionHelp": "Eklenti yüklediyseniz ancak algılamıyorsa, tarayıcınızın uzantı menüsünden eklentiyi açın ve ekran adımları takip edin.", + "linkChrome": "Chrome uzantısını yükleyin", + "linkFirefox": "Firefox uzantısını yükleyin", + "notDetecting": "Chrome'a yüklendi, ancak site algılamıyor mu? Sayfayı yenileyin!", + "notDetectingAction": "Sayfayı yenile", + "status": { + "disallowed": "Bu sayfa için uzantı etkinleştirilmemiş", + "disallowedAction": "Uzantıyı etkinleştir", + "failed": "Durum bilgisi alınamadı", + "loading": "Uzantıyı yüklemenizi bekliyoruz", + "outdated": "Uzantınız çok eski", + "success": "Uzantı sorunsuz çalışıyor!" + }, + "submit": "Devam Et", + "title": "Hadi bir uzantıyla başlayalım" + }, + "proxy": { + "back": "Geri Dön", + "explainer": "Ara sunucu yöntemiyle, yüksek kalitede yayınlara kolayca erişin.", + "input": { + "errorConnection": "Proxy'ye bağlanılamadı", + "errorInvalidUrl": "Geçerli bir URL değil", + "errorNotProxy": "Proxy bekleniyordu, web sitesine yönlendirildi", + "label": "Proxy URL", + "placeholder": "https://" + }, + "link": "Proxy oluşturmayı öğrenin", + "submit": "Proxy'yi Gönder", + "title": "Hadi yeni bir proxy oluşturalım" + }, + "start": { + "explainer": "En iyi akış deneyimi için kullanmak istediğiniz akış yöntemini seçmeniz gerekiyor.", + "options": { + "default": { + "text": "Yüksek kaliteli akış istemiyorum,<0 /> <1>varsayılan ayarı kullanın" + }, + "extension": { + "action": "Uzantıyı Yükle", + "description": "En iyi kaynaklara erişmek için tarayıcı uzantısını yükleyin.", + "quality": "En yüksek kalite", + "title": "Tarayıcı uzantısı" + }, + "proxy": { + "action": "Proxy'yi Kur", + "description": "Sadece 5 dakikada proxy kurun ve harika kaynaklara erişin.", + "quality": "İyi kalite", + "title": "Özel Proxy" + } + }, + "title": "SkoolTV ile sizi hazır hale getirelim" + } + }, + "overlays": { + "close": "Kapat" + }, + "player": { + "back": { + "default": "Ana sayfaya dön", + "short": "Geri dön" + }, + "casting": { + "enabled": "Cihaza yansıtılıyor..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "HLS oynatma listesi bağlantısını kopyala", + "disclaimer": "İndirme bağlantıları doğrudan sağlayıcının kendisinden alınır. SkoolTV'in sağlanan indirme bağlantıları üzerinde hiçbir konrolü yoktur.", + "downloadSubtitle": "Geçerli altyazıyı indir", + "downloadVideo": "Videoyu indir", + "hlsDisclaimer": "İndirmeler doğrudan sağlayıcıdan alınır. SkoolTV, indirmelerin nasıl sağlanacağı üzerinde kontrole sahip değildir.

Lütfen bir HLS oynatma listesi indirdiğinizi unutmayın; ileri seviye bilginiz yoksa indirmeniz önerilmez. akış biçimleri. Farklı formatlar için farklı kaynakları deneyin.", + "onAndroid": { + "1": "Android'e indirmek için önce indir butonuna basın, sonra açılan yeni sayfada video üzerine basılı tutun, ardından Videoyu indir seçeneğini seçin.", + "shortTitle": "İndir / Android", + "title": "Android'e indirme" + }, + "onIos": { + "1": "iOS'a indirmek için öncelikle indir butonuna basın, sonra açılan yeni sayfada 'e basın, hemen ardından Dosyalara Kaydet 'e basın.", + "shortTitle": "İndir / iOS", + "title": "iOS'a indirme" + }, + "onPc": { + "1": "Bilgisayarda önce indir butonuna tıklayın, sonra ise açılan yeni sayfada videoya sağ tıklayın ve Videoyu farklı kaydet seçeneğini seçin", + "shortTitle": "İndir / Bilgisayar", + "title": "Bilgisayara indirme" + }, + "title": "İndir" + }, + "episodes": { + "button": "Bölümler", + "emptyState": "Bu sezonda hiç bölüm yok, sonra tekrar deneyin!", + "episodeBadge": "B{{episode}}", + "loadingError": "Sezon yüklenirken hata oluştu", + "loadingList": "Yükleniyor...", + "loadingTitle": "Yükleniyor...", + "unairedEpisodes": "Bu sezondaki bir veya daha fazla bölüm henüz yayınlanmadığı için devre dışı bırakılmıştır." + }, + "playback": { + "speedLabel": "Oynatma hızı", + "title": "Oynatma ayarları" + }, + "quality": { + "automaticLabel": "Otomatik kalite", + "hint": "Farklı kalite seçenekleri elde etmek için <0>kaynak değiştirmeyi deneyebilirsiniz.", + "iosNoQuality": "Apple tarafından tanımlanan sınırlamalar nedeniyle, iOS'ta bu kaynak için kalite seçimi mevcut değildir. Farklı kalite seçenekleri elde etmek için <0>başka bir kaynağa geçmeyi deneyebilirsiniz.", + "title": "Kalite" + }, + "settings": { + "audioItem": "Ses", + "downloadItem": "İndir", + "enableSubtitles": "Altyazıları Etkinleştir", + "experienceSection": "İzleme deneyimi", + "playbackItem": "Oynatma ayarları", + "qualityItem": "Kalite", + "sourceItem": "Video kaynakları", + "subtitleItem": "Altyazı ayarları", + "videoSection": "Video ayarları" + }, + "sources": { + "failed": { + "text": "Video bulunmaya çalışılırken sorun oluştu, lütfen farklı bir kaynak deneyin.", + "title": "Video alınırken sorun oluştu" + }, + "noEmbeds": { + "text": "Herhangi bir video bulamadık, lütfen farklı bir kaynak deneyin.", + "title": "Video bulunamadı" + }, + "noStream": { + "text": "Bu kaynakta bu film ya da dizi için akış bulunmamaktadır.", + "title": "Akış yok" + }, + "title": "Kaynaklar", + "unknownOption": "Bilinmeyen" + }, + "subtitles": { + "customChoice": "Dosya sürükleyin veya yükleyin", + "customizeLabel": "Seçenekler", + "dropSubtitleFile": "Altyazı dosyasını buraya sürükleyin", + "offChoice": "Kapat", + "settings": { + "backlink": "Kişisel altyazılar", + "delay": "Altyazı gecikmesi", + "fixCapitals": "Büyük harf kullanımını düzelt" + }, + "title": "Altyazılar", + "unknownLanguage": "Bilinmeyen" + } + }, + "metadata": { + "api": { + "text": "API üstverisi yüklenemedi, lütfen internet bağlantınızı kontrol edin.", + "title": "API üstverisi yüklenemedi" + }, + "dmca": { + "badge": "Kaldırıldı", + "text": "Üzgünüz, bu içerik telif hakkı ihlali veya yayından kaldırma bildirimi nedeniyle kullanılamıyor.", + "title": "İçerik kaldırıldı" + }, + "extensionPermission": { + "badge": "İzin Gerekli", + "button": "Uzantıyı kullanın", + "text": "Tarayıcı uzantısını yüklemişsiniz, ancak uzantıyı kullanmaya başlamak için izninize ihtiyacımız var.", + "title": "Uzantıyı Kişiselleştir" + }, + "failed": { + "badge": "Başarısız oldu", + "homeButton": "Ana sayfaya dön", + "text": "Medyanın üstverisi TMDB'den alınamadı. Lütfen TMDB'nin göküp çökmediğini veya internet bağlantınız üzerinden engellenmediğini kontrol edin.", + "title": "Üstveri yüklenemedi" + }, + "notFound": { + "badge": "Bulunamadı", + "homeButton": "Ana sayfaya dön", + "text": "İstediğiniz medyayı bulamadık. URL'yi yanlış girdiniz ya da medya kaldırıldı.", + "title": "Medya bulunamadı." + } + }, + "nextEpisode": { + "cancel": "Vazgeç", + "next": "Sonraki bölüm" + }, + "playbackError": { + "badge": "Oynatma hatası", + "errors": { + "errorAborted": "Medyanın alınması kullanıcının isteği üzerine iptal edildi.", + "errorDecode": "Daha önce kullanılabilir olduğu belirlenmiş olmasına rağmen, medya kaynağının kodu çözülmeye çalışılırken bir hata oluştu ve bu da bir hataya neden oldu.", + "errorGenericMedia": "Bilinmeyen medya hatası oluştu.", + "errorNetwork": "Medya önceden mevcut olsa da başarıyla alınmasını engelleyen bir tür ağ hatası oluştu.", + "errorNotSupported": "Medya veya medya sağlayıcısı desteklenmiyor." + }, + "homeButton": "Ana sayfaya git", + "text": "Medya oynatılmaya çalışılırken bir hata oluştu. Lütfen tekrar deneyin.", + "title": "Video oynatılamadı!" + }, + "scraping": { + "extensionFailure": { + "badge": "Eklenti devre dışı", + "enableExtension": "Eklentiyi etkinleştir", + "homeButton": "Eve git", + "text": "SkoolTV uzantısını kurdunuz. Kullanmaya başlamak için, uzantıyı bu site için etkinleştirmeniz gerekiyor.", + "title": "Lütfen eklentiyi etkinleştirin" + }, + "items": { + "failure": "Hata oluştu", + "notFound": "Video mevcut değil", + "pending": "Videolar aranıyor..." + }, + "notFound": { + "badge": "Bulunamadı", + "detailsButton": "Ayrıntıları göster", + "homeButton": "Ana sayfaya git", + "text": "Sağlayıcılarımız arasında arama yaptık ve aradığınız medyayı bulamadık! Medyaları barındırmıyoruz ve mevcut olanlar üzerinde hiçbir kontrolümüz yok. Daha fazla ayrıntı için lütfen aşağıdaki 'Ayrıntıları göster' seçeneğine tıklayın.", + "title": "Bunu bulamadık" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} kaldı • {{timeFinished, datetime}}'de bitiyor", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Lütfen sağ taraftaki Captcha'yı çözerek insan olduğunuzu doğrulayın. Bu, SkoolTV'i güvende tutmak içindir!", + "error": "İnsan olduğunuz doğrulanamadı. Lütfen tekrar deneyin.", + "title": "İnsan olduğunuzu doğrulamamız gerekiyor.", + "verifyingHumanity": "İnsan olduğunuz doğrulanıyor..." + } + }, + "screens": { + "dmca": { + "text": "SkoolTV'in DMCA iletişim sayfasına hoş geldiniz! Fikri mülkiyet haklarına saygı duyuyoruz ve telif hakkıyla ilgili endişeleri hızlı bir şekilde ele almak istiyoruz. Telif hakkıyla korunan çalışmanızın platformumuzda uygunsuz şekilde kullanıldığını düşünüyorsanız lütfen aşağıdaki e-postaya ayrıntılı bir DMCA bildirimi gönderin. Lütfen telif hakkıyla korunan materyalin açıklamasını, iletişim bilgilerinizi ve iyi niyet beyanınızı ekleyin. Bu sorunları derhal çözmeye kararlıyız ve ayrıca SkoolTV'i yaratıcılığa ve telif haklarına saygılı bir yer olarak tutma konusundaki işbirliğiniz için teşekkür ederiz.", + "title": "DMCA" + }, + "loadingApp": "Uygulama yükleniyor", + "loadingUser": "Profiliniz yükleniyor", + "loadingUserError": { + "logout": "Çıkış yap", + "reset": "Özel sunucuyu sıfırla", + "text": "Profiliniz yüklenemedi", + "textWithReset": "Profiliniz özel sunucunuzdan yüklenemedi, varsayılan sunucuya sıfırlamak ister misiniz?" + }, + "migration": { + "failed": "Verileriniz taşınamadı.", + "inProgress": "Lütfen bekleyin, verilerinizi taşıyoruz. Bu çok uzun sürmez." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Cihaz adı", + "deviceNamePlaceholder": "Kişisel telefon", + "editProfile": "Düzenle", + "logoutButton": "Çıkış yap" + }, + "actions": { + "delete": { + "button": "Hesabı sil", + "confirmButton": "Hesabı sil", + "confirmDescription": "Hesabınızı silmek istediğinize emin misiniz? Tüm verileriniz kaybedilecek!", + "confirmTitle": "Emin misiniz?", + "text": "Bu işlem geri alınamaz. Tüm veriler silinir ve hiçbir şey kurtarılamaz.", + "title": "Hesabı sil" + }, + "title": "Eylemler" + }, + "devices": { + "deviceNameLabel": "Cihaz adı", + "failed": "Oturumlar yüklenemedi", + "removeDevice": "Sil", + "title": "Cihazlar" + }, + "profile": { + "finish": "Düzenlemeyi bitir", + "firstColor": "Birinci profil rengi", + "secondColor": "İkinci profil rengi", + "title": "Profil resmini düzenle", + "userIcon": "Kullanıcı simgesi" + }, + "register": { + "cta": "Hadi başlayalım", + "text": "İzleme ilerlemenizi cihazlar arasında paylaşın ve eşit tutun.", + "title": "Buluta eşitle" + }, + "title": "Hesap" + }, + "appearance": { + "activeTheme": "Aktif", + "themes": { + "blue": "Mavi", + "default": "Varsayılan", + "gray": "Gri", + "red": "Kırmızı", + "teal": "Turkuaz" + }, + "title": "Görünüm" + }, + "connections": { + "server": { + "description": "Verilerinizi depolamak için özel bir arkayüze bağlanmak istiyorsanız, bunu etkinleştirin ve URL'yi sağlayın. <0>Yönergeler.", + "label": "Özel sunucu", + "urlLabel": "Özel sunucu URL'si" + }, + "setup": { + "doSetup": "Başlayın", + "errorStatus": { + "description": "Kurulumda dikkat etmeniz gereken bir veya daha fazla öğe var gibi görünüyor.", + "title": "Dikkatinizi gerektiren bir şey var" + }, + "itemError": "Kurulum sırasında bir hata oluşmuş olabilir. Sorunu çözmek için kurulum adımlarını tekrar izleyin.", + "items": { + "default": "Varsayılan ayarlar", + "extension": "Tarayıcı uzantısı", + "proxy": "Özel Proxy" + }, + "redoSetup": "Kurulumu tekrar yapın", + "successStatus": { + "description": "Sevdiğiniz şeyleri izlemek için her şey hazır. Başlayın ve keyfini çıkarın.", + "title": "Tamam!" + }, + "unsetStatus": { + "description": "Kurulum sürecini başlatmak için lütfen sağdaki düğmeye tıklayın.", + "title": "Kurulumu tamamlamadınız" + } + }, + "title": "Bağlantılar", + "workers": { + "addButton": "Yeni işleyici ekle", + "description": "Uygulamanın çalışması için tüm trafik vekil sunucular üzerinden yönlendirilir. Kendi işleyicilerinizi getirmek istiyorsanız bunu etkinleştirin.<0>Yönergeler.", + "emptyState": "Henüz işleyici yok, aşağıya bir tane ekleyin", + "label": "Özel vekil sunucu işleyici kullan", + "urlLabel": "İşleyici URL'leri", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Uygulama dili", + "languageDescription": "Uygulamanın tamamı için seçili dil", + "thumbnail": "Küçük resimler oluştur", + "thumbnailDescription": "Çoğu video için ön izleme görseli bulunmaz. Bu ayarı etkinleştirerek anında oluşturulmasını sağlayabilirsiniz, ancak bu videonuzu yavaşlatabilir.", + "thumbnailLabel": "Küçük resim oluştur", + "title": "Ayarlar" + }, + "reset": "Sıfırla", + "save": "Kaydet", + "sidebar": { + "info": { + "appVersion": "Uygulama sürümü", + "backendUrl": "Arkayüz URL'si", + "backendVersion": "Arkayüz sürümü", + "hostname": "Ana makine adı", + "insecure": "Güvensiz", + "notLoggedIn": "Giriş yapmadınız", + "secure": "Güvenli", + "title": "Uygulama bilgisi", + "unknownVersion": "Bilinmeyen", + "userId": "Kullanıcı Kimliği" + } + }, + "subtitles": { + "backgroundBlurLabel": "Arka plan bulanıklığı", + "backgroundLabel": "Arka plan opaklığı", + "colorLabel": "Renk", + "previewQuote": "Korkmamalıyım. Korku aklın katilidir.", + "textSizeLabel": "Yazı boyutu", + "title": "Altyazılar" + }, + "unsaved": "Kaydedilmemiş değişiklikleriniz mevcut" + } +} diff --git a/src/assets/locales/uk.json b/src/assets/locales/uk.json new file mode 100644 index 0000000..a588302 --- /dev/null +++ b/src/assets/locales/uk.json @@ -0,0 +1,547 @@ +{ + "about": { + "description": "SkoolTV це веб-додаток, який шукає інтернет для стрімінгових відтворень. Команда прагне до мінімалістичного стилю в споживанні контенту.", + "faqTitle": "Загальні питання", + "q1": { + "body": "SkoolTV не зберігає жодного контенту. Коли ви натискаєте щось для перегляду, в Інтернеті виконується пошук вибраного медіа (на екрані завантаження та на вкладці «джерела відео» ви можете побачити, яке джерело ви використовуєте). Медіафайли ніколи не завантажуються за допомогою \"SkoolTV\", усе відбувається через цей механізм пошуку.", + "title": "Звідки береться вміст?" + }, + "q2": { + "body": "Неможливо подати запит на шоу чи фільм, оскільки SkoolTV не керує жодним вмістом. Весь контент переглядається через джерела в Інтернеті.", + "title": "Де я можу подати запит на шоу чи фільм?" + }, + "q3": { + "body": "Наші результати пошуку надходять від The Movie Database (TMDB) і відображаються незалежно від того, чи насправді є вміст у наших джерелах.", + "title": "Результати пошуку відображають шоу чи фільм, чому я не можу його відтворити?" + }, + "title": "Про SkoolTV" + }, + "actions": { + "copied": "Скопійовано", + "copy": "Копіювати" + }, + "auth": { + "createAccount": "У вас ще немає облікового запису? <0>Створити обліковий запис.", + "deviceNameLabel": "Ім'я пристрою", + "deviceNamePlaceholder": "Особистий телефон", + "generate": { + "description": "Ваша парольна фраза виступає як ваше ім'я користувача та пароль. Переконайтеся, що ви зберігаєте його в безпеці, оскільки вам буде потрібно вводити його для входу в свій обліковий запис", + "next": "Я зберіг(ла) свою парольну фразу", + "passphraseFrameLabel": "Парольна фраза", + "title": "Ваша парольна фраза" + }, + "hasAccount": "Вже є аккаунт? <0>Увійдіть тут.", + "login": { + "description": "Будь ласка, введіть свій пароль для входу до вашого облікового запису", + "deviceLengthError": "Будь ласка, введіть назву пристрою", + "passphraseLabel": "Парольна фраза з 12 слів", + "passphrasePlaceholder": "Парольна фраза", + "submit": "Логін", + "title": "Увійти до свого облікового запису", + "validationError": "Неправильна або неповна парольна фраза" + }, + "register": { + "information": { + "color1": "Перший колір профілю", + "color2": "Другий колір профілю", + "header": "Введіть ім'я для вашого пристрою та виберіть кольори та іконку користувача за вашим бажанням", + "icon": "Іконка користувача", + "next": "Наступний", + "title": "Інформація про обліковий запис" + } + }, + "trust": { + "failed": { + "text": "Чи ви налаштували це правильно?", + "title": "Не вдалося зв’язатися з сервером" + }, + "host": "Ви під’єднуєтеся до <0>{{hostname}} – підтвердьте, що довіряєте йому, перш ніж створювати обліковий запис", + "no": "Повернутися назад", + "noHost": "Сервер не був налаштований, тому ви не можете створити обліковий запис", + "noHostTitle": "Сервер не налаштований!", + "title": "Чи довіряєте ви цьому серверу?", + "yes": "Я довіряю цьому серверу" + }, + "verify": { + "description": "Будь ласка, введіть свою парольну фразу, яка була раніше, щоб підтвердити її збереження та створити обліковий запис", + "invalidData": "Дані недійсні", + "noMatch": "Парольна фраза не збігається", + "passphraseLabel": "Ваша парольна фраза з 12 слів", + "recaptchaFailed": "Валідація капчі не вдалася", + "register": "Створити акаунт", + "title": "Підтвердьте свою парольну фразу" + } + }, + "errors": { + "badge": "Це зламалося", + "details": "Деталі помилки", + "reloadPage": "Перезавантажити сторінку", + "showError": "Показати деталі помилки", + "title": "Ми зіткнулися з помилкою!" + }, + "footer": { + "legal": { + "disclaimer": "Застереження", + "disclaimerText": "SkoolTV не містить жодних файлів, він лише посилається на сторонні служби. Юридичні питання слід вирішувати з хостами та провайдерами файлів. SkoolTV не несе відповідальності за будь-які медіафайли, показані постачальниками відео." + }, + "links": { + "discord": "Діскорд", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Дивіться свої улюблені шоу та фільми за допомогою цього відкритого стрімінгового додатка." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Про", + "dmca": "DMCA", + "login": "Логін", + "onboarding": "Встановлення", + "pagetitle": "{{title}} - SkoolTV", + "register": "Зареєструватися", + "settings": "Налаштування" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Закладки" + }, + "continueWatching": { + "sectionTitle": "Продовжити перегляд" + }, + "mediaList": { + "stopEditing": "Зупинити редагування" + }, + "search": { + "allResults": "Це все, що ми маємо!", + "failed": "Не вдалося знайти медіафайли, повторіть спробу!", + "loading": "Завантаження...", + "noResults": "Ми не змогли знайти нічого!", + "placeholder": { + "default": "Що ви хочете подивитися?", + "extra": [ + "Що ви бажаєте дослідити?", + "Що у вашому списку спостереження?", + "Який ваш улюблений фільм?", + "Який ваш улюблений серіал?" + ] + }, + "sectionTitle": "Результати пошуку" + }, + "titles": { + "day": { + "default": "Що б ви хотіли подивитися сьогодні вдень?", + "extra": [ + "Хочете пригод? Парк Юрського періоду може стати ідеальним вибором." + ] + }, + "morning": { + "default": "Що б ви хотіли подивитися сьогодні вранці?", + "extra": [ + "Я чув, що \"Перед сходом сонця\" гарний" + ] + }, + "night": { + "default": "Що б ви хотіли подивитися сьогодні ввечері?", + "extra": [ + "Втомився? Я чув, що \"Екзорцист\" хороший." + ] + } + } + }, + "media": { + "episodeDisplay": "С{{season}} Е{{episode}}", + "types": { + "movie": "Фільм", + "show": "Шоу" + } + }, + "navigation": { + "banner": { + "offline": "Перевірте підключення до Інтернету" + }, + "menu": { + "about": "Про нас", + "logout": "Вийти", + "register": "Синхронізація з хмарою", + "settings": "Налаштування", + "support": "Підтримка" + } + }, + "notFound": { + "badge": "Не знайдено", + "goHome": "На головну", + "message": "Ми шукали всюди: під смітниками, у шафі, за проксі-сервером, але зрештою не змогли знайти сторінку, яку ви шукали.", + "title": "Не вдалося знайти цю сторінку" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Скасувати", + "confirm": "Використовувати налаштування за умовчанням", + "description": "Налаштування за замовчуванням не мають найкращих потоків і можуть бути нестерпно повільними.", + "title": "Ви впевнені?" + }, + "extension": { + "back": "Повернутись назад", + "explainer": "Використовуючи розширення для браузера, ви можете отримати найякісніші трансляції, які ми можемо запропонувати. Просто встановивши його.", + "explainerIos": "На жаль, розширення браузера не підтримується на iOS, натисніть Повернутися, щоб вибрати інший варіант.", + "extensionHelp": "Якщо ви встановили розширення, але воно не виявлено, відкрийте розширення в меню розширень вашого браузеру і дотримуйтеся вказівок на екрані.", + "linkChrome": "Встанови Chrome розширення", + "linkFirefox": "Встанови Firefox розширення", + "notDetecting": "Встановили в Chrome, але сайт його не виявляє? Спробуйте перезавантажити сторінку!", + "notDetectingAction": "Оновити сторінку", + "status": { + "disallowed": "Розширення не ввімкнено для цієї сторінки", + "disallowedAction": "Активувати розширення", + "failed": "Не вдалося отримати статус", + "loading": "Очікуємо, поки ви встановите розширення", + "outdated": "Версія розширення застаріла", + "success": "Розширення працює як очікувалося!" + }, + "submit": "Продовжити", + "title": "Почати використовувати розширення" + }, + "proxy": { + "back": "Повернутись назад", + "explainer": "З використанням проксі ви можете отримати високоякісні потоки, створивши самостійний проксі-сервіс.", + "input": { + "errorConnection": "Не вдалося підключитися до проксі", + "errorInvalidUrl": "Не валідний URL", + "errorNotProxy": "Очікувався проксі, але отримано вебсайт", + "label": "URL проксі", + "placeholder": "https://" + }, + "link": "Дізнайтесь як створити проксі", + "submit": "Надати проксі", + "title": "Давайте створимо новий проксі" + }, + "start": { + "explainer": "Щоб отримати найкращу трансляцію, вам потрібно буде вибрати, який метод стрімінгу ви хочете використовувати.", + "options": { + "default": { + "text": "Мені не потрібна хороша якість потоків,<0 /> <1>використовувати налаштування за замовчуванням" + }, + "extension": { + "action": "Встановити розширення", + "description": "Встановіть розширення для браузера та отримайте доступ до найкращих джерел.", + "quality": "Найкраща якість", + "title": "Розширення браузера" + }, + "proxy": { + "action": "Налаштування проксі", + "description": "Налаштуйте проксі всього за 5 хвилин і отримайте доступ до чудових джерел.", + "quality": "Гарна якість", + "title": "Користувацький проксі" + } + }, + "title": "Давайте налаштуємо вам SkoolTV" + } + }, + "overlays": { + "close": "Закрити" + }, + "player": { + "back": { + "default": "На головну", + "short": "Назад" + }, + "casting": { + "enabled": "Трансляція на пристрій..." + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "Копіювати посилання на плейлист HLS", + "disclaimer": "Завантаження беруться безпосередньо від провайдера. У SkoolTV немає контролю над тим, як надаються завантаження.", + "downloadSubtitle": "Завантажити поточні субтитри", + "downloadVideo": "Завантажити відео", + "hlsDisclaimer": "Завантаження виконуються безпосередньо від постачальника. У SkoolTV немає контролю над тим, як надаються завантаження.

Зверніть увагу, що ви завантажуєте список відтворення HLS, його не рекомендується завантажувати, якщо ви не знайомі з розширеними форматами потокового передавання. Спробуйте різні джерела для інших форматів.", + "onAndroid": { + "1": "Щоб завантажити на Android, натисніть кнопку завантаження, потім на новій сторінці торкніться й утримуйте відео, а потім виберіть зберегти.", + "shortTitle": "Завантажити / Android", + "title": "Завантажити на Android" + }, + "onIos": { + "1": "Щоб завантажити на iOS, натисніть кнопку завантаження, далі на новій сторінці, натисніть , а потім Зберегти у файли .", + "shortTitle": "Завантажити / iOS", + "title": "Завантаження на iOS" + }, + "onPc": { + "1": "На комп'ютері натисніть кнопку завантаження, далі на новій вкладці клацніть правим кліком по відео та виберіть Зберегти відео як", + "shortTitle": "Завантажити / Комп'ютер", + "title": "Завантаження на комп'ютер" + }, + "title": "Завантажити" + }, + "episodes": { + "button": "Епізоди", + "emptyState": "У цьому сезоні немає серій, перевірте пізніше!", + "episodeBadge": "Е{{episode}}", + "loadingError": "Помилка завантаження сезону", + "loadingList": "Завантаження...", + "loadingTitle": "Завантаження...", + "unairedEpisodes": "Один або кілька епізодів у цьому сезоні недоступні, оскільки вони ще не вийшли в ефір." + }, + "playback": { + "speedLabel": "Швидкість відтворення", + "title": "Налаштування відтворення" + }, + "quality": { + "automaticLabel": "Якість автоматична", + "hint": "Спробуйте <0>переключити джерело, аби отримати інші варіанти якості.", + "iosNoQuality": "Через обмеження, встановлені Apple, вибір якості не доступний у системі iOS для цього джерела. Ви можете спробувати <0>змінити джерело, щоб отримати інші варіанти якості.", + "title": "Якість" + }, + "settings": { + "downloadItem": "Завантажити", + "enableSubtitles": "Увімкнути субтитри", + "experienceSection": "Враження від перегляду", + "playbackItem": "Налаштування відтворення", + "qualityItem": "Якість", + "sourceItem": "Джерела відео", + "subtitleItem": "Налаштування субтитрів", + "videoSection": "Налаштування відео" + }, + "sources": { + "failed": { + "text": "Під час спроби знайти будь-яке відео сталася помилка. Спробуйте інше джерело.", + "title": "Не вдалося отримати дані" + }, + "noEmbeds": { + "text": "Ми не змогли знайти жодних вставок. Будь ласка, спробуйте інше джерело.", + "title": "Не знайдено вбудованих елементів" + }, + "noStream": { + "text": "Це джерело не має потоків для цього фільму чи шоу.", + "title": "Немає потоку" + }, + "title": "Джерела", + "unknownOption": "Невідомий" + }, + "subtitles": { + "customChoice": "Виберіть субтитри з файлу", + "customizeLabel": "Налаштувати", + "offChoice": "Вимкнено", + "settings": { + "backlink": "Власні субтитри", + "delay": "Затримка субтитрів", + "fixCapitals": "Виправити використання великих літер" + }, + "title": "Субтитри", + "unknownLanguage": "Невідомий" + } + }, + "metadata": { + "api": { + "text": "Не вдалося завантажити метадані API, перевірте підключення до Інтернету.", + "title": "Не вдалося завантажити метадані API" + }, + "dmca": { + "badge": "Видалено", + "text": "Це медіа більше не доступне через повідомлення про видалення або позов про порушення авторських прав.", + "title": "Медіа було видалено" + }, + "extensionPermission": { + "badge": "Дозвіл Відсутній", + "button": "Використовувати розширення", + "text": "У вас вже є розширення для браузера, але нам потрібен ваш дозвіл, щоб почати використовувати його.", + "title": "Налаштуйте продовження" + }, + "failed": { + "badge": "Не вдалося", + "homeButton": "Повернутися на головну", + "text": "Не вдалося завантажити метадані мультимедіа з TMDB. Перевірте, чи не відбувається збій TMDB або чи не є заблоковано у вашому інтернет-з'єднанні.", + "title": "Не вдалося завантажити метадані" + }, + "notFound": { + "badge": "Не знайдено", + "homeButton": "Повернутися на головну", + "text": "Не вдалося знайти запитані мультимедіа. Вони або були вилучені, або ви змінили URL.", + "title": "Не вдалося знайти це мультимедіа." + } + }, + "nextEpisode": { + "cancel": "Відмінити", + "next": "Наступний епізод" + }, + "playbackError": { + "badge": "Помилка відтворення", + "errors": { + "errorAborted": "Завантаження мультимедіа було скасовано на вимогу користувача.", + "errorDecode": "Незважаючи на те, що раніше було заявлено, що медіа-ресурс придатний для використання, при спробі декодування медіа-ресурсу виникла проблема, яка призвела до помилки.", + "errorGenericMedia": "Виникла невідома помилка мультимедіа.", + "errorNetwork": "Виникла якась помилка мережі, яка завадила успішному завантаженню мультимедіа, незважаючи на те, що раніше вони були доступні.", + "errorNotSupported": "Медіаоб'єкт або провайдер медіа не підтримується." + }, + "homeButton": "Повернутися на головну", + "text": "Сталася помилка при спробі відтворити медіа. Будь ласка спробуйте ще раз.", + "title": "Сталася помилка при відтворенні відео!" + }, + "scraping": { + "items": { + "failure": "Сталася помилка", + "notFound": "Не має цього відео", + "pending": "Шукаємо відео..." + }, + "notFound": { + "badge": "Не знайдено", + "detailsButton": "Показати деталі", + "homeButton": "Повернутись на головну сторінку", + "text": "Ми здійснили пошук серед наших провайдерів і не знайшли медіафайлів, які ви шукаєте! Ми не розміщуємо медіафайли та не контролюємо доступність. Будь ласка, натисніть 'Показати деталі' нижче, щоб дізнатися більше.", + "title": "Ми не знайшли цього" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} залишилось • Закінчити в {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Будь ласка, переконайтеся, що ви людина, заповнивши капчу праворуч. Це робиться для безпеки SkoolTV!", + "error": "Не вдалося підтвердити вашу людяність. Будь ласка, спробуйте ще раз.", + "title": "Ми повинні переконатися, що ви людина.", + "verifyingHumanity": "Перевіряємо вашу людяність..." + } + }, + "screens": { + "dmca": { + "text": "Вітаємо на нашій сторінці зв'язку DMCA! Ми поважаємо права інтелектуальної власності і хочемо вирішити будь-які проблеми з авторськими правами швидко. Якщо ви вважаєте, що ваші авторські права були неправильно використані на нашій платформі, будь ласка, надішліть детальне повідомлення DMCA на електронну адресу нижче. Будь ласка, вкажіть опис авторського матеріалу, ваші контактні дані та заяву про добросовісну віру. Ми зобов'язані вирішити ці питання оперативно і вдячні за вашу співпрацю в збереженні SkoolTV місцем, яке поважає творчість та авторські права.", + "title": "DMCA" + }, + "loadingApp": "Завантаження застосунку", + "loadingUser": "Завантаження вашого профілю", + "loadingUserError": { + "logout": "Вийти", + "reset": "Перезавантажити власний сервер", + "text": "Сталася помилка при завантаженні вашого профілю", + "textWithReset": "Сталася помилка при завантаженні вашого профілю з вашого сервера, чи бажаєте повернутись на стандартний сервер?" + }, + "migration": { + "failed": "Сталася помилка під час міграції даних.", + "inProgress": "Будь ласка, зачекайте, відбувається міграція ваших даних. Це не повинно зайняти багато часу." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Назва пристрою", + "deviceNamePlaceholder": "Номер телефону", + "editProfile": "Редагувати", + "logoutButton": "Вийти" + }, + "actions": { + "delete": { + "button": "Видалити акаунт", + "confirmButton": "Видалити акаунт", + "confirmDescription": "Ви впевнені, що хочете видалити свій акаунт? Всі ваші дані будуть втрачені!", + "confirmTitle": "Ви впевнені?", + "text": "Ця дія незворотна. Всі дані будуть видалені і нічого не можна буде відновити.", + "title": "Видалити акаунт" + }, + "title": "Дії" + }, + "devices": { + "deviceNameLabel": "Назва пристрою", + "failed": "Сталася помилка при завантаженні сесій", + "removeDevice": "Видалити", + "title": "Пристрої" + }, + "profile": { + "finish": "Завершити редагування", + "firstColor": "Перший колір профілю", + "secondColor": "Другий колір профілю", + "title": "Редагувати фото профілю", + "userIcon": "Іконка користувача" + }, + "register": { + "cta": "Зареєструватися", + "text": "Діліться своїм прогресом перегляду між пристроями та синхронізуйте їх.", + "title": "Синхронізація з хмарою" + }, + "title": "Обліковий запис" + }, + "appearance": { + "activeTheme": "Активна тема", + "themes": { + "blue": "Блакитний", + "default": "За замовчуванням", + "gray": "Сірий", + "red": "Червоний", + "teal": "Бірюзовий" + }, + "title": "Вигляд" + }, + "connections": { + "server": { + "description": "Якщо ви бажаєте підключитися до користувацького сервера для зберігання даних, увімкніть це та вкажіть URL-адресу. <0>Інструкції.", + "label": "Власний сервер", + "urlLabel": "URL сервера" + }, + "setup": { + "doSetup": "Виконайте налаштування", + "errorStatus": { + "description": "Здається, що один або декілька пунктів у цьому налаштуванні потребують вашої уваги.", + "title": "Дещо потребує вашої уваги" + }, + "itemError": "Щось не так із цією настройкою. Пройдіть налаштування ще раз, щоб виправити це.", + "items": { + "default": "Налаштування за замовчанням", + "extension": "Розширення", + "proxy": "Користувацький проксі" + }, + "redoSetup": "Повторити налаштування", + "successStatus": { + "description": "Усе готово для того, щоб ви могли почати дивитися улюблені медіа.", + "title": "Все готово!" + }, + "unsetStatus": { + "description": "Будь ласка, натисніть кнопку праворуч, щоб розпочати процес налаштування.", + "title": "Ви не завершили налаштування" + } + }, + "title": "З'єднання", + "workers": { + "addButton": "Додати нового працівника", + "description": "Щоб додаток працював, весь трафік маршрутизується через проксі-сервери. Увімкніть це, якщо ви хочете використовувати власні проксі воркери. <0>Інструкція.", + "emptyState": "Немає працівників", + "label": "Використовувати власних проксі-працівників", + "urlLabel": "URL-у працівника", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Мова додатку", + "languageDescription": "Мова застосована до всього додатку.", + "thumbnail": "Створити мініатюри", + "thumbnailDescription": "Часто відео не мають мініатюр. Ви можете активувати цей параметр для їх генерації під час відтворення, але це може уповільнити відтворення відео.", + "thumbnailLabel": "Сгенерувати мініатюри", + "title": "Параметри" + }, + "reset": "Скинути налаштування", + "save": "Зберегти", + "sidebar": { + "info": { + "appVersion": "Версія застосунку", + "backendUrl": "URL сервера", + "backendVersion": "Версія сервера", + "hostname": "Ім'я хоста", + "insecure": "Небезпечно", + "notLoggedIn": "Ви не увійшли", + "secure": "Безпечно", + "title": "Інформація про застосунок", + "unknownVersion": "Невідомо", + "userId": "ID користувача" + } + }, + "subtitles": { + "backgroundBlurLabel": "Розмиття фону", + "backgroundLabel": "Прозорість фону", + "colorLabel": "Колір", + "previewQuote": "Я не повинен боятися. Страх вбиває розум.", + "textSizeLabel": "Розмір шрифту", + "title": "Субтитри" + }, + "unsaved": "У вас є незбережені зміни" + } +} diff --git a/src/assets/locales/uwu.json b/src/assets/locales/uwu.json new file mode 100644 index 0000000..ae1f616 --- /dev/null +++ b/src/assets/locales/uwu.json @@ -0,0 +1,614 @@ +{ + "about": { + "description": "uwu-flix is a fowk of m-movie-web that is ensuwed t-to stay up even OwO a-a-aftew the shutdown of movie-web.app. uwu-flix wuns on a p-pwivate, sewf-hosted VPS. I wun this site at a woss; thewe awe nyo ads due t-to my bewiefs in fwee media.", + "faqTitle": "Common questions", + "q1": { + "body": "uwu-flix does nyot host any OwO content. When you cwick ^w^ on something t-to watch, the intewnyet is seawched fow the sewected media (-(On the w-w-woading scween and in the 'video s-souwces' tab you c-can see which souwce you'we using). Media nyevew gets upwoaded by majesty.wow, evewything is thwough this seawching mechanyism.", + "title": "Whewe does the content come fwom!?" + }, + "q2": { + "body": "I do nyot cowwect donyations fow uwu-flix. aww >w< donyations go diwectwy t-to the m-movie-web team's kofi", + "title": "Whewe do my donyations go?!?1" + }, + "q3": { + "body": "It's nyot possibwe t-to wequest a show ow (・`ω´・) m-movie, uwu-flix does nyot manyage any OwO content. aww >w< content is v-viewed thwough souwces on the intewnyet.", + "title": "Whewe c-can I wequest a show ow (・`ω´・) movie?" + }, + "q4": { + "body": "O-Ouw seawch wesuwts awe powewed by The Movie D-Database (TMDB) and d-d-dispway wegawdwess of whethew ouw souwces actuawwy have the content.", + "title": "the seawch wesuwts d-d-dispway the show ow (・`ω´・) m-movie, why can't I pway it?!?1" + }, + "q5": { + "body": "aww >w< data is synced t-to the sudo-backend which is diffewent than the communyity ;;w;; backend and is independentwy hosted by me, anyonye is fwee t-to use this as w-w-weww.", + "title": "What about my data and stuff?!!" + }, + "q6": { + "body": "Weww uwu-flix has a twittew account that c-can be found in the footew (・`ω´・) of this page as weww as a wink t-to the souwce code on Github.", + "title": "How c-can I find out m-m-mowe?!?!" + }, + "title": "About uwu-flix (^▽^)" + }, + "actions": { + "copied": "Copied", + "copy": "Copy" + }, + "auth": { + "createAccount": "Don't have an account yet 😬 <0>Cweate an account.", + "deviceNameLabel": "Device nyame", + "deviceNamePlaceholder": "Pewsonyaw phonye", + "generate": { + "description": "Youw passphwase acts as youw usewnyame ;;w;; and passwowd. Make suwe t-to k-k-keep i-it safe ;;w;; as you wiww nyeed t-to entew i-it t-to wogin t-to youw account. Do NyOT wose youw passphwase!", + "next": "I have saved my passphwase", + "passphraseFrameLabel": "Passphwase", + "title": "Your passphwase" + }, + "hasAccount": "Already have an account? <0>Login here.", + "login": { + "description": "Pwease entew youw passphwase t-to wogin t-to youw account", + "deviceLengthError": "Pwease entew a device nyame", + "passphraseLabel": "12-Word passphwase", + "passphrasePlaceholder": "passphwase", + "submit": "Login", + "title": "Login to your account", + "validationError": "Incorrect or incomplete passphwase /ᐠ. .ᐟ\\" + }, + "register": { + "information": { + "color1": "Profile color one", + "color2": "Profile color two", + "header": "Entew a nyame fow youw device then pick cowows and a usew icon of youw choosing!!11", + "icon": "User icon", + "next": "Next", + "title": "Account infowmation" + } + }, + "trust": { + "failed": { + "text": "Did you configuwe i-it cowwectwy!!11", + "title": "Faiwed t-to weach sewvew" + }, + "noHostTitle": "Sewvew nyot configuwed?!!", + "noHost": "The sewvew has nyot been configuwed, thewefowe you cannyot ^w^ cweate an account", + "host": "You awe connyecting t-to <0>{{hostname}} - pwease confiwm you twust i-it befowe making an account...", + "no": "Go back", + "title": "Do you twust this sewvew?!!", + "yes": "I twust this sewvew !!!" + }, + "verify": { + "description": "Pwease entew youw passphwase fwom eawwiew ;;w;; t-to confiwm you have saved i-it and t-to cweate youw account", + "invalidData": "Data is nyot vawid", + "noMatch": "Passphwase d-doesn't match 😭", + "passphraseLabel": "Y-Y-Youw 12-wowd passphwase", + "recaptchaFailed": "WeCaptcha vawidation f-faiwed", + "register": "Create account", + "title": "Confiwm youw passphwase" + } + }, + "errors": { + "badge": "It bwoke 💀", + "details": "Ewwow detaiws OwO", + "reloadPage": "Wewoad the page", + "showError": "Show ewwow detaiws", + "title": "We encountewed an ewwow!!11" + }, + "footer": { + "legal": { + "disclaimer": "Discwaimew ◝(ᵔᵕᵔ)◜", + "disclaimerText": "Pwease note ^w^: uwu-flix does nyot host any OwO fiwes itsewf but instead onwy dispway's content fwom 3wd pawty pwovidews. Wegaw issues shouwd be taken up with them." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub", + "twitter": "Twitter" + }, + "tagline": "Watch youw favowite shows and movies fow fwee with nyo ads evew!!11 >w< (っ'ヮ'c)" + }, + "global": { + "name": "uwu-flix", + "pages": { + "about": "About", + "dmca": "DMCA", + "discover": "Discover", + "support": "Support", + "login": "Login", + "onboarding": "Setup", + "pagetitle": "{{title}} - uwu-flix", + "register": "Register", + "settings": "Settings" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Bookmawks" + }, + "continueWatching": { + "sectionTitle": "Continyue Watching... *screeches*" + }, + "mediaList": { + "stopEditing": "Stop editing" + }, + "search": { + "allResults": "That's aww we *notices buldge* have...", + "failed": "Faiwed t-to find media, *runs away* twy again!!11", + "loading": "Woading...", + "noResults": "We couwdn't find anything :(", + "placeholder": { + "default": "What do you w-want t-to watch?!?1", + "extra": [ + "What awe you in the mood >w< f-f-fow?", + "Shouwd we *notices buldge* dewete youw bwowsew histowy? ;;w;;", + "What do you w-want t-to stweam?", + "uwu-flix is the best *starts twerking* site e-e-evew!", + "What's on youw watchwist today?", + "How was youw day?", + "My bad >w< the site nyevew wowks...", + "Isn't uwu-flix just *whispers to self* the best?", + ">ᴗ<" + ] + }, + "sectionTitle": "Seawch wesuwts" + }, + "titles": { + "day": { + "default": "What w-wouwd you wike t-to watch this aftewnyoon!!11", + "extra": [ + " /ᐠ>ヮ<ᐟ\\ฅ" + ] + }, + "morning": { + "default": "What w-wouwd you wike t-to watch this mownying?!! *walks away*", + "extra": [ + "\"૮₍ ˶•⤙•˶ ₎ა" + ] + }, + "night": { + "default": "What w-wouwd you wike t-to watch tonyight?!!", + "extra": [ + "(づ ᴗ _ᴗ)づ♡" + ] + }, + "420": { + "default": "What w-wouwd you wike t-to watch this 4/20!? *cries*", + "extra": [ + "(づ ᴗ _ᴗ)づ♡ Weed!" + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} - E{{episode}}", + "unreleased": "Unweweased", + "types": { + "movie": "Movie", + "show": "Show" + } + }, + "navigation": { + "banner": { + "offline": "Check youw intewnyet connyection." + }, + "menu": { + "about": "About us", + "logout": "Log out", + "register": "Register an account", + "settings": "Settings", + "support": "Suppowt" + } + }, + "notFound": { + "badge": "Nyot found", + "goHome": "Back t-to home", + "reloadButton": "Twy again", + "message": "We wooked everywhere: undew the bins, in the cwoset, behind the pwoxy but uwtimatewy couwdn't find the page you awe wooking fow. (ಥ﹏ಥ)", + "title": "Couwdn't find that page" + }, + "downtimeNotice": { + "badge": "Issues", + "goHome": "Go home", + "message": "uwu-flix is expewiencing issues with some p-pwovidews again, if you cant find ow (・`ω´・) pway a show pwease change the souwce. Expect this ewwow t-to pewsist thwoughout the bewow times.", + "timeFrame": "March 31th 11:00 PM - 5:00 AM EST", + "title": "Provider issues" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Cancel", + "confirm": "Use defauwt setup", + "description": "the *runs away* defauwt setup does nyot have the best *starts twerking* stweams and c-can be unbeawabwy swow. ( ͠° ͟ʖ ͡-͡°)", + "title": "Awe you suwe?!?!" + }, + "extension": { + "back": "Go back", + "explainer": "Using the bwowsew extension, you c-can get the best *starts twerking* stweams we have t-to offew. W-With just a simpwe instaww. 👌", + "explainerIos": "unfowtunyatewy, the bwowsew extension is nyot suppowted on i-i-iOS, Pwess Go back OwO t-to choose anyothew option.", + "extensionHelp": "If you've instawwed the extension but it's nyot detected, open the extension thwough youw bwowsews extension menyu and fowwow the steps on scween.", + "linkChrome": "Instaww Chwome extension", + "linkFirefox": "Instaww Firefox extension", + "notDetecting": "I-Instawwed on Chwome, but the site isn't detecting it?!?1 Twy wewoading the page?!?", + "notDetectingAction": "Weowoad da page", + "status": { + "disallowed": "Extension is nyot enyabwed fow this page (,,>﹏<,,)", + "disallowedAction": "Enyabwe extension", + "failed": "Faiwed t-to wequest status", + "loading": "Waiting fow you t-to instaww the extension", + "outdated": "Extension vewsion too *twerks* owd", + "success": "Extension is w-wowking as expected?!?1" + }, + "submit": "Continyue", + "title": "Wet's stawt with an extension!!11!!" + }, + "proxy": { + "back": "Go back", + "explainer": "W-With the pwoxy method, you c-can get gweat quawity stweams by making a sewf-sewvice pwoxy.", + "input": { + "errorConnection": "Couwd nyot connyect ÚwÚ t-to pwoxy", + "errorInvalidUrl": "Nyot a vawid URL", + "errorNotProxy": "expected *runs away* a pwoxy but got a website", + "label": "Pwoxy URL", + "placeholder": "https://" + }, + "link": "Weawn how t-to make a pwoxy", + "submit": "Submit pwoxy", + "title": "Wet's make a nyew pwoxy" + }, + "start": { + "explainer": "To get the best *starts twerking* stweams possibwe, you wiww nyeed t-to choose which stweaming method you w-want t-to use. *walks away*", + "options": { + "default": { + "text": "I don't w-want good *whispers to self* quawity stweams,<0 /> *walks away* <1>use the defauwt setupʔ" + }, + "extension": { + "action": "Instaww extension", + "description": "Instaww bwowsew extension and gain access t-to the best *starts twerking* souwces, but wemembew t-to enyabwe i-it fow this site.", + "quality": "Best quawity", + "title": "Bwowsew extension" + }, + "proxy": { + "action": "Setup pwoxy", + "description": "setup a fwee pwoxy in just 5 minyutes and gain access t-to gweat souwces...", + "quality": "Good quawity", + "title": "Custom pwoxy" + } + }, + "title": "Wet's get you setup with uwu-flix 🥳" + } + }, + "overlays": { + "close": "Close" + }, + "player": { + "back": { + "default": "Back to home", + "short": "Back" + }, + "casting": { + "enabled": "Casting t-to device 🎬" + }, + "menus": { + "downloads": { + "disclaimer": "Downwoads awe taken diwectwy fwom the x3 pwovidew. uwu-flix does nyot have contwow uvw how the downwoads awe pwovided.", + "copyHlsPlaylist": "Copy H-HWS pwaywist wink", + "downloadSubtitle": "Downwoad cuwwent subtitwe", + "downloadVideo": "Downwoad v-v-video", + "hlsDisclaimer": "Downwoads awe taken diwectwy fwom the pwovidew. uwufwix does nyot have contwow uvw how the downwoads awe pwovided.

Pwease nyote you awe downwoading an H-HWS pwaywist, it is nyot wecommended t-to downwoad if you awe nyot famiwiaw with advanced stweaming fowmats. Twy diffewent souwces fow diffewent fowmats.", + "onAndroid": { + "1": "To downwoad on A-A-Andwoid, cwick ^w^ the downwoad button ;;w;; then, on the nyew page, tap and howd on the x3 video, then sewect save.", + "shortTitle": "Downwoad / Android", + "title": "Downwoading on Android" + }, + "onIos": { + "1": "To downwoad on i-i-iOS, cwick ^w^ the x3 downwoad button ;;w;; then, on the nyew page, cwick ^w^ , then Save t-to Fiwes <-.", + "shortTitle": "Downwoad / iOS", + "title": "Downwoadipng on iOS" + }, + "onPc": { + "1": "On PC, UwU cwick ^w^ the x3 downwoad button ;;w;; then, on the x3 nyew page, wight cwick ^w^ the v-v-video and sewect Save v-v-video as *huggles tightly*", + "shortTitle": "Downwoad / PC", + "title": "Downwoading on PC" + }, + "title": "Downwoad OwO" + }, + "episodes": { + "button": "Episodes", + "emptyState": "Thewe awe nyo episodes in this season, ^-^ check back watew (sowwy)?!?1", + "episodeBadge": "E{{episode}}", + "loadingError": "Ewwow w-w-woading season", + "loadingList": "Loading...", + "loadingTitle": "Loading...", + "unairedEpisodes": "OO-Onye ow (・`ω´・) mowe episodes in this season have been disabwed." + }, + "playback": { + "speedLabel": "Pwayback speed", + "title": "Pwayback settings" + }, + "quality": { + "automaticLabel": "Automatic quawity", + "hint": "You c-can twy <0>switching souwce t-to get diffewent quawity options.", + "iosNoQuality": "Due t-to Appwe-definyed (-(common IOS L) wimitations, quawity sewection is nyot avaiwabwe on iOS fow this souwce. You c-can twy <0>switching t-to anyothewsouwce t-to get diffewent quawity options.", + "title": "Quality" + }, + "settings": { + "downloadItem": "Downwoad", + "enableSubtitles": "Enyabwe Subtitwes ;;w;;", + "experienceSection": "Viewing expewience", + "playbackItem": "Pwayback settings", + "audioItem": "Audio", + "qualityItem": "Quawity", + "sourceItem": "video souwces", + "subtitleItem": "Subtitwe settings", + "videoSection": "Video settings" + }, + "sources": { + "failed": { + "text": "Thewe was an ewwow whiwe t-twying t-to find any v-videos... Twy a diffewent souwce!?", + "title": "Faiwed t-to scwape" + }, + "noEmbeds": { + "text": "We wewe unyabwe ;;w;; t-to find any OwO embeds, pwease twy a diffewent souwce.", + "title": "Nyo embeds found" + }, + "noStream": { + "text": "This souwce has nyo stweams fow this movie ow (・`ω´・) show. /ᐠ - ˕ ---マ Ⳋ", + "title": "No stweam :(" + }, + "title": "Souwces", + "unknownOption": "Unknyown" + }, + "subtitles": { + "customChoice": "Dwop ow upwoad fiwe", + "customizeLabel": "Customize", + "offChoice": "Off", + "settings": { + "backlink": "Custom subtitwes", + "delay": "Subtitwe deway", + "fixCapitals": "Fix capitawization" + }, + "title": "Subtitwes", + "unknownLanguage": "Unknyown", + "dropSubtitleFile": "Dwop subtitwe fiwe h-h-hewe" + } + }, + "metadata": { + "api": { + "text": "Couwd nyot woad API metadata, pwease check youw intewnyet connyection.", + "title": "Faiwed t-to woad API metadata" + }, + "dmca": { + "badge": "Wemuvd", + "text": "This media is nyo wongew avaiwabwe due t-to a takedown nyotice ow (・`ω´・) copywight UwU cwaim. *huggles tightly*", + "title": "Media has been wemuvd" + }, + "extensionPermission": { + "badge": "Pewmission M-Missing", + "button": "Use extension", + "text": "You have the bwowsew extension, but we *notices buldge* nyeed youw pewmission t-to get stawted u-using the e-extension. (¬_¬)", + "title": "Configuwe the extension" + }, + "failed": { + "badge": "Faiwed", + "homeButton": "Go home", + "text": "Couwd nyot woad the media's metadata fwom TMDB. Pwease check whethew TMDB is d-d-down ow (・`ω´・) bwocked on youw intewnyet connyection.", + "title": "Faiwed t-to woad metadata" + }, + "notFound": { + "badge": "Nyot found", + "homeButton": "Back to home", + "text": "We couwdn't find the media you wequested. Eithew it's been wemuvd ow (・`ω´・) you tampewed with the UWW (-(nyaughty).", + "title": "Couwdn't find that media." + } + }, + "nextEpisode": { + "replay": "Wepway", + "next": "Nyext episode", + "nextSeason": "Nyext season" + }, + "playbackError": { + "badge": "Pwayback ewwow", + "errors": { + "errorAborted": "The fetching of the media was a-abowted by the usew's wequest.", + "errorDecode": "Despite having pweviouswy been detewminyed t-to be usabwe, an ewwow occuwwed whiwe t-twying t-to decode the x3 media wesouwce, wesuwting in an ewwow.", + "errorGenericMedia": "Unknyown media ewwow occuwwed.", + "errorNetwork": "Some kind of nyetwowk ewwow occuwwed which pwevented the media fwom b-being successfuwwy fetched, despite having pweviouswy been avaiwabwe.", + "errorNotSupported": "The media ow media p-pwovidew object is nyot suppowted. ^-^" + }, + "homeButton": "Go home", + "text": "Thewe was an ewwow t-twying t-to pway the media 😖. Pwease twy again.", + "title": "Faiwed t-to pway video?!?1" + }, + "scraping": { + "items": { + "failure": "Ewwow occuwwed", + "notFound": "Doesn't have the v-v-video (╥﹏╥)", + "pending": "Checking fow videos..." + }, + "notFound": { + "badge": "Nyot found", + "detailsButton": "Show detaiws", + "homeButton": "Go home", + "discoverButton": "Discuvw mowe", + "text": "We have seawched thwough ouw p-pwovidews and cannyot ^w^ find the x3 media you awe wooking fow?!?! We do nyot host the media and have nyo contwow uvw what is avaiwabwe. Pwease cwick ^w^ 'Show d-detaiws' bewow fow mowe detaiws.", + "title": "We couwdn't find that" + }, + "extensionFailure": { + "badge": "Extension disabwed", + "homeButton": "Go home", + "enableExtension": "Enyabwe extension", + "title": "Pwease enyabwe the extension", + "text": "You've instawwed the s-SkoolTV e-extension. To stawt u-using it, you nyeed t-to enyabwe the extension fow this site." + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} left • Finish at {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "Pwease pwuv youw humanyity by compweting the Captcha on the wight. This is t-to k-k-keep uwu-flix safe!?", + "error": "Faiwed t-to vewify youw humanyity?!! Pwease twy again.", + "title": "Awe You a Wobot 🤖?", + "verifyingHumanity": "Vewifying youw humanyity... (^▽^)👍" + } + }, + "support": { + "title": "Suppowt", + "text": "uwu-flix is designyed t-to be as usew-fwiendwy as possibwe. Howevew, peopwe stiww have questions and issues. This page is h-h-hewe t-to hewp wesowve these showtcomings", + "q1": { + "body": "weww, :3 you c-can join the officiaw <0>SkoolTV discowd and ask questions thewe ow (・`ω´・) you c-can emaiw the onye pwovided at the bottom of this page.", + "title": "Where can I get help?" + }, + "q2": { + "body": "We have a <0>GitHub whewe you c-can cweate a detaiwed issue in ouw wepositowy. Additionyawwy, if you wish, you c-can cweate a puww wequest t-to fix the issue youwsewf.", + "title": "H-How c-can I wepowt a bug ow issue!!11 (・`ω´・)" + } + }, + "screens": { + "dmca": { + "text": "Wewcome t-to uwu-flix's DMCA contact page *runs away*. If you b-bewieve youw copywighted wowk (・`ω´・) has been impwopewwy used on ouw pwatfowm (😢), pwease send a detaiwed DMCA nyotice to: dmca@example.com bewow. Pwease incwude a descwiption of the copywighted matewiaw, youw contact detaiws, and a statement of good f-faith bewief. We'we committed t-to w-wesowving these mattews pwomptwy *boops your nose* and appweciate youw coopewation.", + "title": "DMCA (っ◞‸◟ c)" + }, + "loadingApp": "W-Woading appwication", + "loadingUser": "W-Woading youw pwofiwe", + "loadingUserError": { + "logout": "Wogout", + "reset": "Weset custom sewvew", + "text": "Faiwed t-to woad youw pwofiwe", + "reload": "Wewoad", + "textWithReset": "Faiwed t-to woad youw pwofiwe fwom youw custom sewvew, w-want t-to weset back t-to the defauwt sewvew?!!" + }, + "migration": { + "failed": "Faiwed t-to migwate youw data. 😿", + "inProgress": "Pwease howd, we awe migwating youw data. This shouwdn't take wong..." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Device nyame", + "deviceNamePlaceholder": "Pewsonyaw phonye", + "editProfile": "Edit", + "logoutButton": "Wog out" + }, + "admin": { + "title": "Admin panyew", + "text": "Utiwize toows made fow testing uwu-flix's condition.", + "button": "Check i-it out" + }, + "actions": { + "delete": { + "button": "Dewete account", + "confirmButton": "Dewete account", + "confirmDescription": "Awe you suwe you w-want t-to dewete youw account!!11 Aww >w< youw data wiww be wost?!! ૮₍˶Ó﹏Ò ⑅-⑅₎ა", + "confirmTitle": "Awe you suwe?!?!", + "text": "This action is iwwevewsibwe. aww >w< data wiww be deweted and nyothing *runs away* c-can be wecuvwed.", + "title": "Dewete account" + }, + "title": "Actions :3" + }, + "devices": { + "deviceNameLabel": "Device nyame", + "failed": "Faiwed t-to woad sessions", + "removeDevice": "Wemuv", + "title": "D-Devices" + }, + "profile": { + "finish": "Finyish editing", + "firstColor": "P-Pwofiwe c-cowow onye", + "secondColor": "P-Pwofiwe c-cowow two", + "title": "Edit pwofiwe pictuwe", + "userIcon": "Usew icon" + }, + "register": { + "cta": "Get stawted", + "text": "Shawe youw watch pwogwess between devices and k-k-keep them synced. ( ̧⸝⸝⍢⸝⸝)ෆ", + "title": "Sync t-to the cwoud" + }, + "title": "Account" + }, + "appearance": { + "activeTheme": "Active", + "themes": { + "blue": "Blue", + "default": "Default", + "gray": "Gray", + "red": "Red", + "teal": "Teal" + }, + "title": "Appeawance" + }, + "connections": { + "server": { + "description": "If you w-wouwd wike t-to connyect t-to a custom backend t-to stowe youw d-d-data, enyabwe this and pwovide the x3 UWW. <0>Instwuctions.", + "label": "Custom sewvew", + "urlLabel": "Custom sewvew URL" + }, + "setup": { + "doSetup": "Do setup", + "errorStatus": { + "description": "It seems that onye ow (・`ω´・) mowe items in this setup nyeed youw attention.", + "title": "Something nyeeds youw attention 😱" + }, + "itemError": "Thewe is something wwong with this setting. Go thwough setup again t-to fix it. >w< (ᴗ_ ᴗ。)", + "items": { + "default": "Defauwt setup", + "extension": "Extension", + "proxy": "Custom pwoxy" + }, + "redoSetup": "Wedo setup", + "successStatus": { + "description": "Aww >w< things awe in pwace fow you t-to stawt watching youw favowite media. (๑>◡<๑)", + "title": "Evewything is set up?!?1" + }, + "unsetStatus": { + "description": "Pwease cwick ^w^ the button ;;w;; t-to the x3 wight t-to stawt the setup pwocess.", + "title": "You haven't gonye thwough setup" + } + }, + "title": "Connyections", + "workers": { + "addButton": "Add nyew w-w-wowkew", + "description": "To make the x3 appwication function, ;;w;; aww twaffic is wouted thwough pwoxies. Enyabwe this if you w-want t-to b-bwing youw own wowkews. <0>Instwuctions.", + "emptyState": "Nyo wowkews yet >w<, add onye bewow", + "label": "Use custom pwoxy wowkews", + "urlLabel": "Wowkew URLs", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "Appwication wanguage", + "languageDescription": "Wanguage appwied t-to the entiwe a-appwication, onwy Engwish has siwwy stuff 🙁.", + "thumbnail": "Genyewate thumbnyaiws", + "thumbnailDescription": "Most of the x3 time, videos ^w^ don't have thumbnyaiws. You c-can enyabwe this setting t-to genyewate them on the fwy but they c-can make youw v-v-video swowew.", + "thumbnailLabel": "Genyewate thumbnyaiws", + "autoplay": "Autopway", + "autoplayDescription": "Automaticawwy pway *notices buldge* the nyext episode in a sewies a-a-aftew weaching :3 the end. Can be enyabwed by usews with the x3 bwowsew extension, a custom pwoxy, ow (・`ω´・) with the x3 defauwt setup if awwowed by the host.", + "autoplayLabel": "Autopway", + "title": "Pwefewences" + }, + "reset": "Weset", + "save": "Save", + "sidebar": { + "info": { + "appVersion": "App vewsion", + "backendUrl": "Backend URL", + "backendVersion": "Backend version", + "hostname": "Hostnyame", + "insecure": "Insecuwe", + "notLoggedIn": "You awe nyot wogged in", + "secure": "Secuwe", + "title": "App stats", + "unknownVersion": "Unknyown", + "userId": "Usew ID" + } + }, + "subtitles": { + "backgroundLabel": "Backgwound opacity", + "backgroundBlurLabel": "Background bwuw", + "colorLabel": "Cowow", + "previewQuote": "A wizard is never late, Frodo Baggins. Nor is he early. He arrives precisely when he means to.", + "textSizeLabel": "Text size", + "title": "Subtitwes" + }, + "unsaved": "You have unsaved changes... ฅ^•ﻌ•^ฅ" + } +} diff --git a/src/assets/locales/vi.json b/src/assets/locales/vi.json new file mode 100644 index 0000000..13b475d --- /dev/null +++ b/src/assets/locales/vi.json @@ -0,0 +1,210 @@ +{ + "about": { + "description": "SkoolTV là một ứng dụng web tìm kiếm các nguồn truyền phát trực tuyến trên Internet. Nhóm phát triển ứng dụng này nhắm đến một cách dễ dàng hơn trong việc tiêu thụ nội dung.", + "faqTitle": "Các câu hỏi thường gặp", + "q1": { + "body": "SkoolTV không lưu trữ bất kì nội dung nào. Khi bạn chọn xem một nội dung nào đó, ứng dụng sẽ tìm kiếm nội dung đó trên Internet (Khi nội dung tải và trong tab 'nguồn video' bạn sẽ tìm thấy nguồn đang được dùng). Nội dung không bao giờ được tải lên trên SkoolTV, mọi thứ đều được tìm kiếm thông qua phương thức này.", + "title": "Nội dung đến từ đâu?" + }, + "q2": { + "body": "Việc yêu cầu thêm một chương trình truyền hình hoặc phim là điều bất khả thi bởi vì SkoolTV không quản lý bất kỳ nội dung nào. Tất cả nội dung được truyền thông qua những nguồn trên internet.", + "title": "Tôi có thể yêu cầu thêm một chương trình truyền hình hoặc phim ở đâu?" + }, + "q3": { + "body": "Các kết quả tìm kiếm được cung cấp bởi The Movie Database (TMDB) và hiện lên bất kể các nguồn của trang thực sự có lưu trữ nội dung đó hay không.", + "title": "Tại sao kết quả tìm kiếm hiển thị chương trình truyền hình hoặc phim nhưng tôi không thể xem nó?" + }, + "title": "Về SkoolTV" + }, + "actions": { + "copied": "Đã sao chép", + "copy": "Sao chép" + }, + "auth": { + "createAccount": "Chưa có tài khoản? <0>Hãy tạo tài khoản.", + "deviceNameLabel": "Tên thiết bị", + "deviceNamePlaceholder": "Điện thoại cá nhân", + "generate": { + "description": "Mật ngữ của bạn đóng vai trò là tên người dùng và mật khẩu của bạn. Hãy giữ nó an toàn vì bạn sẽ cần nhập nó để đăng nhập vào tài khoản của bạn", + "next": "Tôi đã lưu giữ mật ngữ của mình", + "passphraseFrameLabel": "Mật ngữ", + "title": "Mật ngữ của bạn" + }, + "hasAccount": "Đã có tài khoản? <0>Hãy đăng nhập.", + "login": { + "description": "Hãy nhập mật ngữ của bạn để đăng nhập vào tài khoản", + "deviceLengthError": "Hãy nhập tên thiết bị", + "passphraseLabel": "Mật ngữ gồm 12 từ", + "passphrasePlaceholder": "Mật ngữ", + "submit": "Đăng nhập", + "title": "Đăng nhập vào tài khoản của bạn", + "validationError": "Mật ngữ không chính xác hoặc không đầy đủ" + }, + "register": { + "information": { + "color1": "Màu hồ sơ số một", + "color2": "Màu hồ sơ số hai", + "header": "Hãy nhập tên cho thiết bị của bạn và chọn màu sắc và biểu tượng người dùng", + "icon": "Biểu tượng người dùng", + "next": "Tiếp theo", + "title": "Thông tin tài khoản" + } + }, + "trust": { + "failed": { + "text": "Bạn đã cài đặt nó một cách chính xác chưa?", + "title": "Không thể truy vấn máy chủ" + }, + "host": "Bạn đang kết nối đến máy chủ <0>{{hostname}} - vui lòng chắc chắn rằng bạn tin tưởng máy chủ này trước khi tạo tài khoản", + "no": "Quay lại", + "title": "Bạn có tin tưởng máy chủ này không?", + "yes": "Tôi tin tưởng máy chủ này" + }, + "verify": { + "description": "Vui lòng nhập mật ngữ của bạn lúc nãy đễ chắc chắn rằng bạn đã lưu nó và để tạo tài khoản", + "invalidData": "Dữ liệu không hợp lệ", + "noMatch": "Mật ngữ không khớp", + "passphraseLabel": "Mật ngữ 12 ký tự của bạn", + "recaptchaFailed": "Xác minh bằng ReCaptcha không hợp lệ", + "register": "Tạo tài khoản", + "title": "Nhập lại mật ngữ của bạn" + } + }, + "errors": { + "badge": "Lỗi", + "details": "Thông tin về lỗi", + "reloadPage": "Tải lại trang", + "showError": "Hiển thị thông tin về lỗi", + "title": "Đã xảy ra lỗi!" + }, + "footer": { + "legal": { + "disclaimer": "Tuyên bố miễn trừ trách nhiệm", + "disclaimerText": "SkoolTV không lưu trữ bất kì file nào, nó chỉ đến những đường dẫn của các dịch vụ bên thứ ba. Bất kỳ vấn đề nào về pháp lý nên được đưa đến chủ sỡ hữu của file hoặc những nhà cung cấp đó. SkoolTV hoàn toàn không chịu trách nhiệm cho bất kỳ nội dung nào được chiếu từ các nhà cung cấp." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Xem các chương trình và phim yêu thích của bạn với ứng dụng phát trực tuyến nguồn mở này." + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "Thông tin", + "dmca": "DMCA", + "login": "Đăng nhập", + "onboarding": "Cài đặt", + "pagetitle": "{{title}} - SkoolTV", + "register": "Đăng ký", + "settings": "Cài đặt" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Đánh dấu" + }, + "continueWatching": { + "sectionTitle": "Tiếp tục xem" + }, + "mediaList": { + "stopEditing": "Hoàn thành" + }, + "search": { + "allResults": "Đó là tất cả chúng tôi có!", + "failed": "Không thể tìm thấy nội dung, hãy thử lại!", + "loading": "Đang tải...", + "noResults": "Chúng tôi không thể tìm thấy gì!", + "placeholder": { + "default": "Bạn muốn xem gì?", + "extra": [] + }, + "sectionTitle": "Kết quả tìm kiếm" + }, + "titles": { + "day": { + "default": "Chiều nay bạn muốn coi gì?", + "extra": [ + "Cảm thấy muốn phiêu lưu? Phim Công viên kỷ Jura có thể là sự lựa chọn hoàn hảo cho bạn." + ] + }, + "morning": { + "default": "Sáng nay bạn muốn coi gì?", + "extra": [ + "Tôi nghe nói rằng bộ phim Before Sunrise hay đấy" + ] + }, + "night": { + "default": "Đêm nay bạn muốn coi gì?", + "extra": [ + "Cảm thấy mệt? Tôi nghe nói phim The Exorcist hay đấy." + ] + } + } + }, + "media": { + "episodeDisplay": "M{{season}} T{{episode}}", + "types": { + "movie": "Phim", + "show": "Chương trình truyền hình" + } + }, + "navigation": { + "banner": { + "offline": "Hãy kiểm tra kết nối Internet của bạn" + }, + "menu": { + "about": "Về chúng tôi", + "logout": "Đăng xuất", + "register": "Đồng bộ hóa với đám mây", + "settings": "Cài đặt", + "support": "Hỗ trợ" + } + }, + "notFound": { + "badge": "Không tìm thấy", + "goHome": "Quay lại trang chính", + "message": "Chúng tôi đã tìm kiếm khắp nơi: dưới thùng rác, trong tủ quần áo, đằng sau máy chủ proxy nhưng vẫn không thể tìm thấy trang bạn đang tìm kiếm.", + "title": "Không thể tìm thấy trang" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "Huỷ", + "confirm": "Chọn cài đặt mặc định", + "description": "Cài đặt mặc định có thể dẫn đến việc phát video chậm.", + "title": "Bạn có chắc không?" + }, + "extension": { + "back": "Trở lại", + "explainer": "Bạn có thể sử dụng các nguồn tốt nhất mà chúng tôi cung cấp bằng cách sử dụng tiện ích mở rộng trình duyệt. Đơn giản chỉ cần cài đặt." + } + }, + "player": { + "back": { + "default": "Quay lại trang chính", + "short": "Quay lại" + }, + "menus": { + "episodes": { + "button": "Tập", + "loadingList": "Đang tải...", + "loadingTitle": "Đang tải..." + }, + "sources": { + "title": "Nguồn" + } + }, + "metadata": { + "notFound": { + "badge": "Không tìm thấy", + "homeButton": "Quay lại trang chính", + "text": "Chúng tôi không thể tìm thấy nội dung mà bạn yêu cầu. Hoặc là nó đã bị xóa, hoặc bạn đã xáo trộn URL.", + "title": "Không thể tìm thấy nội dung." + } + }, + "playbackError": { + "title": "Rất tiếc, đã hỏng!" + } + } +} diff --git a/src/assets/locales/zh-Hant.json b/src/assets/locales/zh-Hant.json new file mode 100644 index 0000000..d391307 --- /dev/null +++ b/src/assets/locales/zh-Hant.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "SkoolTV 是一款在互聯網上搜尋串流媒體的網路應用程式。團隊致力於讓使用者以最簡約的方式觀看內容。", + "faqTitle": "常見問題", + "q1": { + "body": "SkoolTV 不託管任何內容。您點選觀看內容時,系統均從互聯網搜尋(在加載提示頁和“視頻源”選項卡中,您可以看到正在使用的源)。媒體從未在 SkoolTV 中上傳,所有內容均通過搜索機制而得。", + "title": "內容來自哪裡?" + }, + "q2": { + "body": "無法主動要求影視劇或其他節目,SkoolTV 不管理任何內容。所有內容均從網路影片來源取得並供您觀看。", + "title": "我可以從哪裡請求觀看影視劇或其他節目?" + }, + "q3": { + "body": "我們的搜尋結果由電影資料庫(TMDB)驅動,無論視訊來源是否有對應內容,都會顯示結果。", + "title": "搜尋結果中已顯示了電視劇或其他節目,為何我無法播放?" + }, + "title": "關於 SkoolTV" + }, + "actions": { + "copied": "已複製", + "copy": "複製" + }, + "auth": { + "createAccount": "還沒有帳戶? <0>建立一個", + "deviceNameLabel": "裝置名稱", + "deviceNamePlaceholder": "我的手機", + "generate": { + "description": "您的密碼短語相當於使用者名稱與密碼。由於您需要輸入它來登入帳戶,請確保將其存放到安全位置", + "next": "我已經儲存密碼短語", + "passphraseFrameLabel": "密碼短語", + "title": "您的密碼短語" + }, + "hasAccount": "已經擁有帳戶? <0>點此登入。 ", + "login": { + "description": "請輸入密碼短語以登入您的帳戶", + "deviceLengthError": "請輸入裝置名稱", + "passphraseLabel": "12 字密碼短語", + "passphrasePlaceholder": "密碼短語", + "submit": "登入", + "title": "登入您的帳戶", + "validationError": "密碼短語不正確或不完整" + }, + "register": { + "information": { + "color1": "頭像配色一", + "color2": "輪廓顏色二", + "header": "為您的裝置輸入名稱,並選取一組代表色和一個使用者圖示", + "icon": "使用者圖示", + "next": "下一步", + "title": "帳號資訊" + } + }, + "trust": { + "failed": { + "text": "您的配置是否正確?", + "title": "無法連接伺服器" + }, + "host": "您正在連線到 <0>{{hostname}} - 在建立帳戶之前,請確保您信任它", + "no": "返回", + "noHost": "因為沒有配置伺服器,所以你不能夠創建帳戶", + "noHostTitle": "没有配置伺服器!", + "title": "您是否信任這個伺服器?", + "yes": "我信任這個伺服器" + }, + "verify": { + "description": "請輸入早前的密碼短語,以確認您已經保存它,並建立您的帳戶", + "invalidData": "資料無效", + "noMatch": "密碼短語不匹配", + "passphraseLabel": "您的 12 字密碼短語", + "recaptchaFailed": "ReCaptcha 驗證失敗", + "register": "創建帳戶", + "title": "確認您的密碼短語" + } + }, + "errors": { + "badge": "它壞了", + "details": "錯誤詳情", + "reloadPage": "重新加載頁面", + "showError": "顯示錯誤詳情", + "title": "我們遇到了一個錯誤!" + }, + "footer": { + "legal": { + "disclaimer": "免責聲明", + "disclaimerText": "SkoolTV 不託管任何文件,僅連結至第三方服務。法律問題應由文件託管者和內容提供者解決。 SkoolTV 對影片提供者顯示的任何媒體檔案不承擔任何責任。" + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "使用這個開源串流媒體應用程式觀看您最喜歡的節目和電影。" + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "關於", + "dmca": "DMCA", + "login": "登入", + "onboarding": "設定", + "pagetitle": "{{title}} - SkoolTV", + "register": "註冊", + "settings": "設定" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "書籤" + }, + "continueWatching": { + "sectionTitle": "繼續觀看" + }, + "mediaList": { + "stopEditing": "停止編輯" + }, + "search": { + "allResults": "以上是我們能找到的所有結果!", + "failed": "未能找到媒體,請重試!", + "loading": "載入中...", + "noResults": "我们找不到任何结果!", + "placeholder": { + "default": "您想看什麼?", + "extra": [ + "你想探索什麼?", + "你的觀看清單有甚麼電影/電視劇?", + "你最喜愛的電影是甚麽?", + "你最喜愛的電視劇是甚麽?" + ] + }, + "sectionTitle": "搜索結果" + }, + "titles": { + "day": { + "default": "您今天下午想看什麼?", + "extra": [ + "想要來場冒險嗎?《侏羅紀公園》可能是完美選擇。" + ] + }, + "morning": { + "default": "您今天早上想看什麼?", + "extra": [ + "我聽說《情留半天》不錯" + ] + }, + "night": { + "default": "您今晚想看什麼?", + "extra": [ + "你疲倦嗎?我聽說《驅魔人》不錯。" + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "電影", + "show": "節目" + }, + "unreleased": "尚未上映" + }, + "navigation": { + "banner": { + "offline": "請檢查您的網絡連接" + }, + "menu": { + "about": "關於我們", + "logout": "登出", + "register": "同步到雲端", + "settings": "設定", + "support": "支援" + } + }, + "notFound": { + "badge": "未找到", + "goHome": "返回首頁", + "message": "我們到處尋找:在垃圾桶下面,在壁櫥裡,在代理伺服器後面,但最終找不到您要找的頁面。", + "title": "找不到該頁面" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "取消", + "confirm": "使用預設設置", + "description": "默認設置沒有最好的串流,並且可能慢得令人難以忍受。", + "title": "您確定嗎?" + }, + "extension": { + "back": "返回", + "explainer": "使用瀏覽器擴充功能,您可以獲得我們提供的最佳直播。只需簡單的安裝。", + "explainerIos": "不幸的是,iOS 不支援瀏覽器擴充功能,按 返回 選擇其他選項。", + "extensionHelp": "如果您已安裝該擴充功能,但未檢測到該擴充功能, 請通過瀏覽器的擴充功能功能表打開該擴展 程式 ,然後按照螢幕上的步驟操作。", + "linkChrome": "安裝 Chrome 擴充功能", + "linkFirefox": "安裝 Firefox 擴充功能", + "notDetecting": "安裝在 Chrome 上,但網站沒有檢測到它?嘗試重新載入頁面!", + "notDetectingAction": "重新加載頁面", + "status": { + "disallowed": "未為此頁面啟用瀏覽器擴充功能", + "disallowedAction": "啟用瀏覽器擴充功能", + "failed": "無法請求狀態", + "loading": "等待您安裝瀏覽器擴充功能", + "outdated": "瀏覽器擴充功能版本太舊", + "success": "瀏覽器擴充功能正在正常運作!" + }, + "submit": "繼續", + "title": "讓我們從瀏覽器擴充功能開始" + }, + "proxy": { + "back": "返回", + "explainer": "使用代理伺服器,您可以通過製作自定代理伺服器來獲得高品質的串流。", + "input": { + "errorConnection": "無法連接到代理伺服器", + "errorInvalidUrl": "URL 無效", + "errorNotProxy": "期待一個代理伺服器,但得到了一個網站", + "label": "代理伺服器 URL", + "placeholder": "https://" + }, + "link": "瞭解如何製作代理伺服器", + "submit": "提交代理伺服器", + "title": "讓我們創建一個新的代理伺服器" + }, + "start": { + "explainer": "為了獲得最好的串流媒體,您需要選擇您想使用的串流方法。", + "options": { + "default": { + "text": "我不想要高品質的串流,<0 /> <1> 使用預設設置" + }, + "extension": { + "action": "安裝瀏覽器擴充功能", + "description": "安裝瀏覽器擴充功能來使用最佳資源。", + "quality": "最好的品質", + "title": "瀏覽器擴充功能" + }, + "proxy": { + "action": "設置代理伺服器", + "description": "只需 5 分鐘即可設置代理伺服器並訪問優質來源。", + "quality": "好品質", + "title": "自訂代理伺服器" + } + }, + "title": "讓我們為您設定 SkoolTV" + } + }, + "overlays": { + "close": "關閉" + }, + "player": { + "back": { + "default": "返回首頁", + "short": "後退" + }, + "casting": { + "enabled": "正在投放到裝置…" + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "複製 HLS 播放清單鏈接", + "disclaimer": "視頻直接從供應商處獲取。SkoolTV 無法控制下載的提供方式。", + "downloadSubtitle": "下載當前字幕", + "downloadVideo": "下載視頻", + "hlsDisclaimer": "下載直接從供應商處獲取。SkoolTV 無法控制下載的提供方式。

請注意,您正在下載 HLS 播放清單, 如果您不熟悉高級流媒體格式,則不建議下載 。嘗試使用不同格式的不同來源。", + "onAndroid": { + "1": "要在 Android 上下載,請按下下載按鈕,然後在新頁面上點擊並按住 視頻,然後選擇 保存。", + "shortTitle": "下載 / Android", + "title": "在Android上下載" + }, + "onIos": { + "1": "要在 iOS 上下載,請按下下載按鈕,然後在新頁面上,按下 然後保存到檔案 。", + "shortTitle": "下載 / iOS", + "title": "正在 iOS 上下载" + }, + "onPc": { + "1": "在PC上,按下下載按鈕,然後在新頁面上右鍵按下視頻並選擇 將視頻另存為", + "shortTitle": "下載 / PC", + "title": "正在PC 上下载" + }, + "title": "下載" + }, + "episodes": { + "button": "集數", + "emptyState": "該季暫無集數,請稍後再來!", + "episodeBadge": "E{{episode}}", + "loadingError": "加載集數時出錯", + "loadingList": "載入中...", + "loadingTitle": "載入中...", + "unairedEpisodes": "本季中的一集或多集已因尚未播出而被禁用。" + }, + "playback": { + "speedLabel": "播放速度", + "title": "播放設置" + }, + "quality": { + "automaticLabel": "自動品質", + "hint": "您可以嘗試<0>切換源以獲得不同的質量選項。", + "iosNoQuality": "由於 Apple 的限制,此來源的品質選擇在 iOS 上不可用。您可以嘗試<0>切換到另一個來源以獲得不同的質量選項。", + "title": "品質" + }, + "settings": { + "audioItem": "音頻", + "downloadItem": "下載", + "enableSubtitles": "啟用字幕", + "experienceSection": "觀看體驗", + "playbackItem": "播放設定", + "qualityItem": "品質", + "sourceItem": "影片來源", + "subtitleItem": "字幕設定", + "videoSection": "影片設定" + }, + "sources": { + "failed": { + "text": "嘗試查找任何視頻時出錯,請嘗試其他來源。", + "title": "無法刮取" + }, + "noEmbeds": { + "text": "我們無法找到任何嵌入内容,請嘗試其他來源。", + "title": "未找到嵌入内容" + }, + "noStream": { + "text": "此來源沒有此電影或節目的串流。", + "title": "無視頻源" + }, + "title": "來源", + "unknownOption": "未知" + }, + "subtitles": { + "customChoice": "把字幕檔案拖入或上傳", + "customizeLabel": "自訂", + "dropSubtitleFile": "將字幕檔案拖曳到這裡", + "offChoice": "關閉", + "settings": { + "backlink": "自訂字幕", + "delay": "字幕延遲", + "fixCapitals": "修復大小寫" + }, + "title": "字幕", + "unknownLanguage": "未知" + } + }, + "metadata": { + "api": { + "text": "無法載入 API 元數據,請檢查您的互聯網連接。", + "title": "載入 API 元數據失敗" + }, + "dmca": { + "badge": "已移除", + "text": "由於收到刪除通知或版權聲明,此媒體不再可用。", + "title": "媒體已被移除" + }, + "extensionPermission": { + "badge": "缺少權限", + "button": "使用瀏覽器擴充功能", + "text": "您已安裝瀏覽器擴展功能,但我們需要您的許可才能啟用它。", + "title": "配置瀏覽器擴充功能" + }, + "failed": { + "badge": "失敗", + "homeButton": "返回首頁", + "text": "無法從 TMDB 載入媒體的元資料。請檢查 TMDB 是否斷線或在您的網路連線中被封鎖。", + "title": "載入元資料失敗" + }, + "notFound": { + "badge": "未找到", + "homeButton": "返回首頁", + "text": "我們無法找到您請求的媒體。它可能已被刪除,或者您修改了 URL。", + "title": "無法找到媒體。" + } + }, + "nextEpisode": { + "cancel": "取消", + "next": "下一集" + }, + "playbackError": { + "badge": "播放錯誤", + "errors": { + "errorAborted": "媒體的提取因使用者的請求而中止。", + "errorDecode": "儘管之前已確定可用,但在嘗試解碼媒體資源時發生錯誤,從而導致錯誤。", + "errorGenericMedia": "發生未知的媒體錯誤。", + "errorNetwork": "發生了某種網路錯誤,導致無法成功提取媒體,儘管以前可用。", + "errorNotSupported": "不支援媒體或媒體提供者物件。" + }, + "homeButton": "返回首頁", + "text": "嘗試播放媒體時出錯。請再試一次。", + "title": "無法播放視頻!" + }, + "scraping": { + "extensionFailure": { + "badge": "擴充功能已被禁用", + "enableExtension": "啟用擴充功能", + "homeButton": "回到首頁", + "text": "您已安裝該擴充功能, 你要啟用擴充程式去用它。", + "title": "請啟用擴充功能" + }, + "items": { + "failure": "發生錯誤", + "notFound": "沒有視頻", + "pending": "尋找影片中..." + }, + "notFound": { + "badge": "未找到", + "detailsButton": "顯示詳情", + "homeButton": "返回首頁", + "text": "我們已經搜索了我們的供應商,但找不到您正在尋找的媒體!我們不託管媒體,也無法控制可用的內容。請點擊下面的「顯示詳情」瞭解更多詳情。", + "title": "我們找不到" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "剩餘{{timeLeft}} • 在{{timeFinished, datetime}}完結", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "請通過右側的驗證碼來確認您是人類。這是為了保護 SkoolTV 的安全!", + "error": "無法驗證您是一個人類。請再試一次。", + "title": "我們需要驗證您是否為人類。", + "verifyingHumanity": "正在驗證您是不是一個人類..." + } + }, + "screens": { + "dmca": { + "text": "歡迎來到SkoolTV的DMCA聯繫頁面!我們尊重智慧財產權,並希望迅速解決任何版權問題。如果您認為您的版權作品在我們的平臺上被不當使用,請向以下電子郵件發送詳細的DMCA通知。請附上受版權保護材料的描述、您的聯繫方式以及善意信念的聲明。我們致力於迅速解決這些問題,並感謝您的合作,使電影網成為一個尊重創意和版權的地方。", + "title": "DMCA" + }, + "loadingApp": "正在載入應用程式", + "loadingUser": "正在載入您的個人資料", + "loadingUserError": { + "logout": "登出", + "reset": "重置您的自定義伺服器", + "text": "無法載入您的個人資料", + "textWithReset": "無法從您的自定義伺服器載入設定檔,您想要重置回預設伺服器?" + }, + "migration": { + "failed": "資料遷移失敗。", + "inProgress": "請稍等,我們正在遷移您的數據。這不應該需要太久。" + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "設備名稱", + "deviceNamePlaceholder": "個人電話", + "editProfile": "編輯", + "logoutButton": "登出" + }, + "actions": { + "delete": { + "button": "刪除帳戶", + "confirmButton": "刪除帳戶", + "confirmDescription": "您確定要刪除您的帳戶嗎?所有數據都將丟失!", + "confirmTitle": "您確定嗎?", + "text": "此操作不可逆轉。所有數據將被刪除,且無法恢復。", + "title": "刪除帳戶" + }, + "title": "操作" + }, + "devices": { + "deviceNameLabel": "設備名稱", + "failed": "無法載入", + "removeDevice": "刪除", + "title": "設備" + }, + "profile": { + "finish": "完成編輯", + "firstColor": "頭像配色一", + "secondColor": "頭像配色二", + "title": "編輯個人資料圖片", + "userIcon": "用戶圖示" + }, + "register": { + "cta": "開始使用", + "text": "在設備之間共用並持續同步您的觀看進度。", + "title": "同步到雲端" + }, + "title": "帳戶" + }, + "appearance": { + "activeTheme": "使用中", + "themes": { + "blue": "藍色", + "default": "預設", + "gray": "灰色", + "red": "紅色", + "teal": "青色" + }, + "title": "外觀" + }, + "connections": { + "server": { + "description": "若您想連接到自定義後端保存數據,請啟用此選項並提供 URL。<0>查看指引", + "label": "自訂伺服器", + "urlLabel": "自訂伺服器 URL" + }, + "setup": { + "doSetup": "進行設置", + "errorStatus": { + "description": "此設置中的一項或多項似乎需要您注意。", + "title": "有些事情需要你注意" + }, + "itemError": "此設置有問題。重新設置以修復它。", + "items": { + "default": "預設設置", + "extension": "擴展程式", + "proxy": "自訂代理伺服器" + }, + "redoSetup": "重做設置", + "successStatus": { + "description": "一切都已準備就緒,您可以開始觀看自己喜歡的媒體。", + "title": "一切都設置好了!" + }, + "unsetStatus": { + "description": "請按下右側的按鈕開始設置過程。", + "title": "您尚未完成設置" + } + }, + "title": "連接", + "workers": { + "addButton": "添加新的 Worker", + "description": "為了使應用程式正常運行,所有流量都通過代理伺服器。如果要自帶 Worker,請啟用此功能。 <0>說明", + "emptyState": "還沒有Worker,在下面添加一個", + "label": "使用自訂代理伺服器 Workers", + "urlLabel": "Worker URLs", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "應用程式語言", + "languageDescription": "語言已應用於整個應用程式。", + "thumbnail": "生成縮圖", + "thumbnailDescription": "大多數時候,視頻沒有縮圖。您可以啟用此設置以即時生成它們,但它們會使您的視頻變慢。", + "thumbnailLabel": "生成縮圖", + "title": "偏好設定" + }, + "reset": "重置", + "save": "保存", + "sidebar": { + "info": { + "appVersion": "應用版本", + "backendUrl": "後端URL", + "backendVersion": "後端版本", + "hostname": "主機名", + "insecure": "不安全", + "notLoggedIn": "您尚未登錄", + "secure": "安全", + "title": "應用程式的資訊", + "unknownVersion": "未知", + "userId": "使用者ID" + } + }, + "subtitles": { + "backgroundBlurLabel": "背景模糊", + "backgroundLabel": "背景不透明度", + "colorLabel": "顏色", + "previewQuote": "我絕不能害怕。 恐懼會扼殺思維能力。", + "textSizeLabel": "字體大小", + "title": "字幕" + }, + "unsaved": "您有未儲存的變更" + } +} diff --git a/src/assets/locales/zh.json b/src/assets/locales/zh.json new file mode 100644 index 0000000..ce9de26 --- /dev/null +++ b/src/assets/locales/zh.json @@ -0,0 +1,557 @@ +{ + "about": { + "description": "SkoolTV 是一款在互联网上搜寻流媒体的网络应用程序。团队致力于让用户采取最简约的方式消费内容。", + "faqTitle": "常见问题", + "q1": { + "body": "SkoolTV 不托管任何内容。您点选观看内容时,系统均从互联网搜寻(在加载提示页和“视频源”选项卡中,您可以看到正在使用的源)。媒体从未在 SkoolTV 中上传,所有内容均通过搜索机制而得。", + "title": "内容来自哪里?" + }, + "q2": { + "body": "无法主动请求影视剧或其他节目,SkoolTV 不管理任何内容。所有内容均从互联网视频源获取并供您观看。", + "title": "我可以从哪里请求观看影视剧或其他节目?" + }, + "q3": { + "body": "我们的搜索结果由电影数据库(TMDB)驱动,无论视频源是否有对应内容,均会显示结果。", + "title": "搜索结果中已显示了影视剧或其他节目,为何我无法播放?" + }, + "title": "关于 SkoolTV" + }, + "actions": { + "copied": "已复制", + "copy": "复制" + }, + "auth": { + "createAccount": "还没有账户? <0>创建一个", + "deviceNameLabel": "设备名称", + "deviceNamePlaceholder": "如:我的手机", + "generate": { + "description": "您的密码短语相当于用户名与密码。由于您需要输入它来登录账户,请确保将其存放到安全位置", + "next": "我已保存密码短语", + "passphraseFrameLabel": "密码短语", + "title": "您的密码短语" + }, + "hasAccount": "已经拥有账户?<0>点击此处登录。", + "login": { + "description": "请输入密码短语以登录您的账户", + "deviceLengthError": "请输入设备名称", + "passphraseLabel": "12 词密码短语", + "passphrasePlaceholder": "密码短语", + "submit": "登录", + "title": "登录您的账户", + "validationError": "密码短语不正确或不完整" + }, + "register": { + "information": { + "color1": "头像配色一", + "color2": "头像配色二", + "header": "为您的设备输入名称,并选取一组代表色和一个用户图标", + "icon": "用户图标", + "next": "下一步", + "title": "账户信息" + } + }, + "trust": { + "failed": { + "text": "您的配置是否正确?", + "title": "服务器无法接通" + }, + "host": "您正在连接到 <0>{{hostname}} - 在创建账户前,确保您信任它", + "no": "返回", + "noHost": "服务器尚未进行配置,因此您无法创建账户", + "noHostTitle": "未配置服务器!", + "title": "您是否信任这个服务器?", + "yes": "我信任这个服务器" + }, + "verify": { + "description": "请输入早先的密码短语,以确认您已经保存它,并创建您的账户", + "invalidData": "数据无效", + "noMatch": "密码短语不匹配", + "passphraseLabel": "您的 12 词密码短语", + "recaptchaFailed": "ReCaptcha 验证失败", + "register": "创建账户", + "title": "确认您的密码短语" + } + }, + "errors": { + "badge": "坏了", + "details": "错误细节", + "reloadPage": "刷新页面", + "showError": "显示错误细节", + "title": "我们遇到了错误!" + }, + "footer": { + "legal": { + "disclaimer": "免责声明", + "disclaimerText": "SkoolTV 不托管任何文件,仅链接到第三方服务。 法律问题应由文件托管者和内容提供者解决。 SkoolTV 对视频提供者显示的任何媒体文件不承担任何责任。" + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "在这个开源流媒体应用上观看你最喜爱的影视剧或其他节目。" + }, + "global": { + "name": "SkoolTV", + "pages": { + "about": "关于", + "dmca": "DMCA", + "login": "登录", + "onboarding": "设定", + "pagetitle": "{{title}} - SkoolTV", + "register": "注册", + "settings": "设置" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "书签" + }, + "continueWatching": { + "sectionTitle": "继续观看" + }, + "mediaList": { + "stopEditing": "停止编辑" + }, + "search": { + "allResults": "以上是我们能找到的所有结果!", + "failed": "查找媒体失败,请重试!", + "loading": "载入中……", + "noResults": "我们找不到任何结果!", + "placeholder": { + "default": "您想看些什么?", + "extra": [ + "您想探索些什么?", + "您的片单上都有啥?", + "您最喜欢的影片是什么?", + "您最喜欢的剧目是什么?" + ] + }, + "sectionTitle": "搜索结果" + }, + "titles": { + "day": { + "default": "您今天下午想看什么?", + "extra": [ + "想要来场冒险?《侏罗纪公园》可能是最佳选项。" + ] + }, + "morning": { + "default": "您今早想看什么?", + "extra": [ + "我听说《爱在黎明破晓前》不错" + ] + }, + "night": { + "default": "您今晚想看什么?", + "extra": [ + "累了?我听说《驱魔人》不错。" + ] + } + } + }, + "media": { + "episodeDisplay": "第{{season}}季 第{{episode}}集", + "types": { + "movie": "电影", + "show": "电视节目" + }, + "unreleased": "未发布" + }, + "navigation": { + "banner": { + "offline": "请检查您的互联网连接" + }, + "menu": { + "about": "关于我们", + "logout": "登出", + "register": "同步到云端", + "settings": "设置", + "support": "支持" + } + }, + "notFound": { + "badge": "未找到", + "goHome": "返回首页", + "message": "我们已经到处找过了:不管是废纸篓下、橱柜中还是代理服务之外,但最终并没有发现您查找的页面。", + "title": "无法找到页面" + }, + "onboarding": { + "defaultConfirm": { + "cancel": "取消", + "confirm": "使用默认设定", + "description": "默认设定不具备最好的视频流,并且播放速度可能慢得难以忍受。", + "title": "您确定吗?" + }, + "extension": { + "back": "返回", + "explainer": "使用浏览器扩展,您可以获得我们提供的最佳串流。只需简单的安装即可。", + "explainerIos": "很遗憾,浏览器扩展不被 iOS 支持,单击返回以选择其他选项。", + "extensionHelp": "如您已安装扩展程序但未被检测到,请从浏览器的扩展菜单打开扩展 并按屏幕上的指示操作。", + "linkChrome": "安装 Chrome 扩展程序", + "linkFirefox": "安装 Firefox 扩展程序", + "notDetecting": "已在 Chrome 上安装,但网站未能检测到?尝试刷新页面!", + "notDetectingAction": "刷新页面", + "status": { + "disallowed": "扩展程序未对本页面启用", + "disallowedAction": "启用扩展程序", + "failed": "请求状态失败", + "loading": "正等待您安装扩展程序", + "outdated": "扩展版本过旧", + "success": "扩展程序工作正常!" + }, + "submit": "继续", + "title": "让我们从扩展程序开始" + }, + "proxy": { + "back": "返回", + "explainer": "使用代理方式,您可以通过自助代理服务获得高质量的串流。", + "input": { + "errorConnection": "无法连接到代理", + "errorInvalidUrl": "URL 无效", + "errorNotProxy": "检测到常规网站,链接应指向代理", + "label": "代理 URL", + "placeholder": "https://" + }, + "link": "了解如何设置代理", + "submit": "提交代理", + "title": "让我们设置新的代理" + }, + "start": { + "explainer": "为了尽可能获得最佳串流,您将要选择使用何种串流方法。", + "options": { + "default": { + "text": "我不想使用高质量串流,<0 /> <1>使用默认设定" + }, + "extension": { + "action": "安装扩展程序", + "description": "安装浏览器扩展并获取最佳视频源。", + "quality": "最佳质量", + "title": "浏览器扩展" + }, + "proxy": { + "action": "设定代理", + "description": "在 5 分钟内设定好代理并获取优质资源。", + "quality": "高质量", + "title": "自定义代理" + } + }, + "title": "让我们为您设定 SkoolTV" + } + }, + "overlays": { + "close": "关闭" + }, + "player": { + "back": { + "default": "返回首页", + "short": "返回" + }, + "casting": { + "enabled": "正在投放到设备…" + }, + "menus": { + "downloads": { + "copyHlsPlaylist": "复制 HLS 播放列表链接", + "disclaimer": "下载内容是直接从内容提供者获取的。SkoolTV 无法控制下载内容如何被提供。", + "downloadSubtitle": "下载当前字幕", + "downloadVideo": "下载视频", + "hlsDisclaimer": "下载内容是直接从内容提供者获取的。SkoolTV 无法控制下载内容如何被提供。

请注意,您正在下载 HLS 播放列表,如您不熟悉高级流媒体格式,我们不推荐此操作。如需下载其他格式,请尝试切换视频源。", + "onAndroid": { + "1": "要从 Android 下载,先点击下载按钮,之后在新的页面上, 点击并按住视频,然后选择 保存。", + "shortTitle": "下载 / Android", + "title": "正在 Android 上下载" + }, + "onIos": { + "1": "要从 iOS 下载,点击下载按钮,之后在新的页面上,点击 ,然后保存到文件 。", + "shortTitle": "下载 / iOS", + "title": "正在 iOS 上下载" + }, + "onPc": { + "1": "在 PC 上,点击下载按钮,之后在新的页面上,右击视频并选择 另存视频为", + "shortTitle": "下载 / PC", + "title": "正在 PC 上下载" + }, + "title": "下载" + }, + "episodes": { + "button": "分集", + "emptyState": "该季暂无剧集,请稍后再来!", + "episodeBadge": "第{{episode}}集", + "loadingError": "加载分季时发生错误", + "loadingList": "载入中……", + "loadingTitle": "载入中……", + "unairedEpisodes": "本季中的一集或多集已因尚未播出而被禁用。" + }, + "playback": { + "speedLabel": "播放速度", + "title": "播放设置" + }, + "quality": { + "automaticLabel": "自动质量", + "hint": "您可以尝试<0>切换视频源以获取不同的质量选项。", + "iosNoQuality": "由于苹果施加的限制,该视频源的质量选择在 iOS 上不可用。您可以尝试<0>切换到其他视频源以获取不同的质量选项。", + "title": "质量" + }, + "settings": { + "audioItem": "音频", + "downloadItem": "下载", + "enableSubtitles": "启用字幕", + "experienceSection": "观看体验", + "playbackItem": "播放设置", + "qualityItem": "质量", + "sourceItem": "视频源", + "subtitleItem": "字幕设置", + "videoSection": "视频设置" + }, + "sources": { + "failed": { + "text": "尝试获取任何视频时均发生错误,请尝试其他视频源。", + "title": "刮取失败" + }, + "noEmbeds": { + "text": "我们无法找到任何嵌入内容,请尝试其他视频源。", + "title": "未找到嵌入内容" + }, + "noStream": { + "text": "此视频源没有该影片或节目的串流。", + "title": "没有流" + }, + "title": "视频源", + "unknownOption": "未知" + }, + "subtitles": { + "customChoice": "拖入或上传文件", + "customizeLabel": "自定义", + "dropSubtitleFile": "将字幕拖入这里", + "offChoice": "关闭", + "settings": { + "backlink": "自定义字幕", + "delay": "字幕延时", + "fixCapitals": "修整大小写" + }, + "title": "字幕", + "unknownLanguage": "未知" + } + }, + "metadata": { + "api": { + "text": "无法载入 API 元数据,请检查您的互联网连接。", + "title": "载入 API 元数据失败" + }, + "dmca": { + "badge": "已移除", + "text": "由于收到删除通知或版权声索,此媒体不再可用。", + "title": "媒体已被移除" + }, + "extensionPermission": { + "badge": "缺失权限", + "button": "使用扩展程序", + "text": "您已安装浏览器扩展,但我们需要您的许可才能启用它。", + "title": "配置扩展程序" + }, + "failed": { + "badge": "失败", + "homeButton": "返回首页", + "text": "无法从 TMDB 载入媒体的元数据。请检查 TMDB 是否掉线或在您的网络连接中被屏蔽。", + "title": "载入元数据失败" + }, + "notFound": { + "badge": "未找到", + "homeButton": "返回首页", + "text": "我们无法找到您请求的媒体。它可能已被删除,或您篡改了 URL.", + "title": "无法找到媒体。" + } + }, + "nextEpisode": { + "cancel": "取消", + "next": "下一集" + }, + "playbackError": { + "badge": "播放错误", + "errors": { + "errorAborted": "媒体获取已根据用户请求中止。", + "errorDecode": "尽管媒体资源此前已确定可用,但在尝试解码时产生问题,导致错误。", + "errorGenericMedia": "发生了未知的媒体错误。", + "errorNetwork": "发生了一些网络错误,导致媒体无法成功获取,尽管此前它可用。", + "errorNotSupported": "该媒体或媒体提供者对象不被支持。" + }, + "homeButton": "返回首页", + "text": "尝试播放媒体时发生错误。请重试。", + "title": "视频播放失败!" + }, + "scraping": { + "extensionFailure": { + "badge": "扩展程序已禁用", + "enableExtension": "启用扩展程序", + "homeButton": "返回首页", + "text": "您已经安装 SkoolTV 扩展程序。要开始使用,您需要为此站点启用扩展。", + "title": "请启用扩展程序" + }, + "items": { + "failure": "发生了错误", + "notFound": "没有视频", + "pending": "正在检测视频…" + }, + "notFound": { + "badge": "未找到", + "detailsButton": "显示细节", + "homeButton": "返回首页", + "text": "我们已在所有内容提供者中搜索,但无法发现您搜寻的媒体内容!我们并不托管媒体内容,也无法控制有什么内容可用。请点击下方的“显示细节”了解更多。", + "title": "我们无法找到它" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "剩余 {{timeLeft}} • 完结于 {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + }, + "turnstile": { + "description": "请完成右侧的验证码以验证您是人类。这是为了确保 SkoolTV 的安全!", + "error": "验证失败。请重试。", + "title": "我们需要验证您是不是人类。", + "verifyingHumanity": "正在验证您是否为人类…" + } + }, + "screens": { + "dmca": { + "text": "欢迎来到 SkoolTV 的 DMCA 联系页面!我们尊重知识产权,并希望迅速解决任何版权问题。如果您认为您的版权作品在我们的平台上被不当使用,请发送详细的 DMCA 通知至以下邮箱。同时请附上受版权保护的材料的描述、您的具体联系方式以及善意信念声明。 我们承诺及时解决这些问题,并感谢您的合作,让 SkoolTV 成为尊重创意和版权之地。", + "title": "DMCA" + }, + "loadingApp": "正在载入应用程序", + "loadingUser": "正在载入您的个人资料", + "loadingUserError": { + "logout": "登出", + "reset": "重设自定义服务器", + "text": "载入您的个人资料失败", + "textWithReset": "从您的自定义服务器载入个人资料失败,您想重设到默认服务器吗?" + }, + "migration": { + "failed": "迁移您的数据失败。", + "inProgress": "请稍候,我们正在迁移您的数据。这不会花很多时间。" + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "设备名称", + "deviceNamePlaceholder": "如:个人电话", + "editProfile": "编辑", + "logoutButton": "登出" + }, + "actions": { + "delete": { + "button": "删除账户", + "confirmButton": "删除账户", + "confirmDescription": "您确定要删除账户吗?所有数据将会丢失!", + "confirmTitle": "您确定吗?", + "text": "此操作不可逆。所有数据将被删除且无法恢复。", + "title": "删除账户" + }, + "title": "操作" + }, + "devices": { + "deviceNameLabel": "设备名称", + "failed": "载入会话失败", + "removeDevice": "移除", + "title": "设备" + }, + "profile": { + "finish": "完成编辑", + "firstColor": "个人资料颜色 1", + "secondColor": "个人资料颜色 2", + "title": "编辑个人资料图像", + "userIcon": "用户图标" + }, + "register": { + "cta": "开始使用", + "text": "在设备之间共享并持续同步您的观看进度。", + "title": "同步到云端" + }, + "title": "账户" + }, + "appearance": { + "activeTheme": "已激活", + "themes": { + "blue": "蓝色", + "default": "默认", + "gray": "灰色", + "red": "红色", + "teal": "青色" + }, + "title": "外观" + }, + "connections": { + "server": { + "description": "若您想连接到自定义后端保存数据,请启用此选项并提供 URL。 <0>查看指引", + "label": "自定义服务器", + "urlLabel": "自定义服务器 URL" + }, + "setup": { + "doSetup": "进行设定", + "errorStatus": { + "description": "看起来此配置中的一项或多项需要您的注意。", + "title": "有件事需要您的注意" + }, + "itemError": "此设置存在错误。再次进行设定过程以修复它。", + "items": { + "default": "默认设定", + "extension": "扩展程序", + "proxy": "自定义代理" + }, + "redoSetup": "重新进行设定", + "successStatus": { + "description": "一切已经就绪,您可以开始观赏喜爱的媒体了。", + "title": "一切就绪!" + }, + "unsetStatus": { + "description": "请单击右侧的按钮开始进行设定。", + "title": "您尚未完成设定" + } + }, + "title": "连接", + "workers": { + "addButton": "添加新的 Worker", + "description": "要让应用程序正常运作,所有流量会通过代理路由。若您想使用自己的 Worker,请启用该选项。 <0>查看指引", + "emptyState": "还没有 Worker,在下方添加一个", + "label": "使用自定义代理 Worker", + "urlLabel": "Worker URL", + "urlPlaceholder": "https://" + } + }, + "preferences": { + "language": "应用程序语言", + "languageDescription": "作用于整个应用程序的语言。", + "thumbnail": "生成缩略图", + "thumbnailDescription": "大多数时候,视频没有缩略图。您可以启用此设置以在视频播放时动态生成它们,但此选项可能会拖慢视频速度。", + "thumbnailLabel": "生成缩略图", + "title": "偏好设置" + }, + "reset": "重设", + "save": "保存", + "sidebar": { + "info": { + "appVersion": "应用版本", + "backendUrl": "后端 URL", + "backendVersion": "后端版本", + "hostname": "主机名", + "insecure": "不安全", + "notLoggedIn": "您尚未登录", + "secure": "安全", + "title": "应用信息", + "unknownVersion": "未知", + "userId": "用户 ID" + } + }, + "subtitles": { + "backgroundBlurLabel": "背景模糊", + "backgroundLabel": "背景不透明度", + "colorLabel": "颜色", + "previewQuote": "我不能害怕。恐惧是心灵的杀手。", + "textSizeLabel": "字体大小", + "title": "字幕" + }, + "unsaved": "您有未保存的更改" + } +} diff --git a/src/assets/templates/opensearch.xml.hbs b/src/assets/templates/opensearch.xml.hbs new file mode 100644 index 0000000..7e34e16 --- /dev/null +++ b/src/assets/templates/opensearch.xml.hbs @@ -0,0 +1,6 @@ + + SkoolTV + The place for your favorite movies & shows + UTF-8 + + diff --git a/src/backend/accounts/auth.ts b/src/backend/accounts/auth.ts new file mode 100644 index 0000000..71b2317 --- /dev/null +++ b/src/backend/accounts/auth.ts @@ -0,0 +1,35 @@ +import { ofetch } from "ofetch"; + +export interface SessionResponse { + id: string; + userId: string; + createdAt: string; + accessedAt: string; + device: string; + userAgent: string; +} +export interface LoginResponse { + session: SessionResponse; + token: string; +} + +export function getAuthHeaders(token: string): Record { + return { + authorization: `Bearer ${token}`, + }; +} + +export async function accountLogin( + url: string, + id: string, + deviceName: string, +): Promise { + return ofetch("/auth/login", { + method: "POST", + body: { + id, + device: deviceName, + }, + baseURL: url, + }); +} diff --git a/src/backend/accounts/bookmarks.ts b/src/backend/accounts/bookmarks.ts new file mode 100644 index 0000000..7949541 --- /dev/null +++ b/src/backend/accounts/bookmarks.ts @@ -0,0 +1,64 @@ +import { ofetch } from "ofetch"; + +import { getAuthHeaders } from "@/backend/accounts/auth"; +import { BookmarkResponse } from "@/backend/accounts/user"; +import { AccountWithToken } from "@/stores/auth"; +import { BookmarkMediaItem } from "@/stores/bookmarks"; + +export interface BookmarkMetaInput { + title: string; + year: number; + poster?: string; + type: string; +} + +export interface BookmarkInput { + tmdbId: string; + meta: BookmarkMetaInput; +} + +export function bookmarkMediaToInput( + tmdbId: string, + item: BookmarkMediaItem, +): BookmarkInput { + return { + meta: { + title: item.title, + type: item.type, + poster: item.poster, + year: item.year ?? 0, + }, + tmdbId, + }; +} + +export async function addBookmark( + url: string, + account: AccountWithToken, + input: BookmarkInput, +) { + return ofetch( + `/users/${account.userId}/bookmarks/${input.tmdbId}`, + { + method: "POST", + headers: getAuthHeaders(account.token), + baseURL: url, + body: input, + }, + ); +} + +export async function removeBookmark( + url: string, + account: AccountWithToken, + id: string, +) { + return ofetch<{ tmdbId: string }>( + `/users/${account.userId}/bookmarks/${id}`, + { + method: "DELETE", + headers: getAuthHeaders(account.token), + baseURL: url, + }, + ); +} diff --git a/src/backend/accounts/crypto.ts b/src/backend/accounts/crypto.ts new file mode 100644 index 0000000..9fe5138 --- /dev/null +++ b/src/backend/accounts/crypto.ts @@ -0,0 +1,131 @@ +import { pbkdf2Async } from "@noble/hashes/pbkdf2"; +import { sha256 } from "@noble/hashes/sha256"; +import { generateMnemonic, validateMnemonic } from "@scure/bip39"; +import { wordlist } from "@scure/bip39/wordlists/english"; +import forge from "node-forge"; + +type Keys = { + privateKey: Uint8Array; + publicKey: Uint8Array; + seed: Uint8Array; +}; + +async function seedFromMnemonic(mnemonic: string) { + return pbkdf2Async(sha256, mnemonic, "mnemonic", { + c: 2048, + dkLen: 32, + }); +} + +export function verifyValidMnemonic(mnemonic: string) { + return validateMnemonic(mnemonic, wordlist); +} + +export async function keysFromMnemonic(mnemonic: string): Promise { + const seed = await seedFromMnemonic(mnemonic); + + const { privateKey, publicKey } = forge.pki.ed25519.generateKeyPair({ + seed, + }); + + return { + privateKey, + publicKey, + seed, + }; +} + +export function genMnemonic(): string { + return generateMnemonic(wordlist); +} + +export async function signCode( + code: string, + privateKey: Uint8Array, +): Promise { + return forge.pki.ed25519.sign({ + encoding: "utf8", + message: code, + privateKey, + }); +} + +export function bytesToBase64(bytes: Uint8Array) { + return forge.util.encode64(String.fromCodePoint(...bytes)); +} + +export function bytesToBase64Url(bytes: Uint8Array): string { + return bytesToBase64(bytes) + .replace(/\//g, "_") + .replace(/\+/g, "-") + .replace(/=+$/, ""); +} + +export async function signChallenge(keys: Keys, challengeCode: string) { + const signature = await signCode(challengeCode, keys.privateKey); + return bytesToBase64Url(signature); +} + +export function base64ToBuffer(data: string) { + return forge.util.binary.base64.decode(data); +} + +export function base64ToStringBuffer(data: string) { + return forge.util.createBuffer(base64ToBuffer(data)); +} + +export function stringBufferToBase64(buffer: forge.util.ByteStringBuffer) { + return forge.util.encode64(buffer.getBytes()); +} + +export async function encryptData(data: string, secret: Uint8Array) { + if (secret.byteLength !== 32) + throw new Error("Secret must be at least 256-bit"); + + const iv = await new Promise((resolve, reject) => { + forge.random.getBytes(16, (err, bytes) => { + if (err) reject(err); + resolve(bytes); + }); + }); + + const cipher = forge.cipher.createCipher( + "AES-GCM", + forge.util.createBuffer(secret), + ); + cipher.start({ + iv, + tagLength: 128, + }); + cipher.update(forge.util.createBuffer(data, "utf8")); + cipher.finish(); + + const encryptedData = cipher.output; + const tag = cipher.mode.tag; + + return `${forge.util.encode64(iv)}.${stringBufferToBase64( + encryptedData, + )}.${stringBufferToBase64(tag)}` as const; +} + +export function decryptData(data: string, secret: Uint8Array) { + if (secret.byteLength !== 32) throw new Error("Secret must be 256-bit"); + + const [iv, encryptedData, tag] = data.split("."); + + const decipher = forge.cipher.createDecipher( + "AES-GCM", + forge.util.createBuffer(secret), + ); + decipher.start({ + iv: base64ToStringBuffer(iv), + tag: base64ToStringBuffer(tag), + tagLength: 128, + }); + decipher.update(base64ToStringBuffer(encryptedData)); + const pass = decipher.finish(); + + if (!pass) throw new Error("Error decrypting data"); + + return decipher.output.toString(); +} diff --git a/src/backend/accounts/import.ts b/src/backend/accounts/import.ts new file mode 100644 index 0000000..3caaffb --- /dev/null +++ b/src/backend/accounts/import.ts @@ -0,0 +1,33 @@ +import { ofetch } from "ofetch"; + +import { getAuthHeaders } from "@/backend/accounts/auth"; +import { AccountWithToken } from "@/stores/auth"; + +import { BookmarkInput } from "./bookmarks"; +import { ProgressInput } from "./progress"; + +export function importProgress( + url: string, + account: AccountWithToken, + progressItems: ProgressInput[], +) { + return ofetch(`/users/${account.userId}/progress/import`, { + method: "PUT", + body: progressItems, + baseURL: url, + headers: getAuthHeaders(account.token), + }); +} + +export function importBookmarks( + url: string, + account: AccountWithToken, + bookmarks: BookmarkInput[], +) { + return ofetch(`/users/${account.userId}/bookmarks`, { + method: "PUT", + body: bookmarks, + baseURL: url, + headers: getAuthHeaders(account.token), + }); +} diff --git a/src/backend/accounts/login.ts b/src/backend/accounts/login.ts new file mode 100644 index 0000000..13c8026 --- /dev/null +++ b/src/backend/accounts/login.ts @@ -0,0 +1,48 @@ +import { ofetch } from "ofetch"; + +import { SessionResponse } from "@/backend/accounts/auth"; + +export interface ChallengeTokenResponse { + challenge: string; +} + +export async function getLoginChallengeToken( + url: string, + publicKey: string, +): Promise { + return ofetch("/auth/login/start", { + method: "POST", + body: { + publicKey, + }, + baseURL: url, + }); +} + +export interface LoginResponse { + session: SessionResponse; + token: string; +} + +export interface LoginInput { + publicKey: string; + challenge: { + code: string; + signature: string; + }; + device: string; +} + +export async function loginAccount( + url: string, + data: LoginInput, +): Promise { + return ofetch("/auth/login/complete", { + method: "POST", + body: { + namespace: "movie-web", + ...data, + }, + baseURL: url, + }); +} diff --git a/src/backend/accounts/meta.ts b/src/backend/accounts/meta.ts new file mode 100644 index 0000000..0886dc1 --- /dev/null +++ b/src/backend/accounts/meta.ts @@ -0,0 +1,15 @@ +import { ofetch } from "ofetch"; + +export interface MetaResponse { + version: string; + name: string; + description?: string; + hasCaptcha: boolean; + captchaClientKey?: string; +} + +export async function getBackendMeta(url: string): Promise { + return ofetch("/meta", { + baseURL: url, + }); +} diff --git a/src/backend/accounts/progress.ts b/src/backend/accounts/progress.ts new file mode 100644 index 0000000..511d1c5 --- /dev/null +++ b/src/backend/accounts/progress.ts @@ -0,0 +1,115 @@ +import { ofetch } from "ofetch"; + +import { getAuthHeaders } from "@/backend/accounts/auth"; +import { ProgressResponse } from "@/backend/accounts/user"; +import { AccountWithToken } from "@/stores/auth"; +import { ProgressMediaItem, ProgressUpdateItem } from "@/stores/progress"; + +export interface ProgressInput { + meta?: { + title: string; + year: number; + poster?: string; + type: string; + }; + tmdbId: string; + watched: number; + duration: number; + seasonId?: string; + episodeId?: string; + seasonNumber?: number; + episodeNumber?: number; + updatedAt?: string; +} + +export function progressUpdateItemToInput( + item: ProgressUpdateItem, +): ProgressInput { + return { + duration: item.progress?.duration ?? 0, + watched: item.progress?.watched ?? 0, + tmdbId: item.tmdbId, + meta: { + title: item.title ?? "", + type: item.type ?? "", + year: item.year ?? NaN, + poster: item.poster, + }, + episodeId: item.episodeId, + seasonId: item.seasonId, + episodeNumber: item.episodeNumber, + seasonNumber: item.seasonNumber, + }; +} + +export function progressMediaItemToInputs( + tmdbId: string, + item: ProgressMediaItem, +): ProgressInput[] { + if (item.type === "show") { + return Object.entries(item.episodes).flatMap(([_, episode]) => ({ + duration: item.progress?.duration ?? episode.progress.duration, + watched: item.progress?.watched ?? episode.progress.watched, + tmdbId, + meta: { + title: item.title ?? "", + type: item.type ?? "", + year: item.year ?? NaN, + poster: item.poster, + }, + episodeId: episode.id, + seasonId: episode.seasonId, + episodeNumber: episode.number, + seasonNumber: item.seasons[episode.seasonId].number, + updatedAt: new Date(episode.updatedAt).toISOString(), + })); + } + return [ + { + duration: item.progress?.duration ?? 0, + watched: item.progress?.watched ?? 0, + tmdbId, + updatedAt: new Date(item.updatedAt).toISOString(), + meta: { + title: item.title ?? "", + type: item.type ?? "", + year: item.year ?? NaN, + poster: item.poster, + }, + }, + ]; +} + +export async function setProgress( + url: string, + account: AccountWithToken, + input: ProgressInput, +) { + return ofetch( + `/users/${account.userId}/progress/${input.tmdbId}`, + { + method: "PUT", + headers: getAuthHeaders(account.token), + baseURL: url, + body: input, + }, + ); +} + +export async function removeProgress( + url: string, + account: AccountWithToken, + id: string, + episodeId?: string, + seasonId?: string, +) { + await ofetch(`/users/${account.userId}/progress/${id}`, { + method: "DELETE", + headers: getAuthHeaders(account.token), + baseURL: url, + body: { + episodeId, + seasonId, + }, + }); +} diff --git a/src/backend/accounts/register.ts b/src/backend/accounts/register.ts new file mode 100644 index 0000000..8fd0f9e --- /dev/null +++ b/src/backend/accounts/register.ts @@ -0,0 +1,55 @@ +import { ofetch } from "ofetch"; + +import { SessionResponse } from "@/backend/accounts/auth"; +import { UserResponse } from "@/backend/accounts/user"; + +export interface ChallengeTokenResponse { + challenge: string; +} + +export async function getRegisterChallengeToken( + url: string, + captchaToken?: string, +): Promise { + return ofetch("/auth/register/start", { + method: "POST", + body: { + captchaToken, + }, + baseURL: url, + }); +} + +export interface RegisterResponse { + user: UserResponse; + session: SessionResponse; + token: string; +} + +export interface RegisterInput { + publicKey: string; + challenge: { + code: string; + signature: string; + }; + device: string; + profile: { + colorA: string; + colorB: string; + icon: string; + }; +} + +export async function registerAccount( + url: string, + data: RegisterInput, +): Promise { + return ofetch("/auth/register/complete", { + method: "POST", + body: { + namespace: "movie-web", + ...data, + }, + baseURL: url, + }); +} diff --git a/src/backend/accounts/sessions.ts b/src/backend/accounts/sessions.ts new file mode 100644 index 0000000..34c4af3 --- /dev/null +++ b/src/backend/accounts/sessions.ts @@ -0,0 +1,49 @@ +import { ofetch } from "ofetch"; + +import { getAuthHeaders } from "@/backend/accounts/auth"; +import { AccountWithToken } from "@/stores/auth"; + +export interface SessionResponse { + id: string; + userId: string; + createdAt: string; + accessedAt: string; + device: string; + userAgent: string; +} + +export interface SessionUpdate { + deviceName: string; +} + +export async function getSessions(url: string, account: AccountWithToken) { + return ofetch(`/users/${account.userId}/sessions`, { + headers: getAuthHeaders(account.token), + baseURL: url, + }); +} + +export async function updateSession( + url: string, + account: AccountWithToken, + update: SessionUpdate, +) { + return ofetch(`/sessions/${account.sessionId}`, { + method: "PATCH", + headers: getAuthHeaders(account.token), + body: update, + baseURL: url, + }); +} + +export async function removeSession( + url: string, + token: string, + sessionId: string, +) { + return ofetch(`/sessions/${sessionId}`, { + method: "DELETE", + headers: getAuthHeaders(token), + baseURL: url, + }); +} diff --git a/src/backend/accounts/settings.ts b/src/backend/accounts/settings.ts new file mode 100644 index 0000000..c749795 --- /dev/null +++ b/src/backend/accounts/settings.ts @@ -0,0 +1,39 @@ +import { ofetch } from "ofetch"; + +import { getAuthHeaders } from "@/backend/accounts/auth"; +import { AccountWithToken } from "@/stores/auth"; + +export interface SettingsInput { + applicationLanguage?: string; + applicationTheme?: string | null; + defaultSubtitleLanguage?: string; + proxyUrls?: string[] | null; +} + +export interface SettingsResponse { + applicationTheme?: string | null; + applicationLanguage?: string | null; + defaultSubtitleLanguage?: string | null; + proxyUrls?: string[] | null; +} + +export function updateSettings( + url: string, + account: AccountWithToken, + settings: SettingsInput, +) { + return ofetch(`/users/${account.userId}/settings`, { + method: "PUT", + body: settings, + baseURL: url, + headers: getAuthHeaders(account.token), + }); +} + +export function getSettings(url: string, account: AccountWithToken) { + return ofetch(`/users/${account.userId}/settings`, { + method: "GET", + baseURL: url, + headers: getAuthHeaders(account.token), + }); +} diff --git a/src/backend/accounts/user.ts b/src/backend/accounts/user.ts new file mode 100644 index 0000000..4708dd2 --- /dev/null +++ b/src/backend/accounts/user.ts @@ -0,0 +1,178 @@ +import { ofetch } from "ofetch"; + +import { SessionResponse, getAuthHeaders } from "@/backend/accounts/auth"; +import { AccountWithToken } from "@/stores/auth"; +import { BookmarkMediaItem } from "@/stores/bookmarks"; +import { ProgressMediaItem } from "@/stores/progress"; + +export interface UserResponse { + id: string; + namespace: string; + name: string; + roles: string[]; + createdAt: string; + profile: { + colorA: string; + colorB: string; + icon: string; + }; +} + +export interface UserEdit { + profile?: { + colorA: string; + colorB: string; + icon: string; + }; +} + +export interface BookmarkResponse { + tmdbId: string; + meta: { + title: string; + year: number; + poster?: string; + type: "show" | "movie"; + }; + updatedAt: string; +} + +export interface ProgressResponse { + tmdbId: string; + season: { + id?: string; + number?: number; + }; + episode: { + id?: string; + number?: number; + }; + meta: { + title: string; + year: number; + poster?: string; + type: "show" | "movie"; + }; + duration: string; + watched: string; + updatedAt: string; +} + +export function bookmarkResponsesToEntries(responses: BookmarkResponse[]) { + const entries = responses.map((bookmark) => { + const item: BookmarkMediaItem = { + ...bookmark.meta, + updatedAt: new Date(bookmark.updatedAt).getTime(), + }; + return [bookmark.tmdbId, item] as const; + }); + + return Object.fromEntries(entries); +} + +export function progressResponsesToEntries(responses: ProgressResponse[]) { + const items: Record = {}; + + responses.forEach((v) => { + if (!items[v.tmdbId]) { + items[v.tmdbId] = { + title: v.meta.title, + poster: v.meta.poster, + type: v.meta.type, + updatedAt: new Date(v.updatedAt).getTime(), + episodes: {}, + seasons: {}, + year: v.meta.year, + }; + } + + const item = items[v.tmdbId]; + + // Since each watched episode is a single array entry but with the same tmdbId, the root item updatedAt will only have the first episode's timestamp (which is not the newest). + // Here, we are setting it explicitly so the updatedAt always has the highest updatedAt from the episodes. + if (new Date(v.updatedAt).getTime() > item.updatedAt) { + item.updatedAt = new Date(v.updatedAt).getTime(); + } + + if (item.type === "movie") { + item.progress = { + duration: Number(v.duration), + watched: Number(v.watched), + }; + } + + if (item.type === "show" && v.season.id && v.episode.id) { + item.seasons[v.season.id] = { + id: v.season.id, + number: v.season.number ?? 0, + title: "", + }; + item.episodes[v.episode.id] = { + id: v.episode.id, + number: v.episode.number ?? 0, + title: "", + progress: { + duration: Number(v.duration), + watched: Number(v.watched), + }, + seasonId: v.season.id, + updatedAt: new Date(v.updatedAt).getTime(), + }; + } + }); + + return items; +} + +export async function getUser( + url: string, + token: string, +): Promise<{ user: UserResponse; session: SessionResponse }> { + return ofetch<{ user: UserResponse; session: SessionResponse }>( + "/users/@me", + { + headers: getAuthHeaders(token), + baseURL: url, + }, + ); +} + +export async function editUser( + url: string, + account: AccountWithToken, + object: UserEdit, +): Promise<{ user: UserResponse; session: SessionResponse }> { + return ofetch<{ user: UserResponse; session: SessionResponse }>( + `/users/${account.userId}`, + { + method: "PATCH", + headers: getAuthHeaders(account.token), + body: object, + baseURL: url, + }, + ); +} + +export async function deleteUser( + url: string, + account: AccountWithToken, +): Promise { + return ofetch(`/users/${account.userId}`, { + headers: getAuthHeaders(account.token), + baseURL: url, + }); +} + +export async function getBookmarks(url: string, account: AccountWithToken) { + return ofetch(`/users/${account.userId}/bookmarks`, { + headers: getAuthHeaders(account.token), + baseURL: url, + }); +} + +export async function getProgress(url: string, account: AccountWithToken) { + return ofetch(`/users/${account.userId}/progress`, { + headers: getAuthHeaders(account.token), + baseURL: url, + }); +} diff --git a/src/backend/extension/compatibility.ts b/src/backend/extension/compatibility.ts new file mode 100644 index 0000000..00188a0 --- /dev/null +++ b/src/backend/extension/compatibility.ts @@ -0,0 +1,7 @@ +import { satisfies } from "semver"; + +const allowedExtensionRange = "^1.0.2"; + +export function isAllowedExtensionVersion(version: string): boolean { + return satisfies(version, allowedExtensionRange); +} diff --git a/src/backend/extension/messaging.ts b/src/backend/extension/messaging.ts new file mode 100644 index 0000000..bf0e325 --- /dev/null +++ b/src/backend/extension/messaging.ts @@ -0,0 +1,86 @@ +import { + MessagesMetadata, + sendToBackgroundViaRelay, +} from "@plasmohq/messaging"; + +import { isAllowedExtensionVersion } from "@/backend/extension/compatibility"; +import { ExtensionMakeRequestResponse } from "@/backend/extension/plasmo"; + +export const RULE_IDS = { + PREPARE_STREAM: 1, + SET_DOMAINS_HLS: 2, + SET_DOMAINS_HLS_AUDIO: 3, +}; + +// for some reason, about 500 ms is needed after +// page load before the extension starts responding properly +const isExtensionReady = new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, 500); +}); + +let activeExtension = false; + +async function sendMessage( + message: MessageKey, + payload: MessagesMetadata[MessageKey]["req"] | undefined = undefined, + timeout: number = -1, +) { + await isExtensionReady; + return new Promise((resolve) => { + if (timeout >= 0) setTimeout(() => resolve(null), timeout); + sendToBackgroundViaRelay< + MessagesMetadata[MessageKey]["req"], + MessagesMetadata[MessageKey]["res"] + >({ + name: message, + body: payload, + }) + .then((res) => { + activeExtension = true; + resolve(res); + }) + .catch(() => { + activeExtension = false; + resolve(null); + }); + }); +} + +export async function sendExtensionRequest( + ops: MessagesMetadata["makeRequest"]["req"], +): Promise | null> { + return sendMessage("makeRequest", ops); +} + +export async function setDomainRule( + ops: MessagesMetadata["prepareStream"]["req"], +): Promise { + return sendMessage("prepareStream", ops); +} + +export async function sendPage( + ops: MessagesMetadata["openPage"]["req"], +): Promise { + return sendMessage("openPage", ops); +} + +export async function extensionInfo(): Promise< + MessagesMetadata["hello"]["res"] | null +> { + const message = await sendMessage("hello", undefined, 500); + return message; +} + +export function isExtensionActiveCached(): boolean { + return activeExtension; +} + +export async function isExtensionActive(): Promise { + const info = await extensionInfo(); + if (!info?.success) return false; + const allowedVersion = isAllowedExtensionVersion(info.version); + if (!allowedVersion) return false; + return info.allowed && info.hasPermission; +} diff --git a/src/backend/extension/plasmo.ts b/src/backend/extension/plasmo.ts new file mode 100644 index 0000000..14a5481 --- /dev/null +++ b/src/backend/extension/plasmo.ts @@ -0,0 +1,71 @@ +export interface ExtensionBaseRequest {} + +export type ExtensionBaseResponse = + | ({ + success: true; + } & T) + | { + success: false; + error: string; + }; + +export type ExtensionHelloResponse = ExtensionBaseResponse<{ + version: string; + allowed: boolean; + hasPermission: boolean; +}>; + +export interface ExtensionMakeRequest extends ExtensionBaseRequest { + url: string; + method: string; + headers?: Record; + body?: string | Record; + bodyType?: "string" | "FormData" | "URLSearchParams" | "object"; +} + +export type ExtensionMakeRequestBodyType = ExtensionMakeRequest["bodyType"]; + +export type ExtensionMakeRequestResponse = ExtensionBaseResponse<{ + response: { + statusCode: number; + headers: Record; + finalUrl: string; + body: T; + }; +}>; + +export interface ExtensionPrepareStreamRequest extends ExtensionBaseRequest { + ruleId: number; + targetDomains: string[]; + requestHeaders?: Record; + responseHeaders?: Record; +} + +export interface MmMetadata { + hello: { + req: ExtensionBaseRequest; + res: ExtensionHelloResponse; + }; + makeRequest: { + req: ExtensionMakeRequest; + res: ExtensionMakeRequestResponse; + }; + prepareStream: { + req: ExtensionPrepareStreamRequest; + res: ExtensionBaseResponse; + }; + openPage: { + req: ExtensionBaseRequest & { + page: string; + redirectUrl: string; + }; + res: ExtensionBaseResponse; + }; +} + +interface MpMetadata {} + +declare module "@plasmohq/messaging" { + interface MessagesMetadata extends MmMetadata {} + interface PortsMetadata extends MpMetadata {} +} diff --git a/src/backend/extension/request.ts b/src/backend/extension/request.ts new file mode 100644 index 0000000..5885225 --- /dev/null +++ b/src/backend/extension/request.ts @@ -0,0 +1,17 @@ +import { ExtensionMakeRequestBodyType } from "./plasmo"; + +export function getBodyTypeFromBody( + body: unknown, +): ExtensionMakeRequestBodyType { + if (typeof body === "string") return "string"; + if (body instanceof FormData) return "FormData"; + if (body instanceof URLSearchParams) return "URLSearchParams"; + return "object"; +} + +export function convertBodyToObject(body: unknown): any { + if (body instanceof FormData || body instanceof URLSearchParams) { + return [...body]; + } + return body; +} diff --git a/src/backend/extension/streams.ts b/src/backend/extension/streams.ts new file mode 100644 index 0000000..af535f3 --- /dev/null +++ b/src/backend/extension/streams.ts @@ -0,0 +1,43 @@ +import { Stream } from "@movie-web/providers"; + +import { RULE_IDS, setDomainRule } from "@/backend/extension/messaging"; + +function extractDomain(url: string): string | null { + try { + const u = new URL(url); + return u.hostname; + } catch { + return null; + } +} + +function extractDomainsFromStream(stream: Stream): string[] { + if (stream.type === "hls") { + return [extractDomain(stream.playlist)].filter((v): v is string => !!v); + } + if (stream.type === "file") { + return Object.values(stream.qualities) + .map((v) => extractDomain(v.url)) + .filter((v): v is string => !!v); + } + return []; +} + +function buildHeadersFromStream(stream: Stream): Record { + const headers: Record = {}; + Object.entries(stream.headers ?? {}).forEach((entry) => { + headers[entry[0]] = entry[1]; + }); + Object.entries(stream.preferredHeaders ?? {}).forEach((entry) => { + headers[entry[0]] = entry[1]; + }); + return headers; +} + +export async function prepareStream(stream: Stream) { + await setDomainRule({ + ruleId: RULE_IDS.PREPARE_STREAM, + targetDomains: extractDomainsFromStream(stream), + requestHeaders: buildHeadersFromStream(stream), + }); +} diff --git a/src/backend/helpers/fetch.ts b/src/backend/helpers/fetch.ts new file mode 100644 index 0000000..f9aa145 --- /dev/null +++ b/src/backend/helpers/fetch.ts @@ -0,0 +1,79 @@ +import { ofetch } from "ofetch"; + +import { getApiToken, setApiToken } from "@/backend/helpers/providerApi"; +import { getLoadbalancedProxyUrl } from "@/backend/providers/fetchers"; + +type P = Parameters>; +type R = ReturnType>; + +const baseFetch = ofetch.create({ + retry: 0, +}); + +export function makeUrl(url: string, data: Record) { + let parsedUrl: string = url; + Object.entries(data).forEach(([k, v]) => { + parsedUrl = parsedUrl.replace(`{${k}}`, encodeURIComponent(v)); + }); + return parsedUrl; +} + +export function mwFetch(url: string, ops: P[1] = {}): R { + return baseFetch(url, ops); +} + +export async function singularProxiedFetch( + proxyUrl: string, + url: string, + ops: P[1] = {}, +): R { + let combinedUrl = ops?.baseURL ?? ""; + if ( + combinedUrl.length > 0 && + combinedUrl.endsWith("/") && + url.startsWith("/") + ) + combinedUrl += url.slice(1); + else if ( + combinedUrl.length > 0 && + !combinedUrl.endsWith("/") && + !url.startsWith("/") + ) + combinedUrl += `/${url}`; + else combinedUrl += url; + + const parsedUrl = new URL(combinedUrl); + Object.entries(ops?.params ?? {}).forEach(([k, v]) => { + parsedUrl.searchParams.set(k, v); + }); + Object.entries(ops?.query ?? {}).forEach(([k, v]) => { + parsedUrl.searchParams.set(k, v); + }); + + let headers = ops.headers ?? {}; + const apiToken = await getApiToken(); + if (apiToken) + headers = { + ...headers, + "X-Token": apiToken, + }; + + return baseFetch(proxyUrl, { + ...ops, + baseURL: undefined, + params: { + destination: parsedUrl.toString(), + }, + query: {}, + headers, + onResponse(context) { + const tokenHeader = context.response.headers.get("X-Token"); + if (tokenHeader) setApiToken(tokenHeader); + ops.onResponse?.(context); + }, + }); +} + +export function proxiedFetch(url: string, ops: P[1] = {}): R { + return singularProxiedFetch(getLoadbalancedProxyUrl(), url, ops); +} diff --git a/src/backend/helpers/providerApi.ts b/src/backend/helpers/providerApi.ts new file mode 100644 index 0000000..528e392 --- /dev/null +++ b/src/backend/helpers/providerApi.ts @@ -0,0 +1,163 @@ +import { MetaOutput, NotFoundError, ScrapeMedia } from "@movie-web/providers"; +import { jwtDecode } from "jwt-decode"; + +import { mwFetch } from "@/backend/helpers/fetch"; +import { getTurnstileToken, isTurnstileInitialized } from "@/stores/turnstile"; + +let metaDataCache: MetaOutput[] | null = null; +let token: null | string = null; + +export function setCachedMetadata(data: MetaOutput[]) { + metaDataCache = data; +} + +export function getCachedMetadata(): MetaOutput[] { + return metaDataCache ?? []; +} + +export function setApiToken(newToken: string) { + token = newToken; +} + +function getTokenIfValid(): null | string { + if (!token) return null; + try { + const body = jwtDecode(token); + if (!body.exp) return `jwt|${token}`; + if (Date.now() / 1000 < body.exp) return `jwt|${token}`; + } catch (err) { + // we dont care about parse errors + } + return null; +} + +export async function fetchMetadata(base: string) { + if (metaDataCache) return; + const data = await mwFetch(`${base}/metadata`); + metaDataCache = data.flat(); +} + +function scrapeMediaToQueryMedia(media: ScrapeMedia) { + let extra: Record = {}; + if (media.type === "show") { + extra = { + episodeNumber: media.episode.number.toString(), + episodeTmdbId: media.episode.tmdbId, + seasonNumber: media.season.number.toString(), + seasonTmdbId: media.season.tmdbId, + }; + } + + return { + type: media.type, + releaseYear: media.releaseYear.toString(), + imdbId: media.imdbId, + tmdbId: media.tmdbId, + title: media.title, + ...extra, + }; +} + +function addQueryDataToUrl(url: URL, data: Record) { + Object.entries(data).forEach((entry) => { + if (entry[1]) url.searchParams.set(entry[0], entry[1]); + }); +} + +export function makeProviderUrl(base: string) { + const makeUrl = (p: string) => new URL(`${base}${p}`); + return { + scrapeSource(sourceId: string, media: ScrapeMedia) { + const url = makeUrl("/scrape/source"); + addQueryDataToUrl(url, scrapeMediaToQueryMedia(media)); + addQueryDataToUrl(url, { id: sourceId }); + return url.toString(); + }, + scrapeAll(media: ScrapeMedia) { + const url = makeUrl("/scrape"); + addQueryDataToUrl(url, scrapeMediaToQueryMedia(media)); + return url.toString(); + }, + scrapeEmbed(embedId: string, embedUrl: string) { + const url = makeUrl("/scrape/embed"); + addQueryDataToUrl(url, { id: embedId, url: embedUrl }); + return url.toString(); + }, + }; +} + +export async function getApiToken(): Promise { + let apiToken = getTokenIfValid(); + if (!apiToken && isTurnstileInitialized()) { + apiToken = `turnstile|${await getTurnstileToken()}`; + } + return apiToken; +} + +function parseEventInput(inp: string): any { + if (inp.length === 0) return {}; + return JSON.parse(inp); +} + +export async function connectServerSideEvents( + url: string, + endEvents: string[], +) { + const apiToken = await getApiToken(); + + // insert token, if its set + const parsedUrl = new URL(url); + if (apiToken) parsedUrl.searchParams.set("token", apiToken); + const eventSource = new EventSource(parsedUrl.toString()); + + let promReject: (reason?: any) => void; + let promResolve: (value: T) => void; + const promise = new Promise((resolve, reject) => { + promResolve = resolve; + promReject = reject; + }); + + endEvents.forEach((evt) => { + eventSource.addEventListener(evt, (e) => { + eventSource.close(); + promResolve(parseEventInput(e.data)); + }); + }); + + eventSource.addEventListener("token", (e) => { + setApiToken(parseEventInput(e.data)); + }); + + eventSource.addEventListener("error", (err: MessageEvent) => { + eventSource.close(); + if (err.data) { + const data = JSON.parse(err.data); + let errObj = new Error("scrape error"); + if (data.name === NotFoundError.name) + errObj = new NotFoundError("Notfound from server"); + Object.assign(errObj, data); + promReject(errObj); + return; + } + + console.error("Failed to connect to SSE", err); + promReject(err); + }); + + eventSource.addEventListener("message", (ev) => { + if (!ev) { + eventSource.close(); + return; + } + setTimeout(() => { + promReject(new Error("SSE closed improperly")); + }, 1000); + }); + + return { + promise: () => promise, + on(event: string, cb: (data: Data) => void) { + eventSource.addEventListener(event, (e) => cb(JSON.parse(e.data))); + }, + }; +} diff --git a/src/backend/helpers/report.ts b/src/backend/helpers/report.ts new file mode 100644 index 0000000..4aa19f0 --- /dev/null +++ b/src/backend/helpers/report.ts @@ -0,0 +1,168 @@ +import { ScrapeMedia } from "@movie-web/providers"; +import { nanoid } from "nanoid"; +import { ofetch } from "ofetch"; +import { useCallback } from "react"; + +import { isExtensionActiveCached } from "@/backend/extension/messaging"; +import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape"; +import { BACKEND_URL } from "@/setup/constants"; +import { useAuthStore } from "@/stores/auth"; +import { PlayerMeta } from "@/stores/player/slices/source"; + +// for anybody who cares - these are anonymous metrics. +// They are just used for figuring out if providers are broken or not +const metricsEndpoint = `${BACKEND_URL}/metrics/providers`; +const captchaMetricsEndpoint = `${BACKEND_URL}/metrics/captcha`; +const batchId = () => nanoid(32); + +export type ProviderMetric = { + tmdbId: string; + type: string; + title: string; + seasonId?: string; + episodeId?: string; + status: "failed" | "notfound" | "success"; + providerId: string; + embedId?: string; + errorMessage?: string; + fullError?: string; +}; + +export type ScrapeTool = "default" | "custom-proxy" | "extension"; + +export function getScrapeTool(): ScrapeTool { + if (isExtensionActiveCached()) return "extension"; + const hasProxySet = !!useAuthStore.getState().proxySet; + if (hasProxySet) return "custom-proxy"; + return "default"; +} + +function getStackTrace(error: Error, lines: number) { + const topMessage = error.toString(); + const stackTraceLines = (error.stack ?? "").split("\n", lines + 1); + stackTraceLines.pop(); + return `${topMessage}\n\n${stackTraceLines.join("\n")}`; +} + +export async function reportProviders(items: ProviderMetric[]): Promise { + if (!BACKEND_URL) return; + return ofetch(metricsEndpoint, { + method: "POST", + body: { + items, + tool: getScrapeTool(), + batchId: batchId(), + }, + }); +} + +const segmentStatusMap: Record< + ScrapingSegment["status"], + ProviderMetric["status"] | null +> = { + success: "success", + notfound: "notfound", + failure: "failed", + pending: null, + waiting: null, +}; + +export function scrapeSourceOutputToProviderMetric( + media: PlayerMeta, + providerId: string, + embedId: string | null, + status: ProviderMetric["status"], + err: unknown | null, +): ProviderMetric { + const episodeId = media.episode?.tmdbId; + const seasonId = media.season?.tmdbId; + let error: undefined | Error; + if (err instanceof Error) error = err; + + return { + status, + providerId, + title: media.title, + tmdbId: media.tmdbId, + type: media.type, + embedId: embedId ?? undefined, + episodeId, + seasonId, + errorMessage: error?.message, + fullError: error ? getStackTrace(error, 5) : undefined, + }; +} + +export function scrapeSegmentToProviderMetric( + media: ScrapeMedia, + providerId: string, + segment: ScrapingSegment, +): ProviderMetric | null { + const status = segmentStatusMap[segment.status]; + if (!status) return null; + let episodeId: string | undefined; + let seasonId: string | undefined; + if (media.type === "show") { + episodeId = media.episode.tmdbId; + seasonId = media.season.tmdbId; + } + let error: undefined | Error; + if (segment.error instanceof Error) error = segment.error; + + return { + status, + providerId, + title: media.title, + tmdbId: media.tmdbId, + type: media.type, + embedId: segment.embedId, + episodeId, + seasonId, + errorMessage: segment.reason ?? error?.message, + fullError: error ? getStackTrace(error, 5) : undefined, + }; +} + +export function scrapePartsToProviderMetric( + media: ScrapeMedia, + order: ScrapingItems[], + sources: Record, +): ProviderMetric[] { + const output: ProviderMetric[] = []; + + order.forEach((orderItem) => { + const source = sources[orderItem.id]; + orderItem.children.forEach((embedId) => { + const embed = sources[embedId]; + if (!embed.embedId) return; + const metric = scrapeSegmentToProviderMetric(media, source.id, embed); + if (!metric) return; + output.push(metric); + }); + + const metric = scrapeSegmentToProviderMetric(media, source.id, source); + if (!metric) return; + output.push(metric); + }); + + return output; +} + +export function useReportProviders() { + const report = useCallback((items: ProviderMetric[]) => { + if (items.length === 0) return; + reportProviders(items).catch(() => {}); + }, []); + + return { report }; +} + +export function reportCaptchaSolve(success: boolean) { + if (!BACKEND_URL) return; + ofetch(captchaMetricsEndpoint, { + method: "POST", + body: { + success, + }, + }).catch(() => {}); +} diff --git a/src/backend/helpers/subs.ts b/src/backend/helpers/subs.ts new file mode 100644 index 0000000..01bf4f7 --- /dev/null +++ b/src/backend/helpers/subs.ts @@ -0,0 +1,65 @@ +import { list } from "subsrt-ts"; + +import { proxiedFetch } from "@/backend/helpers/fetch"; +import { convertSubtitlesToSrt } from "@/components/player/utils/captions"; +import { CaptionListItem } from "@/stores/player/slices/source"; +import { SimpleCache } from "@/utils/cache"; + +import { + isExtensionActiveCached, + sendExtensionRequest, +} from "../extension/messaging"; + +export const subtitleTypeList = list().map((type) => `.${type}`); +const downloadCache = new SimpleCache(); +downloadCache.setCompare((a, b) => a === b); +const expirySeconds = 24 * 60 * 60; + +/** + * Always returns SRT + */ +export async function downloadCaption( + caption: CaptionListItem, +): Promise { + const cached = downloadCache.get(caption.url); + if (cached) return cached; + + let data: string | undefined; + if (caption.needsProxy) { + if (isExtensionActiveCached()) { + const extensionResponse = await sendExtensionRequest({ + url: caption.url, + method: "GET", + }); + if ( + !extensionResponse?.success || + typeof extensionResponse.response.body !== "string" + ) { + throw new Error("failed to get caption data from extension"); + } + + data = extensionResponse.response.body; + } else { + data = await proxiedFetch(caption.url, { responseType: "text" }); + } + } else { + data = await fetch(caption.url).then((v) => v.text()); + } + if (!data) throw new Error("failed to get caption data"); + + const output = convertSubtitlesToSrt(data); + downloadCache.set(caption.url, output, expirySeconds); + return output; +} + +/** + * Downloads the WebVTT content. No different than a simple + * get request with a cache. + */ +export async function downloadWebVTT(url: string): Promise { + const cached = downloadCache.get(url); + if (cached) return cached; + + const data = await fetch(url).then((v) => v.text()); + return data; +} diff --git a/src/backend/metadata/getmeta.ts b/src/backend/metadata/getmeta.ts new file mode 100644 index 0000000..cfb34b9 --- /dev/null +++ b/src/backend/metadata/getmeta.ts @@ -0,0 +1,216 @@ +import { FetchError } from "ofetch"; + +import { formatJWMeta, mediaTypeToJW } from "./justwatch"; +import { + TMDBIdToUrlId, + TMDBMediaToMediaType, + formatTMDBMeta, + getEpisodes, + getMediaDetails, + getMediaPoster, + getMovieFromExternalId, + mediaTypeToTMDB, +} from "./tmdb"; +import { + JWDetailedMeta, + JWSeasonMetaResult, + JW_API_BASE, +} from "./types/justwatch"; +import { MWMediaMeta, MWMediaType } from "./types/mw"; +import { + TMDBContentTypes, + TMDBMediaResult, + TMDBMovieData, + TMDBSeasonMetaResult, + TMDBShowData, +} from "./types/tmdb"; +import { makeUrl, proxiedFetch } from "../helpers/fetch"; + +export interface DetailedMeta { + meta: MWMediaMeta; + imdbId?: string; + tmdbId?: string; +} + +export function formatTMDBMetaResult( + details: TMDBShowData | TMDBMovieData, + type: MWMediaType, +): TMDBMediaResult { + if (type === MWMediaType.MOVIE) { + const movie = details as TMDBMovieData; + return { + id: details.id, + title: movie.title, + object_type: mediaTypeToTMDB(type), + poster: getMediaPoster(movie.poster_path) ?? undefined, + original_release_date: new Date(movie.release_date), + }; + } + if (type === MWMediaType.SERIES) { + const show = details as TMDBShowData; + return { + id: details.id, + title: show.name, + object_type: mediaTypeToTMDB(type), + seasons: show.seasons.map((v) => ({ + id: v.id, + season_number: v.season_number, + title: v.name, + })), + poster: getMediaPoster(show.poster_path) ?? undefined, + original_release_date: new Date(show.first_air_date), + }; + } + + throw new Error("unsupported type"); +} + +export async function getMetaFromId( + type: MWMediaType, + id: string, + seasonId?: string, +): Promise { + const details = await getMediaDetails(id, mediaTypeToTMDB(type)); + + if (!details) return null; + + const imdbId = details.external_ids.imdb_id ?? undefined; + + let seasonData: TMDBSeasonMetaResult | undefined; + + if (type === MWMediaType.SERIES) { + const seasons = (details as TMDBShowData).seasons; + + let selectedSeason = seasons.find((v) => v.id.toString() === seasonId); + if (!selectedSeason) { + selectedSeason = seasons.find((v) => v.season_number === 1); + } + + if (selectedSeason) { + const episodes = await getEpisodes( + details.id.toString(), + selectedSeason.season_number, + ); + + seasonData = { + id: selectedSeason.id.toString(), + season_number: selectedSeason.season_number, + title: selectedSeason.name, + episodes, + }; + } + } + + const tmdbmeta = formatTMDBMetaResult(details, type); + if (!tmdbmeta) return null; + const meta = formatTMDBMeta(tmdbmeta, seasonData); + if (!meta) return null; + + return { + meta, + imdbId, + tmdbId: id, + }; +} + +export async function getLegacyMetaFromId( + type: MWMediaType, + id: string, + seasonId?: string, +): Promise { + const queryType = mediaTypeToJW(type); + + let data: JWDetailedMeta; + try { + const url = makeUrl("/content/titles/{type}/{id}/locale/en_US", { + type: queryType, + id, + }); + data = await proxiedFetch(url, { baseURL: JW_API_BASE }); + } catch (err) { + if (err instanceof FetchError) { + // 400 and 404 are treated as not found + if (err.statusCode === 400 || err.statusCode === 404) return null; + } + throw err; + } + + let imdbId = data.external_ids.find( + (v) => v.provider === "imdb_latest", + )?.external_id; + if (!imdbId) + imdbId = data.external_ids.find((v) => v.provider === "imdb")?.external_id; + + let tmdbId = data.external_ids.find( + (v) => v.provider === "tmdb_latest", + )?.external_id; + if (!tmdbId) + tmdbId = data.external_ids.find((v) => v.provider === "tmdb")?.external_id; + + let seasonData: JWSeasonMetaResult | undefined; + if (data.object_type === "show") { + const seasonToScrape = seasonId ?? data.seasons?.[0].id.toString() ?? ""; + const url = makeUrl("/content/titles/show_season/{id}/locale/en_US", { + id: seasonToScrape, + }); + seasonData = await proxiedFetch(url, { baseURL: JW_API_BASE }); + } + + return { + meta: formatJWMeta(data, seasonData), + imdbId, + tmdbId, + }; +} + +export function isLegacyUrl(url: string): boolean { + if (url.startsWith("/media/JW") || url.startsWith("/media/tmdb-show")) + return true; + return false; +} + +export function isLegacyMediaType(url: string): boolean { + if (url.startsWith("/media/tmdb-show")) return true; + return false; +} + +export async function convertLegacyUrl( + url: string, +): Promise { + if (!isLegacyUrl(url)) return undefined; + + const urlParts = url.split("/").slice(2); + const [, type, id] = urlParts[0].split("-", 3); + const suffix = urlParts + .slice(1) + .map((v) => `/${v}`) + .join(""); + + if (isLegacyMediaType(url)) { + const details = await getMediaDetails(id, TMDBContentTypes.TV); + return `/media/${TMDBIdToUrlId( + MWMediaType.SERIES, + details.id.toString(), + details.name, + )}${suffix}`; + } + + const mediaType = TMDBMediaToMediaType(type as TMDBContentTypes); + const meta = await getLegacyMetaFromId(mediaType, id); + + if (!meta) return undefined; + const { tmdbId, imdbId } = meta; + if (!tmdbId && !imdbId) return undefined; + + // movies always have an imdb id on tmdb + if (imdbId && mediaType === MWMediaType.MOVIE) { + const movieId = await getMovieFromExternalId(imdbId); + if (movieId) { + return `/media/${TMDBIdToUrlId(mediaType, movieId, meta.meta.title)}`; + } + + if (tmdbId) { + return `/media/${TMDBIdToUrlId(mediaType, tmdbId, meta.meta.title)}`; + } + } +} diff --git a/src/backend/metadata/justwatch.ts b/src/backend/metadata/justwatch.ts new file mode 100644 index 0000000..f4c7906 --- /dev/null +++ b/src/backend/metadata/justwatch.ts @@ -0,0 +1,84 @@ +import { + JWContentTypes, + JWMediaResult, + JWSeasonMetaResult, + JW_IMAGE_BASE, +} from "./types/justwatch"; +import { MWMediaMeta, MWMediaType, MWSeasonMeta } from "./types/mw"; + +export function mediaTypeToJW(type: MWMediaType): JWContentTypes { + if (type === MWMediaType.MOVIE) return "movie"; + if (type === MWMediaType.SERIES) return "show"; + throw new Error("unsupported type"); +} + +export function JWMediaToMediaType(type: string): MWMediaType { + if (type === "movie") return MWMediaType.MOVIE; + if (type === "show") return MWMediaType.SERIES; + throw new Error("unsupported type"); +} + +export function formatJWMeta( + media: JWMediaResult, + season?: JWSeasonMetaResult, +): MWMediaMeta { + const type = JWMediaToMediaType(media.object_type); + let seasons: undefined | MWSeasonMeta[]; + if (type === MWMediaType.SERIES) { + seasons = media.seasons + ?.sort((a, b) => a.season_number - b.season_number) + .map( + (v): MWSeasonMeta => ({ + id: v.id.toString(), + number: v.season_number, + title: v.title, + }), + ); + } + + return { + title: media.title, + id: media.id.toString(), + year: media.original_release_year?.toString(), + poster: media.poster + ? `${JW_IMAGE_BASE}${media.poster.replace("{profile}", "s166")}` + : undefined, + type, + seasons: seasons as any, + seasonData: season + ? ({ + id: season.id.toString(), + number: season.season_number, + title: season.title, + episodes: season.episodes + .sort((a, b) => a.episode_number - b.episode_number) + .map((v) => ({ + id: v.id.toString(), + number: v.episode_number, + title: v.title, + })), + } as any) + : (undefined as any), + }; +} + +export function JWMediaToId(media: MWMediaMeta): string { + return ["JW", mediaTypeToJW(media.type), media.id].join("-"); +} + +export function decodeJWId( + paramId: string, +): { id: string; type: MWMediaType } | null { + const [prefix, type, id] = paramId.split("-", 3); + if (prefix !== "JW") return null; + let mediaType; + try { + mediaType = JWMediaToMediaType(type); + } catch { + return null; + } + return { + type: mediaType, + id, + }; +} diff --git a/src/backend/metadata/search.ts b/src/backend/metadata/search.ts new file mode 100644 index 0000000..fff6411 --- /dev/null +++ b/src/backend/metadata/search.ts @@ -0,0 +1,35 @@ +import { SimpleCache } from "@/utils/cache"; +import { MediaItem } from "@/utils/mediaTypes"; + +import { + formatTMDBMetaToMediaItem, + formatTMDBSearchResult, + multiSearch, +} from "./tmdb"; +import { MWQuery } from "./types/mw"; + +const cache = new SimpleCache(); +cache.setCompare((a, b) => { + return a.searchQuery.trim() === b.searchQuery.trim(); +}); +cache.initialize(); + +export async function searchForMedia(query: MWQuery): Promise { + if (cache.has(query)) return cache.get(query) as MediaItem[]; + const { searchQuery } = query; + + const data = await multiSearch(searchQuery); + const results = data.map((v) => { + const formattedResult = formatTMDBSearchResult(v, v.media_type); + return formatTMDBMetaToMediaItem(formattedResult); + }); + + const movieWithPosters = results.filter((movie) => movie.poster); + const movieWithoutPosters = results.filter((movie) => !movie.poster); + + const sortedresult = movieWithPosters.concat(movieWithoutPosters); + + // cache results for 1 hour + cache.set(query, sortedresult, 3600); + return sortedresult; +} diff --git a/src/backend/metadata/tmdb.ts b/src/backend/metadata/tmdb.ts new file mode 100644 index 0000000..28c716d --- /dev/null +++ b/src/backend/metadata/tmdb.ts @@ -0,0 +1,295 @@ +import slugify from "slugify"; + +import { conf } from "@/setup/config"; +import { MediaItem } from "@/utils/mediaTypes"; + +import { MWMediaMeta, MWMediaType, MWSeasonMeta } from "./types/mw"; +import { + ExternalIdMovieSearchResult, + TMDBContentTypes, + TMDBEpisodeShort, + TMDBMediaResult, + TMDBMovieData, + TMDBMovieSearchResult, + TMDBSearchResult, + TMDBSeason, + TMDBSeasonMetaResult, + TMDBShowData, + TMDBShowSearchResult, +} from "./types/tmdb"; +import { mwFetch } from "../helpers/fetch"; + +export function mediaTypeToTMDB(type: MWMediaType): TMDBContentTypes { + if (type === MWMediaType.MOVIE) return TMDBContentTypes.MOVIE; + if (type === MWMediaType.SERIES) return TMDBContentTypes.TV; + throw new Error("unsupported type"); +} + +export function mediaItemTypeToMediaType(type: MediaItem["type"]): MWMediaType { + if (type === "movie") return MWMediaType.MOVIE; + if (type === "show") return MWMediaType.SERIES; + throw new Error("unsupported type"); +} + +export function TMDBMediaToMediaType(type: TMDBContentTypes): MWMediaType { + if (type === TMDBContentTypes.MOVIE) return MWMediaType.MOVIE; + if (type === TMDBContentTypes.TV) return MWMediaType.SERIES; + throw new Error("unsupported type"); +} + +export function TMDBMediaToMediaItemType( + type: TMDBContentTypes, +): MediaItem["type"] { + if (type === TMDBContentTypes.MOVIE) return "movie"; + if (type === TMDBContentTypes.TV) return "show"; + throw new Error("unsupported type"); +} + +export function formatTMDBMeta( + media: TMDBMediaResult, + season?: TMDBSeasonMetaResult, +): MWMediaMeta { + const type = TMDBMediaToMediaType(media.object_type); + let seasons: undefined | MWSeasonMeta[]; + if (type === MWMediaType.SERIES) { + seasons = media.seasons + ?.sort((a, b) => a.season_number - b.season_number) + .map( + (v): MWSeasonMeta => ({ + title: v.title, + id: v.id.toString(), + number: v.season_number, + }), + ); + } + + return { + title: media.title, + id: media.id.toString(), + year: media.original_release_date?.getFullYear()?.toString(), + poster: media.poster, + type, + seasons: seasons as any, + seasonData: season + ? { + id: season.id.toString(), + number: season.season_number, + title: season.title, + episodes: season.episodes + .sort((a, b) => a.episode_number - b.episode_number) + .map((v) => ({ + id: v.id.toString(), + number: v.episode_number, + title: v.title, + air_date: v.air_date, + })), + } + : (undefined as any), + }; +} + +export function formatTMDBMetaToMediaItem(media: TMDBMediaResult): MediaItem { + const type = TMDBMediaToMediaItemType(media.object_type); + + return { + title: media.title, + id: media.id.toString(), + year: media.original_release_date?.getFullYear() ?? 0, + release_date: media.original_release_date, + poster: media.poster, + type, + }; +} + +export function TMDBIdToUrlId( + type: MWMediaType, + tmdbId: string, + title: string, +) { + return [ + "tmdb", + mediaTypeToTMDB(type), + tmdbId, + slugify(title, { lower: true, strict: true }), + ].join("-"); +} + +export function TMDBMediaToId(media: MWMediaMeta): string { + return TMDBIdToUrlId(media.type, media.id, media.title); +} + +export function mediaItemToId(media: MediaItem): string { + return TMDBIdToUrlId( + mediaItemTypeToMediaType(media.type), + media.id, + media.title, + ); +} + +export function decodeTMDBId( + paramId: string, +): { id: string; type: MWMediaType } | null { + const [prefix, type, id] = paramId.split("-", 3); + if (prefix !== "tmdb") return null; + let mediaType; + try { + mediaType = TMDBMediaToMediaType(type as TMDBContentTypes); + } catch { + return null; + } + return { + type: mediaType, + id, + }; +} + +const tmdbBaseUrl1 = "https://api.themoviedb.org/3"; +const tmdbBaseUrl2 = "https://api.tmdb.org/3"; + +const apiKey = conf().TMDB_READ_API_KEY; + +const tmdbHeaders = { + accept: "application/json", + Authorization: `Bearer ${apiKey}`, +}; + +function abortOnTimeout(timeout: number): AbortSignal { + const controller = new AbortController(); + setTimeout(() => controller.abort(), timeout); + return controller.signal; +} + +export async function get(url: string, params?: object): Promise { + if (!apiKey) throw new Error("TMDB API key not set"); + try { + return await mwFetch(encodeURI(url), { + headers: tmdbHeaders, + baseURL: tmdbBaseUrl1, + params: { + ...params, + }, + signal: abortOnTimeout(5000), + }); + } catch (err) { + return mwFetch(encodeURI(url), { + headers: tmdbHeaders, + baseURL: tmdbBaseUrl2, + params: { + ...params, + }, + signal: abortOnTimeout(30000), + }); + } +} + +export async function multiSearch( + query: string, +): Promise<(TMDBMovieSearchResult | TMDBShowSearchResult)[]> { + const data = await get("search/multi", { + query, + include_adult: false, + language: "en-US", + page: 1, + }); + // filter out results that aren't movies or shows + const results = data.results.filter( + (r) => + r.media_type === TMDBContentTypes.MOVIE || + r.media_type === TMDBContentTypes.TV, + ); + return results; +} + +export async function generateQuickSearchMediaUrl( + query: string, +): Promise { + const data = await multiSearch(query); + if (data.length === 0) return undefined; + const result = data[0]; + const title = + result.media_type === TMDBContentTypes.MOVIE ? result.title : result.name; + + return `/media/${TMDBIdToUrlId( + TMDBMediaToMediaType(result.media_type), + result.id.toString(), + title, + )}`; +} + +// Conditional type which for inferring the return type based on the content type +type MediaDetailReturn = + T extends TMDBContentTypes.MOVIE + ? TMDBMovieData + : T extends TMDBContentTypes.TV + ? TMDBShowData + : never; + +export function getMediaDetails< + T extends TMDBContentTypes, + TReturn = MediaDetailReturn, +>(id: string, type: T): Promise { + if (type === TMDBContentTypes.MOVIE) { + return get(`/movie/${id}`, { append_to_response: "external_ids" }); + } + if (type === TMDBContentTypes.TV) { + return get(`/tv/${id}`, { append_to_response: "external_ids" }); + } + throw new Error("Invalid media type"); +} + +export function getMediaPoster(posterPath: string | null): string | undefined { + if (posterPath) return `https://image.tmdb.org/t/p/w342/${posterPath}`; +} + +export async function getEpisodes( + id: string, + season: number, +): Promise { + const data = await get(`/tv/${id}/season/${season}`); + return data.episodes.map((e) => ({ + id: e.id, + episode_number: e.episode_number, + title: e.name, + air_date: e.air_date, + })); +} + +export async function getMovieFromExternalId( + imdbId: string, +): Promise { + const data = await get(`/find/${imdbId}`, { + external_source: "imdb_id", + }); + + const movie = data.movie_results[0]; + if (!movie) return undefined; + + return movie.id.toString(); +} + +export function formatTMDBSearchResult( + result: TMDBMovieSearchResult | TMDBShowSearchResult, + mediatype: TMDBContentTypes, +): TMDBMediaResult { + const type = TMDBMediaToMediaType(mediatype); + if (type === MWMediaType.SERIES) { + const show = result as TMDBShowSearchResult; + return { + title: show.name, + poster: getMediaPoster(show.poster_path), + id: show.id, + original_release_date: new Date(show.first_air_date), + object_type: mediatype, + }; + } + + const movie = result as TMDBMovieSearchResult; + + return { + title: movie.title, + poster: getMediaPoster(movie.poster_path), + id: movie.id, + original_release_date: new Date(movie.release_date), + object_type: mediatype, + }; +} diff --git a/src/backend/metadata/types/justwatch.ts b/src/backend/metadata/types/justwatch.ts new file mode 100644 index 0000000..b55e9e2 --- /dev/null +++ b/src/backend/metadata/types/justwatch.ts @@ -0,0 +1,65 @@ +export type JWContentTypes = "movie" | "show"; + +export type JWSearchQuery = { + content_types: JWContentTypes[]; + page: number; + page_size: number; + query: string; +}; + +export type JWPage = { + items: T[]; + page: number; + page_size: number; + total_pages: number; + total_results: number; +}; + +export const JW_API_BASE = "https://apis.justwatch.com"; +export const JW_IMAGE_BASE = "https://images.justwatch.com"; + +export type JWSeasonShort = { + title: string; + id: number; + season_number: number; +}; + +export type JWEpisodeShort = { + title: string; + id: number; + episode_number: number; +}; + +export type JWMediaResult = { + title: string; + poster?: string; + id: number; + original_release_year?: number; + jw_entity_id: string; + object_type: JWContentTypes; + seasons?: JWSeasonShort[]; +}; + +export type JWSeasonMetaResult = { + title: string; + id: string; + season_number: number; + episodes: JWEpisodeShort[]; +}; + +export type JWExternalIdType = + | "eidr" + | "imdb_latest" + | "imdb" + | "tmdb_latest" + | "tmdb" + | "tms"; + +export interface JWExternalId { + provider: JWExternalIdType; + external_id: string; +} + +export interface JWDetailedMeta extends JWMediaResult { + external_ids: JWExternalId[]; +} diff --git a/src/backend/metadata/types/mw.ts b/src/backend/metadata/types/mw.ts new file mode 100644 index 0000000..7589c83 --- /dev/null +++ b/src/backend/metadata/types/mw.ts @@ -0,0 +1,53 @@ +export enum MWMediaType { + MOVIE = "movie", + SERIES = "series", + ANIME = "anime", +} + +export type MWSeasonMeta = { + id: string; + number: number; + title: string; +}; + +export type MWSeasonWithEpisodeMeta = { + id: string; + number: number; + title: string; + episodes: { + id: string; + number: number; + title: string; + air_date: string; + }[]; +}; + +type MWMediaMetaBase = { + title: string; + id: string; + year?: string; + poster?: string; +}; + +type MWMediaMetaSpecific = + | { + type: MWMediaType.MOVIE | MWMediaType.ANIME; + seasons: undefined; + } + | { + type: MWMediaType.SERIES; + seasons: MWSeasonMeta[]; + seasonData: MWSeasonWithEpisodeMeta; + }; + +export type MWMediaMeta = MWMediaMetaBase & MWMediaMetaSpecific; + +export interface MWQuery { + searchQuery: string; +} + +export interface DetailedMeta { + meta: MWMediaMeta; + imdbId?: string; + tmdbId?: string; +} diff --git a/src/backend/metadata/types/tmdb.ts b/src/backend/metadata/types/tmdb.ts new file mode 100644 index 0000000..5d082f5 --- /dev/null +++ b/src/backend/metadata/types/tmdb.ts @@ -0,0 +1,289 @@ +export enum TMDBContentTypes { + MOVIE = "movie", + TV = "tv", +} + +export type TMDBSeasonShort = { + title: string; + id: number; + season_number: number; +}; + +export type TMDBEpisodeShort = { + title: string; + id: number; + episode_number: number; + air_date: string; +}; + +export type TMDBMediaResult = { + title: string; + poster?: string; + id: number; + original_release_date?: Date; + object_type: TMDBContentTypes; + seasons?: TMDBSeasonShort[]; +}; + +export type TMDBSeasonMetaResult = { + title: string; + id: string; + season_number: number; + episodes: TMDBEpisodeShort[]; +}; + +export interface TMDBShowData { + adult: boolean; + backdrop_path: string | null; + created_by: { + id: number; + credit_id: string; + name: string; + gender: number; + profile_path: string | null; + }[]; + episode_run_time: number[]; + first_air_date: string; + genres: { + id: number; + name: string; + }[]; + homepage: string; + id: number; + in_production: boolean; + languages: string[]; + last_air_date: string; + last_episode_to_air: { + id: number; + name: string; + overview: string; + vote_average: number; + vote_count: number; + air_date: string; + episode_number: number; + production_code: string; + runtime: number | null; + season_number: number; + show_id: number; + still_path: string | null; + } | null; + name: string; + next_episode_to_air: { + id: number; + name: string; + overview: string; + vote_average: number; + vote_count: number; + air_date: string; + episode_number: number; + production_code: string; + runtime: number | null; + season_number: number; + show_id: number; + still_path: string | null; + } | null; + networks: { + id: number; + logo_path: string; + name: string; + origin_country: string; + }[]; + number_of_episodes: number; + number_of_seasons: number; + origin_country: string[]; + original_language: string; + original_name: string; + overview: string; + popularity: number; + poster_path: string | null; + production_companies: { + id: number; + logo_path: string | null; + name: string; + origin_country: string; + }[]; + production_countries: { + iso_3166_1: string; + name: string; + }[]; + seasons: { + air_date: string; + episode_count: number; + id: number; + name: string; + overview: string; + poster_path: string | null; + season_number: number; + }[]; + spoken_languages: { + english_name: string; + iso_639_1: string; + name: string; + }[]; + status: string; + tagline: string; + type: string; + vote_average: number; + vote_count: number; + external_ids: { + imdb_id: string | null; + }; +} + +export interface TMDBMovieData { + adult: boolean; + backdrop_path: string | null; + belongs_to_collection: { + id: number; + name: string; + poster_path: string | null; + backdrop_path: string | null; + } | null; + budget: number; + genres: { + id: number; + name: string; + }[]; + homepage: string | null; + id: number; + imdb_id: string | null; + original_language: string; + original_title: string; + overview: string | null; + popularity: number; + poster_path: string | null; + production_companies: { + id: number; + logo_path: string | null; + name: string; + origin_country: string; + }[]; + production_countries: { + iso_3166_1: string; + name: string; + }[]; + release_date: string; + revenue: number; + runtime: number | null; + spoken_languages: { + english_name: string; + iso_639_1: string; + name: string; + }[]; + status: string; + tagline: string | null; + title: string; + video: boolean; + vote_average: number; + vote_count: number; + external_ids: { + imdb_id: string | null; + }; +} + +export interface TMDBEpisodeResult { + season: number; + number: number; + title: string; + ids: { + trakt: number; + tvdb: number; + imdb: string; + tmdb: number; + }; +} + +export interface TMDBEpisode { + air_date: string; + episode_number: number; + id: number; + name: string; + overview: string; + production_code: string; + runtime: number; + season_number: number; + show_id: number; + still_path: string | null; + vote_average: number; + vote_count: number; + crew: any[]; + guest_stars: any[]; +} + +export interface TMDBSeason { + _id: string; + air_date: string; + episodes: TMDBEpisode[]; + name: string; + overview: string; + id: number; + poster_path: string | null; + season_number: number; +} + +export interface ExternalIdMovieSearchResult { + movie_results: { + adult: boolean; + backdrop_path: string; + id: number; + title: string; + original_language: string; + original_title: string; + overview: string; + poster_path: string; + media_type: string; + genre_ids: number[]; + popularity: number; + release_date: string; + video: boolean; + vote_average: number; + vote_count: number; + }[]; + person_results: any[]; + tv_results: any[]; + tv_episode_results: any[]; + tv_season_results: any[]; +} + +export interface TMDBMovieSearchResult { + adult: boolean; + backdrop_path: string; + id: number; + title: string; + original_language: string; + original_title: string; + overview: string; + poster_path: string; + media_type: TMDBContentTypes.MOVIE; + genre_ids: number[]; + popularity: number; + release_date: string; + video: boolean; + vote_average: number; + vote_count: number; +} + +export interface TMDBShowSearchResult { + adult: boolean; + backdrop_path: string; + id: number; + name: string; + original_language: string; + original_name: string; + overview: string; + poster_path: string; + media_type: TMDBContentTypes.TV; + genre_ids: number[]; + popularity: number; + first_air_date: string; + vote_average: number; + vote_count: number; + origin_country: string[]; +} + +export interface TMDBSearchResult { + page: number; + results: (TMDBMovieSearchResult | TMDBShowSearchResult)[]; + total_pages: number; + total_results: number; +} diff --git a/src/backend/providers/fetchers.ts b/src/backend/providers/fetchers.ts new file mode 100644 index 0000000..5cb6f6b --- /dev/null +++ b/src/backend/providers/fetchers.ts @@ -0,0 +1,88 @@ +import { Fetcher, makeSimpleProxyFetcher } from "@movie-web/providers"; + +import { sendExtensionRequest } from "@/backend/extension/messaging"; +import { getApiToken, setApiToken } from "@/backend/helpers/providerApi"; +import { getProviderApiUrls, getProxyUrls } from "@/utils/proxyUrls"; + +import { convertBodyToObject, getBodyTypeFromBody } from "../extension/request"; + +function makeLoadbalancedList(getter: () => string[]) { + let listIndex = -1; + return () => { + const fetchers = getter(); + if (listIndex === -1 || listIndex >= fetchers.length) { + listIndex = Math.floor(Math.random() * fetchers.length); + } + const proxyUrl = fetchers[listIndex]; + listIndex = (listIndex + 1) % fetchers.length; + return proxyUrl; + }; +} + +export const getLoadbalancedProxyUrl = makeLoadbalancedList(getProxyUrls); +export const getLoadbalancedProviderApiUrl = + makeLoadbalancedList(getProviderApiUrls); + +async function fetchButWithApiTokens( + input: RequestInfo | URL, + init?: RequestInit | undefined, +): Promise { + const apiToken = await getApiToken(); + const headers = new Headers(init?.headers); + if (apiToken) headers.set("X-Token", apiToken); + const response = await fetch( + input, + init + ? { + ...init, + headers, + } + : undefined, + ); + const newApiToken = response.headers.get("X-Token"); + if (newApiToken) setApiToken(newApiToken); + return response; +} + +export function makeLoadBalancedSimpleProxyFetcher() { + const fetcher: Fetcher = async (a, b) => { + const currentFetcher = makeSimpleProxyFetcher( + getLoadbalancedProxyUrl(), + fetchButWithApiTokens, + ); + return currentFetcher(a, b); + }; + return fetcher; +} + +function makeFinalHeaders( + readHeaders: string[], + headers: Record, +): Headers { + const lowercasedHeaders = readHeaders.map((v) => v.toLowerCase()); + return new Headers( + Object.entries(headers).filter((entry) => + lowercasedHeaders.includes(entry[0].toLowerCase()), + ), + ); +} + +export function makeExtensionFetcher() { + const fetcher: Fetcher = async (url, ops) => { + const result = await sendExtensionRequest({ + url, + ...ops, + body: convertBodyToObject(ops.body), + bodyType: getBodyTypeFromBody(ops.body), + }); + if (!result?.success) throw new Error(`extension error: ${result?.error}`); + const res = result.response; + return { + body: res.body, + finalUrl: res.finalUrl, + statusCode: res.statusCode, + headers: makeFinalHeaders(ops.readHeaders, res.headers), + }; + }; + return fetcher; +} diff --git a/src/backend/providers/providers.ts b/src/backend/providers/providers.ts new file mode 100644 index 0000000..20aae64 --- /dev/null +++ b/src/backend/providers/providers.ts @@ -0,0 +1,36 @@ +import { + makeProviders, + makeStandardFetcher, + targets, +} from "@movie-web/providers"; + +import { isExtensionActiveCached } from "@/backend/extension/messaging"; +import { + makeExtensionFetcher, + makeLoadBalancedSimpleProxyFetcher, +} from "@/backend/providers/fetchers"; + +export function getProviders() { + if (isExtensionActiveCached()) { + return makeProviders({ + fetcher: makeStandardFetcher(fetch), + proxiedFetcher: makeExtensionFetcher(), + target: targets.BROWSER_EXTENSION, + consistentIpForRequests: true, + }); + } + + return makeProviders({ + fetcher: makeStandardFetcher(fetch), + proxiedFetcher: makeLoadBalancedSimpleProxyFetcher(), + target: targets.BROWSER, + }); +} + +export function getAllProviders() { + return makeProviders({ + fetcher: makeStandardFetcher(fetch), + target: targets.BROWSER_EXTENSION, + consistentIpForRequests: true, + }); +} diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx new file mode 100644 index 0000000..ec883de --- /dev/null +++ b/src/components/Avatar.tsx @@ -0,0 +1,95 @@ +import classNames from "classnames"; +import { useMemo } from "react"; + +import { base64ToBuffer, decryptData } from "@/backend/accounts/crypto"; +import { Icon, Icons } from "@/components/Icon"; +import { UserIcon } from "@/components/UserIcon"; +import { AccountProfile } from "@/pages/parts/auth/AccountCreatePart"; +import { useAuthStore } from "@/stores/auth"; + +export interface AvatarProps { + profile: AccountProfile["profile"]; + sizeClass?: string; + iconClass?: string; + bottom?: React.ReactNode; +} + +export function Avatar(props: AvatarProps) { + return ( +
+
+ +
+ {props.bottom ? ( +
+ {props.bottom} +
+ ) : null} +
+ ); +} + +export function UserAvatar(props: { + sizeClass?: string; + iconClass?: string; + bottom?: React.ReactNode; + withName?: boolean; +}) { + const auth = useAuthStore(); + + const bufferSeed = useMemo( + () => + auth.account && auth.account.seed + ? base64ToBuffer(auth.account.seed) + : null, + [auth], + ); + + if (!auth.account || auth.account === null) return null; + + const deviceName = bufferSeed + ? decryptData(auth.account.deviceName, bufferSeed) + : "..."; + + return ( + <> + + {props.withName && bufferSeed ? ( + + {deviceName.length >= 20 + ? `${deviceName.slice(0, 20 - 1)}…` + : deviceName} + + ) : null} + + ); +} + +export function NoUserAvatar(props: { iconClass?: string }) { + return ( +
+ +
+ ); +} diff --git a/src/components/DropFile.tsx b/src/components/DropFile.tsx new file mode 100644 index 0000000..8b0ab84 --- /dev/null +++ b/src/components/DropFile.tsx @@ -0,0 +1,51 @@ +import { useEffect, useState } from "react"; +import type { DragEvent, ReactNode } from "react"; + +interface FileDropHandlerProps { + children: ReactNode; + className: string; + onDrop: (event: DragEvent) => void; + onDraggingChange: (isDragging: boolean) => void; +} + +export function FileDropHandler(props: FileDropHandlerProps) { + const [dragging, setDragging] = useState(false); + + const handleDragEnter = (event: DragEvent) => { + event.preventDefault(); + setDragging(true); + }; + + const handleDragLeave = (event: DragEvent) => { + if (!event.currentTarget.contains(event.relatedTarget as Node)) { + setDragging(false); + } + }; + + const handleDragOver = (event: DragEvent) => { + event.preventDefault(); + }; + + const handleDrop = (event: DragEvent) => { + event.preventDefault(); + setDragging(false); + + props.onDrop(event); + }; + + useEffect(() => { + props.onDraggingChange(dragging); + }, [dragging, props]); + + return ( +
+ {props.children} +
+ ); +} diff --git a/src/components/FlagIcon.tsx b/src/components/FlagIcon.tsx new file mode 100644 index 0000000..ec9ea5a --- /dev/null +++ b/src/components/FlagIcon.tsx @@ -0,0 +1,74 @@ +import classNames from "classnames"; + +import { getCountryCodeForLocale } from "@/utils/language"; +import "flag-icons/css/flag-icons.min.css"; + +export interface FlagIconProps { + country?: string; + langCode?: string; +} + +export function FlagIcon(props: FlagIconProps) { + let countryCode: string | null = props.country ?? null; + if (props.langCode) countryCode = getCountryCodeForLocale(props.langCode); + + if (props.langCode === "tok") + return ( +
+ +
+ ); + + if (props.langCode === "pirate") + return ( +
+ +
+ ); + + if (props.langCode === "cat") + return ( +
+ +
+ ); + + if (props.langCode === "uwu") + return ( +
+ +
+ ); + + if (props.langCode === "minion") + return ( +
+
+
+
+
+
+
+ ); + + // Galicia - Not a country (Is a region of Spain) so have to add the flag manually + if (props.langCode === "gl-ES") + return ( +
+ +
+ ); + + let backgroundClass = "bg-video-context-flagBg"; + if (countryCode === "np") backgroundClass = "bg-white"; + + return ( + + ); +} diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx new file mode 100644 index 0000000..dda27f5 --- /dev/null +++ b/src/components/Icon.tsx @@ -0,0 +1,189 @@ +import classNames from "classnames"; +import { memo, useEffect, useRef } from "react"; + +export enum Icons { + SEARCH = "search", + BOOKMARK = "bookmark", + BOOKMARK_OUTLINE = "bookmark_outline", + CLOCK = "clock", + EYE = "eye", + EYE_SLASH = "eyeSlash", + ARROW_LEFT = "arrowLeft", + ARROW_RIGHT = "arrowRight", + CHEVRON_DOWN = "chevronDown", + CHEVRON_UP = "chevronUp", + CHEVRON_RIGHT = "chevronRight", + CHEVRON_LEFT = "chevronLeft", + CLAPPER_BOARD = "clapperBoard", + FILM = "film", + DRAGON = "dragon", + WARNING = "warning", + MOVIE_WEB = "movieWeb", + TWITTER = "twitter", + DISCORD = "discord", + GITHUB = "github", + PLAY = "play", + PAUSE = "pause", + EXPAND = "expand", + COMPRESS = "compress", + VOLUME = "volume", + VOLUME_MED = "volume_med", + VOLUME_LOW = "volume_low", + VOLUME_X = "volume_x", + X = "x", + EDIT = "edit", + AIRPLAY = "airplay", + EPISODES = "episodes", + SKIP_FORWARD = "skip_forward", + SKIP_BACKWARD = "skip_backward", + FILE = "file", + CAPTIONS = "captions", + LINK = "link", + CASTING = "casting", + CIRCLE_EXCLAMATION = "circle_exclamation", + DOWNLOAD = "download", + GEAR = "gear", + WATCH_PARTY = "watch_party", + PICTURE_IN_PICTURE = "pictureInPicture", + CHECKMARK = "checkmark", + TACHOMETER = "tachometer", + MAIL = "mail", + CIRCLE_CHECK = "circle_check", + SKIP_EPISODE = "skip_episode", + MORE_VERTICAL = "more_vertical", + IOS_SHARE = "ios_share", + IOS_FILES = "ios_files", + WAND = "wand", + COPY = "copy", + USER = "user", + UP_DOWN_ARROW = "up_down_arrow", + RISING_STAR = "rising_star", + SETTINGS = "settings", + COINS = "coins", + LOGOUT = "logout", + MENU = "menu", + LOCK = "lock", + UNLOCK = "unlock", + CIRCLE_QUESTION = "circle_question", + BRUSH = "brush", + UPLOAD = "upload", + WEB = "web", +} + +export interface IconProps { + icon: Icons; + className?: string; +} + +const iconList: Record = { + search: ``, + bookmark: ``, + clock: ``, + eye: ``, + eyeSlash: ``, + arrowLeft: ``, + chevronDown: ``, + chevronUp: ``, + chevronRight: ``, + chevronLeft: ``, + clapperBoard: ``, + film: ``, + dragon: ``, + warning: ``, + arrowRight: ``, + movieWeb: ``, + discord: ``, + twitter: ``, + github: ``, + play: ``, + pause: ``, + expand: ``, + compress: ``, + volume: ``, + volume_med: ``, + volume_low: ``, + volume_x: ``, + x: ``, + edit: ``, + bookmark_outline: ``, + airplay: ``, + episodes: ``, + skip_forward: ``, + skip_backward: ``, + file: ``, + captions: ``, + link: ``, + circle_exclamation: ``, + casting: "", + download: ``, + gear: ``, + watch_party: ``, + pictureInPicture: ``, + checkmark: ``, + tachometer: ``, + mail: ``, + circle_check: ``, + skip_episode: ``, + more_vertical: ``, + ios_share: ``, + ios_files: ``, + wand: ``, + copy: ``, + user: ``, + up_down_arrow: ``, + rising_star: ``, + settings: ``, + coins: ``, + logout: ``, + menu: ``, + lock: ``, + unlock: ``, + circle_question: ``, + brush: ``, + upload: ``, + web: ` + + + + + + + + + + + `, +}; + +function ChromeCastButton() { + const ref = useRef(null); + + useEffect(() => { + const tag = document.createElement("google-cast-launcher"); + tag.setAttribute("id", "castbutton"); + ref.current?.appendChild(tag); + }, []); + + return
; +} + +export const Icon = memo((props: IconProps) => { + if (props.icon === Icons.CASTING) { + return ; + } + + const flipClass = + props.icon === Icons.ARROW_LEFT || + props.icon === Icons.ARROW_RIGHT || + props.icon === Icons.CHEVRON_LEFT || + props.icon === Icons.CHEVRON_RIGHT + ? "rtl:-scale-x-100" + : ""; + + return ( + + ); +}); diff --git a/src/components/LinksDropdown.tsx b/src/components/LinksDropdown.tsx new file mode 100644 index 0000000..f45cd50 --- /dev/null +++ b/src/components/LinksDropdown.tsx @@ -0,0 +1,178 @@ +import classNames from "classnames"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; + +import { base64ToBuffer, decryptData } from "@/backend/accounts/crypto"; +import { UserAvatar } from "@/components/Avatar"; +import { Icon, Icons } from "@/components/Icon"; +import { Transition } from "@/components/utils/Transition"; +import { useAuth } from "@/hooks/auth/useAuth"; +import { conf } from "@/setup/config"; +import { useAuthStore } from "@/stores/auth"; + +function Divider() { + return
; +} + +function GoToLink(props: { + children: React.ReactNode; + href?: string; + className?: string; + onClick?: () => void; +}) { + const navigate = useNavigate(); + + const goTo = (href: string) => { + if (href.startsWith("http")) { + window.open(href, "_blank"); + } else { + window.scrollTo(0, 0); + navigate(href); + } + }; + + return ( + { + evt.preventDefault(); + if (props.href) goTo(props.href); + else props.onClick?.(); + }} + className={props.className} + > + {props.children} + + ); +} + +function DropdownLink(props: { + children: React.ReactNode; + href?: string; + icon?: Icons; + highlight?: boolean; + className?: string; + onClick?: () => void; +}) { + return ( + + {props.icon ? : null} + {props.children} + + ); +} + +function CircleDropdownLink(props: { icon: Icons; href: string }) { + return ( + + + + ); +} + +export function LinksDropdown(props: { children: React.ReactNode }) { + const { t } = useTranslation(); + const [open, setOpen] = useState(false); + const deviceName = useAuthStore((s) => s.account?.deviceName); + const seed = useAuthStore((s) => s.account?.seed); + const bufferSeed = useMemo( + () => (seed ? base64ToBuffer(seed) : null), + [seed], + ); + const { logout } = useAuth(); + + useEffect(() => { + function onWindowClick(evt: MouseEvent) { + if ((evt.target as HTMLElement).closest(".is-dropdown")) return; + setOpen(false); + } + + window.addEventListener("click", onWindowClick); + return () => window.removeEventListener("click", onWindowClick); + }, []); + + const toggleOpen = useCallback(() => { + setOpen((s) => !s); + }, []); + + return ( +
+
evt.key === "Enter" && toggleOpen()} + > + {props.children} + +
+ +
+ {deviceName && bufferSeed ? ( + + + {decryptData(deviceName, bufferSeed)} + + ) : ( + + {t("navigation.menu.register")} + + )} + + + {t("navigation.menu.settings")} + + + {t("navigation.menu.about")} + + + {t("navigation.menu.discover")} + + {deviceName ? ( + + {t("navigation.menu.logout")} + + ) : null} + +
+ + + + +
+
+
+
+ ); +} diff --git a/src/components/UserIcon.tsx b/src/components/UserIcon.tsx new file mode 100644 index 0000000..9dfe380 --- /dev/null +++ b/src/components/UserIcon.tsx @@ -0,0 +1,42 @@ +import { memo } from "react"; + +import { Icon, Icons } from "@/components/Icon"; + +export enum UserIcons { + CAT = "cat", + WEED = "weed", + USER_GROUP = "userGroup", + COUCH = "couch", + MOBILE = "mobile", + TICKET = "ticket", +} + +export interface UserIconProps { + icon: UserIcons; + className?: string; +} + +const iconList: Record = { + cat: ``, + weed: ``, + userGroup: ``, + couch: ``, + mobile: ``, + ticket: ``, +}; + +export const UserIcon = memo((props: UserIconProps) => { + const icon = iconList[props.icon]; + if (!icon) return ; + return ( + + ); +}); diff --git a/src/components/buttons/Button.tsx b/src/components/buttons/Button.tsx new file mode 100644 index 0000000..8502e50 --- /dev/null +++ b/src/components/buttons/Button.tsx @@ -0,0 +1,148 @@ +import classNames from "classnames"; +import { ReactNode, useCallback } from "react"; +import { useNavigate } from "react-router-dom"; + +import { Icon, Icons } from "@/components/Icon"; +import { Spinner } from "@/components/layout/Spinner"; + +interface Props { + icon?: Icons; + onClick?: ( + event: React.MouseEvent, + ) => void; + children?: ReactNode; + theme?: "white" | "purple" | "secondary" | "danger"; + padding?: string; + className?: string; + href?: string; + disabled?: boolean; + download?: string; + loading?: boolean; +} + +export function Button(props: Props) { + const navigate = useNavigate(); + const { onClick, href, loading } = props; + const cb = useCallback( + ( + event: React.MouseEvent< + HTMLAnchorElement | HTMLButtonElement, + MouseEvent + >, + ) => { + if (loading) return; + if (href && !onClick) { + event.preventDefault(); + if (!href.includes("http")) { + navigate(href); + } else { + window.open(href, "_blank", "noreferrer"); + } + } else onClick?.(event); + }, + [loading, href, onClick, navigate], + ); + + let colorClasses = "bg-white hover:bg-gray-200 text-black"; + if (props.theme === "purple") + colorClasses = "bg-buttons-purple hover:bg-buttons-purpleHover text-white"; + if (props.theme === "secondary") + colorClasses = + "bg-buttons-cancel hover:bg-buttons-cancelHover transition-colors duration-100 text-white"; + if (props.theme === "danger") + colorClasses = "bg-buttons-danger hover:bg-buttons-dangerHover text-white"; + + let classes = classNames( + "tabbable cursor-pointer inline-flex items-center justify-center rounded-lg font-medium transition-[transform,background-color] duration-100 active:scale-105 md:px-8", + props.padding ?? "px-4 py-3", + props.className, + colorClasses, + props.disabled ? "!cursor-not-allowed bg-opacity-60 text-opacity-60" : null, + ); + + if (props.disabled) + classes = classes + .split(" ") + .filter( + (className) => + !className.startsWith("hover:") && !className.startsWith("active:"), + ) + .join(" "); + + const content = ( + <> + {props.icon && !props.loading ? ( + + + + ) : null} + {props.loading ? ( + + + + ) : null} + {props.children} + + ); + + if ( + props.href && + (props.href.startsWith("https://") || props.href?.startsWith("data:")) + ) + return ( + + {content} + + ); + + if (props.href) + return ( + + {content} + + ); + + return ( + + ); +} + +// Sometimes you can't use normal button, due to not having access to a useHistory context +// When that happens, use this! +interface ButtonPlainProps { + onClick?: () => void; + children?: ReactNode; + theme?: "white" | "purple" | "secondary"; + className?: string; +} + +export function ButtonPlain(props: ButtonPlainProps) { + let colorClasses = "bg-white hover:bg-gray-200 text-black"; + if (props.theme === "purple") + colorClasses = "bg-buttons-purple hover:bg-buttons-purpleHover text-white"; + if (props.theme === "secondary") + colorClasses = + "bg-buttons-cancel hover:bg-buttons-cancelHover transition-colors duration-100 text-white"; + + const classes = classNames( + "cursor-pointer inline-flex items-center justify-center rounded-lg font-medium transition-[transform,background-color] duration-100 active:scale-105 md:px-8", + "px-4 py-3", + props.className, + colorClasses, + ); + + return ( + + ); +} diff --git a/src/components/buttons/EditButton.tsx b/src/components/buttons/EditButton.tsx new file mode 100644 index 0000000..c303943 --- /dev/null +++ b/src/components/buttons/EditButton.tsx @@ -0,0 +1,37 @@ +import { useAutoAnimate } from "@formkit/auto-animate/react"; +import { useCallback } from "react"; +import { useTranslation } from "react-i18next"; + +import { Icon, Icons } from "@/components/Icon"; + +export interface EditButtonProps { + editing: boolean; + onEdit?: (editing: boolean) => void; +} + +export function EditButton(props: EditButtonProps) { + const { t } = useTranslation(); + const [parent] = useAutoAnimate(); + + const onClick = useCallback(() => { + props.onEdit?.(!props.editing); + }, [props]); + + return ( + + ); +} diff --git a/src/components/buttons/IconPatch.tsx b/src/components/buttons/IconPatch.tsx new file mode 100644 index 0000000..945c91b --- /dev/null +++ b/src/components/buttons/IconPatch.tsx @@ -0,0 +1,34 @@ +import { Icon, Icons } from "@/components/Icon"; + +export interface IconPatchProps { + active?: boolean; + onClick?: () => void; + clickable?: boolean; + className?: string; + icon: Icons; + transparent?: boolean; + downsized?: boolean; +} + +export function IconPatch(props: IconPatchProps) { + const clickableClasses = props.clickable + ? "cursor-pointer hover:scale-110 hover:bg-pill-backgroundHover hover:text-white active:scale-125" + : ""; + const transparentClasses = props.transparent + ? "bg-opacity-0 hover:bg-opacity-50" + : ""; + const activeClasses = props.active + ? "bg-pill-backgroundHover text-white" + : ""; + const sizeClasses = props.downsized ? "h-10 w-10" : "h-12 w-12"; + + return ( +
+
+ +
+
+ ); +} diff --git a/src/components/buttons/Toggle.tsx b/src/components/buttons/Toggle.tsx new file mode 100644 index 0000000..8cedc24 --- /dev/null +++ b/src/components/buttons/Toggle.tsx @@ -0,0 +1,23 @@ +import classNames from "classnames"; + +export function Toggle(props: { onClick?: () => void; enabled?: boolean }) { + return ( + + ); +} diff --git a/src/components/form/ColorPicker.tsx b/src/components/form/ColorPicker.tsx new file mode 100644 index 0000000..ae32315 --- /dev/null +++ b/src/components/form/ColorPicker.tsx @@ -0,0 +1,40 @@ +import classNames from "classnames"; + +import { Icon, Icons } from "../Icon"; + +const colors = ["#0A54FF", "#CF2E68", "#F9DD7F", "#7652DD", "#2ECFA8"]; +export const initialColor = colors[0]; + +export function ColorPicker(props: { + label: string; + value: string; + onInput: (v: string) => void; +}) { + return ( +
+ {props.label ? ( +

{props.label}

+ ) : null} + +
+ {colors.map((color) => { + return ( + + ); + })} +
+
+ ); +} diff --git a/src/components/form/Dropdown.tsx b/src/components/form/Dropdown.tsx new file mode 100644 index 0000000..df647b5 --- /dev/null +++ b/src/components/form/Dropdown.tsx @@ -0,0 +1,68 @@ +import { Listbox, Transition } from "@headlessui/react"; +import React, { Fragment } from "react"; + +import { Icon, Icons } from "@/components/Icon"; + +export interface OptionItem { + id: string; + name: string; + leftIcon?: React.ReactNode; +} + +interface DropdownProps { + selectedItem: OptionItem; + setSelectedItem: (value: OptionItem) => void; + options: Array; +} + +export function Dropdown(props: DropdownProps) { + return ( +
+ + {() => ( + <> + + + {props.selectedItem.leftIcon + ? props.selectedItem.leftIcon + : null} + {props.selectedItem.name} + + + + + + + + {props.options.map((opt) => ( + + `cursor-pointer flex gap-4 items-center relative select-none py-3 pl-4 pr-4 ${ + active + ? "bg-background-secondaryHover text-type-link" + : "text-white" + }` + } + key={opt.id} + value={opt} + > + {opt.leftIcon ? opt.leftIcon : null} + {opt.name} + + ))} + + + + )} + +
+ ); +} diff --git a/src/components/form/IconPicker.tsx b/src/components/form/IconPicker.tsx new file mode 100644 index 0000000..7ede61d --- /dev/null +++ b/src/components/form/IconPicker.tsx @@ -0,0 +1,48 @@ +import classNames from "classnames"; + +import { UserIcon, UserIcons } from "../UserIcon"; + +const icons = [ + UserIcons.CAT, + UserIcons.WEED, + UserIcons.USER_GROUP, + UserIcons.COUCH, + UserIcons.MOBILE, + UserIcons.TICKET, +]; +export const initialIcon = icons[0]; + +export function IconPicker(props: { + label: string; + value: UserIcons; + onInput: (v: UserIcons) => void; +}) { + return ( +
+ {props.label ? ( +

{props.label}

+ ) : null} + +
+ {icons.map((icon) => { + return ( + + ); + })} +
+
+ ); +} diff --git a/src/components/form/PassphraseDisplay.tsx b/src/components/form/PassphraseDisplay.tsx new file mode 100644 index 0000000..9291837 --- /dev/null +++ b/src/components/form/PassphraseDisplay.tsx @@ -0,0 +1,57 @@ +import { useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useCopyToClipboard, useMountedState } from "react-use"; + +import { Icon, Icons } from "../Icon"; + +export function PassphraseDisplay(props: { mnemonic: string }) { + const { t } = useTranslation(); + const individualWords = props.mnemonic.split(" "); + + const [, copy] = useCopyToClipboard(); + + const [hasCopied, setHasCopied] = useState(false); + const isMounted = useMountedState(); + + const timeout = useRef>(); + + function copyMnemonic() { + copy(props.mnemonic); + setHasCopied(true); + if (timeout.current) clearTimeout(timeout.current); + timeout.current = setTimeout(() => isMounted() && setHasCopied(false), 500); + } + + return ( +
+
+

+ {t("auth.generate.passphraseFrameLabel")} +

+ +
+
+ {individualWords.map((word, i) => ( +
+ {word} +
+ ))} +
+
+ ); +} diff --git a/src/components/form/SearchBar.tsx b/src/components/form/SearchBar.tsx new file mode 100644 index 0000000..f3cc15f --- /dev/null +++ b/src/components/form/SearchBar.tsx @@ -0,0 +1,78 @@ +import c from "classnames"; +import { forwardRef, useState } from "react"; + +import { Flare } from "@/components/utils/Flare"; + +import { Icon, Icons } from "../Icon"; +import { TextInputControl } from "../text-inputs/TextInputControl"; + +export interface SearchBarProps { + placeholder?: string; + onChange: (value: string, force: boolean) => void; + onUnFocus: (newSearch?: string) => void; + value: string; +} + +export const SearchBarInput = forwardRef( + (props, ref) => { + const [focused, setFocused] = useState(false); + + function setSearch(value: string) { + props.onChange(value, true); + } + + return ( + + + +
+ +
+ + { + setFocused(false); + props.onUnFocus(); + }} + onFocus={() => setFocused(true)} + onChange={(val) => setSearch(val)} + value={props.value} + className="w-full flex-1 bg-transparent px-4 py-4 pl-12 text-search-text placeholder-search-placeholder focus:outline-none sm:py-4 sm:pr-2" + placeholder={props.placeholder} + /> + + {props.value.length > 0 && ( +
{ + props.onUnFocus(""); + if (ref && typeof ref !== "function") { + ref.current?.focus(); + } + }} + className="cursor-pointer hover:text-white absolute bottom-0 right-2 top-0 flex justify-center my-auto h-10 w-10 items-center hover:bg-search-hoverBackground active:scale-110 text-search-icon rounded-full transition-[transform,background-color] duration-200" + > + +
+ )} +
+
+ ); + }, +); diff --git a/src/components/form/SortableList.tsx b/src/components/form/SortableList.tsx new file mode 100644 index 0000000..70984c8 --- /dev/null +++ b/src/components/form/SortableList.tsx @@ -0,0 +1,109 @@ +import { + DndContext, + DragEndEvent, + KeyboardSensor, + MouseSensor, + TouchSensor, + closestCenter, + useSensor, + useSensors, +} from "@dnd-kit/core"; +import { + restrictToParentElement, + restrictToVerticalAxis, +} from "@dnd-kit/modifiers"; +import { + SortableContext, + arrayMove, + sortableKeyboardCoordinates, + useSortable, + verticalListSortingStrategy, +} from "@dnd-kit/sortable"; +import { CSS } from "@dnd-kit/utilities"; +import classNames from "classnames"; + +import { Icon, Icons } from "../Icon"; + +export interface Item { + id: string; + name: string; + disabled?: boolean; +} + +function SortableItem(props: { item: Item }) { + const { attributes, listeners, setNodeRef, transform, transition } = + useSortable({ id: props.item.id }); + + const style = { + transform: CSS.Transform.toString(transform), + transition, + }; + + return ( +
+ {props.item.name} + {props.item.disabled && } + +
+ ); +} + +export function SortableList(props: { + items: Item[]; + setItems: (items: Item[]) => void; +}) { + const sensors = useSensors( + useSensor(TouchSensor, { + activationConstraint: { + delay: 75, + tolerance: 1, + }, + }), + useSensor(MouseSensor), + useSensor(KeyboardSensor, { + coordinateGetter: sortableKeyboardCoordinates, + }), + ); + + const handleDragEnd = (event: DragEndEvent) => { + const { active, over } = event; + if (!over) return; + if (active.id !== over.id) { + const currentItems = props.items; + const oldIndex = currentItems.findIndex((item) => item.id === active.id); + const newIndex = currentItems.findIndex((item) => item.id === over.id); + const newItems = arrayMove(currentItems, oldIndex, newIndex); + props.setItems(newItems); + } + }; + + return ( + + +
+ {props.items.map((item) => ( + + ))} +
+
+
+ ); +} diff --git a/src/components/layout/Box.tsx b/src/components/layout/Box.tsx new file mode 100644 index 0000000..d1e3002 --- /dev/null +++ b/src/components/layout/Box.tsx @@ -0,0 +1,9 @@ +import { ReactNode } from "react"; + +export function Box(props: { children?: ReactNode }) { + return ( +
+ {props.children} +
+ ); +} diff --git a/src/components/layout/BrandPill.tsx b/src/components/layout/BrandPill.tsx new file mode 100644 index 0000000..89fae77 --- /dev/null +++ b/src/components/layout/BrandPill.tsx @@ -0,0 +1,36 @@ +import classNames from "classnames"; +import { useTranslation } from "react-i18next"; + +import { Icon, Icons } from "@/components/Icon"; +import { useIsMobile } from "@/hooks/useIsMobile"; + +export function BrandPill(props: { + clickable?: boolean; + header?: boolean; + backgroundClass?: string; +}) { + const { t } = useTranslation(); + const isMobile = useIsMobile(); + + return ( +
+ + + {t("global.name")} + +
+ ); +} diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx new file mode 100644 index 0000000..e988840 --- /dev/null +++ b/src/components/layout/Footer.tsx @@ -0,0 +1,113 @@ +import { useCallback } from "react"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import type { RequireExactlyOne } from "type-fest"; + +import { Icon, Icons } from "@/components/Icon"; +import { BrandPill } from "@/components/layout/BrandPill"; +import { WideContainer } from "@/components/layout/WideContainer"; +import { shouldHaveDmcaPage } from "@/pages/Dmca"; +import { conf } from "@/setup/config"; + +// to and href are mutually exclusive +type FooterLinkProps = RequireExactlyOne< + { + children: React.ReactNode; + icon: Icons; + to: string; + href: string; + }, + "to" | "href" +>; + +function FooterLink(props: FooterLinkProps) { + const navigate = useNavigate(); + + const navigateTo = useCallback(() => { + if (!props.to) return; + + navigate(props.to); + }, [navigate, props.to]); + + return ( + + + {props.children} + + ); +} + +function Dmca() { + const { t } = useTranslation(); + + if (!shouldHaveDmcaPage()) return null; + if (window.location.hash === "#/dmca") return null; + + return ( + + {t("footer.links.dmca")} + + ); +} + +export function Footer() { + const { t } = useTranslation(); + + return ( +
+ +
+
+ +
+

{t("footer.tagline")}

+
+
+

+ {t("footer.legal.disclaimer")} +

+

{t("footer.legal.disclaimerText")}

+
+
+ + {t("footer.links.github")} + + + {t("footer.links.discord")} + + + {t("footer.links.twitter")} + +
+ +
+
+
+ +
+
+
+ ); +} + +export function FooterView(props: { + children: React.ReactNode; + className?: string; +}) { + return ( +
+
{props.children}
+
+
+ ); +} diff --git a/src/components/layout/IconPill.tsx b/src/components/layout/IconPill.tsx new file mode 100644 index 0000000..6530e77 --- /dev/null +++ b/src/components/layout/IconPill.tsx @@ -0,0 +1,13 @@ +import { Icon, Icons } from "@/components/Icon"; + +export function IconPill(props: { icon: Icons; children?: React.ReactNode }) { + return ( +
+ + {props.children} +
+ ); +} diff --git a/src/components/layout/LargeCard.tsx b/src/components/layout/LargeCard.tsx new file mode 100644 index 0000000..dbc010a --- /dev/null +++ b/src/components/layout/LargeCard.tsx @@ -0,0 +1,58 @@ +import classNames from "classnames"; + +export function LargeCard(props: { + children: React.ReactNode; + top?: React.ReactNode; +}) { + return ( +
+ {props.top ? ( +
+ {props.top} +
+ ) : null} +
+ {props.children} +
+
+ ); +} + +export function LargeCardText(props: { + title: string; + children?: React.ReactNode; + icon?: React.ReactNode; +}) { + return ( +
+
+ {props.icon ? ( +
{props.icon}
+ ) : null} +

{props.title}

+ {props.children ? ( +
{props.children}
+ ) : null} +
+
+ ); +} + +export function LargeCardButtons(props: { + children: React.ReactNode; + splitAlign?: boolean; +}) { + return ( +
+
+ {props.children} +
+
+ ); +} diff --git a/src/components/layout/Loading.tsx b/src/components/layout/Loading.tsx new file mode 100644 index 0000000..4c4c62b --- /dev/null +++ b/src/components/layout/Loading.tsx @@ -0,0 +1,22 @@ +export interface LoadingProps { + text?: string; + className?: string; +} + +export function Loading(props: LoadingProps) { + return ( +
+
+
+
+
+
+
+
+ {props.text && props.text.length ? ( +

{props.text}

+ ) : null} +
+
+ ); +} diff --git a/src/components/layout/Navigation.tsx b/src/components/layout/Navigation.tsx new file mode 100644 index 0000000..90e91e5 --- /dev/null +++ b/src/components/layout/Navigation.tsx @@ -0,0 +1,130 @@ +import classNames from "classnames"; +import { Link, To, useNavigate } from "react-router-dom"; + +import { NoUserAvatar, UserAvatar } from "@/components/Avatar"; +import { IconPatch } from "@/components/buttons/IconPatch"; +import { Icons } from "@/components/Icon"; +import { LinksDropdown } from "@/components/LinksDropdown"; +import { Lightbar } from "@/components/utils/Lightbar"; +import { useAuth } from "@/hooks/auth/useAuth"; +import { BlurEllipsis } from "@/pages/layouts/SubPageLayout"; +import { conf } from "@/setup/config"; +import { useBannerSize } from "@/stores/banner"; + +import { BrandPill } from "./BrandPill"; + +export interface NavigationProps { + bg?: boolean; + noLightbar?: boolean; + doBackground?: boolean; +} + +export function Navigation(props: NavigationProps) { + const bannerHeight = useBannerSize(); + const navigate = useNavigate(); + const { loggedIn } = useAuth(); + + const handleClick = (path: To) => { + window.scrollTo(0, 0); + navigate(path); + }; + + return ( + <> + {/* lightbar */} + {!props.noLightbar ? ( +
+
+ +
+
+ ) : null} + + {/* backgrounds - these are seperate because of z-index issues */} +
+
+ {props.doBackground ? ( +
+ +
+ ) : null} +
+
+
+
+
+
+ + {/* content */} + + + ); +} diff --git a/src/components/layout/ProgressRing.tsx b/src/components/layout/ProgressRing.tsx new file mode 100644 index 0000000..d0e680a --- /dev/null +++ b/src/components/layout/ProgressRing.tsx @@ -0,0 +1,39 @@ +interface Props { + className?: string; + radius?: number; + percentage: number; + backingRingClassname?: string; +} + +export function ProgressRing(props: Props) { + const radius = props.radius ?? 40; + + return ( + + + + + ); +} diff --git a/src/components/layout/SectionHeading.tsx b/src/components/layout/SectionHeading.tsx new file mode 100644 index 0000000..ef99455 --- /dev/null +++ b/src/components/layout/SectionHeading.tsx @@ -0,0 +1,28 @@ +import { ReactNode } from "react"; + +import { Icon, Icons } from "@/components/Icon"; + +interface SectionHeadingProps { + icon?: Icons; + title: string; + children?: ReactNode; + className?: string; +} + +export function SectionHeading(props: SectionHeadingProps) { + return ( +
+
+

+ {props.icon ? ( + + + + ) : null} + {props.title} +

+ {props.children} +
+
+ ); +} diff --git a/src/components/layout/SettingsCard.tsx b/src/components/layout/SettingsCard.tsx new file mode 100644 index 0000000..4be0ce9 --- /dev/null +++ b/src/components/layout/SettingsCard.tsx @@ -0,0 +1,37 @@ +import classNames from "classnames"; + +export function SettingsCard(props: { + children: React.ReactNode; + className?: string; + paddingClass?: string; +}) { + return ( +
+ {props.children} +
+ ); +} + +export function SolidSettingsCard(props: { + children: React.ReactNode; + className?: string; + paddingClass?: string; +}) { + return ( +
+ {props.children} +
+ ); +} diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx new file mode 100644 index 0000000..f5c2a17 --- /dev/null +++ b/src/components/layout/Sidebar.tsx @@ -0,0 +1,47 @@ +import classNames from "classnames"; + +import { Icon, Icons } from "@/components/Icon"; + +export function SidebarSection(props: { + title: string; + children: React.ReactNode; + className?: string; +}) { + return ( +
+

+ {props.title} +

+ {props.children} +
+ ); +} + +export function SidebarLink(props: { + children: React.ReactNode; + icon: Icons; + active?: boolean; + onClick?: () => void; +}) { + return ( + + ); +} diff --git a/src/components/layout/Spinner.css b/src/components/layout/Spinner.css new file mode 100644 index 0000000..aa7cc1b --- /dev/null +++ b/src/components/layout/Spinner.css @@ -0,0 +1,19 @@ +.spinner { + width: 1em; + height: 1em; + border: 0.12em solid var(--color,white); + border-bottom-color: transparent; + border-radius: 50%; + display: inline-block; + box-sizing: border-box; + animation: spinner-rotation 800ms linear infinite; +} + +@keyframes spinner-rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/src/components/layout/Spinner.tsx b/src/components/layout/Spinner.tsx new file mode 100644 index 0000000..77e06cf --- /dev/null +++ b/src/components/layout/Spinner.tsx @@ -0,0 +1,9 @@ +import "./Spinner.css"; + +interface SpinnerProps { + className?: string; +} + +export function Spinner(props: SpinnerProps) { + return
; +} diff --git a/src/components/layout/Stepper.tsx b/src/components/layout/Stepper.tsx new file mode 100644 index 0000000..75dc150 --- /dev/null +++ b/src/components/layout/Stepper.tsx @@ -0,0 +1,25 @@ +export interface StepperProps { + current: number; + steps: number; + className?: string; +} + +export function Stepper(props: StepperProps) { + const percentage = (props.current / props.steps) * 100; + + return ( +
+

+ {props.current}/{props.steps} +

+
+
+
+
+ ); +} diff --git a/src/components/layout/ThinContainer.tsx b/src/components/layout/ThinContainer.tsx new file mode 100644 index 0000000..f4116d9 --- /dev/null +++ b/src/components/layout/ThinContainer.tsx @@ -0,0 +1,44 @@ +import classNames from "classnames"; +import { ReactNode } from "react"; + +interface ThinContainerProps { + classNames?: string; + children?: ReactNode; +} + +export function ThinContainer(props: ThinContainerProps) { + return ( +
+ {props.children} +
+ ); +} + +export function ThiccContainer(props: ThinContainerProps) { + return ( +
+ {props.children} +
+ ); +} + +export function CenterContainer(props: ThinContainerProps) { + return ( +
+
{props.children}
+
+ ); +} diff --git a/src/components/layout/WideContainer.tsx b/src/components/layout/WideContainer.tsx new file mode 100644 index 0000000..bcccd5e --- /dev/null +++ b/src/components/layout/WideContainer.tsx @@ -0,0 +1,19 @@ +import { ReactNode } from "react"; + +interface WideContainerProps { + classNames?: string; + children?: ReactNode; + ultraWide?: boolean; +} + +export function WideContainer(props: WideContainerProps) { + return ( +
+ {props.children} +
+ ); +} diff --git a/src/components/media/MediaBookmark.tsx b/src/components/media/MediaBookmark.tsx new file mode 100644 index 0000000..45e8f9e --- /dev/null +++ b/src/components/media/MediaBookmark.tsx @@ -0,0 +1,47 @@ +import { useCallback, useMemo } from "react"; + +import { Icons } from "@/components/Icon"; +import { useBookmarkStore } from "@/stores/bookmarks"; +import { PlayerMeta } from "@/stores/player/slices/source"; +import { MediaItem } from "@/utils/mediaTypes"; + +import { IconPatch } from "../buttons/IconPatch"; + +interface MediaBookmarkProps { + media: MediaItem; +} + +export function MediaBookmarkButton({ media }: MediaBookmarkProps) { + const addBookmark = useBookmarkStore((s) => s.addBookmark); + const removeBookmark = useBookmarkStore((s) => s.removeBookmark); + const bookmarks = useBookmarkStore((s) => s.bookmarks); + const meta: PlayerMeta | undefined = useMemo(() => { + return media.year !== undefined + ? { + type: media.type, + title: media.title, + tmdbId: media.id, + releaseYear: media.year, + poster: media.poster, + } + : undefined; + }, [media]); + const isBookmarked = !!bookmarks[meta?.tmdbId ?? ""]; + + const toggleBookmark = useCallback(() => { + if (!meta) return; + if (isBookmarked) removeBookmark(meta.tmdbId); + else addBookmark(meta); + }, [isBookmarked, meta, addBookmark, removeBookmark]); + + const buttonOpacityClass = + media.year === undefined ? "hover:opacity-100" : "hover:opacity-95"; + + return ( + + ); +} diff --git a/src/components/media/MediaCard.tsx b/src/components/media/MediaCard.tsx new file mode 100644 index 0000000..edf1076 --- /dev/null +++ b/src/components/media/MediaCard.tsx @@ -0,0 +1,224 @@ +import classNames from "classnames"; +import { useCallback } from "react"; +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; + +import { mediaItemToId } from "@/backend/metadata/tmdb"; +import { DotList } from "@/components/text/DotList"; +import { Flare } from "@/components/utils/Flare"; +import { useIsMobile } from "@/hooks/useIsMobile"; +import { useSearchQuery } from "@/hooks/useSearchQuery"; +import { MediaItem } from "@/utils/mediaTypes"; + +import { MediaBookmarkButton } from "./MediaBookmark"; +import { IconPatch } from "../buttons/IconPatch"; +import { Icons } from "../Icon"; + +export interface MediaCardProps { + media: MediaItem; + linkable?: boolean; + series?: { + episode: number; + season?: number; + episodeId: string; + seasonId: string; + }; + percentage?: number; + closable?: boolean; + onClose?: () => void; +} + +function checkReleased(media: MediaItem): boolean { + const isReleasedYear = Boolean( + media.year && media.year <= new Date().getFullYear(), + ); + const isReleasedDate = Boolean( + media.release_date && media.release_date <= new Date(), + ); + + // If the media has a release date, use that, otherwise use the year + const isReleased = media.release_date ? isReleasedDate : isReleasedYear; + + return isReleased; +} + +function MediaCardContent({ + media, + linkable, + series, + percentage, + closable, + onClose, +}: MediaCardProps) { + const { t } = useTranslation(); + const percentageString = `${Math.round(percentage ?? 0).toFixed(0)}%`; + + const isReleased = useCallback(() => checkReleased(media), [media]); + + const canLink = linkable && !closable && isReleased(); + + const dotListContent = [t(`media.types.${media.type}`)]; + + const [searchQuery] = useSearchQuery(); + + const { isMobile } = useIsMobile(); + + if (media.year) { + dotListContent.push(media.year.toFixed()); + } + + if (!isReleased()) { + dotListContent.push(t("media.unreleased")); + } + + return ( + e.key === "Enter" && e.currentTarget.click()} + > + + +
+ {series ? ( +
+

+ {t("media.episodeDisplay", { + season: series.season || 1, + episode: series.episode, + })} +

+
+ ) : null} + + {percentage !== undefined ? ( + <> +
+
+
+
+
+
+
+ + ) : null} + +
e.preventDefault()} + > + +
+ + {searchQuery.length > 0 ? ( +
e.preventDefault()}> + +
+ ) : null} + +
+ closable && onClose?.()} + icon={Icons.X} + /> +
+
+

+ {media.title} +

+ + + + ); +} + +export function MediaCard(props: MediaCardProps) { + const content = ; + + const isReleased = useCallback( + () => checkReleased(props.media), + [props.media], + ); + + const canLink = props.linkable && !props.closable && isReleased(); + + let link = canLink + ? `/media/${encodeURIComponent(mediaItemToId(props.media))}` + : "#"; + if (canLink && props.series) { + if (props.series.season === 0 && !props.series.episodeId) { + link += `/${encodeURIComponent(props.series.seasonId)}`; + } else { + link += `/${encodeURIComponent( + props.series.seasonId, + )}/${encodeURIComponent(props.series.episodeId)}`; + } + } + + if (!canLink) return {content}; + return ( + + {content} + + ); +} diff --git a/src/components/media/MediaGrid.tsx b/src/components/media/MediaGrid.tsx new file mode 100644 index 0000000..adb9b93 --- /dev/null +++ b/src/components/media/MediaGrid.tsx @@ -0,0 +1,18 @@ +import { forwardRef } from "react"; + +interface MediaGridProps { + children?: React.ReactNode; +} + +export const MediaGrid = forwardRef( + (props, ref) => { + return ( +
+ {props.children} +
+ ); + }, +); diff --git a/src/components/media/WatchedMediaCard.tsx b/src/components/media/WatchedMediaCard.tsx new file mode 100644 index 0000000..b7640ef --- /dev/null +++ b/src/components/media/WatchedMediaCard.tsx @@ -0,0 +1,51 @@ +import { useMemo } from "react"; + +import { useProgressStore } from "@/stores/progress"; +import { + ShowProgressResult, + shouldShowProgress, +} from "@/stores/progress/utils"; +import { MediaItem } from "@/utils/mediaTypes"; + +import { MediaCard } from "./MediaCard"; + +function formatSeries(series?: ShowProgressResult | null) { + if (!series || !series.episode || !series.season) return undefined; + return { + episode: series.episode?.number, + season: series.season?.number, + episodeId: series.episode?.id, + seasonId: series.season?.id, + }; +} + +export interface WatchedMediaCardProps { + media: MediaItem; + closable?: boolean; + onClose?: () => void; +} + +export function WatchedMediaCard(props: WatchedMediaCardProps) { + const progressItems = useProgressStore((s) => s.items); + const item = useMemo(() => { + return progressItems[props.media.id]; + }, [progressItems, props.media]); + const itemToDisplay = useMemo( + () => (item ? shouldShowProgress(item) : null), + [item], + ); + const percentage = itemToDisplay?.show + ? (itemToDisplay.progress.watched / itemToDisplay.progress.duration) * 100 + : undefined; + + return ( + + ); +} diff --git a/src/components/overlays/Modal.tsx b/src/components/overlays/Modal.tsx new file mode 100644 index 0000000..08abdbb --- /dev/null +++ b/src/components/overlays/Modal.tsx @@ -0,0 +1,42 @@ +import { ReactNode, useCallback } from "react"; +import { Helmet } from "react-helmet-async"; + +import { OverlayPortal } from "@/components/overlays/OverlayDisplay"; +import { useQueryParam } from "@/hooks/useQueryParams"; + +export function useModal(id: string) { + const [currentModal, setCurrentModal] = useQueryParam("m"); + const show = useCallback(() => setCurrentModal(id), [id, setCurrentModal]); + const hide = useCallback(() => setCurrentModal(null), [setCurrentModal]); + return { + id, + isShown: currentModal === id, + show, + hide, + }; +} + +export function ModalCard(props: { children?: ReactNode }) { + return ( +
+
+ {props.children} +
+
+ ); +} + +export function Modal(props: { id: string; children?: ReactNode }) { + const modal = useModal(props.id); + + return ( + + + + +
+ {props.children} +
+
+ ); +} diff --git a/src/components/overlays/OverlayAnchor.tsx b/src/components/overlays/OverlayAnchor.tsx new file mode 100644 index 0000000..4939ab1 --- /dev/null +++ b/src/components/overlays/OverlayAnchor.tsx @@ -0,0 +1,20 @@ +import classNames from "classnames"; +import { ReactNode } from "react"; + +interface Props { + id: string; + children?: ReactNode; + className?: string; +} + +export function OverlayAnchor(props: Props) { + return ( +
+
+ {props.children} +
+ ); +} diff --git a/src/components/overlays/OverlayDisplay.tsx b/src/components/overlays/OverlayDisplay.tsx new file mode 100644 index 0000000..18045a0 --- /dev/null +++ b/src/components/overlays/OverlayDisplay.tsx @@ -0,0 +1,147 @@ +import classNames from "classnames"; +import FocusTrap from "focus-trap-react"; +import { ReactNode, useCallback, useEffect, useRef, useState } from "react"; +import { createPortal } from "react-dom"; +import { useTranslation } from "react-i18next"; + +import { Transition } from "@/components/utils/Transition"; +import { + useInternalOverlayRouter, + useRouterAnchorUpdate, +} from "@/hooks/useOverlayRouter"; +import { TurnstileProvider, getTurnstile } from "@/stores/turnstile"; + +export interface OverlayProps { + id: string; + children?: ReactNode; + darken?: boolean; +} + +function TurnstileInteractive() { + const { t } = useTranslation(); + const [show, setShow] = useState(false); + + useEffect(() => { + getTurnstile(); + }, []); + + // this may not rerender with different dom structure, must be exactly the same always + return ( +
+
+
+

+ {t("player.turnstile.title")} +

+

+ {t("player.turnstile.description")} +

+
+ setShow(shouldShow)} + /> +
+
+ ); +} + +export function OverlayDisplay(props: { children: ReactNode }) { + const router = useInternalOverlayRouter("hello world :)"); + const refRouter = useRef(router); + + // close router on first mount, we dont want persist routes for overlays + useEffect(() => { + const r = refRouter.current; + r.close(); + return () => { + r.close(); + }; + }, []); + return ( +
+ + {props.children} +
+ ); +} + +export function OverlayPortal(props: { + children?: ReactNode; + darken?: boolean; + show?: boolean; + close?: () => void; +}) { + const [portalElement, setPortalElement] = useState(null); + const ref = useRef(null); + const close = props.close; + + useEffect(() => { + const element = ref.current?.closest(".popout-location"); + setPortalElement(element ?? document.body); + }, []); + + return ( +
+ {portalElement + ? createPortal( + + +
+ +
+ + + {/* a tabable index that does nothing - used so focus trap doesn't error when nothing is rendered yet */} +
+ {props.children} + +
+ +
, + portalElement, + ) + : null} +
+ ); +} + +export function Overlay(props: OverlayProps) { + const router = useInternalOverlayRouter(props.id); + const realClose = router.close; + + // listen for anchor updates + useRouterAnchorUpdate(props.id); + + const close = useCallback(() => { + realClose(); + }, [realClose]); + + return ( + + {props.children} + + ); +} diff --git a/src/components/overlays/OverlayPage.tsx b/src/components/overlays/OverlayPage.tsx new file mode 100644 index 0000000..f15ebaa --- /dev/null +++ b/src/components/overlays/OverlayPage.tsx @@ -0,0 +1,60 @@ +import classNames from "classnames"; +import { ReactNode, useEffect, useMemo } from "react"; + +import { + Transition, + TransitionAnimations, +} from "@/components/utils/Transition"; +import { useIsMobile } from "@/hooks/useIsMobile"; +import { useInternalOverlayRouter } from "@/hooks/useOverlayRouter"; +import { useOverlayStore } from "@/stores/overlay/store"; + +interface Props { + id: string; + path: string; + children?: ReactNode; + className?: string; + height: number; + width: number; +} + +export function OverlayPage(props: Props) { + const router = useInternalOverlayRouter(props.id); + const backwards = router.showBackwardsTransition(props.path); + const show = router.isCurrentPage(props.path); + const registerRoute = useOverlayStore((s) => s.registerRoute); + const path = useMemo(() => router.makePath(props.path), [props.path, router]); + const { isMobile } = useIsMobile(); + + useEffect(() => { + registerRoute({ + id: path, + width: props.width, + height: props.height, + }); + }, [props.height, props.width, path, registerRoute]); + + const width = !isMobile ? `${props.width}px` : "100%"; + let animation: TransitionAnimations = "none"; + if (backwards === "yes" || backwards === "no") + animation = backwards === "yes" ? "slide-full-left" : "slide-full-right"; + + return ( + +
+ {props.children} +
+
+ ); +} diff --git a/src/components/overlays/OverlayRouter.tsx b/src/components/overlays/OverlayRouter.tsx new file mode 100644 index 0000000..dc36926 --- /dev/null +++ b/src/components/overlays/OverlayRouter.tsx @@ -0,0 +1,101 @@ +import { a, easings, useSpring } from "@react-spring/web"; +import { ReactNode, useEffect, useMemo, useRef } from "react"; + +import { OverlayAnchorPosition } from "@/components/overlays/positions/OverlayAnchorPosition"; +import { OverlayMobilePosition } from "@/components/overlays/positions/OverlayMobilePosition"; +import { Flare } from "@/components/utils/Flare"; +import { useIsMobile } from "@/hooks/useIsMobile"; +import { useInternalOverlayRouter } from "@/hooks/useOverlayRouter"; +import { useOverlayStore } from "@/stores/overlay/store"; + +interface OverlayRouterProps { + children?: ReactNode; + id: string; +} + +function RouterBase(props: { id: string; children: ReactNode }) { + const ref = useRef(null); + const { isMobile } = useIsMobile(); + + const routes = useOverlayStore((s) => s.routes); + const router = useInternalOverlayRouter(props.id); + const routeMeta = useMemo( + () => routes[router.currentRoute ?? ""], + [routes, router], + ); + + const [dimensions, api] = useSpring( + () => ({ + from: { + height: `${routeMeta?.height ?? 0}px`, + width: isMobile ? "100%" : `${routeMeta?.width ?? 0}px`, + }, + config: { + easing: easings.linear, + }, + }), + [], + ); + + const currentState = useRef(null); + useEffect(() => { + const data = { + height: routeMeta?.height, + width: routeMeta?.width, + isMobile, + }; + const dataStr = JSON.stringify(data); + if (dataStr !== currentState.current) { + const oldData = currentState.current + ? JSON.parse(currentState.current) + : null; + currentState.current = dataStr; + if (data.isMobile) { + api.set({ + width: "100%", + }); + api.start({ + height: `${routeMeta?.height ?? 0}px`, + }); + } else if (oldData?.height === undefined && data.height !== undefined) { + api.set({ + height: `${routeMeta?.height ?? 0}px`, + width: `${routeMeta?.width ?? 0}px`, + }); + } else { + api.start({ + height: `${routeMeta?.height ?? 0}px`, + width: `${routeMeta?.width ?? 0}px`, + }); + } + } + }, [routeMeta?.height, routeMeta?.width, isMobile, api]); + + return ( + + + + + {props.children} + + + + ); +} + +export function OverlayRouter(props: OverlayRouterProps) { + const { isMobile } = useIsMobile(); + const content = {props.children}; + + if (isMobile) return {content}; + return {content}; +} diff --git a/src/components/overlays/positions/OverlayAnchorPosition.tsx b/src/components/overlays/positions/OverlayAnchorPosition.tsx new file mode 100644 index 0000000..f4120d9 --- /dev/null +++ b/src/components/overlays/positions/OverlayAnchorPosition.tsx @@ -0,0 +1,74 @@ +import classNames from "classnames"; +import { ReactNode, useCallback, useEffect, useRef, useState } from "react"; + +import { useOverlayStore } from "@/stores/overlay/store"; + +interface AnchorPositionProps { + children?: ReactNode; + className?: string; +} + +function useCalculatePositions() { + const anchorPoint = useOverlayStore((s) => s.anchorPoint); + const ref = useRef(null); + const [left, setLeft] = useState(0); + const [top, setTop] = useState(0); + const [cardRect, setCardRect] = useState(null); + + const calculateAndSetCoords = useCallback( + (anchor: typeof anchorPoint, card: DOMRect) => { + if (!anchor) return; + const buttonCenter = anchor.x + anchor.w / 2; + const bottomReal = window.innerHeight - (anchor.y + anchor.h); + + setTop(window.innerHeight - bottomReal - anchor.h - card.height - 30); + setLeft( + Math.min( + buttonCenter - card.width / 2, + window.innerWidth - card.width - 30, + ), + ); + }, + [], + ); + + useEffect(() => { + if (!anchorPoint || !cardRect) return; + calculateAndSetCoords(anchorPoint, cardRect); + }, [anchorPoint, calculateAndSetCoords, cardRect]); + + useEffect(() => { + if (!ref.current) return; + function checkBox() { + const divRect = ref.current?.getBoundingClientRect(); + setCardRect(divRect ?? null); + } + checkBox(); + const observer = new ResizeObserver(checkBox); + observer.observe(ref.current); + return () => { + observer.disconnect(); + }; + }, []); + + return [ref, left, top] as const; +} + +export function OverlayAnchorPosition(props: AnchorPositionProps) { + const [ref, left, top] = useCalculatePositions(); + + return ( +
*]:pointer-events-auto z-10 flex dir-neutral:items-start rtl:justify-start ltr:justify-end dir-neutral:origin-top-left touch-none", + props.className, + ])} + > + {props.children} +
+ ); +} diff --git a/src/components/overlays/positions/OverlayMobilePosition.tsx b/src/components/overlays/positions/OverlayMobilePosition.tsx new file mode 100644 index 0000000..53b2100 --- /dev/null +++ b/src/components/overlays/positions/OverlayMobilePosition.tsx @@ -0,0 +1,37 @@ +import classNames from "classnames"; +import { ReactNode } from "react"; +import { useTranslation } from "react-i18next"; + +import { useInternalOverlayRouter } from "@/hooks/useOverlayRouter"; + +interface MobilePositionProps { + children?: ReactNode; + className?: string; +} + +export function OverlayMobilePosition(props: MobilePositionProps) { + const router = useInternalOverlayRouter("hello world :)"); + const { t } = useTranslation(); + + return ( +
+ {props.children} + + {/* Close button */} + + {/* Gradient to hide the progress */} +
+
+ ); +} diff --git a/src/components/player/Player.tsx b/src/components/player/Player.tsx new file mode 100644 index 0000000..df8e807 --- /dev/null +++ b/src/components/player/Player.tsx @@ -0,0 +1,11 @@ +export * from "./atoms"; +export * from "./base/Container"; +export * from "./base/TopControls"; +export * from "./base/CenterControls"; +export * from "./base/BottomControls"; +export * from "./base/BlackOverlay"; +export * from "./base/BackLink"; +export * from "./base/LeftSideControls"; +export * from "./base/CenterMobileControls"; +export * from "./base/SubtitleView"; +export * from "./internals/BookmarkButton"; diff --git a/src/components/player/README.md b/src/components/player/README.md new file mode 100644 index 0000000..3e3bc0c --- /dev/null +++ b/src/components/player/README.md @@ -0,0 +1,31 @@ +# Video player component + +Video player is quite a complex component, so here is a rundown of all the parts + +# Composable parts +These parts can be used to build any shape of a video player. + - `/atoms`- any ui element that controls the player. (Seekbar, Pause button, quality selection, etc) + - `/base` - base components that are used to build a player. Like the main container + +# internal parts +These parts are internally used, they aren't exported. Do not use them outside of player internals. + +### `/display` +The display interface, abstraction on how to actually play the content (e.g Video element, chrome casting, etc) + - It must be completely separate from any react code + - It must not interact with state, pass async data back with events + +### `/internals` +Internal components that are always rendered on every player. + - Only components that are always present on the player instance, they must never unmount + +### `/utils` +miscellaneous logic, put anything that is unique to the video player internals. + +### `/hooks` +Hooks only used for video player. + - only exception is usePlayer, as its used outside of the player to control the player + +### `~/src/stores/player` +State for the video player. + - Only parts related to the video player may utilize the state diff --git a/src/components/player/atoms/Airplay.tsx b/src/components/player/atoms/Airplay.tsx new file mode 100644 index 0000000..0d517fc --- /dev/null +++ b/src/components/player/atoms/Airplay.tsx @@ -0,0 +1,17 @@ +import { Icons } from "@/components/Icon"; +import { VideoPlayerButton } from "@/components/player/internals/Button"; +import { usePlayerStore } from "@/stores/player/store"; + +export function Airplay() { + const canAirplay = usePlayerStore((s) => s.interface.canAirplay); + const display = usePlayerStore((s) => s.display); + + if (!canAirplay) return null; + + return ( + display?.startAirplay()} + icon={Icons.AIRPLAY} + /> + ); +} diff --git a/src/components/player/atoms/AutoPlayStart.tsx b/src/components/player/atoms/AutoPlayStart.tsx new file mode 100644 index 0000000..7ae99e8 --- /dev/null +++ b/src/components/player/atoms/AutoPlayStart.tsx @@ -0,0 +1,34 @@ +import { useCallback } from "react"; + +import { Icon, Icons } from "@/components/Icon"; +import { playerStatus } from "@/stores/player/slices/source"; +import { usePlayerStore } from "@/stores/player/store"; + +export function AutoPlayStart() { + const display = usePlayerStore((s) => s.display); + const isPlaying = usePlayerStore((s) => s.mediaPlaying.isPlaying); + const isLoading = usePlayerStore((s) => s.mediaPlaying.isLoading); + const hasPlayedOnce = usePlayerStore((s) => s.mediaPlaying.hasPlayedOnce); + const status = usePlayerStore((s) => s.status); + + const handleClick = useCallback(() => { + display?.play(); + }, [display]); + + if (hasPlayedOnce) return null; + if (isPlaying) return null; + if (isLoading) return null; + if (status !== playerStatus.PLAYING) return null; + + return ( +
+ +
+ ); +} diff --git a/src/components/player/atoms/Captions.tsx b/src/components/player/atoms/Captions.tsx new file mode 100644 index 0000000..89e419e --- /dev/null +++ b/src/components/player/atoms/Captions.tsx @@ -0,0 +1,28 @@ +import { useEffect } from "react"; + +import { Icons } from "@/components/Icon"; +import { OverlayAnchor } from "@/components/overlays/OverlayAnchor"; +import { VideoPlayerButton } from "@/components/player/internals/Button"; +import { useOverlayRouter } from "@/hooks/useOverlayRouter"; +import { usePlayerStore } from "@/stores/player/store"; + +export function Captions() { + const router = useOverlayRouter("settings"); + const setHasOpenOverlay = usePlayerStore((s) => s.setHasOpenOverlay); + + useEffect(() => { + setHasOpenOverlay(router.isRouterActive); + }, [setHasOpenOverlay, router.isRouterActive]); + + return ( + + { + router.open(); + router.navigate("/captionsOverlay"); + }} + icon={Icons.CAPTIONS} + /> + + ); +} diff --git a/src/components/player/atoms/CastingNotification.tsx b/src/components/player/atoms/CastingNotification.tsx new file mode 100644 index 0000000..9c4e423 --- /dev/null +++ b/src/components/player/atoms/CastingNotification.tsx @@ -0,0 +1,22 @@ +import { useTranslation } from "react-i18next"; + +import { Icon, Icons } from "@/components/Icon"; +import { usePlayerStore } from "@/stores/player/store"; + +export function CastingNotification() { + const { t } = useTranslation(); + const isLoading = usePlayerStore((s) => s.mediaPlaying.isLoading); + const display = usePlayerStore((s) => s.display); + const isCasting = display?.getType() === "casting"; + + if (isLoading || !isCasting) return null; + + return ( +
+
+ +
+

{t("player.casting.enabled")}

+
+ ); +} diff --git a/src/components/player/atoms/Chromecast.tsx b/src/components/player/atoms/Chromecast.tsx new file mode 100644 index 0000000..a3d278e --- /dev/null +++ b/src/components/player/atoms/Chromecast.tsx @@ -0,0 +1,56 @@ +import { useCallback, useEffect, useRef, useState } from "react"; + +import { Icons } from "@/components/Icon"; +import { VideoPlayerButton } from "@/components/player/internals/Button"; +import { usePlayerStore } from "@/stores/player/store"; + +export interface ChromecastProps { + className?: string; +} + +export function Chromecast(props: ChromecastProps) { + const [hidden, setHidden] = useState(false); + const isCasting = usePlayerStore((s) => s.interface.isCasting); + const ref = useRef(null); + + const setButtonVisibility = useCallback( + (tag: HTMLElement) => { + const isVisible = (tag.getAttribute("style") ?? "").includes("inline"); + setHidden(!isVisible); + }, + [setHidden], + ); + + useEffect(() => { + const tag = ref.current?.querySelector("google-cast-launcher"); + if (!tag) return; + + const observer = new MutationObserver(() => { + setButtonVisibility(tag); + }); + + observer.observe(tag, { attributes: true, attributeFilter: ["style"] }); + setButtonVisibility(tag); + + return () => { + observer.disconnect(); + }; + }, [setButtonVisibility]); + + return ( +