diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3fb7828c..e22f0967 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -6,86 +6,86 @@ on: - next - graphql pull_request: - branches: - - next - - graphql + branches: + - next + - graphql jobs: - build: - name: Build - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] - steps: + build: + name: Build + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [20.x] + steps: # expect used for unbuffer - - name: Install Native Dependencies - run: | - sudo apt-get update - sudo apt-get install expect + - name: Install Native Dependencies + run: | + sudo apt-get update + sudo apt-get install expect - - name: Checkout - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 - - name: Restore Yarn cache - uses: actions/cache@v4 - with: - path: .yarn/cache - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} + - name: Restore Yarn cache + uses: actions/cache@v4 + with: + path: .yarn/cache + key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} - - name: Setup Yarn - run: corepack enable + - name: Setup Yarn + run: corepack enable - - name: Install Yarn Dependencies - run: | - unbuffer yarn install --immutable | tee yarn_output.log - if cat yarn_output.log | grep YN0060; then - echo "Detected incompatible peer dependencies!" - exit 1 - fi + - name: Install Yarn Dependencies + run: | + unbuffer yarn install --immutable | tee yarn_output.log + if cat yarn_output.log | grep YN0060; then + echo "Detected incompatible peer dependencies!" + exit 1 + fi - - name: Compile - run: | - unbuffer yarn build | tee yarn_output.log - if cat yarn_output.log | grep build.chunkSizeWarningLimit; then - echo "Detected chunk size warning peer dependencies!" - exit 1 - fi + - name: Compile + run: | + unbuffer yarn build | tee yarn_output.log + if cat yarn_output.log | grep build.chunkSizeWarningLimit; then + echo "Detected chunk size warning peer dependencies!" + exit 1 + fi - lint: - name: Run Linter - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] - steps: - - name: Checkout - uses: actions/checkout@v4 + lint: + name: Run Linter + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [20.x] + steps: + - name: Checkout + uses: actions/checkout@v4 - - name: Restore Yarn cache - uses: actions/cache@v4 - with: - path: .yarn/cache - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} + - name: Restore Yarn cache + uses: actions/cache@v4 + with: + path: .yarn/cache + key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} - - name: Setup Yarn - run: corepack enable + - name: Setup Yarn + run: corepack enable - - name: Install Dependencies - run: yarn + - name: Install Dependencies + run: yarn - - name: Run ESLint - run: yarn eslint "**/*.{js,jsx,ts,tsx}" + - name: Run ESLint + run: yarn eslint "**/*.{js,jsx,ts,tsx}" - - name: Run Prettier - run: yarn prettier -c . + - name: Run Prettier + run: yarn prettier -c . diff --git a/.github/workflows/auto-approve-dominions-prs.yml b/.github/workflows/auto-approve-dominions-prs.yml index 40d57858..7529ed29 100644 --- a/.github/workflows/auto-approve-dominions-prs.yml +++ b/.github/workflows/auto-approve-dominions-prs.yml @@ -4,33 +4,33 @@ name: "Auto-Approve Dominion's PRs" on: - pull_request_target: - branches: - - next - - graphql + pull_request_target: + branches: + - next + - graphql concurrency: - group: "approve-dominion-${{ github.head_ref || github.run_id }}-${{ github.event_name }}" - cancel-in-progress: true + group: "approve-dominion-${{ github.head_ref || github.run_id }}-${{ github.event_name }}" + cancel-in-progress: true jobs: - approve-pr-if-dominion-is-author: - name: Approve PR if Dominion is Author - if: github.event.pull_request.user.id == 8171642 && !github.event.pull_request.draft && !contains(github.event.pull_request.body, '- [ ]') && (github.event.pull_request.base.repo.owner.login == 'tgstation' || github.event.pull_request.base.repo.owner.login == 'Cyberboss') - runs-on: ubuntu-latest - steps: - - name: Generate App Token - id: app-token-generation - uses: actions/create-github-app-token@v1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} + approve-pr-if-dominion-is-author: + name: Approve PR if Dominion is Author + if: github.event.pull_request.user.id == 8171642 && !github.event.pull_request.draft && !contains(github.event.pull_request.body, '- [ ]') && (github.event.pull_request.base.repo.owner.login == 'tgstation' || github.event.pull_request.base.repo.owner.login == 'Cyberboss') + runs-on: ubuntu-latest + steps: + - name: Generate App Token + id: app-token-generation + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} - - name: GitHub API Call - run: | - curl --request POST \ - --url https://api.github.com/repos/${{ github.repository }}/pulls/${{github.event.number}}/reviews \ - --header 'authorization: Bearer ${{ steps.app-token-generation.outputs.token }}' \ - --header 'content-type: application/json' \ - -d '{"event":"APPROVE"}' \ - --fail + - name: GitHub API Call + run: | + curl --request POST \ + --url https://api.github.com/repos/${{ github.repository }}/pulls/${{github.event.number}}/reviews \ + --header 'authorization: Bearer ${{ steps.app-token-generation.outputs.token }}' \ + --header 'content-type: application/json' \ + -d '{"event":"APPROVE"}' \ + --fail diff --git a/.github/workflows/chromatic-security.yml b/.github/workflows/chromatic-security.yml index 8113a6b1..8c038912 100644 --- a/.github/workflows/chromatic-security.yml +++ b/.github/workflows/chromatic-security.yml @@ -1,81 +1,81 @@ name: Chromatic Security on: - pull_request: - branches: - - next - - graphql - pull_request_target: - types: - - opened - - reopened - - labeled - - synchronize - branches: - - next - - graphql + pull_request: + branches: + - next + - graphql + pull_request_target: + types: + - opened + - reopened + - labeled + - synchronize + branches: + - next + - graphql concurrency: - group: "chromatic-security-${{ github.head_ref || github.run_id }}-${{ github.event_name }}" - cancel-in-progress: true + group: "chromatic-security-${{ github.head_ref || github.run_id }}-${{ github.event_name }}" + cancel-in-progress: true jobs: - security-checkpoint: - name: Check Chromatic Clearance - if: github.event_name == 'pull_request_target' && (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id || github.event.pull_request.user.id == 49699333) && github.event.pull_request.state == 'open' - runs-on: ubuntu-latest - steps: - - name: Generate App Token - id: app-token-generation - uses: actions/create-github-app-token@v1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} + security-checkpoint: + name: Check Chromatic Clearance + if: github.event_name == 'pull_request_target' && (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id || github.event.pull_request.user.id == 49699333) && github.event.pull_request.state == 'open' + runs-on: ubuntu-latest + steps: + - name: Generate App Token + id: app-token-generation + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} - - name: Comment on new Fork PR - if: github.event.action == 'opened' && !contains(github.event.pull_request.labels.*.name, 'CI Cleared') && github.event.pull_request.user.id != 49699333 - uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 - with: - message: Thank you for contributing to ${{ github.event.pull_request.base.repo.name }}! The workflow '${{ github.workflow }}' requires repository secrets and will not run without approval. Maintainers can add the `CI Cleared` label to allow it to run. Note that any changes to chromaitc-security.yml and chromatic.yml will not be reflected. - GITHUB_TOKEN: ${{ steps.app-token-generation.outputs.token }} + - name: Comment on new Fork PR + if: github.event.action == 'opened' && !contains(github.event.pull_request.labels.*.name, 'CI Cleared') && github.event.pull_request.user.id != 49699333 + uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 + with: + message: Thank you for contributing to ${{ github.event.pull_request.base.repo.name }}! The workflow '${{ github.workflow }}' requires repository secrets and will not run without approval. Maintainers can add the `CI Cleared` label to allow it to run. Note that any changes to chromaitc-security.yml and chromatic.yml will not be reflected. + GITHUB_TOKEN: ${{ steps.app-token-generation.outputs.token }} - - name: Comment on dependabot PR - if: github.event.action == 'opened' && !contains(github.event.pull_request.labels.*.name, 'CI Cleared') && github.event.pull_request.user.id == 49699333 - uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 - with: - message: Set the milestone to the next ${{ (github.head_ref == 'master' && 'patch') || 'minor' }} version, check for supply chain attacks, and then add the `CI Cleared` label to allow CI to run. - GITHUB_TOKEN: ${{ steps.app-token-generation.outputs.token }} + - name: Comment on dependabot PR + if: github.event.action == 'opened' && !contains(github.event.pull_request.labels.*.name, 'CI Cleared') && github.event.pull_request.user.id == 49699333 + uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 + with: + message: Set the milestone to the next ${{ (github.head_ref == 'master' && 'patch') || 'minor' }} version, check for supply chain attacks, and then add the `CI Cleared` label to allow CI to run. + GITHUB_TOKEN: ${{ steps.app-token-generation.outputs.token }} - - name: "Remove Stale 'CI Cleared' Label" - if: github.event.action == 'synchronize' || github.event.action == 'reopened' - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 - with: - labels: CI Cleared - github_token: ${{ steps.app-token-generation.outputs.token }} + - name: "Remove Stale 'CI Cleared' Label" + if: github.event.action == 'synchronize' || github.event.action == 'reopened' + uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 + with: + labels: CI Cleared + github_token: ${{ steps.app-token-generation.outputs.token }} - - name: "Remove 'CI Approval Required' Label" - if: (github.event.action == 'synchronize' || github.event.action == 'reopened') || ((github.event.action == 'opened' || github.event.action == 'labeled') && contains(github.event.pull_request.labels.*.name, 'CI Cleared')) - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 - with: - labels: CI Approval Required - github_token: ${{ steps.app-token-generation.outputs.token }} + - name: "Remove 'CI Approval Required' Label" + if: (github.event.action == 'synchronize' || github.event.action == 'reopened') || ((github.event.action == 'opened' || github.event.action == 'labeled') && contains(github.event.pull_request.labels.*.name, 'CI Cleared')) + uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 + with: + labels: CI Approval Required + github_token: ${{ steps.app-token-generation.outputs.token }} - - name: "Add 'CI Approval Required' Label" - if: (github.event.action == 'synchronize' || github.event.action == 'reopened') || ((github.event.action == 'opened' || github.event.action == 'labeled') && !contains(github.event.pull_request.labels.*.name, 'CI Cleared')) - uses: actions-ecosystem/action-add-labels@18f1af5e3544586314bbe15c0273249c770b2daf - with: - labels: CI Approval Required - github_token: ${{ steps.app-token-generation.outputs.token }} + - name: "Add 'CI Approval Required' Label" + if: (github.event.action == 'synchronize' || github.event.action == 'reopened') || ((github.event.action == 'opened' || github.event.action == 'labeled') && !contains(github.event.pull_request.labels.*.name, 'CI Cleared')) + uses: actions-ecosystem/action-add-labels@18f1af5e3544586314bbe15c0273249c770b2daf + with: + labels: CI Approval Required + github_token: ${{ steps.app-token-generation.outputs.token }} - - name: Fail if PR has Unlabeled new Commits from User - if: (github.event.action == 'synchronize' || github.event.action == 'reopened') || ((github.event.action == 'opened' || github.event.action == 'labeled') && !contains(github.event.pull_request.labels.*.name, 'CI Cleared')) - run: exit 1 + - name: Fail if PR has Unlabeled new Commits from User + if: (github.event.action == 'synchronize' || github.event.action == 'reopened') || ((github.event.action == 'opened' || github.event.action == 'labeled') && !contains(github.event.pull_request.labels.*.name, 'CI Cleared')) + run: exit 1 - chromatic-workflow-call: - name: Chromatic - needs: security-checkpoint - if: (!(cancelled() || failure()) && (needs.security-checkpoint.result == 'success' || (github.event_name != 'pull_request_target' && github.event.pull_request.head.repo.id == github.event.pull_request.base.repo.id && github.event.pull_request.user.id != 49699333))) - uses: ./.github/workflows/chromatic.yml - secrets: inherit - with: - pull_request_number: ${{ github.event.pull_request.number }} + chromatic-workflow-call: + name: Chromatic + needs: security-checkpoint + if: (!(cancelled() || failure()) && (needs.security-checkpoint.result == 'success' || (github.event_name != 'pull_request_target' && github.event.pull_request.head.repo.id == github.event.pull_request.base.repo.id && github.event.pull_request.user.id != 49699333))) + uses: ./.github/workflows/chromatic.yml + secrets: inherit + with: + pull_request_number: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 42f84cf5..4544435d 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -1,60 +1,60 @@ name: "Chromatic" on: - push: - branches: - - next - - graphql - workflow_call: - inputs: - pull_request_number: - description: Pull Request Number - required: true - type: string + push: + branches: + - next + - graphql + workflow_call: + inputs: + pull_request_number: + description: Pull Request Number + required: true + type: string jobs: - chromatic: - name: Run Chromatic - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] - steps: - - name: Checkout - if: github.event_name == 'push' - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Checkout (PR) - if: github.event_name != 'push' - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: refs/pull/${{ inputs.pull_request_number }}/head - - - name: Restore Yarn cache - uses: actions/cache@v4 - with: - path: .yarn/cache - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - - name: Setup Yarn - run: corepack enable - - - name: Install Dependencies - run: yarn install --immutable - - - name: Run Relay - run: yarn relay-build - - - name: Run Chromatic - uses: chromaui/action@latest - with: - projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - exitOnceUploaded: true + chromatic: + name: Run Chromatic + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [20.x] + steps: + - name: Checkout + if: github.event_name == 'push' + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Checkout (PR) + if: github.event_name != 'push' + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: refs/pull/${{ inputs.pull_request_number }}/head + + - name: Restore Yarn cache + uses: actions/cache@v4 + with: + path: .yarn/cache + key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Setup Yarn + run: corepack enable + + - name: Install Dependencies + run: yarn install --immutable + + - name: Run Relay + run: yarn relay-build + + - name: Run Chromatic + uses: chromaui/action@latest + with: + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + exitOnceUploaded: true diff --git a/.storybook/MockRelayEnvironment.tsx b/.storybook/MockRelayEnvironment.tsx index ba080e9c..b555cc12 100644 --- a/.storybook/MockRelayEnvironment.tsx +++ b/.storybook/MockRelayEnvironment.tsx @@ -10,8 +10,8 @@ export type Primitive = null | undefined | string | number | boolean | symbol | type ResolverReturnType = T extends { resolve: infer U } ? ResolverReturnType : T extends (...args: any[]) => infer U - ? U - : never; + ? U + : never; type InferMockResolverFieldReturnType = { [K in keyof T]: ResolverReturnType extends infer FieldResolverReturnType @@ -26,13 +26,13 @@ type InferMockResolvers = T extends object ? U extends (...args: any[]) => any ? never : U extends object - ? { - [K in keyof U]?: ( - context: MockPayloadGenerator.MockResolverContext, - generateId: () => string - ) => InferMockResolverFieldReturnType; - } - : never + ? { + [K in keyof U]?: ( + context: MockPayloadGenerator.MockResolverContext, + generateId: () => string + ) => InferMockResolverFieldReturnType; + } + : never : never : never; diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 12ffc206..8ccf0e74 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,3 @@ { - "recommendations": [ - "dbaeumer.vscode-eslint" - ] + "recommendations": ["dbaeumer.vscode-eslint"] } diff --git a/chromatic.config.json b/chromatic.config.json index d1d8f547..db098653 100644 --- a/chromatic.config.json +++ b/chromatic.config.json @@ -1,5 +1,5 @@ { - "onlyChanged": true, - "projectId": "Project:66f85ece973b20285a9ffa8a", - "zip": true + "onlyChanged": true, + "projectId": "Project:66f85ece973b20285a9ffa8a", + "zip": true } diff --git a/components.json b/components.json index 4e925f7b..d7fbff5d 100644 --- a/components.json +++ b/components.json @@ -1,20 +1,20 @@ { - "$schema": "https://ui.shadcn.com/schema.json", - "style": "new-york", - "rsc": false, - "tsx": true, - "tailwind": { - "config": "tailwind.config.js", - "css": "src/index.css", - "baseColor": "neutral", - "cssVariables": true, - "prefix": "" - }, - "aliases": { - "components": "@/components", - "utils": "@/lib/shadcn/utils", - "ui": "@/components/ui", - "lib": "@/lib/shadcn", - "hooks": "@/lib/shadcn/hooks" - } + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/shadcn/utils", + "ui": "@/components/ui", + "lib": "@/lib/shadcn", + "hooks": "@/lib/shadcn/hooks" + } } diff --git a/eslint.config.js b/eslint.config.js index 03d47302..fac84d8c 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,40 +1,35 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' -import importPlugin from 'eslint-plugin-import'; +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; +import importPlugin from "eslint-plugin-import"; export default tseslint.config( - { ignores: ['dist', 'src/api/grab.js'] }, - { - extends: [ - js.configs.recommended, - ...tseslint.configs.recommended], - files: ['**/*.{ts,tsx}'], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - plugins: { - 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, - 'import': importPlugin - }, - rules: { - ...reactHooks.configs.recommended.rules, - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - 'import/order': [ - 'error', - { - 'newlines-between': "always" + { ignores: ["dist", "src/api/grab.js"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + import: importPlugin + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], + "import/order": [ + "error", + { + "newlines-between": "always" + } + ], + "import/no-relative-parent-imports": "error", + "import/no-useless-path-segments": "error" } - ], - 'import/no-relative-parent-imports': "error", - 'import/no-useless-path-segments': "error" - }, - }, -) + } +); diff --git a/github.relay.config.json b/github.relay.config.json index 7668ecbd..d28e56b8 100644 --- a/github.relay.config.json +++ b/github.relay.config.json @@ -1,30 +1,30 @@ { - "src": "./src", - "language": "typescript", - "schema": "./src/api/github_schema.graphql", - "exclude": [ - "**/node_modules/**", - "**/__mocks__/**", - "**/__generated__/**", - "components/core/**", - "components/graphql/**", - "components/routed/**", - "context/**" - ], - "eagerEsModules": true, - "customScalarTypes": { - "Base64String": "string", - "BigInt": "number", - "Date": "string", - "DateTime": "string", - "Float": "number", - "GitObjectID": "string", - "GitRefname": "string", - "GitSSHRemote": "string", - "GitTimestamp": "string", - "HTML": "string", - "PreciseDateTime": "string", - "URI": "string", - "X509Certificate": "string" - } + "src": "./src", + "language": "typescript", + "schema": "./src/api/github_schema.graphql", + "exclude": [ + "**/node_modules/**", + "**/__mocks__/**", + "**/__generated__/**", + "components/core/**", + "components/graphql/**", + "components/routed/**", + "context/**" + ], + "eagerEsModules": true, + "customScalarTypes": { + "Base64String": "string", + "BigInt": "number", + "Date": "string", + "DateTime": "string", + "Float": "number", + "GitObjectID": "string", + "GitRefname": "string", + "GitSSHRemote": "string", + "GitTimestamp": "string", + "HTML": "string", + "PreciseDateTime": "string", + "URI": "string", + "X509Certificate": "string" + } } diff --git a/index.html b/index.html index b9703309..0567f160 100644 --- a/index.html +++ b/index.html @@ -1,22 +1,51 @@ - - - - + + + + - TGS + TGS - - - - - - - - - -
- - + + + + + + + + + +
+ + diff --git a/package.json b/package.json index b48db135..1924b788 100644 --- a/package.json +++ b/package.json @@ -1,126 +1,126 @@ { - "name": "tgstation-server-webpanel", - "private": true, - "version": "7.0.0", - "tgs_graphql_api_version": "0.4.0", - "tgs_rest_api_version": "10.10.0", - "homepage": "https://tgstation.github.io/tgstation-server-webpanel", - "repository": { - "type": "git", - "url": "git+https://github.com/tgstation/tgstation-server-webpanel.git" - }, - "bugs": { - "url": "https://github.com/tgstation/tgstation-server-webpanel/issues" - }, - "license": "AGPL-3.0-or-later", - "author": { - "name": "Cyberboss" - }, - "contributors": [ - { - "name": "alexkar598", - "url": "https://github.com/alexkar598/" + "name": "tgstation-server-webpanel", + "private": true, + "version": "7.0.0", + "tgs_graphql_api_version": "0.4.0", + "tgs_rest_api_version": "10.10.0", + "homepage": "https://tgstation.github.io/tgstation-server-webpanel", + "repository": { + "type": "git", + "url": "git+https://github.com/tgstation/tgstation-server-webpanel.git" + }, + "bugs": { + "url": "https://github.com/tgstation/tgstation-server-webpanel/issues" + }, + "license": "AGPL-3.0-or-later", + "author": { + "name": "Cyberboss" + }, + "contributors": [ + { + "name": "alexkar598", + "url": "https://github.com/alexkar598/" + } + ], + "type": "module", + "scripts": { + "dev": "concurrently --kill-others \"npm:dev-server\" \"npm:storybook\" \"npm:relay\"", + "dev-server": "vite", + "build": "yarn relay-build && tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build", + "chromatic": "yarn relay-build && npx chromatic", + "relay": "yarn grab-api && relay-compiler github.relay.config.json && relay-compiler --watch relay.config.json", + "relay-build": "yarn grab-api && relay-compiler relay.config.json && relay-compiler github.relay.config.json", + "grab-api": "node --no-warnings src/api/grab.js" + }, + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.6.0", + "@fortawesome/free-brands-svg-icons": "^6.6.0", + "@fortawesome/free-solid-svg-icons": "^6.6.0", + "@fortawesome/react-fontawesome": "^0.2.2", + "@hookform/resolvers": "^3.9.0", + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-navigation-menu": "^1.2.1", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", + "@radix-ui/react-toast": "^1.2.2", + "@radix-ui/react-tooltip": "^1.1.3", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "estree-walker": "^3.0.3", + "graphql": "16.x", + "graphql-sse": "^2.5.3", + "lucide-react": "^0.453.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-hook-form": "^7.53.1", + "react-intl": "^6.8.4", + "react-relay": "^18.1.0", + "react-router-dom": "^6.27.0", + "tailwind-merge": "^2.5.4", + "tailwindcss-animate": "^1.0.7", + "uuid": "^10.0.0", + "zod": "^3.23.8" + }, + "devDependencies": { + "@chromatic-com/storybook": "3.1.0", + "@eslint/js": "^9.13.0", + "@rollup/pluginutils": "^5.1.3", + "@storybook/addon-essentials": "^8.3.6", + "@storybook/addon-interactions": "^8.3.6", + "@storybook/addon-links": "^8.3.6", + "@storybook/blocks": "^8.3.6", + "@storybook/channels": "^8.3.6", + "@storybook/components": "^8.3.6", + "@storybook/core-events": "^8.3.6", + "@storybook/manager-api": "^8.3.6", + "@storybook/preview-api": "^8.3.6", + "@storybook/react": "^8.3.6", + "@storybook/react-vite": "^8.3.6", + "@storybook/test": "^8.3.6", + "@storybook/theming": "^8.3.6", + "@types/node": "^22.7.9", + "@types/react": "^18", + "@types/react-dom": "^18.3.1", + "@types/react-relay": "^16.0.6", + "@types/relay-test-utils": "^18.0.0", + "@types/uuid": "^10", + "@vitejs/plugin-react": "^4.3.3", + "autoprefixer": "^10.4.20", + "babel-plugin-relay": "^18.1.0", + "chromatic": "^11.15.0", + "concurrently": "^9.0.1", + "escodegen": "^2.1.0", + "eslint": "^9.13.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.14", + "eslint-plugin-storybook": "0.10.1", + "globals": "^15.11.0", + "postcss": "^8.4.47", + "prettier": "^3.3.3", + "relay-compiler": "^18.1.0", + "relay-test-utils": "^18.1.0", + "rollup-plugin-jsx-remove-attributes": "^2.0.3", + "storybook": "^8.3.6", + "storybook-addon-remix-react-router": "^3.0.1", + "tailwindcss": "^3.4.14", + "type-fest": "^4.26.1", + "typescript": "^5.6.3", + "typescript-eslint": "^8.11.0", + "vite": "^5.4.10", + "vite-plugin-relay": "^2.1.0" + }, + "packageManager": "yarn@4.5.0", + "eslintConfig": { + "extends": [ + "plugin:storybook/recommended" + ] } - ], - "type": "module", - "scripts": { - "dev": "concurrently --kill-others \"npm:dev-server\" \"npm:storybook\" \"npm:relay\"", - "dev-server": "vite", - "build": "yarn relay-build && tsc -b && vite build", - "lint": "eslint .", - "preview": "vite preview", - "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build", - "chromatic": "yarn relay-build && npx chromatic", - "relay": "yarn grab-api && relay-compiler github.relay.config.json && relay-compiler --watch relay.config.json", - "relay-build": "yarn grab-api && relay-compiler relay.config.json && relay-compiler github.relay.config.json", - "grab-api": "node --no-warnings src/api/grab.js" - }, - "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.6.0", - "@fortawesome/free-brands-svg-icons": "^6.6.0", - "@fortawesome/free-solid-svg-icons": "^6.6.0", - "@fortawesome/react-fontawesome": "^0.2.2", - "@hookform/resolvers": "^3.9.0", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-dropdown-menu": "^2.1.2", - "@radix-ui/react-icons": "^1.3.0", - "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-navigation-menu": "^1.2.1", - "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-switch": "^1.1.1", - "@radix-ui/react-toast": "^1.2.2", - "@radix-ui/react-tooltip": "^1.1.3", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.1", - "estree-walker": "^3.0.3", - "graphql": "16.x", - "graphql-sse": "^2.5.3", - "lucide-react": "^0.453.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-hook-form": "^7.53.1", - "react-intl": "^6.8.4", - "react-relay": "^18.1.0", - "react-router-dom": "^6.27.0", - "tailwind-merge": "^2.5.4", - "tailwindcss-animate": "^1.0.7", - "uuid": "^10.0.0", - "zod": "^3.23.8" - }, - "devDependencies": { - "@chromatic-com/storybook": "3.1.0", - "@eslint/js": "^9.13.0", - "@rollup/pluginutils": "^5.1.3", - "@storybook/addon-essentials": "^8.3.6", - "@storybook/addon-interactions": "^8.3.6", - "@storybook/addon-links": "^8.3.6", - "@storybook/blocks": "^8.3.6", - "@storybook/channels": "^8.3.6", - "@storybook/components": "^8.3.6", - "@storybook/core-events": "^8.3.6", - "@storybook/manager-api": "^8.3.6", - "@storybook/preview-api": "^8.3.6", - "@storybook/react": "^8.3.6", - "@storybook/react-vite": "^8.3.6", - "@storybook/test": "^8.3.6", - "@storybook/theming": "^8.3.6", - "@types/node": "^22.7.9", - "@types/react": "^18", - "@types/react-dom": "^18.3.1", - "@types/react-relay": "^16.0.6", - "@types/relay-test-utils": "^18.0.0", - "@types/uuid": "^10", - "@vitejs/plugin-react": "^4.3.3", - "autoprefixer": "^10.4.20", - "babel-plugin-relay": "^18.1.0", - "chromatic": "^11.15.0", - "concurrently": "^9.0.1", - "escodegen": "^2.1.0", - "eslint": "^9.13.0", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-react-hooks": "^5.1.0-rc.0", - "eslint-plugin-react-refresh": "^0.4.14", - "eslint-plugin-storybook": "0.10.1", - "globals": "^15.11.0", - "postcss": "^8.4.47", - "prettier": "^3.3.3", - "relay-compiler": "^18.1.0", - "relay-test-utils": "^18.1.0", - "rollup-plugin-jsx-remove-attributes": "^2.0.3", - "storybook": "^8.3.6", - "storybook-addon-remix-react-router": "^3.0.1", - "tailwindcss": "^3.4.14", - "type-fest": "^4.26.1", - "typescript": "^5.6.3", - "typescript-eslint": "^8.11.0", - "vite": "^5.4.10", - "vite-plugin-relay": "^2.1.0" - }, - "packageManager": "yarn@4.5.0", - "eslintConfig": { - "extends": [ - "plugin:storybook/recommended" - ] - } } diff --git a/postcss.config.js b/postcss.config.js index 2e7af2b7..badd1005 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,6 @@ export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/relay.config.json b/relay.config.json index 00c00829..3eaad7d5 100644 --- a/relay.config.json +++ b/relay.config.json @@ -1,19 +1,19 @@ { - "src": "./src", - "language": "typescript", - "schema": "./src/api/tgs_schema.graphql", - "exclude": [ - "**/node_modules/**", - "**/__mocks__/**", - "**/__generated__/**", - "components/github/**" - ], - "eagerEsModules": true, - "customScalarTypes": { - "DateTime": "string", - "Jwt": "string", - "Semver": "string", - "UnsignedInt": "number", - "URL": "string" - } + "src": "./src", + "language": "typescript", + "schema": "./src/api/tgs_schema.graphql", + "exclude": [ + "**/node_modules/**", + "**/__mocks__/**", + "**/__generated__/**", + "components/github/**" + ], + "eagerEsModules": true, + "customScalarTypes": { + "DateTime": "string", + "Jwt": "string", + "Semver": "string", + "UnsignedInt": "number", + "URL": "string" + } } diff --git a/src/components/App.tsx b/src/components/App.tsx index 1a1fb74f..93cf340f 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -52,9 +52,8 @@ const App = (props: IProps) => { )}. Falling back to ${FallbackLocale}.` ); - loadedTranslation = await props.translationFactory.loadTranslation( - FallbackLocale - ); + loadedTranslation = + await props.translationFactory.loadTranslation(FallbackLocale); } } catch (error) { alert( diff --git a/src/components/utils/ErrorCard/ErrorCard.tsx b/src/components/utils/ErrorCard/ErrorCard.tsx index f1220b96..5c66a578 100644 --- a/src/components/utils/ErrorCard/ErrorCard.tsx +++ b/src/components/utils/ErrorCard/ErrorCard.tsx @@ -33,15 +33,15 @@ const ErrorCard = (props: IProps) => { } ) : isErrorMessage - ? tgsError.additionalData || null - : intl.formatMessage( - { - id: "error.withoutstacktrace" - }, - { - version: Pkg.version - } - ); + ? tgsError.additionalData || null + : intl.formatMessage( + { + id: "error.withoutstacktrace" + }, + { + version: Pkg.version + } + ); let errorTitle = "error.somethingwentwrong"; if (props.error instanceof TypeError) { diff --git a/src/components/utils/icolibrary.ts b/src/components/utils/icolibrary.ts index 4efb68ef..c44ef378 100644 --- a/src/components/utils/icolibrary.ts +++ b/src/components/utils/icolibrary.ts @@ -16,7 +16,7 @@ import { faHashtag, faMinus, faUnlock, - faUpload, + faUpload } from "@fortawesome/free-solid-svg-icons"; import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight"; import { faCheck } from "@fortawesome/free-solid-svg-icons/faCheck"; diff --git a/src/context/config/CreateConfig.ts b/src/context/config/CreateConfig.ts index 423e5475..6cbc5b0f 100644 --- a/src/context/config/CreateConfig.ts +++ b/src/context/config/CreateConfig.ts @@ -1,6 +1,4 @@ -import CreateTypedConfigItem, { - CreateStringConfigItem, -} from "./CreateConfigItem"; +import CreateTypedConfigItem, { CreateStringConfigItem } from "./CreateConfigItem"; import Theme from "./Theme"; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -10,32 +8,30 @@ const DefaultServerUrl = "http://localhost:5000"; const InitialServerUrl = import.meta.env.DEV ? DefaultServerUrl : publicPath - ? new URL("..", new URL(publicPath, window.location.href)).href - : DefaultServerUrl; + ? new URL("..", new URL(publicPath, window.location.href)).href + : DefaultServerUrl; export enum JobsWidgetOptions { Auto = "auto", Always = "always", - Never = "never", + Never = "never" } const CreateConfig = (forContext: boolean, darkOverride?: boolean) => { return { Theme: CreateTypedConfigItem( forContext, - (configValue) => configValue as Theme, - (runtimeValue) => runtimeValue.toString(), + configValue => configValue as Theme, + runtimeValue => runtimeValue.toString(), darkOverride ? Theme.Dark : Theme.System, "theme", - (theme) => { + theme => { const root = window.document.documentElement; root.classList.remove("light", "dark"); if (theme === Theme.System) { - const systemTheme = window.matchMedia( - "(prefers-color-scheme: dark)" - ).matches + const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; @@ -47,32 +43,28 @@ const CreateConfig = (forContext: boolean, darkOverride?: boolean) => { } ), GitHubToken: CreateStringConfigItem(forContext, "", "githubtoken"), - ApiPath: CreateStringConfigItem( - forContext, - InitialServerUrl, - "apipath" - ), + ApiPath: CreateStringConfigItem(forContext, InitialServerUrl, "apipath"), JobsWidgetDisplay: CreateTypedConfigItem( forContext, - (configValue) => configValue as JobsWidgetOptions, - (runtimeValue) => runtimeValue, + configValue => configValue as JobsWidgetOptions, + runtimeValue => runtimeValue, JobsWidgetOptions.Auto, "jobswidgetdisplay" ), ShowJson: CreateTypedConfigItem( forContext, - (configValue) => configValue === "true", - (runtimeValue) => runtimeValue.toString(), + configValue => configValue === "true", + runtimeValue => runtimeValue.toString(), import.meta.env.DEV, "showjson" ), ManualPR: CreateTypedConfigItem( forContext, - (configValue) => configValue === "true", - (runtimeValue) => runtimeValue.toString(), + configValue => configValue === "true", + runtimeValue => runtimeValue.toString(), true, "manualpr" - ), + ) }; }; diff --git a/src/context/config/CreateConfigItem.ts b/src/context/config/CreateConfigItem.ts index b8345563..0c513679 100644 --- a/src/context/config/CreateConfigItem.ts +++ b/src/context/config/CreateConfigItem.ts @@ -14,15 +14,13 @@ const CreateTypedConfigItem = ( ): IConfigItem => { const fullStorageKey = `${RootConfigStorageKey}.${storageKey}`; const loader = () => - deserializer( - localStorage.getItem(fullStorageKey) || serializer(defaultValue) - ); + deserializer(localStorage.getItem(fullStorageKey) || serializer(defaultValue)); if (forContext) { return { value: defaultValue, setValue: () => null, - localizationId: fullStorageKey, + localizationId: fullStorageKey }; } @@ -38,7 +36,7 @@ const CreateTypedConfigItem = ( return { value, - setValue: (newValue) => { + setValue: newValue => { const storageValue = serializer(newValue); if (storageValue) { localStorage.setItem(fullStorageKey, storageValue); @@ -48,7 +46,7 @@ const CreateTypedConfigItem = ( setValue(newValue); }, - localizationId: fullStorageKey, + localizationId: fullStorageKey }; }; @@ -59,8 +57,8 @@ export const CreateStringConfigItem = ( ) => CreateTypedConfigItem( forContext, - (configValue) => configValue, - (runtimeValue) => runtimeValue, + configValue => configValue, + runtimeValue => runtimeValue, defaultValue, storageKey ); diff --git a/src/context/config/Theme.ts b/src/context/config/Theme.ts index ef1c93a3..6f2eb7a8 100644 --- a/src/context/config/Theme.ts +++ b/src/context/config/Theme.ts @@ -1,7 +1,7 @@ enum Theme { System = "System", Light = "Light", - Dark = "Dark", + Dark = "Dark" } export default Theme; diff --git a/src/lib/shadcn/utils.ts b/src/lib/shadcn/utils.ts index bd0c391d..e6a8be07 100644 --- a/src/lib/shadcn/utils.ts +++ b/src/lib/shadcn/utils.ts @@ -1,6 +1,6 @@ -import { clsx, type ClassValue } from "clsx" -import { twMerge } from "tailwind-merge" +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) + return twMerge(clsx(inputs)); } diff --git a/src/locales/en.json b/src/locales/en.json index bb59e815..4673ef6d 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,9 +1,9 @@ { - "app.job.cancelled": "Cancelled: ", - "app.job.cancelledby": "Cancelled By: ", - "app.job.completed": "Finished: ", - "app.job.started": "Started: ", - "app.job.startedby": "Started By: ", + "app.job.cancelled": "Cancelled: ", + "app.job.cancelledby": "Cancelled By: ", + "app.job.completed": "Finished: ", + "app.job.started": "Started: ", + "app.job.startedby": "Started By: ", "changepassword.executing": "Changing Password...", "changepassword.form.password": "New Password", "changepassword.form.password.invalid.matches_user": "Password must not match username!", @@ -13,591 +13,591 @@ "changepassword.form.passwordConfirm.invalid.mismatch": "Passwords do not match!", "changepassword.form.passwordConfirm.placeholder": "Re-enter your new password", "changepassword.form.submit": "Change Password", - "config.apipath": "TGS API Path", - "config.apipath.desc": "Sets the API client server's path.", - "config.githubtoken": "Github Token", - "config.githubtoken.desc": "You can supply a private authorization token for github to bypass some rate limiting on the github API.", - "config.instanceeditsidebar": "Instance Edit Sidebar", - "config.instanceeditsidebar.desc": "This controls how the left sidebar menu acts in the instance edit page.", - "config.instanceeditsidebar.enum.auto": "Expand on hover", - "config.instanceeditsidebar.enum.collapse": "Always collapsed", - "config.instanceeditsidebar.enum.expand": "Always expanded", - "config.instanceprobetimer": "Instance permission poll delay", - "config.instanceprobetimer.desc": "After how many seconds should we update the list of instances", - "config.itemsperpage": "Items Per Page", - "config.itemsperpage.desc": "This allows you to configure the amount of items shown at once in lists. Note that not all lists support this option yet.", - "config.jobpollactive": "Active job poll delay (s)", - "config.jobpollactive.desc": "After how many seconds should we check for new jobs if we know about a job", - "config.jobpollinactive": "Inactive job poll delay (s)", - "config.jobpollinactive.desc": "After how many seconds should we check for new jobs if we dont have any active jobs", - "config.jobswidgetdisplay": "Jobs Widget Display", - "config.jobswidgetdisplay.desc": "Display mode for the instance jobs widget", - "config.jobswidgetdisplay.enum.always": "Always display", - "config.jobswidgetdisplay.enum.auto": "Display when there are jobs", - "config.jobswidgetdisplay.enum.never": "Never display", - "config.manualpr": "Show manual PR entry on repository page", - "config.manualpr.desc": "Controls whether or not an input box is displayed to manually testmerge a pr based on its PR number. This option is ignored and the manual PR entry box is always displayed when using a repository hosted on GitLab.", - "config.manualreset": "Show force reset switch on repository page", - "config.manualreset.desc": "Controls whether or not an input box is displayed to force a repository reset. This option is ignored and the manual PR entry box is always displayed when using a repository hosted on GitLab.", - "config.restjobs2": "Force HTTP Polling for Job Updates", - "config.restjobs2.desc": "Workaround for if SignalR job updates are failing", - "config.showjson": "Show JSON objects", - "config.showjson.desc": "Most pages will display the underlying json data if enabled.", - "config.theme": "Theming", - "config.theme.desc": "Set dark mode explicitly or to match your system", - "error.admin.error": "The server has ran into an error while using github's API.", - "error.admin.logs.io": "An IO error occured while processing logs", - "error.admin.rate": "The server has exceeded github's rate limiting. Please try again later.", - "error.admin.update.notfound": "This TGS version does not seem to exist.", - "error.admin.watchdog.avail": "This operation is unavailable due to the launch configuration of TGS.", - "error.api.empty": "No description available", - "error.app": "An error occured in the application", - "error.app.default_creds": "You are using the default TGS credentials. Please click 'Change Password' at earliest convenience!", - "error.app.undefined": "A \"Ghost\" error occured in the application", - "error.axios": "Axios error", - "error.bad_channels_json": "Malformed channels JSON.", - "error.bad_hub_connection": "Lost connection to the SignalR hub.", - "error.bad_tgs_yml_version": "Incorrect .tgs.yml version. Only version 1 is supported.", - "error.bad_yml": "Malformed .yml.", - "error.compile_job_not_found": "Compile job not found.", - "error.errorMessage": "Message:\n{message}\nAdditional Data:\n{additionalData}", - "error.github": "An error occured while interacting with the Github API", - "error.githubtokenmissing": "This GitHub component cannot be loaded because you have not configured a GitHub personal access token in your webpanel settings", - "error.group.not_empty": "The requested group cannot be deleted as it contains users.", - "error.group.not_found": "The requested group cannot be found.", - "error.http.access_denied": "Access denied", - "error.http.access_denied.desc": "Access to this resource is denied", - "error.http.api_mismatch": "API version mismatch", - "error.http.bad_request": "Bad Request", - "error.http.data_integrity": "A data integrity check failed while performing the operation", - "error.http.not_acceptable": "BUG: The server has found the request to be unacceptable.", - "error.http.server_error": "BUG: Server error", - "error.http.server_not_ready": "The server is still starting/stoping!", - "error.http.unimplemented": "This feature is unimplemented.", - "error.job.complete": "Unable to delete the job, perhaps it already completed", - "error.job.not_found": "The specified job could not be found", - "error.login.bad_oauth": "An error occurred while logging in using OAuth", - "error.login.bad_user_pass": "Invalid credentials!", - "error.login.bad_user_pass.desc": "Invalid credentials!", - "error.login.no_creds": "Attempted to login without any credentials", - "error.login.no_creds.desc": "Attempted to login without any credentials", - "error.login.rate_limit": "Failed to login using external provider due to rate limiting. Please try again later", - "error.login.user_disabled": "This user account is disabled", - "error.login.user_disabled.desc": "This user account is disabled", - "error.no_apipath": "No API path set, set an API path on the configuration page.", - "error.no_db_entity": "The database entity for the requested instance could not be retrieved. The instance was likely detached", - "error.no_engine_version": "The target engine version does not exist on the server.", - "error.notfound": "This page has not been found!", - "error.pleasereport": "Oopsie woopsie! Please report this using the \"Report Issue\" button in the bottom left of the page", - "error.routemissingpermissions": "This view cannot be accessed because your TGS account has insufficient permissions", - "error.somethingwentwrong": "Uh oh.... Something went wrong!", - "error.tgsnetworkerror": "An error occured communicating with tgstation-server. Is it running and are you connected?", - "error.transfer.not_available": "Unable to transfer file as it is no longer or never was valid", - "error.transfer.upload_failed": "An error occured while uploading a file", - "error.unhandled_global_response": "The application received an unexpected global response", - "error.unhandled_global_response.desc": "The application received an unexpected global response", - "error.unhandled_response": "The application received an unexpected response", - "error.unhandled_response.desc": "The application received an unexpected response", - "error.user.no_sys_ident": "This system user was not found", - "error.user.no_sys_ident.desc": "This system user was not found", - "error.user.not_found": "This TGS user was not found", - "error.user.not_found.desc": "This TGS user was not found", - "error.withoutstacktrace": "Webpanel Version: {version}\nNo stack trace!", - "error.withstacktrace": "Webpanel Version: {version}\nStack trace:{stackTrace}", - "fields.instance.autoupdate": "Auto-update Interval in minutes (0 to disable)", - "fields.instance.autoupdate.tip": "Interval begins when previous update completes or immediately upon setting.", - "fields.instance.chat.channel.admin": "Admin Channel", - "fields.instance.chat.channel.admin.tip": "This channel can be used to receive messages and issue TGS chat commands designated as admin only", - "fields.instance.chat.channel.discord": "Channel ID", - "fields.instance.chat.channel.discord.tip": "Right click a channel with developer mode enabled to see the option to copy its ID", - "fields.instance.chat.channel.irc": "IRC Channel", - "fields.instance.chat.channel.irc.tip": "Include the '#'", - "fields.instance.chat.channel.system": "System Channel", - "fields.instance.chat.channel.system.tip": "This channel will receive TGS system messages (Restarts and updates)", - "fields.instance.chat.channel.tag": "DMAPI Tag", - "fields.instance.chat.channel.tag.tip": "A string associated with this channel in the DMAPI", - "fields.instance.chat.channel.updates": "Deployments Channel", - "fields.instance.chat.channel.updates.tip": "This channel will receive TGS deployment messages", - "fields.instance.chat.channel.watchdog": "Watchdog Channel", - "fields.instance.chat.channel.watchdog.tip": "This channel will receive live updates as to the state of the active game server process", - "fields.instance.chat.create.channel": "Add Channel", - "fields.instance.chat.create.discord.based.tip": "Know your meme", - "fields.instance.chat.create.discord.branding": "Deployment Embed Branding", - "fields.instance.chat.create.discord.branding.tip": "If the tgstation-server logo, name, and link to repo are shown at the top of deployment embeds", - "fields.instance.chat.create.discord.output": "Show Deployment Messages", - "fields.instance.chat.create.discord.output.tip": "When messages from deployment jobs will be shown in Watchdog-type channels", - "fields.instance.chat.create.discord.token": "Bot Token", - "fields.instance.chat.create.discord.token.tip": "Bot access token retrieved from Discord developers portal", - "fields.instance.chat.create.irc.address": "Server Address", - "fields.instance.chat.create.irc.address.tip": "IP/Domain only", - "fields.instance.chat.create.irc.nick": "Bot Nickname", - "fields.instance.chat.create.irc.pass": "Server Password", - "fields.instance.chat.create.irc.pass.tip": "Setting a password on the server for your IRC bot is HIGHLY recommended", - "fields.instance.chat.create.irc.passtype": "Server Password Type", - "fields.instance.chat.create.irc.port": "Server Port", - "fields.instance.chat.create.irc.ssl": "Connect with SSL", - "fields.instance.chat.create.irc.ssl.tip": "Note: This is dependent on the IRC server's configuration", - "fields.instance.chat.create.save": "Create Chat Bot", - "fields.instance.chat.edit.connection": "Connection String", - "fields.instance.chat.edit.connection.deny": "Lacking read permission. Edit may still available", - "fields.instance.chat.edit.connection.tip": "Contains sensitive information. Consider remaking the bot instead of modifying this due to the internal formatting", - "fields.instance.chat.edit.connection.unloaded": "Not Loaded. Edit available", - "fields.instance.chat.enabled": "Enabled", - "fields.instance.chat.enabled.tip": "If the bot is to be online with the instance", - "fields.instance.chat.limit": "Channel Limit", - "fields.instance.chat.limit.tip": "Maximum number of channels this bot can interact with", - "fields.instance.chat.name": "Chat Bot Name", - "fields.instance.chat.name.tip": "Internal name of the chat bot", - "fields.instance.chat.provider": "Chat Service Provider", - "fields.instance.chat.reconnect": "Reconnection Interval (Minutes)", - "fields.instance.chat.reconnect.tip": "The period at which the bot will attempt to reconnect to the chat service if unexpectedly disconnected", - "fields.instance.chatbotlimit": "Max chatbots", - "fields.instance.cron": "Auto-update cron schedule (6-part, UTC, 0 to disable)", - "fields.instance.deploy.apiport": "DMAPI port (0 for auto)", - "fields.instance.deploy.apiport.desc": "This port should not be public", - "fields.instance.deploy.compilerargs": "Additional Compiler Arguments", - "fields.instance.deploy.compilerargs.desc": "These are added to compiler command lines right before the path to the .dme", - "fields.instance.deploy.projectname": "DME name (blank for auto)", - "fields.instance.deploy.projectname.desc": "This can also be a relative path and shouldn't include the file extension", - "fields.instance.deploy.seclevel": "DMAPI validation security level", - "fields.instance.deploy.seclevel.Safe": "Safe", - "fields.instance.deploy.seclevel.Trusted": "Trusted", - "fields.instance.deploy.seclevel.Ultrasafe": "Ultra-Safe", - "fields.instance.deploy.seclevel.desc": "This is only used for the DMAPI validation", - "fields.instance.deploy.timeout": "Job timeout (in minutes)", - "fields.instance.deploy.timeout.desc": "Time before a compile job is abandonned and cancelled", - "fields.instance.deploy.validateapi": "DMAPI Validation Mode", - "fields.instance.deploy.validateapi.Optional": "Attempt but do not require validation", - "fields.instance.deploy.validateapi.Required": "Require validation to succeed for the deployment to succeed", - "fields.instance.deploy.validateapi.Skipped": "Skip validation disabling all DMAPI features", - "fields.instance.deploy.validateapi.desc": " DMAPI validation check that the DMAPI initializes successfully without any runtimes.", - "fields.instance.filemode": "Static File Edit Mode", - "fields.instance.filemode.Disallowed": "No File Management.", - "fields.instance.filemode.HostWrite": "Authorized users can edit any file.", - "fields.instance.filemode.SystemIdentityWrite": "Users using a system identity can edit files their user has access to.", - "fields.instance.files.create": "Create Directory or Upload File", - "fields.instance.files.create.directory": "Create directory instead of file", - "fields.instance.files.create.name": "File system entry name", - "fields.instance.files.create.name.tip": "The name of the file or directory being created (extension included for files)", - "fields.instance.name": "Instance Name", - "fields.instance.path": "Path on disk", - "fields.instance.perms.owner": "Editing Instance Permissions For", - "fields.instance.perms.owner.switch": "Switch", - "fields.instance.repository.accessToken": "New Access Password", - "fields.instance.repository.accessToken.desc": "For github, this will be a PAT(Private Authentication Token), for other providers, this will be a password", - "fields.instance.repository.accessUser": "Access Username", - "fields.instance.repository.accessUser.desc": "These credentials will be used when cloning the repository or performing authenticated actions", - "fields.instance.repository.autoUpdatesKeepTestMerges": "Preserve test merges when auto updating", - "fields.instance.repository.autoUpdatesKeepTestMerges.desc": "If enabled, auto updates may fail if a merge conflict occurs.", - "fields.instance.repository.autoUpdatesSynchronize": "Push new commits to origin during auto-update", - "fields.instance.repository.autoUpdatesSynchronize.desc": "Used for example, with changelog scripts depending on the setup", - "fields.instance.repository.checkoutsha": "Checkout SHA", - "fields.instance.repository.checkoutsha.desc": "SHA of the commit to checkout", - "fields.instance.repository.clearAccessToken": "Clear Access Credentials", - "fields.instance.repository.committerEmail": "Committer Email", - "fields.instance.repository.committerName": "Committer Name", - "fields.instance.repository.createGitHubDeployments": "Create GitHub Deployments", - "fields.instance.repository.createGitHubDeployments.desc": "Requires access credentials", - "fields.instance.repository.creds.mode": "Credential Type", - "fields.instance.repository.creds.mode.None": "Clear Credentials", - "fields.instance.repository.creds.mode.Password": "Username/Password (INSECURE)", - "fields.instance.repository.creds.mode.Password.password": "Password", - "fields.instance.repository.creds.mode.Password.password.desc": "Account password", - "fields.instance.repository.creds.mode.Password.username": "Username", - "fields.instance.repository.creds.mode.Password.username.desc": "Account username", - "fields.instance.repository.creds.mode.PrivateKey": "GitHub App (Recommended)", - "fields.instance.repository.creds.mode.PrivateKey.id": "Client ID or App ID", - "fields.instance.repository.creds.mode.PrivateKey.id.desc": "GitHub recommends using the client ID", - "fields.instance.repository.creds.mode.PrivateKey.pk": "App Private Key", - "fields.instance.repository.creds.mode.PrivateKey.pk.desc": "The contents of a .pem file generated on the app control panel", - "fields.instance.repository.creds.mode.PrivateKey.username": "GitHub App Name", - "fields.instance.repository.creds.mode.PrivateKey.username.desc": "The name of the GitHub App", - "fields.instance.repository.creds.mode.Token": "Access Token", - "fields.instance.repository.creds.mode.Token.token": "Personal Access Token", - "fields.instance.repository.creds.mode.Token.token.desc": "Generated personal access token", - "fields.instance.repository.creds.mode.Token.username": "Username", - "fields.instance.repository.creds.mode.Token.username.desc": "Username of the account for the token", - "fields.instance.repository.creds.mode.desc": "The type of credential to use", - "fields.instance.repository.enablesubmodules": "Enable submodules", - "fields.instance.repository.gitpassword": "Git access password", - "fields.instance.repository.gituser": "Git access username", - "fields.instance.repository.origincheckoutsha": "Origin SHA", - "fields.instance.repository.origincheckoutsha.desc": "SHA of the origin commit", - "fields.instance.repository.postTestMergeComment": "Post comment when test merge is deployed", - "fields.instance.repository.postTestMergeComment.desc": "This will post a github comment each time a test merge is deployed or updated", - "fields.instance.repository.pushTestMergeCommits": "Push Test Merge Commits", - "fields.instance.repository.pushTestMergeCommits.desc": "This will push commits created by test merges to a temporary branch on the remote. Requires access credentials.", - "fields.instance.repository.ref": "Remote reference (branch)", - "fields.instance.repository.reference": "Reference", - "fields.instance.repository.reference.desc": "Set this to the branch, commit or tag you wish to track", - "fields.instance.repository.showTestMergeCommitters": "Show test merge commiters in public metadata", - "fields.instance.repository.showTestMergeCommitters.desc": "Shows who test merged a PR. This only applies to future commits.", - "fields.instance.repository.updateSubmodules": "Update submodules automatically", - "fields.instance.repository.updateSubmodules.desc": "Submodules will be updated automatically when resetting, checking out or adding a test merge. This is not recursive", - "fields.instance.repository.url": "Remote URL", - "fields.instance.watchdog.additionalparams": "Additional command line parameters", - "fields.instance.watchdog.allowwebclient": "Allow BYOND web client connections", - "fields.instance.watchdog.autostart": "Start server with instance", - "fields.instance.watchdog.autostartprofiler": "Start BYOND profiler automatically", - "fields.instance.watchdog.broadcast": "Broadcast Message", - "fields.instance.watchdog.broadcast.desc": "A message to broadcast to players using the DMAPI. Requires the server be running with an interop version >=5.7.0", - "fields.instance.watchdog.dumpOnHealthCheckRestart": "Create process dump on health check fail restart", - "fields.instance.watchdog.healthcheck": "Health Check Timeout (seconds)", - "fields.instance.watchdog.logoutput": "Log Game Server Output", - "fields.instance.watchdog.mapthreads": "Map Threads Count (0 for default)", - "fields.instance.watchdog.minidumps": "Use minidumps instead of full core dumps", - "fields.instance.watchdog.od_topic_port": "OpenDream Topic Port", - "fields.instance.watchdog.od_topic_port.desc": "Port used to receive world Topic called when launching deployments with the OpenDream engine", - "fields.instance.watchdog.port": "Network port", - "fields.instance.watchdog.securitylevel": "BYOND security level", - "fields.instance.watchdog.securitylevel.Safe": "Safe", - "fields.instance.watchdog.securitylevel.Trusted": "Trusted", - "fields.instance.watchdog.securitylevel.Ultrasafe": "Ultra-Safe", - "fields.instance.watchdog.timeout.startup": "Startup timeout (seconds)", - "fields.instance.watchdog.timeout.topic": "Topic timeout (milliseconds)", - "fields.instance.watchdog.visibility": "BYOND hub visibility", - "fields.instance.watchdog.visibility.Invisible": "Invisible", - "fields.instance.watchdog.visibility.Private": "Private", - "fields.instance.watchdog.visibility.Public": "Public", - "generic.access": "Access", - "generic.accessdenied": "This user does not have access to this page.", - "generic.action": "Action", - "generic.appname": "tgstation-server", - "generic.areyousure": "Are you sure?", - "generic.assert.noinstance": "No instance. Perhaps an error occured.", - "generic.assert.nopermissionset": "No permission set. Perhaps an error occured.", - "generic.assert.nouser": "No user. Perhaps an error occured.", - "generic.cancel": "Cancel", - "generic.clone": "Clone", - "generic.close": "Close", - "generic.commit": "Commit", - "generic.configmode": "Configuration Mode", - "generic.continue": "Continue", - "generic.created": "Created", - "generic.createdby": "Created By", - "generic.datetime": "Date/Time", - "generic.debugwarn": "Be careful to censor out any credentials or tokens when copying errors!", - "generic.details": "Details", - "generic.disable": "Disable", - "generic.disabled": "Disabled", - "generic.download": "Download", - "generic.downloaded": "Downloaded \"{file}\"", - "generic.downloading": "Downloading \"{file}\"...", - "generic.edit": "Edit", - "generic.enable": "Enable", - "generic.enabled": "Enabled", - "generic.entry": "Entry", - "generic.errordetails": "Error Details ({info})", - "generic.false": "False", - "generic.goback": "Go Back", - "generic.goto": "Goto", - "generic.goto.title": "Go to page", - "generic.group": "Group", - "generic.grouped": "Grouped", - "generic.groupid": "Group ID {id}", - "generic.info": "Info", - "generic.instance": "Instance", - "generic.invalid_form": "This form contains invalid values!", - "generic.latest": "Latest", - "generic.name": "Name", - "generic.no_perm": "You do not have the permission to do this", - "generic.not_applicable": "N/A", - "generic.numusers": "{count} Users", - "generic.offline": "Offline", - "generic.online": "Online", - "generic.path": "Path", - "generic.persist": "Persist", - "generic.readonly": "(Read-Only)", - "generic.reset": "Reset", - "generic.save": "Save", - "generic.saveall": "Save All", - "generic.savetab": "Save Tab", - "generic.select": "Select", - "generic.setall": "Set all", - "generic.system.short": "SYSTEM", - "generic.systemidentifier": "System Identifier", - "generic.testmerged": "Testmerged", - "generic.tgs": "TGS", - "generic.true": "True", - "generic.userid": "User ID ", - "generic.view": "View", - "generic.wip": "Work In Progress!", - "generic.wip.desc": "The TGS webpanel is still a work in progress. The feature you are trying to use is not yet available. Until it becomes available, please use the TGS desktop client at ", - "loading.admin": "Loading admin info...", - "loading.app": "Loading app...", - "loading.byond": "Loading BYOND Version Information...", - "loading.chat": "Loading Chat Bots...", - "loading.compile_jobs": "Loading Compile Jobs...", - "loading.deployments": "Loading DreamMaker Settings...", - "loading.info": "Loading Information...", - "loading.instance": "Loading instance...", - "loading.instance.files": "Performing file operation...", - "loading.instance.jobs.list": "Loading job list...", - "loading.instance.list": "Loading instance list...", - "loading.instance.move": "Relocating instance...", - "loading.instance.perms": "Loading Instance Permissions...", - "loading.instance.server": "Loading watchdog information...", - "loading.loading": "Loading...", - "loading.login": "Logging in...", - "loading.logs": "Loading Log(s)...", - "loading.page": "Loading page: ", - "loading.page.notfound": "Loading page: NotFound", - "loading.passwd": "Changing password...", - "loading.perms": "Updating permissions...", - "loading.repo.busy": "The repository is currently busy...", - "loading.repo.cloning": "Cloning repository...", - "loading.repo.commits": "Loading Commits...", - "loading.repo.prs": "Loading PRs...", - "loading.routes": "Loading routes...", - "loading.serverinfo": "Loading Server Information...", - "loading.updating": "Updating server...", - "loading.user.create": "Creating user...", - "loading.user.load": "Loading user information...", - "loading.user.save": "Saving user information...", - "loading.userlist": "Loading user list...", - "loading.version": "Loading versions...", - "login.form.password": "Password", - "login.form.password.placeholder": "Password", - "login.form.submit": "Login", - "login.form.username": "Username", - "login.form.username.invalid.colon": "Usernames cannot contain ':' characters!", - "login.form.username.invalid.empty": "Username cannot be empty!", - "login.form.username.placeholder": "Enter username", - "login.header": "Login to Continue", - "login.oauth": "Sign in with {providerName}", - "login.oauth.provider.discord": "Discord", - "login.oauth.provider.github": "GitHub", - "login.oauth.provider.invision": "Invision Community", - "login.oauth.provider.keycloak": "Keycloak", - "login.oauth.provider.tgforums": "/tg/station 13 Forums", - "login.title": "Login", - "login.type.generic": "Password Login", - "login.type.oauth": "OAuth Login", - "navbar.home": "Home", - "navbar.logout": "Logout", - "navbar.purgecache": "Purge Client Cache", - "navbar.refresh": "Refresh", - "navbar.update": "Server Update Available", - "perms.admin": "Administration Permissions", - "perms.admin.changeversion": "Update TGS", - "perms.admin.changeversion.desc": "Abilty to update TGS to a newer version", - "perms.admin.downloadlogs": "Access TGS logs", - "perms.admin.downloadlogs.desc": "Ability to view and download all TGS logs", - "perms.admin.editownoauthconnections": "Edit own external identity providers", - "perms.admin.editownoauthconnections.desc": "Ability to edit their own identity providers(oauth)", - "perms.admin.editownpassword": "Change Own Password", - "perms.admin.editownpassword.desc": "Ability to change their own password", - "perms.admin.readusers": "View Users", - "perms.admin.readusers.desc": "Ability to view all users", - "perms.admin.restarthost": "Restart TGS", - "perms.admin.restarthost.desc": "Ability to restart TGS", - "perms.admin.uploadversion": "Upload Version .zip", - "perms.admin.uploadversion.desc": "Ability to update the server with an uploaded .zip update package.", - "perms.admin.writeusers": "Edit Users", - "perms.admin.writeusers.desc": "Ability to edit users, if View Users is granted, all users can be edited, otherwise, only the current user can be edited", - "perms.chatbots": "Chat Bots", - "perms.chatbots.create": "Create", - "perms.chatbots.create.desc": "Allows the creation of bew chat bots.", - "perms.chatbots.delete": "Delete", - "perms.chatbots.delete.desc": "Allows the deletion of chat bots.", - "perms.chatbots.read": "Read", - "perms.chatbots.read.desc": "Allows reading all chat bot information aside from their connection strings.", - "perms.chatbots.readconnectionstring": "Read Connection String", - "perms.chatbots.readconnectionstring.desc": "Allows reading the TGS connection string of chat bots. May contain sensitive data", - "perms.chatbots.writechannellimit": "Set Channel Limit", - "perms.chatbots.writechannellimit.desc": "Allows changing the channel limit of chat bots.", - "perms.chatbots.writechannels": "Set Channels", - "perms.chatbots.writechannels.desc": "Allows changing the channels chat bots are connected to.", - "perms.chatbots.writeconnectionstring": "Set Connection String", - "perms.chatbots.writeconnectionstring.desc": "Allows adjusting the TGS connection string of chat bots.", - "perms.chatbots.writeenabled": "Set Enabled", - "perms.chatbots.writeenabled.desc": "Allows activation and deactivation of chat bots.", - "perms.chatbots.writename": "Set Name", - "perms.chatbots.writename.desc": "Allows changing the name of chat bots.", - "perms.chatbots.writeprovider": "Set Provider", - "perms.chatbots.writeprovider.desc": "Allows changing the chat provider of chat bots.", - "perms.chatbots.writereconnectioninterval": "Set Reconnection Interval", - "perms.chatbots.writereconnectioninterval.desc": "Allows changing the interval at which chat bots that have lost connection to their providers will attempt to reconnect.", - "perms.configuration": "Files & Scripts", - "perms.configuration.delete": "Delete Directories", - "perms.configuration.delete.desc": "Allows deleting empty configuration directories where permitted.", - "perms.configuration.list": "Traverse Directories", - "perms.configuration.list.desc": "Allows listing the contents of configuration directories where permitted.", - "perms.configuration.read": "Read Files", - "perms.configuration.read.desc": "Allows downloading configuration files where permitted.", - "perms.configuration.write": "Modify Files", - "perms.configuration.write.desc": "Allows uploading, overwriting, and deleting configuration files where permitted.", - "perms.dreamdaemon": "Server", - "perms.dreamdaemon.broadcastmessage": "Send Broadcast Messages", - "perms.dreamdaemon.broadcastmessage.desc": "Allows sending arbitrary messages from TGS clients to the running game server for broadcasting to players.", - "perms.dreamdaemon.createdump": "Create Process Dump", - "perms.dreamdaemon.createdump.desc": "Allows creating dump files of the game server process while it is running.", - "perms.dreamdaemon.readmetadata": "Read Settings", - "perms.dreamdaemon.readmetadata.desc": "Allows reading the current game server settings.", - "perms.dreamdaemon.readrevision": "View Current Compile Jobs", - "perms.dreamdaemon.readrevision.desc": "Allows reading information about the latest and staged compile jobs.", - "perms.dreamdaemon.restart": "Hard Restart", - "perms.dreamdaemon.restart.desc": "Allows immediately restarting the game server process.", - "perms.dreamdaemon.setadditionalparameters": "Set Additional Parameters", - "perms.dreamdaemon.setadditionalparameters.desc": "Allows adding additional game server launch parameters (Not command line arguments).", - "perms.dreamdaemon.setautostart": "Set Autostart", - "perms.dreamdaemon.setautostart.desc": "Allows setting whether or not the game server will start automatically when the instance comes online.", - "perms.dreamdaemon.sethealthcheckinterval": "Set Health Check Interval", - "perms.dreamdaemon.sethealthcheckinterval.desc": "Allows changing the interval at which health check Topics are sent.", - "perms.dreamdaemon.setlogoutput": "Set Game Server Output Logging", - "perms.dreamdaemon.setlogoutput.desc": "Allows setting whether or not the game server will log it's output to the Diagnostics folder.", - "perms.dreamdaemon.setmapthreads": "Set Map Threads", - "perms.dreamdaemon.setmapthreads.desc": "Allows setting the `-map-threads` command line option.", - "perms.dreamdaemon.setminidumps": "Change Core Dump Type", - "perms.dreamdaemon.setminidumps.desc": "Allows switching between creating minidumps and full core dumps.", - "perms.dreamdaemon.setport": "Set Game Port", - "perms.dreamdaemon.setport.desc": "Allows setting the port the game server listens on.", - "perms.dreamdaemon.setprofiler": "Set Profiler", - "perms.dreamdaemon.setprofiler.desc": "Allows setting the `-profile` command line option.", - "perms.dreamdaemon.setsecurity": "Set Security Level", - "perms.dreamdaemon.setsecurity.desc": "Allows setting the BYOND security level to run the game at (Note: a higher DMAPI setting stored in a compile job can override this).", - "perms.dreamdaemon.setstartuptimeout": "Set Startup Timeout", - "perms.dreamdaemon.setstartuptimeout.desc": "Allows changing the idle/DMAPI detection timeout for starting new servers before it's considered a failure. This also applies to game server instances used during deployments.", - "perms.dreamdaemon.settopictimeout": "Set Topic Timeout", - "perms.dreamdaemon.settopictimeout.desc": "Allows setting the timeout interval for sending Topics to the server before being considered a failure.", - "perms.dreamdaemon.setvisibility": "Set Visibility", - "perms.dreamdaemon.setvisibility.desc": "Allows changing the game server visibility setting.", - "perms.dreamdaemon.setwebclient": "Set Webclient", - "perms.dreamdaemon.setwebclient.desc": "Allows enabling/disabling use of the BYOND webclient.", - "perms.dreamdaemon.shutdown": "Hard Shutdown", - "perms.dreamdaemon.shutdown.desc": "Allows immediately terminating the game server process.", - "perms.dreamdaemon.softrestart": "Graceful Restart", - "perms.dreamdaemon.softrestart.desc": "Allows requesting the server is gracefully restarted (Process restart on world.Reboot()).", - "perms.dreamdaemon.softshutdown": "Graceful Shutdown", - "perms.dreamdaemon.softshutdown.desc": "Allows requesting the server is gracefully shutdown (Process terminiation on world.Reboot()).", - "perms.dreamdaemon.start": "Server Launch", - "perms.dreamdaemon.start.desc": "Allows launching the game server from a shutdown state.", - "perms.dreammaker": "Deployment", - "perms.dreammaker.cancelcompile": "Cancel Deployment", - "perms.dreammaker.cancelcompile.desc": "Allows cancelling deployment jobs.", - "perms.dreammaker.compile": "Create Deployment", - "perms.dreammaker.compile.desc": "Allows starting new deployment jobs.", - "perms.dreammaker.compilejobs": "Read Compile Jobs", - "perms.dreammaker.compilejobs.desc": "Allows reading information about the current and past deployments.", - "perms.dreammaker.read": "Read Deployment Settings", - "perms.dreammaker.read.desc": "Allows reading information about the deployment settings.", - "perms.dreammaker.setapivalidationport": "Set Validation Port", - "perms.dreammaker.setapivalidationport.desc": "Allows changing the port used by the game server to check for the presence of the DMAPI while deploying.", - "perms.dreammaker.setapivalidationrequirement": "Set Validation Requirement", - "perms.dreammaker.setapivalidationrequirement.desc": "Allows setting whether or not the DMAPI is required for successful deployments.", - "perms.dreammaker.setcompilerarguments": "Set Additional Compiler Arguments", - "perms.dreammaker.setcompilerarguments.desc": "Allows setting additional compiler arguments to be passed on the command line.", - "perms.dreammaker.setdme": "Set .dme Path", - "perms.dreammaker.setdme.desc": "Allows overriding TGS' automatic .dme detection in favor of using a different .dme.", - "perms.dreammaker.setsecuritylevel": "Set Validation Security Level", - "perms.dreammaker.setsecuritylevel.desc": "Allows changing the BYOND security level used to validate the DMAPI.", - "perms.dreammaker.settimeout": "Set Deployment Timeout", - "perms.dreammaker.settimeout.desc": "Allows setting the amount of time allowed to pass before a deployment job is automatically cancelled.", - "perms.engine": "Engine", - "perms.engine.cancelinstall": "Cancel Install Job", - "perms.engine.cancelinstall.desc": "Allows cancelling install jobs.", - "perms.engine.deleteinstall": "Delete Engine Version", - "perms.engine.installcustombyondversion": "Install Custom BYOND Version", - "perms.engine.installcustombyondversion.desc": "Allows installing a BYOND version uploaded from a zip file.", - "perms.engine.installcustomopendreamversion": "Install Custom OpenDream Version", - "perms.engine.installcustomopendreamversion.desc": "Allows installing an OpenDream version uploaded from a zip file.", - "perms.engine.installofficialorchangeactivebyondversion": "Activate/Install BYOND Version", - "perms.engine.installofficialorchangeactivebyondversion.desc": "Allows installation and activation of BYOND versions downloaded from the official website. Pre-installed custom versions may also be activated", - "perms.engine.installofficialorchangeactiveopendreamversion": "Activate/Install OpenDream Version", - "perms.engine.installofficialorchangeactiveopendreamversion.desc": "Allows installation and activation of OpenDream versions downloaded from the configured git. Pre-installed custom versions may also be activated", - "perms.engine.listinstalled": "List Installed Versions", - "perms.engine.listinstalled.desc": "Allows reading all installed engine versions.", - "perms.engine.readactive": "Read Active Version", - "perms.engine.readactive.desc": "Allows reading the active engine version.", - "perms.group": "Group", - "perms.group.cantlist": "You lack the permission to list all users. You need it to be able to list all groups", - "perms.group.create": "Create Group", - "perms.group.current": "Current Group: ", - "perms.group.delete.tooltip": "This group contains more than 0 users. Remove all users before deleting the group.", - "perms.group.none": "No group", - "perms.group.rename.tooltip": "Rename", - "perms.group.warning": "This user is linked to the \"{group}\" group. Any change to the permissions will be applied to the group.", - "perms.instance": "Instance Manager Permissions", - "perms.instance.create": "Create Instances", - "perms.instance.create.desc": "Ability to create new instances", - "perms.instance.create.warning": "The current user is not permitted to create instances", - "perms.instance.delete": "Delete Instance", - "perms.instance.delete.desc": "Ablity to delete an instance", - "perms.instance.grantpermissions": "Grant All Permissions", - "perms.instance.grantpermissions.desc": "Ability to grant themselves all permissions on any instance", - "perms.instance.list": "Read All Instances", - "perms.instance.list.desc": "Ability to list and view all instances", - "perms.instance.read": "Read Accessible Instances", - "perms.instance.read.desc": "Ability to list and view instances the user is allowed access to. WARNING: Users who know the instance ID can still use the API to edit it using other permissions even if they lack this one.", - "perms.instance.relocate": "Relocate Instances", - "perms.instance.relocate.desc": "Ablity to change the location of an instance on the file system", - "perms.instance.rename": "Rename Instances", - "perms.instance.rename.desc": "Ability to rename instances", - "perms.instance.setautoupdate": "Set Instance Autoupdate Interval", - "perms.instance.setautoupdate.desc": "Ability to set an instance's interval for automatic code updates", - "perms.instance.setchatbotlimit": "Set Instance Chatbot Limit", - "perms.instance.setchatbotlimit.desc": "Ability to change an instance's maximum amounts of bots", - "perms.instance.setconfiguration": "Set Instance Configuration Mode", - "perms.instance.setconfiguration.desc": "Ability to set an instance's static file editing mode", - "perms.instance.setonline": "Change Instance Online Status", - "perms.instance.setonline.desc": "Ability to set an instance as online or offline", - "perms.instancepermissionset": "Instance Admin", - "perms.instancepermissionset.cantedit": "You require the \"Write\" instance permission set flag to change these values", - "perms.instancepermissionset.create": "Create new Instance Permission Sets", - "perms.instancepermissionset.create.desc": "Allows you to grant access to this instance to other TGS users/groups.", - "perms.instancepermissionset.read": "Read Instance Permission Sets", - "perms.instancepermissionset.read.desc": "Allows you to read the permissions in this instance of other TGS users/groups already registered.", - "perms.instancepermissionset.write": "Write Instance Permission Sets", - "perms.instancepermissionset.write.desc": "Allows you to change or delete the permissions in this instance of both you and other TGS users/groups already registered.", - "perms.repository": "Repository", - "perms.repository.cancelclone": "Cancel Clone", - "perms.repository.cancelclone.desc": "Allows cancelling active repository clone jobs.", - "perms.repository.cancelpendingchanges": "Cancel Pending Changes", - "perms.repository.cancelpendingchanges.desc": "Allows cancelling active repository jobs (Except clone jobs).", - "perms.repository.changeautoupdatesettings": "Change Auto Update Test Merge Settings", - "perms.repository.changeautoupdatesettings.desc": "Allows changing the setting to preserve test merges while updating a branch or synchronize with the remote.", - "perms.repository.changecommitter": "Change Committer", - "perms.repository.changecommitter.desc": "Allows changing the username git commits are written as.", - "perms.repository.changecredentials": "Change Credentials", - "perms.repository.changecredentials.desc": "Allows changing the credentials used to access the repository.", - "perms.repository.changesubmoduleupdate": "Change Submodule Update", - "perms.repository.changesubmoduleupdate.desc": "Allows changing the setting to update submodules with branches.", - "perms.repository.changetestmergecommits": "Change Remote Test Merge Settings", - "perms.repository.changetestmergecommits.desc": "Allows enabling/disabling the settings for pushing test merge commits to the remote in a temporary branch, posting comments when test merges occur, and creating GitHub deployments.", - "perms.repository.delete": "Delete Repository", - "perms.repository.delete.desc": "Allows deleting the cloned repository from disk in order to clone another one.", - "perms.repository.mergepullrequest": "Create Test Merge", - "perms.repository.mergepullrequest.desc": "Allows test merging a commit request from the remote.", - "perms.repository.read": "Read Status Information", - "perms.repository.read.desc": "Allows reading repository status information (HEAD/Committer/Active Test Merges/etc...).", - "perms.repository.reclone": "Reclone Repository", - "perms.repository.reclone.desc": "Allows deletion and subsequent recloning of repository.", - "perms.repository.setorigin": "Clone Repository", - "perms.repository.setorigin.desc": "Allows cloning the repository from a remote if it doesn't exist.", - "perms.repository.setreference": "Checkout Branch/Tag", - "perms.repository.setreference.desc": "Allows checking out a specific branch/tag by it's name.", - "perms.repository.setsha": "Checkout SHA", - "perms.repository.setsha.desc": "Allows checking out a specific commit by it's SHA.", - "perms.repository.updatebranch": "Update Branch", - "perms.repository.updatebranch.desc": "Allows hard reset and merge updates to the repository's current branch.", - "routes.admin": "Administration", - "routes.admin.logs": "TGS Logs", - "routes.admin.update": "TGS Update", - "routes.config": "Webpanel Config", - "routes.home": "Home", - "routes.info": "Info", - "routes.instancecreate": "Add New Instance", - "routes.instanceedit": "Edit Instance", - "routes.instancejobs": "Jobs", - "routes.instancelist": "Instances", - "routes.login": "Log In", - "routes.passwd": "Change Password", - "routes.setup": "PostInstall Setup", - "routes.user_manager": "User Manager", - "routes.usercreate": "Create User", - "routes.useredit": "User Editor", - "routes.usermanager": "Users", - "title": "TGS Webpanel v{version}", + "config.apipath": "TGS API Path", + "config.apipath.desc": "Sets the API client server's path.", + "config.githubtoken": "Github Token", + "config.githubtoken.desc": "You can supply a private authorization token for github to bypass some rate limiting on the github API.", + "config.instanceeditsidebar": "Instance Edit Sidebar", + "config.instanceeditsidebar.desc": "This controls how the left sidebar menu acts in the instance edit page.", + "config.instanceeditsidebar.enum.auto": "Expand on hover", + "config.instanceeditsidebar.enum.collapse": "Always collapsed", + "config.instanceeditsidebar.enum.expand": "Always expanded", + "config.instanceprobetimer": "Instance permission poll delay", + "config.instanceprobetimer.desc": "After how many seconds should we update the list of instances", + "config.itemsperpage": "Items Per Page", + "config.itemsperpage.desc": "This allows you to configure the amount of items shown at once in lists. Note that not all lists support this option yet.", + "config.jobpollactive": "Active job poll delay (s)", + "config.jobpollactive.desc": "After how many seconds should we check for new jobs if we know about a job", + "config.jobpollinactive": "Inactive job poll delay (s)", + "config.jobpollinactive.desc": "After how many seconds should we check for new jobs if we dont have any active jobs", + "config.jobswidgetdisplay": "Jobs Widget Display", + "config.jobswidgetdisplay.desc": "Display mode for the instance jobs widget", + "config.jobswidgetdisplay.enum.always": "Always display", + "config.jobswidgetdisplay.enum.auto": "Display when there are jobs", + "config.jobswidgetdisplay.enum.never": "Never display", + "config.manualpr": "Show manual PR entry on repository page", + "config.manualpr.desc": "Controls whether or not an input box is displayed to manually testmerge a pr based on its PR number. This option is ignored and the manual PR entry box is always displayed when using a repository hosted on GitLab.", + "config.manualreset": "Show force reset switch on repository page", + "config.manualreset.desc": "Controls whether or not an input box is displayed to force a repository reset. This option is ignored and the manual PR entry box is always displayed when using a repository hosted on GitLab.", + "config.restjobs2": "Force HTTP Polling for Job Updates", + "config.restjobs2.desc": "Workaround for if SignalR job updates are failing", + "config.showjson": "Show JSON objects", + "config.showjson.desc": "Most pages will display the underlying json data if enabled.", + "config.theme": "Theming", + "config.theme.desc": "Set dark mode explicitly or to match your system", + "error.admin.error": "The server has ran into an error while using github's API.", + "error.admin.logs.io": "An IO error occured while processing logs", + "error.admin.rate": "The server has exceeded github's rate limiting. Please try again later.", + "error.admin.update.notfound": "This TGS version does not seem to exist.", + "error.admin.watchdog.avail": "This operation is unavailable due to the launch configuration of TGS.", + "error.api.empty": "No description available", + "error.app": "An error occured in the application", + "error.app.default_creds": "You are using the default TGS credentials. Please click 'Change Password' at earliest convenience!", + "error.app.undefined": "A \"Ghost\" error occured in the application", + "error.axios": "Axios error", + "error.bad_channels_json": "Malformed channels JSON.", + "error.bad_hub_connection": "Lost connection to the SignalR hub.", + "error.bad_tgs_yml_version": "Incorrect .tgs.yml version. Only version 1 is supported.", + "error.bad_yml": "Malformed .yml.", + "error.compile_job_not_found": "Compile job not found.", + "error.errorMessage": "Message:\n{message}\nAdditional Data:\n{additionalData}", + "error.github": "An error occured while interacting with the Github API", + "error.githubtokenmissing": "This GitHub component cannot be loaded because you have not configured a GitHub personal access token in your webpanel settings", + "error.group.not_empty": "The requested group cannot be deleted as it contains users.", + "error.group.not_found": "The requested group cannot be found.", + "error.http.access_denied": "Access denied", + "error.http.access_denied.desc": "Access to this resource is denied", + "error.http.api_mismatch": "API version mismatch", + "error.http.bad_request": "Bad Request", + "error.http.data_integrity": "A data integrity check failed while performing the operation", + "error.http.not_acceptable": "BUG: The server has found the request to be unacceptable.", + "error.http.server_error": "BUG: Server error", + "error.http.server_not_ready": "The server is still starting/stoping!", + "error.http.unimplemented": "This feature is unimplemented.", + "error.job.complete": "Unable to delete the job, perhaps it already completed", + "error.job.not_found": "The specified job could not be found", + "error.login.bad_oauth": "An error occurred while logging in using OAuth", + "error.login.bad_user_pass": "Invalid credentials!", + "error.login.bad_user_pass.desc": "Invalid credentials!", + "error.login.no_creds": "Attempted to login without any credentials", + "error.login.no_creds.desc": "Attempted to login without any credentials", + "error.login.rate_limit": "Failed to login using external provider due to rate limiting. Please try again later", + "error.login.user_disabled": "This user account is disabled", + "error.login.user_disabled.desc": "This user account is disabled", + "error.no_apipath": "No API path set, set an API path on the configuration page.", + "error.no_db_entity": "The database entity for the requested instance could not be retrieved. The instance was likely detached", + "error.no_engine_version": "The target engine version does not exist on the server.", + "error.notfound": "This page has not been found!", + "error.pleasereport": "Oopsie woopsie! Please report this using the \"Report Issue\" button in the bottom left of the page", + "error.routemissingpermissions": "This view cannot be accessed because your TGS account has insufficient permissions", + "error.somethingwentwrong": "Uh oh.... Something went wrong!", + "error.tgsnetworkerror": "An error occured communicating with tgstation-server. Is it running and are you connected?", + "error.transfer.not_available": "Unable to transfer file as it is no longer or never was valid", + "error.transfer.upload_failed": "An error occured while uploading a file", + "error.unhandled_global_response": "The application received an unexpected global response", + "error.unhandled_global_response.desc": "The application received an unexpected global response", + "error.unhandled_response": "The application received an unexpected response", + "error.unhandled_response.desc": "The application received an unexpected response", + "error.user.no_sys_ident": "This system user was not found", + "error.user.no_sys_ident.desc": "This system user was not found", + "error.user.not_found": "This TGS user was not found", + "error.user.not_found.desc": "This TGS user was not found", + "error.withoutstacktrace": "Webpanel Version: {version}\nNo stack trace!", + "error.withstacktrace": "Webpanel Version: {version}\nStack trace:{stackTrace}", + "fields.instance.autoupdate": "Auto-update Interval in minutes (0 to disable)", + "fields.instance.autoupdate.tip": "Interval begins when previous update completes or immediately upon setting.", + "fields.instance.chat.channel.admin": "Admin Channel", + "fields.instance.chat.channel.admin.tip": "This channel can be used to receive messages and issue TGS chat commands designated as admin only", + "fields.instance.chat.channel.discord": "Channel ID", + "fields.instance.chat.channel.discord.tip": "Right click a channel with developer mode enabled to see the option to copy its ID", + "fields.instance.chat.channel.irc": "IRC Channel", + "fields.instance.chat.channel.irc.tip": "Include the '#'", + "fields.instance.chat.channel.system": "System Channel", + "fields.instance.chat.channel.system.tip": "This channel will receive TGS system messages (Restarts and updates)", + "fields.instance.chat.channel.tag": "DMAPI Tag", + "fields.instance.chat.channel.tag.tip": "A string associated with this channel in the DMAPI", + "fields.instance.chat.channel.updates": "Deployments Channel", + "fields.instance.chat.channel.updates.tip": "This channel will receive TGS deployment messages", + "fields.instance.chat.channel.watchdog": "Watchdog Channel", + "fields.instance.chat.channel.watchdog.tip": "This channel will receive live updates as to the state of the active game server process", + "fields.instance.chat.create.channel": "Add Channel", + "fields.instance.chat.create.discord.based.tip": "Know your meme", + "fields.instance.chat.create.discord.branding": "Deployment Embed Branding", + "fields.instance.chat.create.discord.branding.tip": "If the tgstation-server logo, name, and link to repo are shown at the top of deployment embeds", + "fields.instance.chat.create.discord.output": "Show Deployment Messages", + "fields.instance.chat.create.discord.output.tip": "When messages from deployment jobs will be shown in Watchdog-type channels", + "fields.instance.chat.create.discord.token": "Bot Token", + "fields.instance.chat.create.discord.token.tip": "Bot access token retrieved from Discord developers portal", + "fields.instance.chat.create.irc.address": "Server Address", + "fields.instance.chat.create.irc.address.tip": "IP/Domain only", + "fields.instance.chat.create.irc.nick": "Bot Nickname", + "fields.instance.chat.create.irc.pass": "Server Password", + "fields.instance.chat.create.irc.pass.tip": "Setting a password on the server for your IRC bot is HIGHLY recommended", + "fields.instance.chat.create.irc.passtype": "Server Password Type", + "fields.instance.chat.create.irc.port": "Server Port", + "fields.instance.chat.create.irc.ssl": "Connect with SSL", + "fields.instance.chat.create.irc.ssl.tip": "Note: This is dependent on the IRC server's configuration", + "fields.instance.chat.create.save": "Create Chat Bot", + "fields.instance.chat.edit.connection": "Connection String", + "fields.instance.chat.edit.connection.deny": "Lacking read permission. Edit may still available", + "fields.instance.chat.edit.connection.tip": "Contains sensitive information. Consider remaking the bot instead of modifying this due to the internal formatting", + "fields.instance.chat.edit.connection.unloaded": "Not Loaded. Edit available", + "fields.instance.chat.enabled": "Enabled", + "fields.instance.chat.enabled.tip": "If the bot is to be online with the instance", + "fields.instance.chat.limit": "Channel Limit", + "fields.instance.chat.limit.tip": "Maximum number of channels this bot can interact with", + "fields.instance.chat.name": "Chat Bot Name", + "fields.instance.chat.name.tip": "Internal name of the chat bot", + "fields.instance.chat.provider": "Chat Service Provider", + "fields.instance.chat.reconnect": "Reconnection Interval (Minutes)", + "fields.instance.chat.reconnect.tip": "The period at which the bot will attempt to reconnect to the chat service if unexpectedly disconnected", + "fields.instance.chatbotlimit": "Max chatbots", + "fields.instance.cron": "Auto-update cron schedule (6-part, UTC, 0 to disable)", + "fields.instance.deploy.apiport": "DMAPI port (0 for auto)", + "fields.instance.deploy.apiport.desc": "This port should not be public", + "fields.instance.deploy.compilerargs": "Additional Compiler Arguments", + "fields.instance.deploy.compilerargs.desc": "These are added to compiler command lines right before the path to the .dme", + "fields.instance.deploy.projectname": "DME name (blank for auto)", + "fields.instance.deploy.projectname.desc": "This can also be a relative path and shouldn't include the file extension", + "fields.instance.deploy.seclevel": "DMAPI validation security level", + "fields.instance.deploy.seclevel.Safe": "Safe", + "fields.instance.deploy.seclevel.Trusted": "Trusted", + "fields.instance.deploy.seclevel.Ultrasafe": "Ultra-Safe", + "fields.instance.deploy.seclevel.desc": "This is only used for the DMAPI validation", + "fields.instance.deploy.timeout": "Job timeout (in minutes)", + "fields.instance.deploy.timeout.desc": "Time before a compile job is abandonned and cancelled", + "fields.instance.deploy.validateapi": "DMAPI Validation Mode", + "fields.instance.deploy.validateapi.Optional": "Attempt but do not require validation", + "fields.instance.deploy.validateapi.Required": "Require validation to succeed for the deployment to succeed", + "fields.instance.deploy.validateapi.Skipped": "Skip validation disabling all DMAPI features", + "fields.instance.deploy.validateapi.desc": " DMAPI validation check that the DMAPI initializes successfully without any runtimes.", + "fields.instance.filemode": "Static File Edit Mode", + "fields.instance.filemode.Disallowed": "No File Management.", + "fields.instance.filemode.HostWrite": "Authorized users can edit any file.", + "fields.instance.filemode.SystemIdentityWrite": "Users using a system identity can edit files their user has access to.", + "fields.instance.files.create": "Create Directory or Upload File", + "fields.instance.files.create.directory": "Create directory instead of file", + "fields.instance.files.create.name": "File system entry name", + "fields.instance.files.create.name.tip": "The name of the file or directory being created (extension included for files)", + "fields.instance.name": "Instance Name", + "fields.instance.path": "Path on disk", + "fields.instance.perms.owner": "Editing Instance Permissions For", + "fields.instance.perms.owner.switch": "Switch", + "fields.instance.repository.accessToken": "New Access Password", + "fields.instance.repository.accessToken.desc": "For github, this will be a PAT(Private Authentication Token), for other providers, this will be a password", + "fields.instance.repository.accessUser": "Access Username", + "fields.instance.repository.accessUser.desc": "These credentials will be used when cloning the repository or performing authenticated actions", + "fields.instance.repository.autoUpdatesKeepTestMerges": "Preserve test merges when auto updating", + "fields.instance.repository.autoUpdatesKeepTestMerges.desc": "If enabled, auto updates may fail if a merge conflict occurs.", + "fields.instance.repository.autoUpdatesSynchronize": "Push new commits to origin during auto-update", + "fields.instance.repository.autoUpdatesSynchronize.desc": "Used for example, with changelog scripts depending on the setup", + "fields.instance.repository.checkoutsha": "Checkout SHA", + "fields.instance.repository.checkoutsha.desc": "SHA of the commit to checkout", + "fields.instance.repository.clearAccessToken": "Clear Access Credentials", + "fields.instance.repository.committerEmail": "Committer Email", + "fields.instance.repository.committerName": "Committer Name", + "fields.instance.repository.createGitHubDeployments": "Create GitHub Deployments", + "fields.instance.repository.createGitHubDeployments.desc": "Requires access credentials", + "fields.instance.repository.creds.mode": "Credential Type", + "fields.instance.repository.creds.mode.None": "Clear Credentials", + "fields.instance.repository.creds.mode.Password": "Username/Password (INSECURE)", + "fields.instance.repository.creds.mode.Password.password": "Password", + "fields.instance.repository.creds.mode.Password.password.desc": "Account password", + "fields.instance.repository.creds.mode.Password.username": "Username", + "fields.instance.repository.creds.mode.Password.username.desc": "Account username", + "fields.instance.repository.creds.mode.PrivateKey": "GitHub App (Recommended)", + "fields.instance.repository.creds.mode.PrivateKey.id": "Client ID or App ID", + "fields.instance.repository.creds.mode.PrivateKey.id.desc": "GitHub recommends using the client ID", + "fields.instance.repository.creds.mode.PrivateKey.pk": "App Private Key", + "fields.instance.repository.creds.mode.PrivateKey.pk.desc": "The contents of a .pem file generated on the app control panel", + "fields.instance.repository.creds.mode.PrivateKey.username": "GitHub App Name", + "fields.instance.repository.creds.mode.PrivateKey.username.desc": "The name of the GitHub App", + "fields.instance.repository.creds.mode.Token": "Access Token", + "fields.instance.repository.creds.mode.Token.token": "Personal Access Token", + "fields.instance.repository.creds.mode.Token.token.desc": "Generated personal access token", + "fields.instance.repository.creds.mode.Token.username": "Username", + "fields.instance.repository.creds.mode.Token.username.desc": "Username of the account for the token", + "fields.instance.repository.creds.mode.desc": "The type of credential to use", + "fields.instance.repository.enablesubmodules": "Enable submodules", + "fields.instance.repository.gitpassword": "Git access password", + "fields.instance.repository.gituser": "Git access username", + "fields.instance.repository.origincheckoutsha": "Origin SHA", + "fields.instance.repository.origincheckoutsha.desc": "SHA of the origin commit", + "fields.instance.repository.postTestMergeComment": "Post comment when test merge is deployed", + "fields.instance.repository.postTestMergeComment.desc": "This will post a github comment each time a test merge is deployed or updated", + "fields.instance.repository.pushTestMergeCommits": "Push Test Merge Commits", + "fields.instance.repository.pushTestMergeCommits.desc": "This will push commits created by test merges to a temporary branch on the remote. Requires access credentials.", + "fields.instance.repository.ref": "Remote reference (branch)", + "fields.instance.repository.reference": "Reference", + "fields.instance.repository.reference.desc": "Set this to the branch, commit or tag you wish to track", + "fields.instance.repository.showTestMergeCommitters": "Show test merge commiters in public metadata", + "fields.instance.repository.showTestMergeCommitters.desc": "Shows who test merged a PR. This only applies to future commits.", + "fields.instance.repository.updateSubmodules": "Update submodules automatically", + "fields.instance.repository.updateSubmodules.desc": "Submodules will be updated automatically when resetting, checking out or adding a test merge. This is not recursive", + "fields.instance.repository.url": "Remote URL", + "fields.instance.watchdog.additionalparams": "Additional command line parameters", + "fields.instance.watchdog.allowwebclient": "Allow BYOND web client connections", + "fields.instance.watchdog.autostart": "Start server with instance", + "fields.instance.watchdog.autostartprofiler": "Start BYOND profiler automatically", + "fields.instance.watchdog.broadcast": "Broadcast Message", + "fields.instance.watchdog.broadcast.desc": "A message to broadcast to players using the DMAPI. Requires the server be running with an interop version >=5.7.0", + "fields.instance.watchdog.dumpOnHealthCheckRestart": "Create process dump on health check fail restart", + "fields.instance.watchdog.healthcheck": "Health Check Timeout (seconds)", + "fields.instance.watchdog.logoutput": "Log Game Server Output", + "fields.instance.watchdog.mapthreads": "Map Threads Count (0 for default)", + "fields.instance.watchdog.minidumps": "Use minidumps instead of full core dumps", + "fields.instance.watchdog.od_topic_port": "OpenDream Topic Port", + "fields.instance.watchdog.od_topic_port.desc": "Port used to receive world Topic called when launching deployments with the OpenDream engine", + "fields.instance.watchdog.port": "Network port", + "fields.instance.watchdog.securitylevel": "BYOND security level", + "fields.instance.watchdog.securitylevel.Safe": "Safe", + "fields.instance.watchdog.securitylevel.Trusted": "Trusted", + "fields.instance.watchdog.securitylevel.Ultrasafe": "Ultra-Safe", + "fields.instance.watchdog.timeout.startup": "Startup timeout (seconds)", + "fields.instance.watchdog.timeout.topic": "Topic timeout (milliseconds)", + "fields.instance.watchdog.visibility": "BYOND hub visibility", + "fields.instance.watchdog.visibility.Invisible": "Invisible", + "fields.instance.watchdog.visibility.Private": "Private", + "fields.instance.watchdog.visibility.Public": "Public", + "generic.access": "Access", + "generic.accessdenied": "This user does not have access to this page.", + "generic.action": "Action", + "generic.appname": "tgstation-server", + "generic.areyousure": "Are you sure?", + "generic.assert.noinstance": "No instance. Perhaps an error occured.", + "generic.assert.nopermissionset": "No permission set. Perhaps an error occured.", + "generic.assert.nouser": "No user. Perhaps an error occured.", + "generic.cancel": "Cancel", + "generic.clone": "Clone", + "generic.close": "Close", + "generic.commit": "Commit", + "generic.configmode": "Configuration Mode", + "generic.continue": "Continue", + "generic.created": "Created", + "generic.createdby": "Created By", + "generic.datetime": "Date/Time", + "generic.debugwarn": "Be careful to censor out any credentials or tokens when copying errors!", + "generic.details": "Details", + "generic.disable": "Disable", + "generic.disabled": "Disabled", + "generic.download": "Download", + "generic.downloaded": "Downloaded \"{file}\"", + "generic.downloading": "Downloading \"{file}\"...", + "generic.edit": "Edit", + "generic.enable": "Enable", + "generic.enabled": "Enabled", + "generic.entry": "Entry", + "generic.errordetails": "Error Details ({info})", + "generic.false": "False", + "generic.goback": "Go Back", + "generic.goto": "Goto", + "generic.goto.title": "Go to page", + "generic.group": "Group", + "generic.grouped": "Grouped", + "generic.groupid": "Group ID {id}", + "generic.info": "Info", + "generic.instance": "Instance", + "generic.invalid_form": "This form contains invalid values!", + "generic.latest": "Latest", + "generic.name": "Name", + "generic.no_perm": "You do not have the permission to do this", + "generic.not_applicable": "N/A", + "generic.numusers": "{count} Users", + "generic.offline": "Offline", + "generic.online": "Online", + "generic.path": "Path", + "generic.persist": "Persist", + "generic.readonly": "(Read-Only)", + "generic.reset": "Reset", + "generic.save": "Save", + "generic.saveall": "Save All", + "generic.savetab": "Save Tab", + "generic.select": "Select", + "generic.setall": "Set all", + "generic.system.short": "SYSTEM", + "generic.systemidentifier": "System Identifier", + "generic.testmerged": "Testmerged", + "generic.tgs": "TGS", + "generic.true": "True", + "generic.userid": "User ID ", + "generic.view": "View", + "generic.wip": "Work In Progress!", + "generic.wip.desc": "The TGS webpanel is still a work in progress. The feature you are trying to use is not yet available. Until it becomes available, please use the TGS desktop client at ", + "loading.admin": "Loading admin info...", + "loading.app": "Loading app...", + "loading.byond": "Loading BYOND Version Information...", + "loading.chat": "Loading Chat Bots...", + "loading.compile_jobs": "Loading Compile Jobs...", + "loading.deployments": "Loading DreamMaker Settings...", + "loading.info": "Loading Information...", + "loading.instance": "Loading instance...", + "loading.instance.files": "Performing file operation...", + "loading.instance.jobs.list": "Loading job list...", + "loading.instance.list": "Loading instance list...", + "loading.instance.move": "Relocating instance...", + "loading.instance.perms": "Loading Instance Permissions...", + "loading.instance.server": "Loading watchdog information...", + "loading.loading": "Loading...", + "loading.login": "Logging in...", + "loading.logs": "Loading Log(s)...", + "loading.page": "Loading page: ", + "loading.page.notfound": "Loading page: NotFound", + "loading.passwd": "Changing password...", + "loading.perms": "Updating permissions...", + "loading.repo.busy": "The repository is currently busy...", + "loading.repo.cloning": "Cloning repository...", + "loading.repo.commits": "Loading Commits...", + "loading.repo.prs": "Loading PRs...", + "loading.routes": "Loading routes...", + "loading.serverinfo": "Loading Server Information...", + "loading.updating": "Updating server...", + "loading.user.create": "Creating user...", + "loading.user.load": "Loading user information...", + "loading.user.save": "Saving user information...", + "loading.userlist": "Loading user list...", + "loading.version": "Loading versions...", + "login.form.password": "Password", + "login.form.password.placeholder": "Password", + "login.form.submit": "Login", + "login.form.username": "Username", + "login.form.username.invalid.colon": "Usernames cannot contain ':' characters!", + "login.form.username.invalid.empty": "Username cannot be empty!", + "login.form.username.placeholder": "Enter username", + "login.header": "Login to Continue", + "login.oauth": "Sign in with {providerName}", + "login.oauth.provider.discord": "Discord", + "login.oauth.provider.github": "GitHub", + "login.oauth.provider.invision": "Invision Community", + "login.oauth.provider.keycloak": "Keycloak", + "login.oauth.provider.tgforums": "/tg/station 13 Forums", + "login.title": "Login", + "login.type.generic": "Password Login", + "login.type.oauth": "OAuth Login", + "navbar.home": "Home", + "navbar.logout": "Logout", + "navbar.purgecache": "Purge Client Cache", + "navbar.refresh": "Refresh", + "navbar.update": "Server Update Available", + "perms.admin": "Administration Permissions", + "perms.admin.changeversion": "Update TGS", + "perms.admin.changeversion.desc": "Abilty to update TGS to a newer version", + "perms.admin.downloadlogs": "Access TGS logs", + "perms.admin.downloadlogs.desc": "Ability to view and download all TGS logs", + "perms.admin.editownoauthconnections": "Edit own external identity providers", + "perms.admin.editownoauthconnections.desc": "Ability to edit their own identity providers(oauth)", + "perms.admin.editownpassword": "Change Own Password", + "perms.admin.editownpassword.desc": "Ability to change their own password", + "perms.admin.readusers": "View Users", + "perms.admin.readusers.desc": "Ability to view all users", + "perms.admin.restarthost": "Restart TGS", + "perms.admin.restarthost.desc": "Ability to restart TGS", + "perms.admin.uploadversion": "Upload Version .zip", + "perms.admin.uploadversion.desc": "Ability to update the server with an uploaded .zip update package.", + "perms.admin.writeusers": "Edit Users", + "perms.admin.writeusers.desc": "Ability to edit users, if View Users is granted, all users can be edited, otherwise, only the current user can be edited", + "perms.chatbots": "Chat Bots", + "perms.chatbots.create": "Create", + "perms.chatbots.create.desc": "Allows the creation of bew chat bots.", + "perms.chatbots.delete": "Delete", + "perms.chatbots.delete.desc": "Allows the deletion of chat bots.", + "perms.chatbots.read": "Read", + "perms.chatbots.read.desc": "Allows reading all chat bot information aside from their connection strings.", + "perms.chatbots.readconnectionstring": "Read Connection String", + "perms.chatbots.readconnectionstring.desc": "Allows reading the TGS connection string of chat bots. May contain sensitive data", + "perms.chatbots.writechannellimit": "Set Channel Limit", + "perms.chatbots.writechannellimit.desc": "Allows changing the channel limit of chat bots.", + "perms.chatbots.writechannels": "Set Channels", + "perms.chatbots.writechannels.desc": "Allows changing the channels chat bots are connected to.", + "perms.chatbots.writeconnectionstring": "Set Connection String", + "perms.chatbots.writeconnectionstring.desc": "Allows adjusting the TGS connection string of chat bots.", + "perms.chatbots.writeenabled": "Set Enabled", + "perms.chatbots.writeenabled.desc": "Allows activation and deactivation of chat bots.", + "perms.chatbots.writename": "Set Name", + "perms.chatbots.writename.desc": "Allows changing the name of chat bots.", + "perms.chatbots.writeprovider": "Set Provider", + "perms.chatbots.writeprovider.desc": "Allows changing the chat provider of chat bots.", + "perms.chatbots.writereconnectioninterval": "Set Reconnection Interval", + "perms.chatbots.writereconnectioninterval.desc": "Allows changing the interval at which chat bots that have lost connection to their providers will attempt to reconnect.", + "perms.configuration": "Files & Scripts", + "perms.configuration.delete": "Delete Directories", + "perms.configuration.delete.desc": "Allows deleting empty configuration directories where permitted.", + "perms.configuration.list": "Traverse Directories", + "perms.configuration.list.desc": "Allows listing the contents of configuration directories where permitted.", + "perms.configuration.read": "Read Files", + "perms.configuration.read.desc": "Allows downloading configuration files where permitted.", + "perms.configuration.write": "Modify Files", + "perms.configuration.write.desc": "Allows uploading, overwriting, and deleting configuration files where permitted.", + "perms.dreamdaemon": "Server", + "perms.dreamdaemon.broadcastmessage": "Send Broadcast Messages", + "perms.dreamdaemon.broadcastmessage.desc": "Allows sending arbitrary messages from TGS clients to the running game server for broadcasting to players.", + "perms.dreamdaemon.createdump": "Create Process Dump", + "perms.dreamdaemon.createdump.desc": "Allows creating dump files of the game server process while it is running.", + "perms.dreamdaemon.readmetadata": "Read Settings", + "perms.dreamdaemon.readmetadata.desc": "Allows reading the current game server settings.", + "perms.dreamdaemon.readrevision": "View Current Compile Jobs", + "perms.dreamdaemon.readrevision.desc": "Allows reading information about the latest and staged compile jobs.", + "perms.dreamdaemon.restart": "Hard Restart", + "perms.dreamdaemon.restart.desc": "Allows immediately restarting the game server process.", + "perms.dreamdaemon.setadditionalparameters": "Set Additional Parameters", + "perms.dreamdaemon.setadditionalparameters.desc": "Allows adding additional game server launch parameters (Not command line arguments).", + "perms.dreamdaemon.setautostart": "Set Autostart", + "perms.dreamdaemon.setautostart.desc": "Allows setting whether or not the game server will start automatically when the instance comes online.", + "perms.dreamdaemon.sethealthcheckinterval": "Set Health Check Interval", + "perms.dreamdaemon.sethealthcheckinterval.desc": "Allows changing the interval at which health check Topics are sent.", + "perms.dreamdaemon.setlogoutput": "Set Game Server Output Logging", + "perms.dreamdaemon.setlogoutput.desc": "Allows setting whether or not the game server will log it's output to the Diagnostics folder.", + "perms.dreamdaemon.setmapthreads": "Set Map Threads", + "perms.dreamdaemon.setmapthreads.desc": "Allows setting the `-map-threads` command line option.", + "perms.dreamdaemon.setminidumps": "Change Core Dump Type", + "perms.dreamdaemon.setminidumps.desc": "Allows switching between creating minidumps and full core dumps.", + "perms.dreamdaemon.setport": "Set Game Port", + "perms.dreamdaemon.setport.desc": "Allows setting the port the game server listens on.", + "perms.dreamdaemon.setprofiler": "Set Profiler", + "perms.dreamdaemon.setprofiler.desc": "Allows setting the `-profile` command line option.", + "perms.dreamdaemon.setsecurity": "Set Security Level", + "perms.dreamdaemon.setsecurity.desc": "Allows setting the BYOND security level to run the game at (Note: a higher DMAPI setting stored in a compile job can override this).", + "perms.dreamdaemon.setstartuptimeout": "Set Startup Timeout", + "perms.dreamdaemon.setstartuptimeout.desc": "Allows changing the idle/DMAPI detection timeout for starting new servers before it's considered a failure. This also applies to game server instances used during deployments.", + "perms.dreamdaemon.settopictimeout": "Set Topic Timeout", + "perms.dreamdaemon.settopictimeout.desc": "Allows setting the timeout interval for sending Topics to the server before being considered a failure.", + "perms.dreamdaemon.setvisibility": "Set Visibility", + "perms.dreamdaemon.setvisibility.desc": "Allows changing the game server visibility setting.", + "perms.dreamdaemon.setwebclient": "Set Webclient", + "perms.dreamdaemon.setwebclient.desc": "Allows enabling/disabling use of the BYOND webclient.", + "perms.dreamdaemon.shutdown": "Hard Shutdown", + "perms.dreamdaemon.shutdown.desc": "Allows immediately terminating the game server process.", + "perms.dreamdaemon.softrestart": "Graceful Restart", + "perms.dreamdaemon.softrestart.desc": "Allows requesting the server is gracefully restarted (Process restart on world.Reboot()).", + "perms.dreamdaemon.softshutdown": "Graceful Shutdown", + "perms.dreamdaemon.softshutdown.desc": "Allows requesting the server is gracefully shutdown (Process terminiation on world.Reboot()).", + "perms.dreamdaemon.start": "Server Launch", + "perms.dreamdaemon.start.desc": "Allows launching the game server from a shutdown state.", + "perms.dreammaker": "Deployment", + "perms.dreammaker.cancelcompile": "Cancel Deployment", + "perms.dreammaker.cancelcompile.desc": "Allows cancelling deployment jobs.", + "perms.dreammaker.compile": "Create Deployment", + "perms.dreammaker.compile.desc": "Allows starting new deployment jobs.", + "perms.dreammaker.compilejobs": "Read Compile Jobs", + "perms.dreammaker.compilejobs.desc": "Allows reading information about the current and past deployments.", + "perms.dreammaker.read": "Read Deployment Settings", + "perms.dreammaker.read.desc": "Allows reading information about the deployment settings.", + "perms.dreammaker.setapivalidationport": "Set Validation Port", + "perms.dreammaker.setapivalidationport.desc": "Allows changing the port used by the game server to check for the presence of the DMAPI while deploying.", + "perms.dreammaker.setapivalidationrequirement": "Set Validation Requirement", + "perms.dreammaker.setapivalidationrequirement.desc": "Allows setting whether or not the DMAPI is required for successful deployments.", + "perms.dreammaker.setcompilerarguments": "Set Additional Compiler Arguments", + "perms.dreammaker.setcompilerarguments.desc": "Allows setting additional compiler arguments to be passed on the command line.", + "perms.dreammaker.setdme": "Set .dme Path", + "perms.dreammaker.setdme.desc": "Allows overriding TGS' automatic .dme detection in favor of using a different .dme.", + "perms.dreammaker.setsecuritylevel": "Set Validation Security Level", + "perms.dreammaker.setsecuritylevel.desc": "Allows changing the BYOND security level used to validate the DMAPI.", + "perms.dreammaker.settimeout": "Set Deployment Timeout", + "perms.dreammaker.settimeout.desc": "Allows setting the amount of time allowed to pass before a deployment job is automatically cancelled.", + "perms.engine": "Engine", + "perms.engine.cancelinstall": "Cancel Install Job", + "perms.engine.cancelinstall.desc": "Allows cancelling install jobs.", + "perms.engine.deleteinstall": "Delete Engine Version", + "perms.engine.installcustombyondversion": "Install Custom BYOND Version", + "perms.engine.installcustombyondversion.desc": "Allows installing a BYOND version uploaded from a zip file.", + "perms.engine.installcustomopendreamversion": "Install Custom OpenDream Version", + "perms.engine.installcustomopendreamversion.desc": "Allows installing an OpenDream version uploaded from a zip file.", + "perms.engine.installofficialorchangeactivebyondversion": "Activate/Install BYOND Version", + "perms.engine.installofficialorchangeactivebyondversion.desc": "Allows installation and activation of BYOND versions downloaded from the official website. Pre-installed custom versions may also be activated", + "perms.engine.installofficialorchangeactiveopendreamversion": "Activate/Install OpenDream Version", + "perms.engine.installofficialorchangeactiveopendreamversion.desc": "Allows installation and activation of OpenDream versions downloaded from the configured git. Pre-installed custom versions may also be activated", + "perms.engine.listinstalled": "List Installed Versions", + "perms.engine.listinstalled.desc": "Allows reading all installed engine versions.", + "perms.engine.readactive": "Read Active Version", + "perms.engine.readactive.desc": "Allows reading the active engine version.", + "perms.group": "Group", + "perms.group.cantlist": "You lack the permission to list all users. You need it to be able to list all groups", + "perms.group.create": "Create Group", + "perms.group.current": "Current Group: ", + "perms.group.delete.tooltip": "This group contains more than 0 users. Remove all users before deleting the group.", + "perms.group.none": "No group", + "perms.group.rename.tooltip": "Rename", + "perms.group.warning": "This user is linked to the \"{group}\" group. Any change to the permissions will be applied to the group.", + "perms.instance": "Instance Manager Permissions", + "perms.instance.create": "Create Instances", + "perms.instance.create.desc": "Ability to create new instances", + "perms.instance.create.warning": "The current user is not permitted to create instances", + "perms.instance.delete": "Delete Instance", + "perms.instance.delete.desc": "Ablity to delete an instance", + "perms.instance.grantpermissions": "Grant All Permissions", + "perms.instance.grantpermissions.desc": "Ability to grant themselves all permissions on any instance", + "perms.instance.list": "Read All Instances", + "perms.instance.list.desc": "Ability to list and view all instances", + "perms.instance.read": "Read Accessible Instances", + "perms.instance.read.desc": "Ability to list and view instances the user is allowed access to. WARNING: Users who know the instance ID can still use the API to edit it using other permissions even if they lack this one.", + "perms.instance.relocate": "Relocate Instances", + "perms.instance.relocate.desc": "Ablity to change the location of an instance on the file system", + "perms.instance.rename": "Rename Instances", + "perms.instance.rename.desc": "Ability to rename instances", + "perms.instance.setautoupdate": "Set Instance Autoupdate Interval", + "perms.instance.setautoupdate.desc": "Ability to set an instance's interval for automatic code updates", + "perms.instance.setchatbotlimit": "Set Instance Chatbot Limit", + "perms.instance.setchatbotlimit.desc": "Ability to change an instance's maximum amounts of bots", + "perms.instance.setconfiguration": "Set Instance Configuration Mode", + "perms.instance.setconfiguration.desc": "Ability to set an instance's static file editing mode", + "perms.instance.setonline": "Change Instance Online Status", + "perms.instance.setonline.desc": "Ability to set an instance as online or offline", + "perms.instancepermissionset": "Instance Admin", + "perms.instancepermissionset.cantedit": "You require the \"Write\" instance permission set flag to change these values", + "perms.instancepermissionset.create": "Create new Instance Permission Sets", + "perms.instancepermissionset.create.desc": "Allows you to grant access to this instance to other TGS users/groups.", + "perms.instancepermissionset.read": "Read Instance Permission Sets", + "perms.instancepermissionset.read.desc": "Allows you to read the permissions in this instance of other TGS users/groups already registered.", + "perms.instancepermissionset.write": "Write Instance Permission Sets", + "perms.instancepermissionset.write.desc": "Allows you to change or delete the permissions in this instance of both you and other TGS users/groups already registered.", + "perms.repository": "Repository", + "perms.repository.cancelclone": "Cancel Clone", + "perms.repository.cancelclone.desc": "Allows cancelling active repository clone jobs.", + "perms.repository.cancelpendingchanges": "Cancel Pending Changes", + "perms.repository.cancelpendingchanges.desc": "Allows cancelling active repository jobs (Except clone jobs).", + "perms.repository.changeautoupdatesettings": "Change Auto Update Test Merge Settings", + "perms.repository.changeautoupdatesettings.desc": "Allows changing the setting to preserve test merges while updating a branch or synchronize with the remote.", + "perms.repository.changecommitter": "Change Committer", + "perms.repository.changecommitter.desc": "Allows changing the username git commits are written as.", + "perms.repository.changecredentials": "Change Credentials", + "perms.repository.changecredentials.desc": "Allows changing the credentials used to access the repository.", + "perms.repository.changesubmoduleupdate": "Change Submodule Update", + "perms.repository.changesubmoduleupdate.desc": "Allows changing the setting to update submodules with branches.", + "perms.repository.changetestmergecommits": "Change Remote Test Merge Settings", + "perms.repository.changetestmergecommits.desc": "Allows enabling/disabling the settings for pushing test merge commits to the remote in a temporary branch, posting comments when test merges occur, and creating GitHub deployments.", + "perms.repository.delete": "Delete Repository", + "perms.repository.delete.desc": "Allows deleting the cloned repository from disk in order to clone another one.", + "perms.repository.mergepullrequest": "Create Test Merge", + "perms.repository.mergepullrequest.desc": "Allows test merging a commit request from the remote.", + "perms.repository.read": "Read Status Information", + "perms.repository.read.desc": "Allows reading repository status information (HEAD/Committer/Active Test Merges/etc...).", + "perms.repository.reclone": "Reclone Repository", + "perms.repository.reclone.desc": "Allows deletion and subsequent recloning of repository.", + "perms.repository.setorigin": "Clone Repository", + "perms.repository.setorigin.desc": "Allows cloning the repository from a remote if it doesn't exist.", + "perms.repository.setreference": "Checkout Branch/Tag", + "perms.repository.setreference.desc": "Allows checking out a specific branch/tag by it's name.", + "perms.repository.setsha": "Checkout SHA", + "perms.repository.setsha.desc": "Allows checking out a specific commit by it's SHA.", + "perms.repository.updatebranch": "Update Branch", + "perms.repository.updatebranch.desc": "Allows hard reset and merge updates to the repository's current branch.", + "routes.admin": "Administration", + "routes.admin.logs": "TGS Logs", + "routes.admin.update": "TGS Update", + "routes.config": "Webpanel Config", + "routes.home": "Home", + "routes.info": "Info", + "routes.instancecreate": "Add New Instance", + "routes.instanceedit": "Edit Instance", + "routes.instancejobs": "Jobs", + "routes.instancelist": "Instances", + "routes.login": "Log In", + "routes.passwd": "Change Password", + "routes.setup": "PostInstall Setup", + "routes.user_manager": "User Manager", + "routes.usercreate": "Create User", + "routes.useredit": "User Editor", + "routes.usermanager": "Users", + "title": "TGS Webpanel v{version}", "toast.serverrestart": "TGS has gone down!", "toast.serverrestart.desc": "Attempting to reauthenticate session after 30s... Other requests will be blocked until complete.", "toast.tokenexpired": "Session expired!", @@ -609,323 +609,323 @@ "toast.usermodified": "User modified!", "toast.usermodified.desc": "Your TGS user has been modified. You are required to reauthenticate.", "view.admin.hostos": "Host Machine OS: ", - "view.admin.logs.button": "TGS Logs", - "view.admin.reboot.button": "Restart TGS", - "view.admin.reboot.modal.body": "Are you sure you wish to restart TGS?", - "view.admin.reboot.modal.title": "Confirmation", - "view.admin.remote": "Remote repository: ", - "view.admin.update.button": "Update TGS", - "view.admin.update.cachekill": "Force refresh cache", - "view.admin.update.current": " (Current)", - "view.admin.update.hideall": "Show only recent versions", - "view.admin.update.latest": " (Latest)", - "view.admin.update.major_warn.body": "You are attempting to switch the major version of TGS from {currentMajor} to {targetMajor}! READ THE RELEASE NOTES CAREFULLY! Most TGS major upgrades constitute a change in the required .NET runtime. If this runtime is not installed PRIOR to updating, TGS will FAIL to restart after upgrading until it is! There also may be REQUIRED configuration changes that, if not made, may also result in a failure to restart!", - "view.admin.update.major_warn.title": "WARNING: Attempting Major TGS Version Change", - "view.admin.update.releasenotes": "Release Notes", - "view.admin.update.selectversion": "Select Version", - "view.admin.update.selectversion.cache": "Last checked @ {date} local time", - "view.admin.update.selectversion.deny": "You do not have permission to update to a GitHub version", - "view.admin.update.showall": "Show all versions", - "view.admin.update.upload": "Upload Update Package", - "view.admin.update.upload.deny": "You do not have permission to update using uploaded packages", - "view.admin.update.wait": "Please take the time to read the release notes before proceeding", - "view.admin.version.current": "Current Version: ", - "view.admin.version.latest": "Latest Version: ", - "view.info.client": "Client Info", - "view.info.controller": "[CONTROLLER]", - "view.info.dmapiversion": "DM API Version: ", - "view.info.gqlapiversion": "GraphQL API Version: ", - "view.info.grouplimit": "Group Limit: ", - "view.info.httpapiversion": "HTTP API Version: ", - "view.info.instancelimit": "Instance Limit: ", - "view.info.minpassword": "Minimum Password Length: ", - "view.info.oauth": "OAuth Support: ", - "view.info.server": "Server Info", - "view.info.swarm": "Swarm Info", - "view.info.swarmversion": "Swarm Protocol Version: ", - "view.info.userlimit": "User Limit: ", - "view.info.version": "Version: ", - "view.instance.chat": "Chat Bots", - "view.instance.chat.channels.deny": "You do not have permission to edit chat bot channels!", - "view.instance.chat.channels.export": "Export Channels to Clipboard", - "view.instance.chat.channels.import": "Import Channels from Clipboard", - "view.instance.chat.create": "Add Bot", - "view.instance.chat.create.channel": "Add Channel", - "view.instance.chat.create.invalid.discord": "Invalid Discord channel ID!", - "view.instance.chat.create.invalid.irc": "Invalid IRC channel!", - "view.instance.chat.create.missing.address": "Missing IRC Server Address!", - "view.instance.chat.create.missing.channel": "Missing channel ID!", - "view.instance.chat.create.missing.name": "Missing Bot Name!", - "view.instance.chat.create.missing.nick": "Missing IRC Bot Nickname!", - "view.instance.chat.create.missing.token": "Missing Discord Bot Token!", - "view.instance.chat.delete": "Delete Bot", - "view.instance.chat.delete.channel": "Delete Channel", - "view.instance.chat.delete.channel.confirm": "Are you sure you want to delete channel \"{channelName}\"?", - "view.instance.chat.delete.confirm": "Are you sure you want to delete chat bot \"{botName}\"?", - "view.instance.chat.delete.deny": "You do not have permission to delete chat bots", - "view.instance.chat.limit": "Maximum of {max} chat bots reached!", - "view.instance.chat.limit.channels": "Maximum of {max} channels reached!", - "view.instance.chat.reload": "Load Connection String", - "view.instance.chat.reload.deny": "You do not have permission to view connection strings", - "view.instance.chat.select_item": "Select an Item on the Left", - "view.instance.config.chatbots": "Chat Bots", - "view.instance.config.instancesettings": "Instance Settings", - "view.instance.config.instanceusers": "Instance Users", - "view.instance.configmode.0": "Disabled", - "view.instance.configmode.1": "Authorized users can read/write", - "view.instance.configmode.2": "Authorized users can read/write using their system user", - "view.instance.create.access_token": "GitHub Token (Optional)", - "view.instance.create.access_user": "GitHub Token Username (Optional)", - "view.instance.create.loading": "Creating Instance...", - "view.instance.create.manual": "Manual Setup", - "view.instance.create.name": "Instance Name", - "view.instance.create.path": "Instance Path on Server", - "view.instance.create.path.prefix": "Prefix:", - "view.instance.create.quick": "Quick Setup", - "view.instance.create.quick.active": "Performing Instance Quick Setup", - "view.instance.create.quick.notice": "Quick setup requires the following:{br}\t- A GitHub hosted repository.{br}\t- A codebase containing a .tgs.yml file in its root.{br}\t- A GitHub personal access token with read access to the repository set in the webpanel settings.", - "view.instance.create.quick.stage.byond": "Starting {version} BYOND install...", - "view.instance.create.quick.stage.cloning": "Starting repository clone...", - "view.instance.create.quick.stage.create_instance": "Creating instance...", - "view.instance.create.quick.stage.download_scripts": "Downloading script \"{script}\"...", - "view.instance.create.quick.stage.settings": "Updating compiler/server settings...", - "view.instance.create.quick.stage.static": "Creating GameStaticFiles directory \"{dir}\"...", - "view.instance.create.quick.stage.static.transfer": "Transferring \"{path}\" from GitHub to GameStaticFiles/{targetPath}...", - "view.instance.create.quick.stage.upload_scripts": "Uploading EventScript \"{script}\"...", - "view.instance.create.quick.stage.yml": "Downloading .tgs.yml...", - "view.instance.create.quick.submit": "Start Quick Setup", - "view.instance.create.quick.warning": "Quick setup may install executable scripts or set the BYOND security level to a less secure value. Ensure you trust the codebase you are targeting.", - "view.instance.create.repo_branch": "GitHub Repository Reference (branch/tag, Optional)", - "view.instance.create.repo_name": "GitHub Repository Name", - "view.instance.create.repo_owner": "GitHub Repository Owner", - "view.instance.create.submit": "Create Instance", - "view.instance.create.title": "New Instance", - "view.instance.deploy.deploy": "Compile & Deploy repository", - "view.instance.deploy.title": "Deployment Settings", - "view.instance.engine": "Version Selector", - "view.instance.engine.add_byond": "Install new BYOND version", - "view.instance.engine.add_od": "Install new OpenDream version", - "view.instance.engine.current_and_list_denied": "This user does not have the permission to access information about BYOND versions", - "view.instance.engine.current_denied": "This user does not have the permission to see the active BYOND version", - "view.instance.engine.current_version": "Active Version: {version}", - "view.instance.engine.custom": "Uploaded from zip file", - "view.instance.engine.list_denied": "This user does not have the permission to list all installed BYOND versions", - "view.instance.engine.upload": "Upload custom version", - "view.instance.files.create": "Create Item", - "view.instance.files.delete": "Delete File", - "view.instance.files.delete.confirm": "Are you sure you want to delete the file \"{path}\"", - "view.instance.files.delete.directory": "Delete Empty Directory", - "view.instance.files.delete.directory.confirm": "Are you sure you want to delete the empty directory \"{directoryName}\"?", - "view.instance.files.delete.directory.populated": "Only empty directories may be deleted", - "view.instance.files.delete.directory.populated.unloaded": "Expand the directory to see if it contains files before deleting it", - "view.instance.files.disallowed": "The instance settings prevent you from using the file browser", - "view.instance.files.disallowed.directory": "You do not have permission to view directory contents. The webpanel does not support file browsing without this permission.", - "view.instance.files.disallowed.directory.delete": "You do not have permission to delete directories", - "view.instance.files.disallowed.read": "You do not have permission to download files.", - "view.instance.files.disallowed.read_no_browse": "You do not have permission to browse nor download files.", - "view.instance.files.disallowed.write": "You do not have permission to create, modify, or delete files.", - "view.instance.files.download": "Download File", - "view.instance.files.download.directory": "Download Zip", - "view.instance.files.download.location": "Downloaded files will be saved in the OS's default download location", - "view.instance.files.file_browser": "File Browser", - "view.instance.files.load_more": "(Click to Load Directory)", - "view.instance.files.replace": "Overwrite with Uploaded File", - "view.instance.files.replace.stale": "Cannot replace file due to being unable to refresh its status!", - "view.instance.files.select_item": "Select an Item on the Left", - "view.instance.files.upload": "Upload and Overwrite File", - "view.instance.files.zip.confirm": "Are you sure you want to download the directory \"{path}\" as a zip? This can be a very intense operation for large folder structures and may not succeed.", - "view.instance.graceful": "Graceful Action", - "view.instance.graceful.None": "None", - "view.instance.graceful.Restart": "Restart", - "view.instance.graceful.Stop": "Shutdown", - "view.instance.graceful.desc": "This action will be applied the next time the server restarts", - "view.instance.info": "Instance Metadata", - "view.instance.jobs.clearfinished": "Clear finished jobs", - "view.instance.jobs.error": "An error occured", - "view.instance.jobs.jobtotal": "{amount} jobs", - "view.instance.jobs.reconnect_in": "Attempting reconnect in {seconds}s...", - "view.instance.jobs.reconnect_now": "Attempting reconnection...", - "view.instance.jobs.reconnected_auth": "Reconnected, authenticating...", - "view.instance.jobs.title": "Job list", - "view.instance.list.grant": "Grant yourself permission to access this instance", - "view.instance.list.grant.deny": "Requires the \"Grant All Permissions\" instance manager right", - "view.instance.list.set.offline": "Take Offline", - "view.instance.list.set.online": "Bring Online", - "view.instance.list.title": "Instance List", - "view.instance.moving": "[MOVING INSTANCE...]", - "view.instance.no_compile_jobs": "You do not have the permission to view deployment information!", - "view.instance.no_metadata": "You do not have the permission to read all settings, only editable fields will be shown. Said fields will only contain default values.", - "view.instance.perms": "Instance Permissions", - "view.instance.perms.create": "Create Instance Permission Set", - "view.instance.perms.delete": "Delete Instance Permission Set", - "view.instance.perms.grant": "Grant Full Permissions", - "view.instance.perms.grant.desc": "You have access to grant yourself full permissions on this instance.", - "view.instance.perms.missing": "This permission set is not registered with the instance", - "view.instance.repo.addmanual": "Add Test Merge", - "view.instance.repo.canthookclone": "Unable to find clone job, refresh page when clone is complete. Please report this!", - "view.instance.repo.clone": "Clone Remote Repository", - "view.instance.repo.conflictlabel": "Merge Conflict", - "view.instance.repo.creds": "Credentials", - "view.instance.repo.creds.desc": "Credentials used to perform operations on the remote repository", - "view.instance.repo.creds.modal.title": "Set Repository Credentials", - "view.instance.repo.delete": "Delete Repo", - "view.instance.repo.delete.desc": "This will delete the local copy of the repository. Instance settings, code modifications, event scripts and static files will be preserved.", - "view.instance.repo.delete.title": "Delete Repository", - "view.instance.repo.deployAfter": "Compile & Deploy after changes", - "view.instance.repo.deployAfter.desc": "Compile and deploy the repository to the server after completing the test merge", - "view.instance.repo.info.name": "Repository Name", - "view.instance.repo.info.origin": "Origin URL", - "view.instance.repo.info.owner": "Repository Owner", - "view.instance.repo.manual": "Manual Test Merge Entry", - "view.instance.repo.manual.desc": "Use this box to manually test merge a pull/merge request by entering its number and clicking \"Add Test Merge\"", - "view.instance.repo.noautomerge": "Automatic test merge management is unavailable due to missing permissions", - "view.instance.repo.norepoinfo": "You lack the permission to display information about the repository", - "view.instance.repo.pending.added": "Testmerge #{number} ({title}) at {commit}", - "view.instance.repo.pending.added.manual": "Manual testmerge of PR #{number}", - "view.instance.repo.pending.deploy": "Queue a deployment of repository code to the server", - "view.instance.repo.pending.none": "No pending changes", - "view.instance.repo.pending.reapply": "Retestmerge #{number} ({title}) at {commit}", - "view.instance.repo.pending.removed": "Removes #{number} ({title})", - "view.instance.repo.pending.renamed": "Change the comment on #{number}", - "view.instance.repo.pending.reset": "Reset repository to local tracked reference", - "view.instance.repo.pending.reset.nobranch": "Recheckout commit {commit}", - "view.instance.repo.pending.title": "Pending Changes", - "view.instance.repo.pending.update": "Reset repository to remote tracked reference", - "view.instance.repo.pending.updated": "Update #{number} ({title}) to {commit}", - "view.instance.repo.reclone": "Reclone Repo", - "view.instance.repo.reclone.desc": "This will delete the local copy of the repository and clone it fresh from its current origin URL. An attempt to checkout the current reference and SHA will occur. Useful as a garbage collection or repair action. Repository credentials, instance settings, code modifications, event scripts and static files will be preserved.", - "view.instance.repo.reclone.title": "Reclone Repository", - "view.instance.repo.repoinfo": "Repository Information", - "view.instance.repo.reposettings": "Repository Settings", - "view.instance.repo.reset": "Reset repository to origin", - "view.instance.repo.reset.desc": "This option will reset the repository to the tracked origin, updating the repository and clearing any test merged PRs", - "view.instance.repo.testmergelabel": "Labelled", - "view.instance.repo.testmerges": "Test Merges", - "view.instance.repo.testmerges.badprovider": "Guided test merges are only supported on github", - "view.instance.repo.tm.by": "Testmerged by:", - "view.instance.repo.tm.comment": "Comment:", - "view.instance.repo.tm.commit": "Commit:", - "view.instance.repo.tm.modal.comment": "Comment", - "view.instance.repo.tm.modal.label": "Select Commit", - "view.instance.repo.tm.modal.tip": "Tip: When clicking the add or update button, hold shift to testmerge the latest commit bypassing this popup!", - "view.instance.repo.tm.modal.title": "Add or Update Testmerge", - "view.instance.repo.update.local": "Reset to Local Origin", - "view.instance.repo.update.local.tip": "Using this option may take you off the current repository reference. In order to update to latest, you will have to manually checkout said reference again.", - "view.instance.repo.update.none": "No Initial Change", - "view.instance.repo.update.remote": "Update to Remote", - "view.instance.server.actions": "Actions", - "view.instance.server.broadcast": "Broadcast", - "view.instance.server.deployment_info": "Deployment Information", - "view.instance.server.deployment_info.active": "Active Deployment", - "view.instance.server.deployment_info.staged": "Staged Deployment", - "view.instance.server.dump": "Dump Process", - "view.instance.server.no_actions": "You do not have permission to commit any actions.", - "view.instance.server.no_graceful": "You do not have permission to get or set the current graceful action.", - "view.instance.server.no_metadata_actions": "You do not have permission to fetch the status of the server, some actions may not work depending on the state of the server.", - "view.instance.server.no_metadata_and_no_settings": "You do not have the permission to list or edit Dream Daemon settings for this instance.", - "view.instance.server.no_metadata_graceful": "You do not have permission to fetch the current graceful action.", - "view.instance.server.prompt.restart": "Are you sure you wish to immediately restart the server?", - "view.instance.server.prompt.stop": "Are you sure you wish to immediately stop the server?", - "view.instance.server.restart": "Restart", - "view.instance.server.settings": "Settings", - "view.instance.server.start": "Start", - "view.instance.server.status": "Status: ", - "view.instance.server.status.DelayedRestart": "Delayed Restart", - "view.instance.server.status.Offline": "Offline", - "view.instance.server.status.Online": "Online", - "view.instance.server.status.Restoring": "Restoring", - "view.instance.server.status.client_count": "Clients", - "view.instance.server.status.client_count.cant": "Update your DMAPI and enable health checks to get client count", - "view.instance.server.status.client_count.pending": "Client count available in {healthCheckSecondsLeft}s...", - "view.instance.server.status.client_count.soon": "Refresh to see client count", - "view.instance.server.status.cpu": "CPU", - "view.instance.server.status.ram": "RAM", - "view.instance.server.status.undefined": "No permission", - "view.instance.server.status.uptime": "Last Restart: ", - "view.instance.server.stop": "Stop", - "view.instanceedit.tabs.chatbots": "Chat Bots", - "view.instanceedit.tabs.config": "Config", - "view.instanceedit.tabs.deployment": "Deployment", - "view.instanceedit.tabs.dreamdaemon": "Server", - "view.instanceedit.tabs.engine": "Engine", - "view.instanceedit.tabs.files": "Files & Scripts", - "view.instanceedit.tabs.info": "Information", - "view.instanceedit.tabs.jobs": "Jobs History", - "view.instanceedit.tabs.repository": "Repository", - "view.instanceedit.tabs.users": "Permissions", - "view.instanceedit.title": "Editing Instance {instancename} ({instanceid})", - "view.meme_0": "Toxic Gamers' Sanctuary", - "view.meme_1": "The Great Spaceman", - "view.meme_10": "Terrible Griefer Society", - "view.meme_11": "Taco-Generating Spacecraft", - "view.meme_12": "Thirsty Gamers' Saloon", - "view.meme_13": "Titanic Gaming Server", - "view.meme_14": "Tragic Space Odyssey", - "view.meme_15": "Tinfoil Hat Guild", - "view.meme_16": "Turbocharged Game Station", - "view.meme_17": "Time-Traveling Game Show", - "view.meme_18": "Totally Gnarly Setup", - "view.meme_19": "Terrifying Ghost Ship", - "view.meme_2": "The Griefers' Stronghold", - "view.meme_20": "Tasty Grilled Sandwich", - "view.meme_21": "Treasure-Gathering Spacefarers", - "view.meme_22": "Tornado-Generating Storm", - "view.meme_23": "Twisted Gaming Society", - "view.meme_24": "Tgstation Sucks", - "view.meme_25": "Terra-Gov Server", - "view.meme_3": "The Gourmet Spaceport", - "view.meme_4": "The Galactic Sh*tshow", - "view.meme_5": "The Grand Syndicate", - "view.meme_6": "The Giant Spacepickle", - "view.meme_7": "The Goofy Spacemen", - "view.meme_8": "The Godly Station", - "view.meme_9": "The Grumpy Scientists", - "view.report": "Report Issue", - "view.setup.disableadmin": "Disable default Admin account", - "view.setup.navigationblock": "Navigation has been disabled for the duration of the setup.", - "view.setup.nextpage": "Next Page", - "view.setup.quit": "Quit Setup", - "view.setup.quitconfirm": "Are you sure you want to exit the setup? You will not be able to return.", - "view.setup.step.1": "Step 1. Create yourself a user account", - "view.setup.step.2": "Step 2. Login using your new user account", - "view.setup.step.3": "Step 3. Disable the default Admin account", - "view.setup.step.4": "Step 4. Configure clientside settings (Optional)", - "view.setup.step.5": "Setup Complete!", - "view.setup.title": "Step By Step Setup Wizard", - "view.user.create.sys": "Create user with system identifier", - "view.user.create.tgs": "Create user with TGS identifier", - "view.user.edit.cantedit": "This user does not have the permission to edit users.", - "view.user.edit.oauth.add": "Add Connection", - "view.user.edit.oauth.connections": "OAuth Connections", - "view.user.edit.oauth.current": "OAuth 2.0 Connections", - "view.user.edit.oauth.id": "Service User ID:", - "view.user.edit.oauth.provider": "Provider", - "view.user.edit.oauth.provider.discord": "Discord", - "view.user.edit.oauth.provider.github": "GitHub", - "view.user.edit.oauth.provider.invisioncommunity": "Invision Community", - "view.user.edit.oauth.provider.keycloak": "Keycloak", - "view.user.edit.oauth.provider.tgforums": "/tg/ Forums", - "view.user.list.cantlist": "This user does not have the permission to list users, only the current user is listed/editable.", - "view.user.passwd.title": "Editing password for ", - "view.utils.deployment_viewer.dmapi_outdated": "Your codebase's DMAPI interop version ({codebase}) is not present or less than tgstation-server's version ({tgs}). Please update your codebase with the latest TGS DMAPI library for full functionality. Click here to go to the latest TGS DMAPI release.", - "view.utils.deployment_viewer.no_jobs": "No deployments have been created!", - "view.utils.deployment_viewer.table.byond": "Engine Version", - "view.utils.deployment_viewer.table.completed_at": "Completed At", - "view.utils.deployment_viewer.table.dmapi": "DMAPI Interop Version", - "view.utils.deployment_viewer.table.id": "Id", - "view.utils.deployment_viewer.table.origin": "Origin SHA", - "view.utils.deployment_viewer.table.pr.comment": "Comment", - "view.utils.deployment_viewer.table.pr.merged_at": "Merged At", - "view.utils.deployment_viewer.table.pr.merged_by": "Merged By", - "view.utils.deployment_viewer.table.pr.number": "Test Merge #", - "view.utils.deployment_viewer.table.pr.title": "Title", - "view.utils.deployment_viewer.table.project": "Project Name", - "view.utils.deployment_viewer.table.revision": "SHA", - "view.utils.deployment_viewer.table.security": "Minimum Security", - "view.utils.deployment_viewer.table.started_at": "Started At", - "view.utils.deployment_viewer.table.started_by": "Started By", - "view.utils.deployment_viewer.test_merges_hint.hide": "Hide Test Merges", - "view.utils.deployment_viewer.test_merges_hint.show": "Show Test Merges", - "warning.screensize": "The TGS webpanel does not guarentee support for viewports with a width of under 992px.", - "warning.screensize.header": "Screen size warning" + "view.admin.logs.button": "TGS Logs", + "view.admin.reboot.button": "Restart TGS", + "view.admin.reboot.modal.body": "Are you sure you wish to restart TGS?", + "view.admin.reboot.modal.title": "Confirmation", + "view.admin.remote": "Remote repository: ", + "view.admin.update.button": "Update TGS", + "view.admin.update.cachekill": "Force refresh cache", + "view.admin.update.current": " (Current)", + "view.admin.update.hideall": "Show only recent versions", + "view.admin.update.latest": " (Latest)", + "view.admin.update.major_warn.body": "You are attempting to switch the major version of TGS from {currentMajor} to {targetMajor}! READ THE RELEASE NOTES CAREFULLY! Most TGS major upgrades constitute a change in the required .NET runtime. If this runtime is not installed PRIOR to updating, TGS will FAIL to restart after upgrading until it is! There also may be REQUIRED configuration changes that, if not made, may also result in a failure to restart!", + "view.admin.update.major_warn.title": "WARNING: Attempting Major TGS Version Change", + "view.admin.update.releasenotes": "Release Notes", + "view.admin.update.selectversion": "Select Version", + "view.admin.update.selectversion.cache": "Last checked @ {date} local time", + "view.admin.update.selectversion.deny": "You do not have permission to update to a GitHub version", + "view.admin.update.showall": "Show all versions", + "view.admin.update.upload": "Upload Update Package", + "view.admin.update.upload.deny": "You do not have permission to update using uploaded packages", + "view.admin.update.wait": "Please take the time to read the release notes before proceeding", + "view.admin.version.current": "Current Version: ", + "view.admin.version.latest": "Latest Version: ", + "view.info.client": "Client Info", + "view.info.controller": "[CONTROLLER]", + "view.info.dmapiversion": "DM API Version: ", + "view.info.gqlapiversion": "GraphQL API Version: ", + "view.info.grouplimit": "Group Limit: ", + "view.info.httpapiversion": "HTTP API Version: ", + "view.info.instancelimit": "Instance Limit: ", + "view.info.minpassword": "Minimum Password Length: ", + "view.info.oauth": "OAuth Support: ", + "view.info.server": "Server Info", + "view.info.swarm": "Swarm Info", + "view.info.swarmversion": "Swarm Protocol Version: ", + "view.info.userlimit": "User Limit: ", + "view.info.version": "Version: ", + "view.instance.chat": "Chat Bots", + "view.instance.chat.channels.deny": "You do not have permission to edit chat bot channels!", + "view.instance.chat.channels.export": "Export Channels to Clipboard", + "view.instance.chat.channels.import": "Import Channels from Clipboard", + "view.instance.chat.create": "Add Bot", + "view.instance.chat.create.channel": "Add Channel", + "view.instance.chat.create.invalid.discord": "Invalid Discord channel ID!", + "view.instance.chat.create.invalid.irc": "Invalid IRC channel!", + "view.instance.chat.create.missing.address": "Missing IRC Server Address!", + "view.instance.chat.create.missing.channel": "Missing channel ID!", + "view.instance.chat.create.missing.name": "Missing Bot Name!", + "view.instance.chat.create.missing.nick": "Missing IRC Bot Nickname!", + "view.instance.chat.create.missing.token": "Missing Discord Bot Token!", + "view.instance.chat.delete": "Delete Bot", + "view.instance.chat.delete.channel": "Delete Channel", + "view.instance.chat.delete.channel.confirm": "Are you sure you want to delete channel \"{channelName}\"?", + "view.instance.chat.delete.confirm": "Are you sure you want to delete chat bot \"{botName}\"?", + "view.instance.chat.delete.deny": "You do not have permission to delete chat bots", + "view.instance.chat.limit": "Maximum of {max} chat bots reached!", + "view.instance.chat.limit.channels": "Maximum of {max} channels reached!", + "view.instance.chat.reload": "Load Connection String", + "view.instance.chat.reload.deny": "You do not have permission to view connection strings", + "view.instance.chat.select_item": "Select an Item on the Left", + "view.instance.config.chatbots": "Chat Bots", + "view.instance.config.instancesettings": "Instance Settings", + "view.instance.config.instanceusers": "Instance Users", + "view.instance.configmode.0": "Disabled", + "view.instance.configmode.1": "Authorized users can read/write", + "view.instance.configmode.2": "Authorized users can read/write using their system user", + "view.instance.create.access_token": "GitHub Token (Optional)", + "view.instance.create.access_user": "GitHub Token Username (Optional)", + "view.instance.create.loading": "Creating Instance...", + "view.instance.create.manual": "Manual Setup", + "view.instance.create.name": "Instance Name", + "view.instance.create.path": "Instance Path on Server", + "view.instance.create.path.prefix": "Prefix:", + "view.instance.create.quick": "Quick Setup", + "view.instance.create.quick.active": "Performing Instance Quick Setup", + "view.instance.create.quick.notice": "Quick setup requires the following:{br}\t- A GitHub hosted repository.{br}\t- A codebase containing a .tgs.yml file in its root.{br}\t- A GitHub personal access token with read access to the repository set in the webpanel settings.", + "view.instance.create.quick.stage.byond": "Starting {version} BYOND install...", + "view.instance.create.quick.stage.cloning": "Starting repository clone...", + "view.instance.create.quick.stage.create_instance": "Creating instance...", + "view.instance.create.quick.stage.download_scripts": "Downloading script \"{script}\"...", + "view.instance.create.quick.stage.settings": "Updating compiler/server settings...", + "view.instance.create.quick.stage.static": "Creating GameStaticFiles directory \"{dir}\"...", + "view.instance.create.quick.stage.static.transfer": "Transferring \"{path}\" from GitHub to GameStaticFiles/{targetPath}...", + "view.instance.create.quick.stage.upload_scripts": "Uploading EventScript \"{script}\"...", + "view.instance.create.quick.stage.yml": "Downloading .tgs.yml...", + "view.instance.create.quick.submit": "Start Quick Setup", + "view.instance.create.quick.warning": "Quick setup may install executable scripts or set the BYOND security level to a less secure value. Ensure you trust the codebase you are targeting.", + "view.instance.create.repo_branch": "GitHub Repository Reference (branch/tag, Optional)", + "view.instance.create.repo_name": "GitHub Repository Name", + "view.instance.create.repo_owner": "GitHub Repository Owner", + "view.instance.create.submit": "Create Instance", + "view.instance.create.title": "New Instance", + "view.instance.deploy.deploy": "Compile & Deploy repository", + "view.instance.deploy.title": "Deployment Settings", + "view.instance.engine": "Version Selector", + "view.instance.engine.add_byond": "Install new BYOND version", + "view.instance.engine.add_od": "Install new OpenDream version", + "view.instance.engine.current_and_list_denied": "This user does not have the permission to access information about BYOND versions", + "view.instance.engine.current_denied": "This user does not have the permission to see the active BYOND version", + "view.instance.engine.current_version": "Active Version: {version}", + "view.instance.engine.custom": "Uploaded from zip file", + "view.instance.engine.list_denied": "This user does not have the permission to list all installed BYOND versions", + "view.instance.engine.upload": "Upload custom version", + "view.instance.files.create": "Create Item", + "view.instance.files.delete": "Delete File", + "view.instance.files.delete.confirm": "Are you sure you want to delete the file \"{path}\"", + "view.instance.files.delete.directory": "Delete Empty Directory", + "view.instance.files.delete.directory.confirm": "Are you sure you want to delete the empty directory \"{directoryName}\"?", + "view.instance.files.delete.directory.populated": "Only empty directories may be deleted", + "view.instance.files.delete.directory.populated.unloaded": "Expand the directory to see if it contains files before deleting it", + "view.instance.files.disallowed": "The instance settings prevent you from using the file browser", + "view.instance.files.disallowed.directory": "You do not have permission to view directory contents. The webpanel does not support file browsing without this permission.", + "view.instance.files.disallowed.directory.delete": "You do not have permission to delete directories", + "view.instance.files.disallowed.read": "You do not have permission to download files.", + "view.instance.files.disallowed.read_no_browse": "You do not have permission to browse nor download files.", + "view.instance.files.disallowed.write": "You do not have permission to create, modify, or delete files.", + "view.instance.files.download": "Download File", + "view.instance.files.download.directory": "Download Zip", + "view.instance.files.download.location": "Downloaded files will be saved in the OS's default download location", + "view.instance.files.file_browser": "File Browser", + "view.instance.files.load_more": "(Click to Load Directory)", + "view.instance.files.replace": "Overwrite with Uploaded File", + "view.instance.files.replace.stale": "Cannot replace file due to being unable to refresh its status!", + "view.instance.files.select_item": "Select an Item on the Left", + "view.instance.files.upload": "Upload and Overwrite File", + "view.instance.files.zip.confirm": "Are you sure you want to download the directory \"{path}\" as a zip? This can be a very intense operation for large folder structures and may not succeed.", + "view.instance.graceful": "Graceful Action", + "view.instance.graceful.None": "None", + "view.instance.graceful.Restart": "Restart", + "view.instance.graceful.Stop": "Shutdown", + "view.instance.graceful.desc": "This action will be applied the next time the server restarts", + "view.instance.info": "Instance Metadata", + "view.instance.jobs.clearfinished": "Clear finished jobs", + "view.instance.jobs.error": "An error occured", + "view.instance.jobs.jobtotal": "{amount} jobs", + "view.instance.jobs.reconnect_in": "Attempting reconnect in {seconds}s...", + "view.instance.jobs.reconnect_now": "Attempting reconnection...", + "view.instance.jobs.reconnected_auth": "Reconnected, authenticating...", + "view.instance.jobs.title": "Job list", + "view.instance.list.grant": "Grant yourself permission to access this instance", + "view.instance.list.grant.deny": "Requires the \"Grant All Permissions\" instance manager right", + "view.instance.list.set.offline": "Take Offline", + "view.instance.list.set.online": "Bring Online", + "view.instance.list.title": "Instance List", + "view.instance.moving": "[MOVING INSTANCE...]", + "view.instance.no_compile_jobs": "You do not have the permission to view deployment information!", + "view.instance.no_metadata": "You do not have the permission to read all settings, only editable fields will be shown. Said fields will only contain default values.", + "view.instance.perms": "Instance Permissions", + "view.instance.perms.create": "Create Instance Permission Set", + "view.instance.perms.delete": "Delete Instance Permission Set", + "view.instance.perms.grant": "Grant Full Permissions", + "view.instance.perms.grant.desc": "You have access to grant yourself full permissions on this instance.", + "view.instance.perms.missing": "This permission set is not registered with the instance", + "view.instance.repo.addmanual": "Add Test Merge", + "view.instance.repo.canthookclone": "Unable to find clone job, refresh page when clone is complete. Please report this!", + "view.instance.repo.clone": "Clone Remote Repository", + "view.instance.repo.conflictlabel": "Merge Conflict", + "view.instance.repo.creds": "Credentials", + "view.instance.repo.creds.desc": "Credentials used to perform operations on the remote repository", + "view.instance.repo.creds.modal.title": "Set Repository Credentials", + "view.instance.repo.delete": "Delete Repo", + "view.instance.repo.delete.desc": "This will delete the local copy of the repository. Instance settings, code modifications, event scripts and static files will be preserved.", + "view.instance.repo.delete.title": "Delete Repository", + "view.instance.repo.deployAfter": "Compile & Deploy after changes", + "view.instance.repo.deployAfter.desc": "Compile and deploy the repository to the server after completing the test merge", + "view.instance.repo.info.name": "Repository Name", + "view.instance.repo.info.origin": "Origin URL", + "view.instance.repo.info.owner": "Repository Owner", + "view.instance.repo.manual": "Manual Test Merge Entry", + "view.instance.repo.manual.desc": "Use this box to manually test merge a pull/merge request by entering its number and clicking \"Add Test Merge\"", + "view.instance.repo.noautomerge": "Automatic test merge management is unavailable due to missing permissions", + "view.instance.repo.norepoinfo": "You lack the permission to display information about the repository", + "view.instance.repo.pending.added": "Testmerge #{number} ({title}) at {commit}", + "view.instance.repo.pending.added.manual": "Manual testmerge of PR #{number}", + "view.instance.repo.pending.deploy": "Queue a deployment of repository code to the server", + "view.instance.repo.pending.none": "No pending changes", + "view.instance.repo.pending.reapply": "Retestmerge #{number} ({title}) at {commit}", + "view.instance.repo.pending.removed": "Removes #{number} ({title})", + "view.instance.repo.pending.renamed": "Change the comment on #{number}", + "view.instance.repo.pending.reset": "Reset repository to local tracked reference", + "view.instance.repo.pending.reset.nobranch": "Recheckout commit {commit}", + "view.instance.repo.pending.title": "Pending Changes", + "view.instance.repo.pending.update": "Reset repository to remote tracked reference", + "view.instance.repo.pending.updated": "Update #{number} ({title}) to {commit}", + "view.instance.repo.reclone": "Reclone Repo", + "view.instance.repo.reclone.desc": "This will delete the local copy of the repository and clone it fresh from its current origin URL. An attempt to checkout the current reference and SHA will occur. Useful as a garbage collection or repair action. Repository credentials, instance settings, code modifications, event scripts and static files will be preserved.", + "view.instance.repo.reclone.title": "Reclone Repository", + "view.instance.repo.repoinfo": "Repository Information", + "view.instance.repo.reposettings": "Repository Settings", + "view.instance.repo.reset": "Reset repository to origin", + "view.instance.repo.reset.desc": "This option will reset the repository to the tracked origin, updating the repository and clearing any test merged PRs", + "view.instance.repo.testmergelabel": "Labelled", + "view.instance.repo.testmerges": "Test Merges", + "view.instance.repo.testmerges.badprovider": "Guided test merges are only supported on github", + "view.instance.repo.tm.by": "Testmerged by:", + "view.instance.repo.tm.comment": "Comment:", + "view.instance.repo.tm.commit": "Commit:", + "view.instance.repo.tm.modal.comment": "Comment", + "view.instance.repo.tm.modal.label": "Select Commit", + "view.instance.repo.tm.modal.tip": "Tip: When clicking the add or update button, hold shift to testmerge the latest commit bypassing this popup!", + "view.instance.repo.tm.modal.title": "Add or Update Testmerge", + "view.instance.repo.update.local": "Reset to Local Origin", + "view.instance.repo.update.local.tip": "Using this option may take you off the current repository reference. In order to update to latest, you will have to manually checkout said reference again.", + "view.instance.repo.update.none": "No Initial Change", + "view.instance.repo.update.remote": "Update to Remote", + "view.instance.server.actions": "Actions", + "view.instance.server.broadcast": "Broadcast", + "view.instance.server.deployment_info": "Deployment Information", + "view.instance.server.deployment_info.active": "Active Deployment", + "view.instance.server.deployment_info.staged": "Staged Deployment", + "view.instance.server.dump": "Dump Process", + "view.instance.server.no_actions": "You do not have permission to commit any actions.", + "view.instance.server.no_graceful": "You do not have permission to get or set the current graceful action.", + "view.instance.server.no_metadata_actions": "You do not have permission to fetch the status of the server, some actions may not work depending on the state of the server.", + "view.instance.server.no_metadata_and_no_settings": "You do not have the permission to list or edit Dream Daemon settings for this instance.", + "view.instance.server.no_metadata_graceful": "You do not have permission to fetch the current graceful action.", + "view.instance.server.prompt.restart": "Are you sure you wish to immediately restart the server?", + "view.instance.server.prompt.stop": "Are you sure you wish to immediately stop the server?", + "view.instance.server.restart": "Restart", + "view.instance.server.settings": "Settings", + "view.instance.server.start": "Start", + "view.instance.server.status": "Status: ", + "view.instance.server.status.DelayedRestart": "Delayed Restart", + "view.instance.server.status.Offline": "Offline", + "view.instance.server.status.Online": "Online", + "view.instance.server.status.Restoring": "Restoring", + "view.instance.server.status.client_count": "Clients", + "view.instance.server.status.client_count.cant": "Update your DMAPI and enable health checks to get client count", + "view.instance.server.status.client_count.pending": "Client count available in {healthCheckSecondsLeft}s...", + "view.instance.server.status.client_count.soon": "Refresh to see client count", + "view.instance.server.status.cpu": "CPU", + "view.instance.server.status.ram": "RAM", + "view.instance.server.status.undefined": "No permission", + "view.instance.server.status.uptime": "Last Restart: ", + "view.instance.server.stop": "Stop", + "view.instanceedit.tabs.chatbots": "Chat Bots", + "view.instanceedit.tabs.config": "Config", + "view.instanceedit.tabs.deployment": "Deployment", + "view.instanceedit.tabs.dreamdaemon": "Server", + "view.instanceedit.tabs.engine": "Engine", + "view.instanceedit.tabs.files": "Files & Scripts", + "view.instanceedit.tabs.info": "Information", + "view.instanceedit.tabs.jobs": "Jobs History", + "view.instanceedit.tabs.repository": "Repository", + "view.instanceedit.tabs.users": "Permissions", + "view.instanceedit.title": "Editing Instance {instancename} ({instanceid})", + "view.meme_0": "Toxic Gamers' Sanctuary", + "view.meme_1": "The Great Spaceman", + "view.meme_10": "Terrible Griefer Society", + "view.meme_11": "Taco-Generating Spacecraft", + "view.meme_12": "Thirsty Gamers' Saloon", + "view.meme_13": "Titanic Gaming Server", + "view.meme_14": "Tragic Space Odyssey", + "view.meme_15": "Tinfoil Hat Guild", + "view.meme_16": "Turbocharged Game Station", + "view.meme_17": "Time-Traveling Game Show", + "view.meme_18": "Totally Gnarly Setup", + "view.meme_19": "Terrifying Ghost Ship", + "view.meme_2": "The Griefers' Stronghold", + "view.meme_20": "Tasty Grilled Sandwich", + "view.meme_21": "Treasure-Gathering Spacefarers", + "view.meme_22": "Tornado-Generating Storm", + "view.meme_23": "Twisted Gaming Society", + "view.meme_24": "Tgstation Sucks", + "view.meme_25": "Terra-Gov Server", + "view.meme_3": "The Gourmet Spaceport", + "view.meme_4": "The Galactic Sh*tshow", + "view.meme_5": "The Grand Syndicate", + "view.meme_6": "The Giant Spacepickle", + "view.meme_7": "The Goofy Spacemen", + "view.meme_8": "The Godly Station", + "view.meme_9": "The Grumpy Scientists", + "view.report": "Report Issue", + "view.setup.disableadmin": "Disable default Admin account", + "view.setup.navigationblock": "Navigation has been disabled for the duration of the setup.", + "view.setup.nextpage": "Next Page", + "view.setup.quit": "Quit Setup", + "view.setup.quitconfirm": "Are you sure you want to exit the setup? You will not be able to return.", + "view.setup.step.1": "Step 1. Create yourself a user account", + "view.setup.step.2": "Step 2. Login using your new user account", + "view.setup.step.3": "Step 3. Disable the default Admin account", + "view.setup.step.4": "Step 4. Configure clientside settings (Optional)", + "view.setup.step.5": "Setup Complete!", + "view.setup.title": "Step By Step Setup Wizard", + "view.user.create.sys": "Create user with system identifier", + "view.user.create.tgs": "Create user with TGS identifier", + "view.user.edit.cantedit": "This user does not have the permission to edit users.", + "view.user.edit.oauth.add": "Add Connection", + "view.user.edit.oauth.connections": "OAuth Connections", + "view.user.edit.oauth.current": "OAuth 2.0 Connections", + "view.user.edit.oauth.id": "Service User ID:", + "view.user.edit.oauth.provider": "Provider", + "view.user.edit.oauth.provider.discord": "Discord", + "view.user.edit.oauth.provider.github": "GitHub", + "view.user.edit.oauth.provider.invisioncommunity": "Invision Community", + "view.user.edit.oauth.provider.keycloak": "Keycloak", + "view.user.edit.oauth.provider.tgforums": "/tg/ Forums", + "view.user.list.cantlist": "This user does not have the permission to list users, only the current user is listed/editable.", + "view.user.passwd.title": "Editing password for ", + "view.utils.deployment_viewer.dmapi_outdated": "Your codebase's DMAPI interop version ({codebase}) is not present or less than tgstation-server's version ({tgs}). Please update your codebase with the latest TGS DMAPI library for full functionality. Click here to go to the latest TGS DMAPI release.", + "view.utils.deployment_viewer.no_jobs": "No deployments have been created!", + "view.utils.deployment_viewer.table.byond": "Engine Version", + "view.utils.deployment_viewer.table.completed_at": "Completed At", + "view.utils.deployment_viewer.table.dmapi": "DMAPI Interop Version", + "view.utils.deployment_viewer.table.id": "Id", + "view.utils.deployment_viewer.table.origin": "Origin SHA", + "view.utils.deployment_viewer.table.pr.comment": "Comment", + "view.utils.deployment_viewer.table.pr.merged_at": "Merged At", + "view.utils.deployment_viewer.table.pr.merged_by": "Merged By", + "view.utils.deployment_viewer.table.pr.number": "Test Merge #", + "view.utils.deployment_viewer.table.pr.title": "Title", + "view.utils.deployment_viewer.table.project": "Project Name", + "view.utils.deployment_viewer.table.revision": "SHA", + "view.utils.deployment_viewer.table.security": "Minimum Security", + "view.utils.deployment_viewer.table.started_at": "Started At", + "view.utils.deployment_viewer.table.started_by": "Started By", + "view.utils.deployment_viewer.test_merges_hint.hide": "Hide Test Merges", + "view.utils.deployment_viewer.test_merges_hint.show": "Show Test Merges", + "warning.screensize": "The TGS webpanel does not guarentee support for viewports with a width of under 992px.", + "warning.screensize.header": "Screen size warning" } diff --git a/src/main.preload.js b/src/main.preload.js index c1f7d91b..071f09fc 100644 --- a/src/main.preload.js +++ b/src/main.preload.js @@ -1,33 +1,45 @@ try { window.publicPath = import.meta.env.VITE_PUBLIC_PATH; function loadChannel(channel) { - const handler = (e) => { - if (channel !== publicPath && confirm("The webpanel has failed to load from " + channel + ", this may be due to a misconfiguration. Press OK to load the webpanel from the fallback. Error: \n" + e)) { + const handler = e => { + if ( + channel !== publicPath && + confirm( + "The webpanel has failed to load from " + + channel + + ", this may be due to a misconfiguration. Press OK to load the webpanel from the fallback. Error: \n" + + e + ) + ) { loadChannel(publicPath); } else { - alert("An error has occured within the webpanel bootstraper: \n" + e) + alert("An error has occured within the webpanel bootstraper: \n" + e); } - } + }; try { if (!channel.endsWith("/")) { channel = channel + "/"; } - fetch(channel + "webpanelmanifest.json").then(e => { - e.json().then(data => { - const entry = data["src/main.tsx"].file; - const scripttag = document.createElement("script"); - scripttag.src = channel + entry; - document.body.append(scripttag); - }).catch(handler) - }).catch(handler); + fetch(channel + "webpanelmanifest.json") + .then(e => { + e.json() + .then(data => { + const entry = data["src/main.tsx"].file; + const scripttag = document.createElement("script"); + scripttag.src = channel + entry; + document.body.append(scripttag); + }) + .catch(handler); + }) + .catch(handler); } catch (e) { - handler(e) + handler(e); } } - if(import.meta.env.VITE_DEV_MODE == "true") { + if (import.meta.env.VITE_DEV_MODE == "true") { import("./main.tsx"); } else { fetch("channel.json", { @@ -35,32 +47,39 @@ try { "X-Webpanel-Fetch-Channel": "true" } }).then(e => { - e.json().then(channel => { - if (channel.publicPath && channel.publicPath !== "") { - if (!channel.publicPath.endsWith("/")) { - channel.publicPath = channel.publicPath + "/"; + e.json() + .then(channel => { + if (channel.publicPath && channel.publicPath !== "") { + if (!channel.publicPath.endsWith("/")) { + channel.publicPath = channel.publicPath + "/"; + } + window.publicPath = channel.publicPath; } - window.publicPath = channel.publicPath - } - document.querySelectorAll(':not(html)').forEach(node => { - const { tpl, tplTarget } = node.dataset; + document.querySelectorAll(":not(html)").forEach(node => { + const { tpl, tplTarget } = node.dataset; - if (!tplTarget) return + if (!tplTarget) return; - node.setAttribute(tplTarget, tpl.replaceAll("!publicpath!", publicPath)) - }); + node.setAttribute(tplTarget, tpl.replaceAll("!publicpath!", publicPath)); + }); - loadChannel(channel.channel) - }).catch((e) => { - if (confirm("An error has occured within the webpanel bootstraper. Press OK to load the webpanel from the fallback. Error:\n" + e)) { - loadChannel(publicPath); - } else { - alert("An error has occured within the webpanel bootstraper: \n" + e) - } - }) - }) + loadChannel(channel.channel); + }) + .catch(e => { + if ( + confirm( + "An error has occured within the webpanel bootstraper. Press OK to load the webpanel from the fallback. Error:\n" + + e + ) + ) { + loadChannel(publicPath); + } else { + alert("An error has occured within the webpanel bootstraper: \n" + e); + } + }); + }); } } catch (e) { - alert("An error has occured within the webpanel bootstraper: \n" + e) + alert("An error has occured within the webpanel bootstraper: \n" + e); } diff --git a/tailwind.config.js b/tailwind.config.js index b5e3e125..6bbb0a16 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,68 +1,78 @@ /** @type {import('tailwindcss').Config} */ export default { darkMode: ["class"], - content: [ - "./index.html", - "./src/**/*.{js,ts,jsx,tsx}", - ], - theme: { - extend: { - borderRadius: { - lg: 'var(--radius)', - md: 'calc(var(--radius) - 2px)', - sm: 'calc(var(--radius) - 4px)' - }, - colors: { - background: 'hsl(var(--background))', - foreground: 'hsl(var(--foreground))', - card: { - DEFAULT: 'hsl(var(--card))', - foreground: 'hsl(var(--card-foreground))' - }, - popover: { - DEFAULT: 'hsl(var(--popover))', - foreground: 'hsl(var(--popover-foreground))' - }, - primary: { - DEFAULT: 'hsl(var(--primary))', - foreground: 'hsl(var(--primary-foreground))' - }, - secondary: { - DEFAULT: 'hsl(var(--secondary))', - foreground: 'hsl(var(--secondary-foreground))' - }, - muted: { - DEFAULT: 'hsl(var(--muted))', - foreground: 'hsl(var(--muted-foreground))' - }, - accent: { - DEFAULT: 'hsl(var(--accent))', - foreground: 'hsl(var(--accent-foreground))' - }, - destructive: { - DEFAULT: 'hsl(var(--destructive))', - foreground: 'hsl(var(--destructive-foreground))' - }, - warning: { - DEFAULT: 'hsl(var(--warning))', - "foreground": 'hsl(var(--warning-foreground))', + content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], + theme: { + extend: { + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)" }, - border: 'hsl(var(--border))', - input: 'hsl(var(--input))', - ring: 'hsl(var(--ring))', - chart: { - '1': 'hsl(var(--chart-1))', - '2': 'hsl(var(--chart-2))', - '3': 'hsl(var(--chart-3))', - '4': 'hsl(var(--chart-4))', - '5': 'hsl(var(--chart-5))' - } - } - }, - fontFamily: { - "bootstrap": ["-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "Noto Sans", "Liberation Sans", "sans-serif", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"] - } - }, - plugins: [require("tailwindcss-animate")], -} - + colors: { + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))" + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))" + }, + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))" + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))" + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))" + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))" + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))" + }, + warning: { + DEFAULT: "hsl(var(--warning))", + foreground: "hsl(var(--warning-foreground))" + }, + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + chart: { + 1: "hsl(var(--chart-1))", + 2: "hsl(var(--chart-2))", + 3: "hsl(var(--chart-3))", + 4: "hsl(var(--chart-4))", + 5: "hsl(var(--chart-5))" + } + } + }, + fontFamily: { + bootstrap: [ + "-apple-system", + "BlinkMacSystemFont", + "Segoe UI", + "Roboto", + "Helvetica Neue", + "Arial", + "Noto Sans", + "Liberation Sans", + "sans-serif", + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji" + ] + } + }, + plugins: [require("tailwindcss-animate")] +}; diff --git a/tsconfig.json b/tsconfig.json index d8433b1a..04f1a754 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,10 @@ { - "files": [], - "references": [ - { "path": "./tsconfig.app.json" }, - { "path": "./tsconfig.node.json" } - ], - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] + "files": [], + "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }], + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } } - } } diff --git a/tsconfig.node.json b/tsconfig.node.json index 0d3d7144..716bc288 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "target": "ES2022", - "lib": ["ES2023"], - "module": "ESNext", - "skipLibCheck": true, + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "isolatedModules": true, - "moduleDetection": "force", - "noEmit": true, + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["vite.config.ts"] + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts"] }