Merge branch 'beta' of https://github.com/pagefaultgames/pokerogue into readme-contributing
@ -1,9 +1,20 @@
|
||||
/** @type {import('dependency-cruiser').IConfiguration} */
|
||||
module.exports = {
|
||||
forbidden: [
|
||||
{
|
||||
name: "only-type-imports",
|
||||
severity: "error",
|
||||
comment: "Files in 'enums/' and '@types/' must only use type imports.",
|
||||
from: {
|
||||
path: ["(^|/)src/@types", "(^|/)src/enums"],
|
||||
},
|
||||
to: {
|
||||
dependencyTypesNot: ["type-only"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no-circular-at-runtime",
|
||||
severity: "warn",
|
||||
severity: "error",
|
||||
comment:
|
||||
"This dependency is part of a circular relationship. You might want to revise " +
|
||||
"your solution (i.e. use dependency inversion, make sure the modules have a single responsibility) ",
|
||||
@ -23,7 +34,7 @@ module.exports = {
|
||||
"add an exception for it in your dependency-cruiser configuration. By default " +
|
||||
"this rule does not scrutinize dot-files (e.g. .eslintrc.js), TypeScript declaration " +
|
||||
"files (.d.ts), tsconfig.json and some of the babel and webpack configs.",
|
||||
severity: "warn",
|
||||
severity: "error",
|
||||
from: {
|
||||
orphan: true,
|
||||
pathNot: [
|
||||
@ -31,6 +42,7 @@ module.exports = {
|
||||
"[.]d[.]ts$", // TypeScript declaration files
|
||||
"(^|/)tsconfig[.]json$", // TypeScript config
|
||||
"(^|/)(?:babel|webpack)[.]config[.](?:js|cjs|mjs|ts|cts|mts|json)$", // other configs
|
||||
"(^|/)test/.+[.]setup[.]ts", // Vitest setup files
|
||||
],
|
||||
},
|
||||
to: {},
|
||||
@ -40,7 +52,7 @@ module.exports = {
|
||||
comment:
|
||||
"A module depends on a node core module that has been deprecated. Find an alternative - these are " +
|
||||
"bound to exist - node doesn't deprecate lightly.",
|
||||
severity: "warn",
|
||||
severity: "error",
|
||||
from: {},
|
||||
to: {
|
||||
dependencyTypes: ["core"],
|
||||
@ -73,7 +85,7 @@ module.exports = {
|
||||
comment:
|
||||
"This module uses a (version of an) npm module that has been deprecated. Either upgrade to a later " +
|
||||
"version of that module, or find an alternative. Deprecated modules are a security risk.",
|
||||
severity: "warn",
|
||||
severity: "error",
|
||||
from: {},
|
||||
to: {
|
||||
dependencyTypes: ["deprecated"],
|
||||
@ -109,7 +121,7 @@ module.exports = {
|
||||
"Likely this module depends on an external ('npm') package that occurs more than once " +
|
||||
"in your package.json i.e. bot as a devDependencies and in dependencies. This will cause " +
|
||||
"maintenance problems later on.",
|
||||
severity: "warn",
|
||||
severity: "error",
|
||||
from: {},
|
||||
to: {
|
||||
moreThanOneDependencyType: true,
|
||||
@ -120,7 +132,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
|
||||
/* rules you might want to tweak for your specific situation: */
|
||||
// rules you might want to tweak for your specific situation:
|
||||
|
||||
{
|
||||
name: "not-to-spec",
|
||||
@ -175,7 +187,7 @@ module.exports = {
|
||||
"in your package.json. This makes sense if your package is e.g. a plugin, but in " +
|
||||
"other cases - maybe not so much. If the use of a peer dependency is intentional " +
|
||||
"add an exception to your dependency-cruiser configuration.",
|
||||
severity: "warn",
|
||||
severity: "error",
|
||||
from: {},
|
||||
to: {
|
||||
dependencyTypes: ["npm-peer"],
|
||||
@ -183,6 +195,7 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
options: {
|
||||
exclude: ["src/plugins/vite/*", "src/vite.env.d.ts"],
|
||||
/* Which modules not to follow further when encountered */
|
||||
doNotFollow: {
|
||||
/* path: an array of regular expressions in strings to match against */
|
||||
@ -222,7 +235,7 @@ module.exports = {
|
||||
true: also detect dependencies that only exist before typescript-to-javascript compilation
|
||||
"specify": for each dependency identify whether it only exists before compilation or also after
|
||||
*/
|
||||
// tsPreCompilationDeps: false,
|
||||
tsPreCompilationDeps: true,
|
||||
|
||||
/* list of extensions to scan that aren't javascript or compile-to-javascript.
|
||||
Empty by default. Only put extensions in here that you want to take into
|
||||
|
@ -1,6 +1,7 @@
|
||||
VITE_BYPASS_LOGIN=1
|
||||
VITE_BYPASS_TUTORIAL=0
|
||||
VITE_SERVER_URL=http://localhost:8001
|
||||
# IDs for discord/google auth go unused due to VITE_BYPASS_LOGIN
|
||||
VITE_DISCORD_CLIENT_ID=1234567890
|
||||
VITE_GOOGLE_CLIENT_ID=1234567890
|
||||
VITE_I18N_DEBUG=0
|
||||
|
11
.github/pull_request_template.md
vendored
@ -14,13 +14,16 @@ Make sure the title includes categorization (choose the one that best fits):
|
||||
- [Balance]: If the PR is related to game balance
|
||||
- [Challenge]: If the PR is adding or modifying challenges
|
||||
- [Refactor]: If the PR is primarily rewriting existing code
|
||||
- [Docs]: If the PR is just adding or modifying documentation (such as tsdocs/code comments)
|
||||
- [Dev]: If the PR is primarily changing something pertaining to development (lefthook hooks, linter rules, etc.)
|
||||
- [i18n]: If the PR is primarily adding/changing locale keys or key usage (may come with an associated locales PR)
|
||||
- [Docs]: If the PR is adding or modifying documentation (such as tsdocs/code comments)
|
||||
- [GitHub]: For changes to GitHub workflows/templates/etc
|
||||
- [Misc]: If no other category fits the PR
|
||||
-->
|
||||
|
||||
<!--
|
||||
Make sure that this PR is not overlapping with someone else's work
|
||||
Please try to keep the PR self-contained (and small)
|
||||
Please try to keep the PR self-contained (and small!)
|
||||
-->
|
||||
|
||||
## What are the changes the user will see?
|
||||
@ -65,8 +68,8 @@ Do the reviewers need to do something special in order to test your changes?
|
||||
- [ ] The PR is self-contained and cannot be split into smaller PRs?
|
||||
- [ ] Have I provided a clear explanation of the changes?
|
||||
- [ ] Have I tested the changes manually?
|
||||
- [ ] Are all unit tests still passing? (`npm run test`)
|
||||
- [ ] Have I created new automated tests (`npm run create-test`) or updated existing tests related to the PR's changes?
|
||||
- [ ] Are all unit tests still passing? (`npm run test:silent`)
|
||||
- [ ] Have I created new automated tests (`npm run test:create`) or updated existing tests related to the PR's changes?
|
||||
- [ ] Have I provided screenshots/videos of the changes (if applicable)?
|
||||
- [ ] Have I made sure that any UI change works for both UI themes (default and legacy)?
|
||||
|
||||
|
15
.github/test-filters.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
all:
|
||||
# Negations syntax from https://github.com/dorny/paths-filter/issues/184#issuecomment-2786521554
|
||||
- "src/**/!(*.{md,py,sh,gitkeep,gitignore})"
|
||||
- "test/**/!(*.{md,py,sh,gitkeep,gitignore})"
|
||||
- "public/**/!(*.{md,py,sh,gitkeep,gitignore})"
|
||||
# Workflows that can impact tests
|
||||
- ".github/workflows/test*.yml"
|
||||
- ".github/test-filters.yml"
|
||||
# top-level files
|
||||
- "package*.json"
|
||||
- ".nvrmc" # Updates to node version can break tests
|
||||
- "vite*" # vite.config.ts, vite.vitest.config.ts, vitest.workspace.ts
|
||||
- "tsconfig*.json" # tsconfig.json tweaking can impact compilation
|
||||
- "global.d.ts"
|
||||
- ".env*"
|
73
.github/workflows/create-release.yml
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
name: Create Release Branch
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
versionName:
|
||||
description: "Name of version (i.e. 1.9.0)"
|
||||
type: string
|
||||
required: true
|
||||
confirmVersion:
|
||||
type: string
|
||||
required: true
|
||||
description: "Confirm version name"
|
||||
|
||||
# explicitly specify the necessary scopes
|
||||
permissions:
|
||||
pull-requests: write
|
||||
actions: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
if: github.repository == 'pagefaultgames/pokerogue' && (vars.BETA_DEPLOY_BRANCH == '' || ! startsWith(vars.BETA_DEPLOY_BRANCH, 'release'))
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed for github cli commands
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Validate provided version
|
||||
# Ensure version matches confirmation and conforms to expected pattern.
|
||||
run: |
|
||||
if [[ "${{ github.event.inputs.versionName }}" != "${{ github.event.inputs.confirmVersion }}" ]]; then
|
||||
echo "Version name does not match confirmation. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! "${{ github.event.inputs.versionName }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "Version name must follow the format X.Y.Z where X, Y, and Z are all numbers. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
# Always base off of beta branch, regardless of the branch the workflow was triggered from.
|
||||
ref: beta
|
||||
- name: Create release branch
|
||||
run: git checkout -b release
|
||||
# In order to be able to open a PR into beta, we need the branch to have at least one change.
|
||||
- name: Overwrite RELEASE file
|
||||
run: |
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
echo "Release v${{ github.event.inputs.versionName }}" > RELEASE
|
||||
git add RELEASE
|
||||
git commit -m "Stage release v${{ github.event.inputs.versionName }}"
|
||||
- name: Push new branch
|
||||
run: git push origin release
|
||||
# The repository variable is used by the deploy-beta workflow to determine whether to deploy from beta or release.
|
||||
- name: Set repository variable
|
||||
run: GITHUB_TOKEN="${{ secrets.RW_VARS_PAT }}" gh variable set BETA_DEPLOY_BRANCH --body "release"
|
||||
- name: Create pull request to main
|
||||
run: |
|
||||
gh pr create --base main \
|
||||
--head release \
|
||||
--title "Release v${{ github.event.inputs.versionName }} to main" \
|
||||
--body "This PR is for the release of v${{ github.event.inputs.versionName }}, and was created automatically by the GitHub Actions workflow invoked by ${{ github.actor }}" \
|
||||
--draft
|
||||
- name: Create pull request to beta
|
||||
run: |
|
||||
gh pr create --base beta \
|
||||
--head release \
|
||||
--title "Release v${{ github.event.inputs.versionName }} to beta" \
|
||||
--body "This PR is for the release of v${{ github.event.inputs.versionName }}, and was created automatically by the GitHub Actions workflow invoked by ${{ github.actor }}" \
|
||||
--draft
|
11
.github/workflows/deploy-beta.yml
vendored
@ -4,18 +4,23 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- beta
|
||||
- release
|
||||
workflow_run:
|
||||
types: completed
|
||||
workflows: ["Post Release Deleted"]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
if: github.repository == 'pagefaultgames/pokerogue'
|
||||
if: github.repository == 'pagefaultgames/pokerogue' && github.ref_name == ${{ vars.BETA_DEPLOY_BRANCH || 'beta' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
submodules: "recursive"
|
||||
ref: ${{ vars.BETA_DEPLOY_BRANCH || 'beta'}}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
node-version-file: ".nvmrc"
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Build
|
||||
|
2
.github/workflows/deploy.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
submodules: 'recursive'
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
node-version-file: '.nvmrc'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Build
|
||||
|
10
.github/workflows/github-pages.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository for Typedoc
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
path: pokerogue_docs
|
||||
@ -34,14 +34,14 @@ jobs:
|
||||
sudo apt update
|
||||
sudo apt install -y git openssh-client
|
||||
|
||||
- name: Setup Node 20.13.1
|
||||
uses: actions/setup-node@v1
|
||||
- name: Setup Node 22.14.1
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version-file: "pokerogue_docs/.nvmrc"
|
||||
|
||||
- name: Checkout repository for Github Pages
|
||||
if: github.event_name == 'push'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: pokerogue_gh
|
||||
ref: gh-pages
|
||||
|
42
.github/workflows/linting.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
name: Linting
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
run-linters:
|
||||
name: Run linters
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install Node.js dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run ESLint
|
||||
run: npm run eslint-ci
|
||||
|
||||
- name: Lint with Biome
|
||||
run: npm run biome-ci
|
||||
|
||||
- name: Check dependencies with depcruise
|
||||
run: npm run depcruise
|
12
.github/workflows/post-release-deleted.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
name: Post Release Deleted
|
||||
on:
|
||||
delete:
|
||||
|
||||
jobs:
|
||||
# Set the BETA_DEPLOY_BRANCH variable to beta when a release branch is deleted
|
||||
update-release-var:
|
||||
if: github.repository == 'pagefaultgames/pokerogue' && github.event.ref_type == 'branch' && github.event.ref == 'release'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set BETA_DEPLOY_BRANCH to beta
|
||||
run: GITHUB_TOKEN="${{ secrets.RW_VARS_PAT }}" gh variable set BETA_DEPLOY_BRANCH --body "beta" --repo "pagefaultgames/pokerogue"
|
40
.github/workflows/quality.yml
vendored
@ -1,40 +0,0 @@
|
||||
name: Biome Code Quality
|
||||
|
||||
on:
|
||||
# Trigger the workflow on push or pull request,
|
||||
# but only for the main branch
|
||||
push:
|
||||
branches:
|
||||
- main # Trigger on push events to the main branch
|
||||
- beta # Trigger on push events to the beta branch
|
||||
pull_request:
|
||||
branches:
|
||||
- main # Trigger on pull request events targeting the main branch
|
||||
- beta # Trigger on pull request events targeting the beta branch
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
run-linters: # Define a job named "run-linters"
|
||||
name: Run linters # Human-readable name for the job
|
||||
runs-on: ubuntu-latest # Specify the latest Ubuntu runner for the job
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository # Step to check out the repository
|
||||
uses: actions/checkout@v4 # Use the checkout action version 4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Set up Node.js # Step to set up Node.js environment
|
||||
uses: actions/setup-node@v4 # Use the setup-node action version 4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Install Node.js dependencies # Step to install Node.js dependencies
|
||||
run: npm ci # Use 'npm ci' to install dependencies
|
||||
|
||||
- name: eslint # Step to run linters
|
||||
run: npm run eslint-ci
|
||||
|
||||
- name: Lint with Biome # Step to run linters
|
||||
run: npm run biome-ci
|
15
.github/workflows/test-shard-template.yml
vendored
@ -12,20 +12,27 @@ on:
|
||||
totalShards:
|
||||
required: true
|
||||
type: number
|
||||
skip:
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Shard ${{ inputs.shard }} of ${{ inputs.totalShards }}
|
||||
# We can't use dynmically named jobs until https://github.com/orgs/community/discussions/13261 is implemented
|
||||
name: Shard
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ !inputs.skip }}
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
submodules: "recursive"
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version-file: ".nvmrc"
|
||||
cache: "npm"
|
||||
- name: Install Node.js dependencies
|
||||
run: npm ci
|
||||
- name: Run tests
|
||||
|
20
.github/workflows/tests.yml
vendored
@ -15,13 +15,29 @@ on:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
check-path-change-filter:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: read
|
||||
outputs:
|
||||
all: ${{ steps.filter.outputs.all }}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36
|
||||
id: filter
|
||||
with:
|
||||
filters: .github/test-filters.yml
|
||||
|
||||
run-tests:
|
||||
name: Run Tests
|
||||
needs: check-path-change-filter
|
||||
strategy:
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
shard: [1, 2, 3, 4, 5]
|
||||
uses: ./.github/workflows/test-shard-template.yml
|
||||
with:
|
||||
project: main
|
||||
shard: ${{ matrix.shard }}
|
||||
totalShards: 10
|
||||
totalShards: 5
|
||||
skip: ${{ needs.check-path-change-filter.outputs.all != 'true'}}
|
||||
|
3
.gitignore
vendored
@ -13,7 +13,8 @@ dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
.vscode
|
||||
*.code-workspace
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
|
75
biome.jsonc
@ -28,63 +28,77 @@
|
||||
".vscode/*",
|
||||
"*.css", // TODO?
|
||||
"*.html", // TODO?
|
||||
"src/overrides.ts",
|
||||
// TODO: these files are too big and complex, ignore them until their respective refactors
|
||||
"src/data/moves/move.ts",
|
||||
"src/data/ability.ts",
|
||||
"src/field/pokemon.ts",
|
||||
|
||||
// this file is just too big:
|
||||
"src/data/balance/tms.ts"
|
||||
]
|
||||
},
|
||||
|
||||
// While it'd be nice to enable consistent sorting, enabling this causes issues due to circular import resolution order
|
||||
// TODO: Remove if we ever get down to 0 circular imports
|
||||
"organizeImports": { "enabled": false },
|
||||
"linter": {
|
||||
"ignore": [
|
||||
"src/phases/move-effect-phase.ts" // TODO: unignore after move-effect-phase refactor
|
||||
],
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"correctness": {
|
||||
"noUndeclaredVariables": "off",
|
||||
"noUnusedVariables": "error",
|
||||
"noSwitchDeclarations": "warn", // TODO: refactor and make this an error
|
||||
"noVoidTypeReturn": "warn", // TODO: Refactor and make this an error
|
||||
"noSwitchDeclarations": "error",
|
||||
"noVoidTypeReturn": "error",
|
||||
"noUnusedImports": "error"
|
||||
},
|
||||
"style": {
|
||||
"noVar": "error",
|
||||
"useEnumInitializers": "off",
|
||||
"useEnumInitializers": "off", // large enums like Moves/Species would make this cumbersome
|
||||
"useBlockStatements": "error",
|
||||
"useConst": "error",
|
||||
"useImportType": "error",
|
||||
"noNonNullAssertion": "off", // TODO: Turn this on ASAP and fix all non-null assertions
|
||||
"noNonNullAssertion": "off", // TODO: Turn this on ASAP and fix all non-null assertions in non-test files
|
||||
"noParameterAssign": "off",
|
||||
"useExponentiationOperator": "off",
|
||||
"useExponentiationOperator": "off", // Too typo-prone and easy to mixup with standard multiplication (* vs **)
|
||||
"useDefaultParameterLast": "off", // TODO: Fix spots in the codebase where this flag would be triggered, and then enable
|
||||
"useSingleVarDeclarator": "off",
|
||||
"useNodejsImportProtocol": "off",
|
||||
"useTemplate": "off" // string concatenation is faster: https://stackoverflow.com/questions/29055518/are-es6-template-literals-faster-than-string-concatenation
|
||||
"useTemplate": "off", // string concatenation is faster: https://stackoverflow.com/questions/29055518/are-es6-template-literals-faster-than-string-concatenation
|
||||
"noNamespaceImport": "error"
|
||||
},
|
||||
"suspicious": {
|
||||
"noDoubleEquals": "error",
|
||||
// While this would be a nice rule to enable, the current structure of the codebase makes this infeasible
|
||||
// due to being used for move/ability `args` params and save data-related code.
|
||||
// This can likely be enabled for all non-utils files once these are eventually reworked, but until then we leave it off.
|
||||
"noExplicitAny": "off",
|
||||
"noAssignInExpressions": "off",
|
||||
"noPrototypeBuiltins": "off",
|
||||
"noFallthroughSwitchClause": "off",
|
||||
"noImplicitAnyLet": "info", // TODO: Refactor and make this an error
|
||||
"noRedeclare": "off", // TODO: Refactor and make this an error
|
||||
"noFallthroughSwitchClause": "error", // Prevents accidental automatic fallthroughs in switch cases (use disable comment if needed)
|
||||
"noImplicitAnyLet": "warn", // TODO: Refactor and make this an error
|
||||
"noRedeclare": "info", // TODO: Refactor and make this an error
|
||||
"noGlobalIsNan": "off",
|
||||
"noAsyncPromiseExecutor": "warn" // TODO: Refactor and make this an error
|
||||
},
|
||||
"complexity": {
|
||||
"noExcessiveCognitiveComplexity": "warn",
|
||||
"noExcessiveCognitiveComplexity": "warn", // TODO: Refactor and make this an error
|
||||
"useLiteralKeys": "off",
|
||||
"noForEach": "off", // Foreach vs for of is not that simple.
|
||||
"noUselessSwitchCase": "off", // Explicit > Implicit
|
||||
"noUselessConstructor": "warn", // TODO: Refactor and make this an error
|
||||
"noUselessConstructor": "error",
|
||||
"noBannedTypes": "warn" // TODO: Refactor and make this an error
|
||||
},
|
||||
"nursery": {
|
||||
"noRestrictedTypes": {
|
||||
"level": "error",
|
||||
"options": {
|
||||
"types": {
|
||||
"integer": {
|
||||
"message": "This is an alias for 'number' that can provide false impressions of what values can actually be contained in this variable. Use 'number' instead.",
|
||||
"use": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -98,7 +112,32 @@
|
||||
"linter": {
|
||||
"rules": {
|
||||
"performance": {
|
||||
"noDelete": "off"
|
||||
"noDelete": "off" // TODO: evaluate if this is necessary for the test(s) to function
|
||||
},
|
||||
"style": {
|
||||
"noNamespaceImport": "off" // this is required for `vi.spyOn` to work in some tests
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Overrides to prevent unused import removal inside `overrides.ts` and enums files (for TSDoc linkcodes)
|
||||
{
|
||||
"include": ["src/overrides.ts", "src/enums/*"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"correctness": {
|
||||
"noUnusedImports": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"include": ["src/overrides.ts"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"style": {
|
||||
"useImportType": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,172 +0,0 @@
|
||||
/**
|
||||
* This script creates a test boilerplate file in the appropriate
|
||||
* directory based on the type selected.
|
||||
* @example npm run create-test
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import inquirer from "inquirer";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
// Get the directory name of the current module file
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const typeChoices = ["Move", "Ability", "Item", "Mystery Encounter"];
|
||||
|
||||
/**
|
||||
* Prompts the user to select a type via list.
|
||||
* @returns {Promise<{selectedOption: string}>} the selected type
|
||||
*/
|
||||
async function promptTestType() {
|
||||
const typeAnswer = await inquirer.prompt([
|
||||
{
|
||||
type: "list",
|
||||
name: "selectedOption",
|
||||
message: "What type of test would you like to create:",
|
||||
choices: [...typeChoices, "EXIT"],
|
||||
},
|
||||
]);
|
||||
|
||||
if (typeAnswer.selectedOption === "EXIT") {
|
||||
console.log("Exiting...");
|
||||
return process.exit();
|
||||
}
|
||||
if (!typeChoices.includes(typeAnswer.selectedOption)) {
|
||||
console.error(`Please provide a valid type (${typeChoices.join(", ")})!`);
|
||||
return await promptTestType();
|
||||
}
|
||||
|
||||
return typeAnswer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompts the user to provide a file name.
|
||||
* @param {string} selectedType
|
||||
* @returns {Promise<{userInput: string}>} the selected file name
|
||||
*/
|
||||
async function promptFileName(selectedType) {
|
||||
const fileNameAnswer = await inquirer.prompt([
|
||||
{
|
||||
type: "input",
|
||||
name: "userInput",
|
||||
message: `Please provide the name of the ${selectedType}:`,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!fileNameAnswer.userInput || fileNameAnswer.userInput.trim().length === 0) {
|
||||
console.error("Please provide a valid file name!");
|
||||
return await promptFileName(selectedType);
|
||||
}
|
||||
|
||||
return fileNameAnswer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the interactive create-test "CLI"
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function runInteractive() {
|
||||
const typeAnswer = await promptTestType();
|
||||
const fileNameAnswer = await promptFileName(typeAnswer.selectedOption);
|
||||
|
||||
const type = typeAnswer.selectedOption.toLowerCase();
|
||||
// Convert fileName from kebab-case or camelCase to snake_case
|
||||
const fileName = fileNameAnswer.userInput
|
||||
.replace(/-+/g, "_") // Convert kebab-case (dashes) to underscores
|
||||
.replace(/([a-z])([A-Z])/g, "$1_$2") // Convert camelCase to snake_case
|
||||
.replace(/\s+/g, "_") // Replace spaces with underscores
|
||||
.toLowerCase(); // Ensure all lowercase
|
||||
// Format the description for the test case
|
||||
|
||||
const formattedName = fileName.replace(/_/g, " ").replace(/\b\w/g, char => char.toUpperCase());
|
||||
// Determine the directory based on the type
|
||||
let dir;
|
||||
let description;
|
||||
switch (type) {
|
||||
case "move":
|
||||
dir = path.join(__dirname, "test", "moves");
|
||||
description = `Moves - ${formattedName}`;
|
||||
break;
|
||||
case "ability":
|
||||
dir = path.join(__dirname, "test", "abilities");
|
||||
description = `Abilities - ${formattedName}`;
|
||||
break;
|
||||
case "item":
|
||||
dir = path.join(__dirname, "test", "items");
|
||||
description = `Items - ${formattedName}`;
|
||||
break;
|
||||
case "mystery encounter":
|
||||
dir = path.join(__dirname, "test", "mystery-encounter", "encounters");
|
||||
description = `Mystery Encounter - ${formattedName}`;
|
||||
break;
|
||||
default:
|
||||
console.error(`Invalid type. Please use one of the following: ${typeChoices.join(", ")}.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Define the content template
|
||||
const content = `import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/testUtils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("${description}", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.moveset([ Moves.SPLASH ])
|
||||
.ability(Abilities.BALL_FETCH)
|
||||
.battleType("single")
|
||||
.disableCrits()
|
||||
.enemySpecies(Species.MAGIKARP)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(Moves.SPLASH);
|
||||
});
|
||||
|
||||
it("should do X", async () => {
|
||||
await game.classicMode.startBattle([ Species.FEEBAS ]);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
});
|
||||
`;
|
||||
|
||||
// Ensure the directory exists
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
|
||||
// Create the file with the given name
|
||||
const filePath = path.join(dir, `${fileName}.test.ts`);
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
console.error(`File "${fileName}.test.ts" already exists.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Write the template content to the file
|
||||
fs.writeFileSync(filePath, content, "utf8");
|
||||
|
||||
console.log(`File created at: ${filePath}`);
|
||||
}
|
||||
|
||||
runInteractive();
|
115
docs/comments.md
@ -1,64 +1,107 @@
|
||||
## How do I comment my code?
|
||||
# Commenting code
|
||||
|
||||
### While we're not enforcing a strict standard, there are some things to keep in mind:
|
||||
People spend more time reading code than writing it (sometimes substantially more so). As such, comments and documentation are **vital** for any large codebase like this.
|
||||
|
||||
## General Guidelines
|
||||
While we're not enforcing a strict standard, here are some things to keep in mind:
|
||||
- Make comments meaningful
|
||||
- Comments should be explaining why a line or block of code exists and what the reason behind it is
|
||||
- Comments should not be repeating chunks of code or explaining what 'true' and 'false' means in typescript
|
||||
- Comments should **NOT** repeat _what_ code _does_[^1] or explain concepts obvious to someone with a basic understanding of the language at hand. Instead, focus on explaining _why_ a line or block of code exists.
|
||||
- Anyone with basic reading comprehension and a good IDE can figure out what code does; gaining a _post hoc_ understanding of the _reasons_ behind its existence takes a lot more digging, effort and bloodshed.
|
||||
- Keep comments readable
|
||||
- A comment's verbosity should roughly scale with the complexity of its subject matter. Some people naturally write shorter or longer comments as a personal style, but summarizing a 300 line function with "does a thing" is about as good as writing nothing. Conversely, writing a paragraph-level response where a basic one-liner would suffice is no less undesirable.
|
||||
- Long comments should ideally be broken into multiple lines at around the 100-120 character mark. This isn't _mandatory_, but avoids unnecessary scrolling in terminals and IDEs.
|
||||
- Make sure comments exist on Functions, Classes, Methods, and Properties
|
||||
- This may be the most important things to comment. When someone goes to use a function/class/method/etc., having a comment reduces the need to flip back and forth between files to figure out how something works. Peek Definition is great until you're three nested functions deep.
|
||||
- The best example of this is JSDoc-style comments as seen below:
|
||||
- When formatted this way, the comment gets shown by intellisense in VS Code or similar IDEs just by hovering over the text!
|
||||
- Functions also show each the comment for parameter as you type them, making keeping track of what each one does in lengthy functions much more clear
|
||||
```js
|
||||
/**
|
||||
* Changes the type-based weather modifier if this move's power would be reduced by it
|
||||
* @param user {@linkcode Pokemon} using this move
|
||||
* @param target {@linkcode Pokemon} target of this move
|
||||
* @param move {@linkcode Move} being used
|
||||
* @param args [0] {@linkcode Utils.NumberHolder} for arenaAttackTypeMultiplier
|
||||
* @returns true if the function succeeds
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
}
|
||||
- These may be the most important things to comment. When someone goes to use a function/class/method/etc., having a comment reduces the need to flip back and forth between files to figure out what XYZ does. Peek Definition is great until you're three nested levels deep.
|
||||
|
||||
/** Set to true when experimental animated sprites from Gen6+ are used */
|
||||
public experimentalSprites: boolean = false;
|
||||
[^1]: With exceptions for extremely long, convoluted or unintuitive methods (though an over-dependency on said comments is likely a symptom of poorly structured code).
|
||||
|
||||
# TSDoc
|
||||
The codebase makes extensive use of [TSDoc](https://tsdoc.org), which is a TypeScript-specific version of [JSDoc](https://jsdoc.app/about-getting-started)
|
||||
that uses similar syntax and attaches to functions, classes, etc.
|
||||
|
||||
When formatted correctly, these comments are shown within VS Code or similar IDEs just by hovering over the function or object.
|
||||
- Functions also show the comment for each parameter as you type them, making keeping track of arguments inside lengthy functions much more clear.
|
||||
|
||||
They can also be used to generate a commentated overview of the codebase. There is a GitHub action that automatically updates [this docs site](https://pagefaultgames.github.io/pokerogue/main/index.html)
|
||||
and you can generate it locally as well via `npm run docs` which will generate into the `typedoc/` directory.
|
||||
|
||||
## Syntax
|
||||
For an example of how TSDoc comments work, here are some TSDoc comments taken from `src/data/moves/move.ts`:
|
||||
```ts
|
||||
/**
|
||||
* Cures the user's party of non-volatile status conditions, ie. Heal Bell, Aromatherapy
|
||||
* @extends MoveAttr
|
||||
* @see {@linkcode apply}
|
||||
* Attribute to put in a {@link https://bulbapedia.bulbagarden.net/wiki/Substitute_(doll) | Substitute Doll} for the user.
|
||||
*/
|
||||
export class DontHealThePartyPlsAttr extends MoveAttr {
|
||||
export class AddSubstituteAttr extends MoveEffectAttr {
|
||||
/** The ratio of the user's max HP that is required to apply this effect */
|
||||
private hpCost: number;
|
||||
/** Whether the damage taken should be rounded up (Shed Tail rounds up) */
|
||||
private roundUp: boolean;
|
||||
|
||||
constructor(hpCost: number, roundUp: boolean) {
|
||||
// code removed
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes 1/4 of the user's maximum HP (rounded down) to create a substitute for the user
|
||||
* @param user - The {@linkcode Pokemon} that used the move.
|
||||
* @param target - n/a
|
||||
* @param move - The {@linkcode Move} with this attribute.
|
||||
* @param args - n/a
|
||||
* @returns `true` if the attribute successfully applies, `false` otherwise
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
// code removed
|
||||
}
|
||||
|
||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
||||
// code removed
|
||||
}
|
||||
|
||||
getCondition(): MoveConditionFunc {
|
||||
// code removed
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the substitute-specific failure message if one should be displayed.
|
||||
* @param user - The pokemon using the move.
|
||||
* @returns The substitute-specific failure message if the conditions apply, otherwise `undefined`
|
||||
*/
|
||||
getFailedText(user: Pokemon, _target: Pokemon, _move: Move): string | undefined {
|
||||
// code removed
|
||||
}
|
||||
}
|
||||
```
|
||||
You'll notice this contains an `{@linkcode Object}` tag for each parameter. This provides an easy type denomination and hyperlink to that type using VS Code's Intellisense. `@linkcode` is used instead of `@link` so that the text appears in monospace which is more obviously a `type` rather than a random hyperlink.
|
||||
|
||||
If you're interested in going more in depth, you can find a reference guide for how comments like these work [here](https://jsdoc.app)
|
||||
Looking at the example given, you'll notice this contains an `{@linkcode XYZ}` tag in some of the parameters. This provides a clickable hyperlink to that type or object in most modern IDEs. (`@linkcode` is used here instead of `@link` so that the text appears in monospace which is more obviously a `type` rather than a random hyperlink.) \
|
||||
Also note the dashes (` - `) between the parameter names and descriptions - these are **mandatory** under the TSDoc spec[^2].
|
||||
|
||||
If you're interested in going more in depth, you can find a reference guide for how comments like these work [on the TSDoc website](https://tsdoc.org).
|
||||
The [playground page](https://tsdoc.org/play/) there can also be used for live testing of examples.
|
||||
|
||||
[^2]: Incidentally, this is also the only place dashes are explicitly _required_.
|
||||
|
||||
### What not to do:
|
||||
- Don't leave comments for code you don't understand
|
||||
- Incorrect information is worse than no information. If you aren't sure how something works, don't make something up to explain it. Ask for help instead.
|
||||
- Incorrect information is worse than no information. If you aren't sure how something works, don't make something up to explain it - ask for help and/or mark it as TODO.
|
||||
- Don't over-comment
|
||||
- Not everything needs an explanation. Try to summarize blocks of code instead of singular lines where possible. Single line comments should call out specific oddities.
|
||||
- Not everything needs a comment. Try to summarize blocks of code instead of singular lines where possible, always preferring giving a reason over stating a fact. Single line comments should call out specific oddities or features.
|
||||
|
||||
## How do Abilities and Moves differ from other classes?
|
||||
While other classes should be fully documented, Abilities and Moves heavily incoperate inheritance (i.e. the `extends` keyword). Because of this, much of the functionality in these classes is duplicated or only slightly changed between classes.
|
||||
### With this in mind, there's a few more things to keep in mind for these:
|
||||
- Do not document any parameters if the function mirrors the one they extend.
|
||||
- Keep this in mind for functions that are not the `apply` function as they are usually sparce and mostly reused
|
||||
- The class itself must be documented
|
||||
- This must include the `@extends BaseClass` and `@see {@linkcode apply}` tags
|
||||
- Keep this in mind for functions that are not the `apply` function as they are usually sparse and mostly reused
|
||||
- Class member variables must be documented
|
||||
- You can use a single line documentation comment for these `/** i.e. a comment like this */`
|
||||
- `args` parameters must be documented if used
|
||||
- This should look something like this when there are multiple:
|
||||
- This should look something vaguely like this when there are multiple:
|
||||
```ts
|
||||
/**
|
||||
...
|
||||
* @param args [0] {@linkcode Utils.NumberHolder} of arenaAttackTypeMultiplier
|
||||
* [1] {@linkcode Utils.BooleanHolder} of cancelled
|
||||
* [2] {@linkcode Utils.BooleanHolder} of rWeDoneYet
|
||||
* @param args -
|
||||
* `[0]` The {@linkcode Move} being used
|
||||
* `[1]` A {@linkcode BooleanHolder} used to track XYZ
|
||||
* `[2]` {@linkcode BooleanHolder} `paramC` - paramC description here
|
||||
...
|
||||
*/
|
||||
```
|
@ -54,13 +54,13 @@ At this point, the enemy (a wild or trainer Pokémon) has decided against switch
|
||||
In `getNextMove()`, the enemy Pokémon chooses a move to use in the following steps:
|
||||
1. If the Pokémon has a move in its Move Queue (e.g. the second turn of a charging move), and the queued move is still usable, use that move against the given target.
|
||||
2. Filter out any moves it can't use within its moveset. The remaining moves make up the enemy's **move pool** for the turn.
|
||||
1. A move can be unusable if it has no PP left or it has been disabled by another move or effect
|
||||
1. A move can be unusable if it has no PP left or it has been disabled by another move or effect.
|
||||
2. If the enemy's move pool is empty, use Struggle.
|
||||
3. Calculate the **move score** of each move in the enemy's move pool.
|
||||
1. A move's move score is equivalent to the move's maximum **target score** among all of the move's possible targets on the field ([more on this later](#calculating-move-and-target-scores)).
|
||||
2. A move's move score is set to -20 if at least one of these conditions are met:
|
||||
- The move is unimplemented (or, more precisely, the move's name ends with " (N)").
|
||||
- Conditions for the move to succeed are not met (unless the move is Sucker Punch, Upper Hand, or Thunderclap, as those moves' conditions can't be resolved before the turn starts).
|
||||
- The move is unimplemented (or, more precisely, the move's name ends with "(N)").
|
||||
- Conditions for the move to succeed are not met (unless the move is Sucker Punch, Upper Hand or Thunderclap, as those moves' conditions can't be resolved until after the turn starts).
|
||||
- The move's target scores are 0 or `NaN` for each target. In this case, the game assumes the target score calculation for that move is unimplemented.
|
||||
4. Sort the move pool in descending order of move scores.
|
||||
5. From here, the enemy's move selection varies based on its `aiType`. If the enemy is a Boss Pokémon or has a Trainer, it uses the `SMART` AI type; otherwise, it uses the `SMART_RANDOM` AI type.
|
||||
@ -73,9 +73,16 @@ In `getNextMove()`, the enemy Pokémon chooses a move to use in the following st
|
||||
|
||||
### Calculating Move and Target Scores
|
||||
|
||||
As part of the move selection process, the enemy Pokémon must compute a **target score (TS)** for each legal target for each move in its move pool. The base target score for all moves is a combination of the move's **user benefit score (UBS)** and **target benefit score (TBS)**.
|
||||
As part of the move selection process, the enemy Pokémon must compute a **target score (TS)** for each legal target for each move in its move pool. The base target score is a combination of the move's **user benefit score (UBS)** and **target benefit score (TBS)**, representing how much the move helps or hinders the user and/or its target(s).
|
||||
|
||||

|
||||
$$
|
||||
\text{TS} = \text{UBS} + \left( \text{TBS} \times
|
||||
\begin{cases}
|
||||
-1 & \text{if target is an opponent} \\
|
||||
1 & \text{otherwise}
|
||||
\end{cases}
|
||||
\right)
|
||||
$$
|
||||
|
||||
A move's UBS and TBS are computed with the respective functions in the `Move` class:
|
||||
|
||||
@ -98,14 +105,33 @@ In addition to the base score from `Move.getTargetBenefitScore()`, attack moves
|
||||
More specifically, the following steps are taken to compute the move's `attackScore`:
|
||||
1. Compute a multiplier based on the move's type effectiveness:
|
||||
|
||||
%7D%5C%5C-2&&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.)
|
||||
$$
|
||||
\text{typeMult} =
|
||||
\begin{cases}
|
||||
2 & \text{if move is super effective (or better)} \\
|
||||
-2 & \text{otherwise}
|
||||
\end{cases}
|
||||
$$
|
||||
2. Compute a multiplier based on the move's category and the user's offensive stats:
|
||||
1. Compute the user's offensive stat ratio:
|
||||
|
||||

|
||||
$$
|
||||
\text{statRatio} =
|
||||
\begin{cases}
|
||||
\frac{\text{userSpAtk}}{\text{userAtk}} & \text{if move is physical} \\
|
||||
\frac{\text{userAtk}}{\text{userSpAtk}} & \text{otherwise}
|
||||
\end{cases}
|
||||
$$
|
||||
2. Compute the stat-based multiplier:
|
||||
|
||||

|
||||
$$
|
||||
\text{statMult} =
|
||||
\begin{cases}
|
||||
2 & \text{if statRatio} \leq 0.75 \\
|
||||
1.5 & \text{if } 0.75 \leq \text{statRatio} \leq 0.875 \\
|
||||
1 & \text{otherwise}
|
||||
\end{cases}
|
||||
$$
|
||||
3. Calculate the move's `attackScore`:
|
||||
|
||||
$\text{attackScore} = (\text{typeMult}\times \text{statMult})+\lfloor \frac{\text{power}}{5} \rfloor$
|
||||
@ -125,13 +151,26 @@ The final step to calculate an attack move's target score (TS) is to multiply th
|
||||
|
||||
The enemy's target selection for single-target moves works in a very similar way to its move selection. Each potential target is given a **target selection score (TSS)** which is based on the move's [target benefit score](#calculating-move-and-target-scores) for that target:
|
||||
|
||||

|
||||
$$
|
||||
\text{TSS} = \text{TBS} \times
|
||||
\begin{cases}
|
||||
-1 & \text{if target is an opponent} \\
|
||||
1 & \text{otherwise}
|
||||
\end{cases}
|
||||
$$
|
||||
|
||||
Once the TSS is calculated for each target, the target is selected as follows:
|
||||
1. Sort the targets (indexes) in decreasing order of their target selection scores (or weights). Let $t_i$ be the index of the *i*-th target in the sorted list, and let $w_i$ be that target's corresponding TSS.
|
||||
2. Normalize the weights. Let $w_n$ be the lowest-weighted target in the sorted list, then:
|
||||
|
||||

|
||||
$$
|
||||
W_i =
|
||||
\begin{cases}
|
||||
w_i + |w_n| & \text{if } w_n \text{ is negative} \\
|
||||
w_i & \text{otherwise}
|
||||
\end{cases}
|
||||
$$
|
||||
|
||||
3. Remove all weights from the list such that $W_i < \frac{W_0}{2}$
|
||||
4. Generate a random integer $R=\text{rand}(0, W_{\text{total}})$ where $W_{\text{total}}$ is the sum of all the remaining weights after Step 3.
|
||||
5. For each target $(t_i, W_i)$,
|
||||
|
@ -1,40 +1,65 @@
|
||||
# ESLint
|
||||
## Key Features
|
||||
# Linting & Formatting
|
||||
|
||||
1. **Automation**:
|
||||
- A pre-commit hook has been added to automatically run ESLint on the added or modified files, ensuring code quality before commits.
|
||||
> "Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
|
||||
>
|
||||
> — Martin Fowler
|
||||
|
||||
2. **Manual Usage**:
|
||||
- If you prefer not to use the pre-commit hook, you can manually run ESLint to automatically fix issues using the command:
|
||||
```sh
|
||||
npx eslint --fix . or npm run eslint
|
||||
```
|
||||
- Running this command will lint all files in the repository.
|
||||
Writing clean, readable code is important, and linters and formatters are an integral part of ensuring code quality and readability.
|
||||
It is for this reason we are using [Biome](https://biomejs.dev), an opinionated linter/formatter (akin to Prettier) with a heavy focus on speed and performance.
|
||||
|
||||
3. **GitHub Action**:
|
||||
- A GitHub Action has been added to automatically run ESLint on every push and pull request, ensuring code quality in the CI/CD pipeline.
|
||||
### Installation
|
||||
You probably installed Biome already without noticing it - it's included inside `package.json` and should've been downloaded when you ran `npm install` after cloning the repo (assuming you followed proper instructions, that is). If you haven't done that yet, go do it.
|
||||
|
||||
## Summary of ESLint Rules
|
||||
# Using Biome
|
||||
|
||||
1. **General Rules**:
|
||||
- **Equality**: Use `===` and `!==` instead of `==` and `!=` (`eqeqeq`).
|
||||
- **Indentation**: Enforce 2-space indentation (`indent`).
|
||||
- **Quotes**: Use doublequotes for strings (`quotes`).
|
||||
- **Variable Declarations**:
|
||||
- Disallow `var`; use `let` or `const` (`no-var`).
|
||||
- Prefer `const` for variables that are never reassigned (`prefer-const`).
|
||||
- **Unused Variables**: Allow unused function parameters but enforce error for other unused variables (`@typescript-eslint/no-unused-vars`).
|
||||
- **End of Line**: Ensure at least one newline at the end of files (`eol-last`).
|
||||
- **Curly Braces**: Enforce the use of curly braces for all control statements (`curly`).
|
||||
- **Brace Style**: Use one true brace style (`1tbs`) for TypeScript-specific syntax (`@typescript-eslint/brace-style`).
|
||||
For the most part, Biome attempts to stay "out of your hair", letting you write code while enforcing a consistent formatting standard and only notifying for errors it can't automatically fix.\
|
||||
On the other hand, if Biome complains about a piece of code, **there's probably a good reason why**. Disable comments should be used sparingly or when readabilty demands it - your first instinct should be to fix the code in question, not disable the rule.
|
||||
|
||||
2. **TypeScript-Specific Rules**:
|
||||
- **Semicolons**:
|
||||
- Enforce semicolons for TypeScript-specific syntax (`@typescript-eslint/semi`).
|
||||
- Disallow unnecessary semicolons (`@typescript-eslint/no-extra-semi`).
|
||||
## Editor Integration
|
||||
Biome has integration with many popular code editors. See [these](https://biomejs.dev/guides/editors/first-party-extensions/) [pages](https://biomejs.dev/guides/editors/third-party-extensions/) for information about enabling Biome in your editor of choice.
|
||||
|
||||
## Benefits
|
||||
## Automated Runs
|
||||
Generally speaking, most users shouldn't need to run Biome directly; in addition to editor integration, [pre-commit hook](../lefthook.yml) will periodically run Biome before each commit.
|
||||
You will **not** be able to push code with `error`-level linting problems - fix them beforehand.
|
||||
|
||||
- **Consistency**: Ensures consistent coding style across the project.
|
||||
- **Code Quality**: Helps catch potential errors and improve overall code quality.
|
||||
- **Readability**: Makes the codebase easier to read and maintain.
|
||||
We also have a [Github Action](../.github/workflows/quality.yml) to verify code quality each time a PR is updated, preventing bad code from inadvertently making its way upstream.
|
||||
|
||||
### Why am I getting errors for code I didn't write?
|
||||
<!-- TODO: Remove this if/when we perform a project wide linting spree -->
|
||||
To save time and minimize friction with existing code, both the pre-commit hook and workflow run will only check files **directly changed** by a given PR or commit.
|
||||
As a result, changes to files not updated since Biome's introduction can cause any _prior_ linting errors in them to resurface and get flagged.
|
||||
This should occur less and less often as time passes and more files are updated to the new standard.
|
||||
|
||||
## Running Biome via CLI
|
||||
If you want Biome to check your files manually, you can run it from the command line like so:
|
||||
|
||||
```sh
|
||||
npx biome check --[flags]
|
||||
```
|
||||
|
||||
A full list of flags and options can be found on [their website](https://biomejs.dev/reference/cli/), but here's a few useful ones to keep in mind:
|
||||
|
||||
- `--write` will cause Biome to write all "safe" fixes and formatting changes directly to your files (rather than just complaining and doing nothing).
|
||||
- `--changed` and `--staged` will only perform checks on all changed or staged files respectively. Biome sources this info from the relevant version control system (in this case Git).
|
||||
- `diagnostic-level=XXX` will only show diagnostics with at least the given severity level (`info/warn/error`). Useful to only focus on errors causing a failed workflow run or similar.
|
||||
|
||||
## Linting Rules
|
||||
|
||||
We primarily use Biome's [recommended ruleset](https://biomejs.dev/linter/rules/) for linting JS/TS, with some customizations to better suit our project's needs[^1].
|
||||
|
||||
Some things to consider:
|
||||
|
||||
- We have disabled rules that prioritize style over performance, such as `useTemplate`.
|
||||
- Some rules are currently disabled or marked as warnings (`warn`) to allow for gradual refactoring without blocking development. **Do not write new code that triggers these warnings.**
|
||||
- The linter is configured to ignore specific files and folders (such as excessively large files or ones in need of refactoring) to improve performance and focus on actionable areas.
|
||||
|
||||
Any questions about linting rules should be brought up in the `#dev-corner` channel in the discord.
|
||||
|
||||
[^1]: A complete list of rules can be found in the `biome.jsonc` file in the project root.
|
||||
|
||||
## What about ESLint?
|
||||
|
||||
<!-- Remove if/when we finally ditch eslint for good -->
|
||||
Our project migrated away from ESLint around March 2025 due to it simply not scaling well enough with the codebase's ever-growing size. The [existing eslint rules](../eslint.config.js) are considered _deprecated_, only kept due to Biome lacking the corresponding rules in its current ruleset.
|
||||
|
||||
No additional ESLint rules should be added under any circumstances - even the few currently in circulation take longer to run than the entire Biome formatting/linting suite combined.
|
@ -1,9 +1,10 @@
|
||||
import tseslint from "@typescript-eslint/eslint-plugin";
|
||||
/** @ts-check */
|
||||
import tseslint from "typescript-eslint";
|
||||
import stylisticTs from "@stylistic/eslint-plugin-ts";
|
||||
import parser from "@typescript-eslint/parser";
|
||||
import importX from "eslint-plugin-import-x";
|
||||
|
||||
export default [
|
||||
export default tseslint.config(
|
||||
{
|
||||
name: "eslint-config",
|
||||
files: ["src/**/*.{ts,tsx,js,jsx}", "test/**/*.{ts,tsx,js,jsx}"],
|
||||
@ -14,12 +15,11 @@ export default [
|
||||
plugins: {
|
||||
"import-x": importX,
|
||||
"@stylistic/ts": stylisticTs,
|
||||
"@typescript-eslint": tseslint,
|
||||
"@typescript-eslint": tseslint.plugin,
|
||||
},
|
||||
rules: {
|
||||
"prefer-const": "error", // Enforces the use of `const` for variables that are never reassigned
|
||||
"no-undef": "off", // Disables the rule that disallows the use of undeclared variables (TypeScript handles this)
|
||||
"no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax
|
||||
"no-extra-semi": "error", // Disallows unnecessary semicolons for TypeScript-specific syntax
|
||||
"import-x/extensions": ["error", "never", { json: "always" }], // Enforces no extension for imports unless json
|
||||
},
|
||||
},
|
||||
@ -33,11 +33,11 @@ export default [
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
"@typescript-eslint": tseslint,
|
||||
"@typescript-eslint": tseslint.plugin,
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/no-floating-promises": "error", // Require Promise-like statements to be handled appropriately. - https://typescript-eslint.io/rules/no-floating-promises/
|
||||
"@typescript-eslint/no-misused-promises": "error", // Disallow Promises in places not designed to handle them. - https://typescript-eslint.io/rules/no-misused-promises/
|
||||
},
|
||||
},
|
||||
];
|
||||
);
|
||||
|
@ -145,6 +145,5 @@
|
||||
</div>
|
||||
<script type="module" src="./src/main.ts"></script>
|
||||
<script src="./src/touch-controls.ts" type="module"></script>
|
||||
<script src="./src/debug.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
@ -2,8 +2,7 @@ pre-commit:
|
||||
parallel: true
|
||||
commands:
|
||||
biome-lint:
|
||||
glob: "*.{js,jsx,ts,tsx}"
|
||||
run: npx @biomejs/biome check --write --reporter=summary {staged_files} --no-errors-on-unmatched
|
||||
run: npx biome check --write --reporter=summary --staged --no-errors-on-unmatched
|
||||
stage_fixed: true
|
||||
skip:
|
||||
- merge
|
||||
@ -13,3 +12,8 @@ post-merge:
|
||||
commands:
|
||||
update-submodules:
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
post-checkout:
|
||||
commands:
|
||||
update-submodules:
|
||||
run: git submodule update --init --recursive
|
258
package-lock.json
generated
@ -1,15 +1,16 @@
|
||||
{
|
||||
"name": "pokemon-rogue-battle",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pokemon-rogue-battle",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.6",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@material/material-color-utilities": "^0.2.7",
|
||||
"compare-versions": "^6.1.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"i18next": "^24.2.2",
|
||||
"i18next-browser-languagedetector": "^8.0.4",
|
||||
@ -17,8 +18,8 @@
|
||||
"i18next-korean-postposition-processor": "^1.0.0",
|
||||
"json-stable-stringify": "^1.2.0",
|
||||
"jszip": "^3.10.1",
|
||||
"phaser": "^3.70.0",
|
||||
"phaser3-rex-plugins": "^1.80.14"
|
||||
"phaser": "^3.88.2",
|
||||
"phaser3-rex-plugins": "^1.80.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
@ -26,7 +27,7 @@
|
||||
"@hpcc-js/wasm": "^2.22.4",
|
||||
"@stylistic/eslint-plugin-ts": "^4.1.0",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"@types/node": "^20.12.13",
|
||||
"@types/node": "^22.13.14",
|
||||
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||
"@typescript-eslint/parser": "^8.28.0",
|
||||
"@vitest/coverage-istanbul": "^3.0.9",
|
||||
@ -38,16 +39,17 @@
|
||||
"lefthook": "^1.11.5",
|
||||
"msw": "^2.7.3",
|
||||
"phaser3spectorjs": "^0.0.8",
|
||||
"rollup": "^4.40.1",
|
||||
"typedoc": "^0.28.1",
|
||||
"typescript": "^5.8.2",
|
||||
"typescript-eslint": "^8.28.0",
|
||||
"vite": "^6.2.0",
|
||||
"vite": "^6.3.4",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitest": "^3.0.9",
|
||||
"vitest-canvas-mock": "^0.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
@ -2160,9 +2162,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.38.0.tgz",
|
||||
"integrity": "sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.1.tgz",
|
||||
"integrity": "sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -2174,9 +2176,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.38.0.tgz",
|
||||
"integrity": "sha512-VUsgcy4GhhT7rokwzYQP+aV9XnSLkkhlEJ0St8pbasuWO/vwphhZQxYEKUP3ayeCYLhk6gEtacRpYP/cj3GjyQ==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.1.tgz",
|
||||
"integrity": "sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -2188,9 +2190,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.38.0.tgz",
|
||||
"integrity": "sha512-buA17AYXlW9Rn091sWMq1xGUvWQFOH4N1rqUxGJtEQzhChxWjldGCCup7r/wUnaI6Au8sKXpoh0xg58a7cgcpg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.1.tgz",
|
||||
"integrity": "sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -2202,9 +2204,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.38.0.tgz",
|
||||
"integrity": "sha512-Mgcmc78AjunP1SKXl624vVBOF2bzwNWFPMP4fpOu05vS0amnLcX8gHIge7q/lDAHy3T2HeR0TqrriZDQS2Woeg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.1.tgz",
|
||||
"integrity": "sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -2216,9 +2218,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.38.0.tgz",
|
||||
"integrity": "sha512-zzJACgjLbQTsscxWqvrEQAEh28hqhebpRz5q/uUd1T7VTwUNZ4VIXQt5hE7ncs0GrF+s7d3S4on4TiXUY8KoQA==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.1.tgz",
|
||||
"integrity": "sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -2230,9 +2232,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.38.0.tgz",
|
||||
"integrity": "sha512-hCY/KAeYMCyDpEE4pTETam0XZS4/5GXzlLgpi5f0IaPExw9kuB+PDTOTLuPtM10TlRG0U9OSmXJ+Wq9J39LvAg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.1.tgz",
|
||||
"integrity": "sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -2244,9 +2246,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.38.0.tgz",
|
||||
"integrity": "sha512-mimPH43mHl4JdOTD7bUMFhBdrg6f9HzMTOEnzRmXbOZqjijCw8LA5z8uL6LCjxSa67H2xiLFvvO67PT05PRKGg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.1.tgz",
|
||||
"integrity": "sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -2258,9 +2260,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.38.0.tgz",
|
||||
"integrity": "sha512-tPiJtiOoNuIH8XGG8sWoMMkAMm98PUwlriOFCCbZGc9WCax+GLeVRhmaxjJtz6WxrPKACgrwoZ5ia/uapq3ZVg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.1.tgz",
|
||||
"integrity": "sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -2272,9 +2274,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.38.0.tgz",
|
||||
"integrity": "sha512-wZco59rIVuB0tjQS0CSHTTUcEde+pXQWugZVxWaQFdQQ1VYub/sTrNdY76D1MKdN2NB48JDuGABP6o6fqos8mA==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.1.tgz",
|
||||
"integrity": "sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -2286,9 +2288,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.38.0.tgz",
|
||||
"integrity": "sha512-fQgqwKmW0REM4LomQ+87PP8w8xvU9LZfeLBKybeli+0yHT7VKILINzFEuggvnV9M3x1Ed4gUBmGUzCo/ikmFbQ==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.1.tgz",
|
||||
"integrity": "sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -2300,9 +2302,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.38.0.tgz",
|
||||
"integrity": "sha512-hz5oqQLXTB3SbXpfkKHKXLdIp02/w3M+ajp8p4yWOWwQRtHWiEOCKtc9U+YXahrwdk+3qHdFMDWR5k+4dIlddg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.1.tgz",
|
||||
"integrity": "sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@ -2314,9 +2316,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.38.0.tgz",
|
||||
"integrity": "sha512-NXqygK/dTSibQ+0pzxsL3r4Xl8oPqVoWbZV9niqOnIHV/J92fe65pOir0xjkUZDRSPyFRvu+4YOpJF9BZHQImw==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.1.tgz",
|
||||
"integrity": "sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@ -2328,9 +2330,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.38.0.tgz",
|
||||
"integrity": "sha512-GEAIabR1uFyvf/jW/5jfu8gjM06/4kZ1W+j1nWTSSB3w6moZEBm7iBtzwQ3a1Pxos2F7Gz+58aVEnZHU295QTg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.1.tgz",
|
||||
"integrity": "sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@ -2342,9 +2344,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.38.0.tgz",
|
||||
"integrity": "sha512-9EYTX+Gus2EGPbfs+fh7l95wVADtSQyYw4DfSBcYdUEAmP2lqSZY0Y17yX/3m5VKGGJ4UmIH5LHLkMJft3bYoA==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.1.tgz",
|
||||
"integrity": "sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@ -2356,9 +2358,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.38.0.tgz",
|
||||
"integrity": "sha512-Mpp6+Z5VhB9VDk7RwZXoG2qMdERm3Jw07RNlXHE0bOnEeX+l7Fy4bg+NxfyN15ruuY3/7Vrbpm75J9QHFqj5+Q==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.1.tgz",
|
||||
"integrity": "sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@ -2370,9 +2372,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.38.0.tgz",
|
||||
"integrity": "sha512-vPvNgFlZRAgO7rwncMeE0+8c4Hmc+qixnp00/Uv3ht2x7KYrJ6ERVd3/R0nUtlE6/hu7/HiiNHJ/rP6knRFt1w==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.1.tgz",
|
||||
"integrity": "sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -2384,9 +2386,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.38.0.tgz",
|
||||
"integrity": "sha512-q5Zv+goWvQUGCaL7fU8NuTw8aydIL/C9abAVGCzRReuj5h30TPx4LumBtAidrVOtXnlB+RZkBtExMsfqkMfb8g==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.1.tgz",
|
||||
"integrity": "sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -2398,9 +2400,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.38.0.tgz",
|
||||
"integrity": "sha512-u/Jbm1BU89Vftqyqbmxdq14nBaQjQX1HhmsdBWqSdGClNaKwhjsg5TpW+5Ibs1mb8Es9wJiMdl86BcmtUVXNZg==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.1.tgz",
|
||||
"integrity": "sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -2412,9 +2414,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.38.0.tgz",
|
||||
"integrity": "sha512-mqu4PzTrlpNHHbu5qleGvXJoGgHpChBlrBx/mEhTPpnAL1ZAYFlvHD7rLK839LLKQzqEQMFJfGrrOHItN4ZQqA==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.1.tgz",
|
||||
"integrity": "sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@ -2426,9 +2428,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.38.0.tgz",
|
||||
"integrity": "sha512-jjqy3uWlecfB98Psxb5cD6Fny9Fupv9LrDSPTQZUROqjvZmcCqNu4UMl7qqhlUUGpwiAkotj6GYu4SZdcr/nLw==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.1.tgz",
|
||||
"integrity": "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -2581,12 +2583,13 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.14.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
|
||||
"integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==",
|
||||
"version": "22.13.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz",
|
||||
"integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/statuses": {
|
||||
@ -3605,6 +3608,12 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/compare-versions": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz",
|
||||
"integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@ -4419,6 +4428,21 @@
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/fdir": {
|
||||
"version": "6.4.4",
|
||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
|
||||
"integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"picomatch": "^3 || ^4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"picomatch": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/file-entry-cache": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||
@ -6219,18 +6243,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/phaser": {
|
||||
"version": "3.80.1",
|
||||
"resolved": "https://registry.npmjs.org/phaser/-/phaser-3.80.1.tgz",
|
||||
"integrity": "sha512-VQGAWoDOkEpAWYkI+PUADv5Ql+SM0xpLuAMBJHz9tBcOLqjJ2wd8bUhxJgOqclQlLTg97NmMd9MhS75w16x1Cw==",
|
||||
"version": "3.88.2",
|
||||
"resolved": "https://registry.npmjs.org/phaser/-/phaser-3.88.2.tgz",
|
||||
"integrity": "sha512-UBgd2sAFuRJbF2xKaQ5jpMWB8oETncChLnymLGHcrnT53vaqiGrQWbUKUDBawKLm24sghjKo4Bf+/xfv8espZQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eventemitter3": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/phaser3-rex-plugins": {
|
||||
"version": "1.80.14",
|
||||
"resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.14.tgz",
|
||||
"integrity": "sha512-eHi3VgryO9umNu6D1yQU5IS6tH4TyC2Y6RgJ495nNp37X2fdYnmYpBfgFg+YaumvtaoOvCkUVyi/YqWNPf2X2A==",
|
||||
"version": "1.80.15",
|
||||
"resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.15.tgz",
|
||||
"integrity": "sha512-Ur973N1W5st6XEYBcJko8eTcEbdDHMM+m7VqvT3j/EJeJwYyJ3bVb33JJDsFgefk3A2iAz2itP/UY7CzxJOJVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dagre": "^0.8.5",
|
||||
@ -6551,9 +6575,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.38.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.38.0.tgz",
|
||||
"integrity": "sha512-5SsIRtJy9bf1ErAOiFMFzl64Ex9X5V7bnJ+WlFMb+zmP459OSWCEG7b0ERZ+PEU7xPt4OG3RHbrp1LJlXxYTrw==",
|
||||
"version": "4.40.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.1.tgz",
|
||||
"integrity": "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -6567,26 +6591,26 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.38.0",
|
||||
"@rollup/rollup-android-arm64": "4.38.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.38.0",
|
||||
"@rollup/rollup-darwin-x64": "4.38.0",
|
||||
"@rollup/rollup-freebsd-arm64": "4.38.0",
|
||||
"@rollup/rollup-freebsd-x64": "4.38.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.38.0",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.38.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.38.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.38.0",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.38.0",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.38.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.38.0",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.38.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.38.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.38.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.38.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.38.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.38.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.38.0",
|
||||
"@rollup/rollup-android-arm-eabi": "4.40.1",
|
||||
"@rollup/rollup-android-arm64": "4.40.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.40.1",
|
||||
"@rollup/rollup-darwin-x64": "4.40.1",
|
||||
"@rollup/rollup-freebsd-arm64": "4.40.1",
|
||||
"@rollup/rollup-freebsd-x64": "4.40.1",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.40.1",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.40.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.40.1",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.40.1",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.40.1",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.40.1",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.40.1",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.40.1",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.40.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.40.1",
|
||||
"@rollup/rollup-linux-x64-musl": "4.40.1",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.40.1",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.40.1",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.40.1",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@ -7035,6 +7059,23 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
|
||||
"integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fdir": "^6.4.4",
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||
}
|
||||
},
|
||||
"node_modules/tinypool": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz",
|
||||
@ -7305,9 +7346,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@ -7405,15 +7446,18 @@
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.2.4",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz",
|
||||
"integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==",
|
||||
"version": "6.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz",
|
||||
"integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.4.4",
|
||||
"picomatch": "^4.0.2",
|
||||
"postcss": "^8.5.3",
|
||||
"rollup": "^4.30.1"
|
||||
"rollup": "^4.34.9",
|
||||
"tinyglobby": "^0.2.13"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
|
21
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "pokemon-rogue-battle",
|
||||
"private": true,
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.6",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
@ -9,19 +9,19 @@
|
||||
"build": "vite build",
|
||||
"build:beta": "vite build --mode beta",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest run",
|
||||
"test": "vitest run --no-isolate",
|
||||
"test:cov": "vitest run --coverage --no-isolate",
|
||||
"test:watch": "vitest watch --coverage --no-isolate",
|
||||
"test:silent": "vitest run --silent --no-isolate",
|
||||
"test:create": "node scripts/create-test/create-test.js",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"eslint": "eslint --fix .",
|
||||
"eslint-ci": "eslint .",
|
||||
"biome": "biome check --write --changed --no-errors-on-unmatched",
|
||||
"biome-ci": "biome ci --diagnostic-level=error --reporter=github --changed --no-errors-on-unmatched",
|
||||
"biome-ci": "biome ci --diagnostic-level=error --reporter=github --no-errors-on-unmatched",
|
||||
"docs": "typedoc",
|
||||
"depcruise": "depcruise src",
|
||||
"depcruise": "depcruise src test",
|
||||
"depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg",
|
||||
"create-test": "node ./create-test-boilerplate.js",
|
||||
"postinstall": "npx lefthook install && npx lefthook run post-merge",
|
||||
"update-version:patch": "npm version patch --force --no-git-tag-version",
|
||||
"update-version:minor": "npm version minor --force --no-git-tag-version",
|
||||
@ -33,7 +33,7 @@
|
||||
"@hpcc-js/wasm": "^2.22.4",
|
||||
"@stylistic/eslint-plugin-ts": "^4.1.0",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"@types/node": "^20.12.13",
|
||||
"@types/node": "^22.13.14",
|
||||
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||
"@typescript-eslint/parser": "^8.28.0",
|
||||
"@vitest/coverage-istanbul": "^3.0.9",
|
||||
@ -48,13 +48,14 @@
|
||||
"typedoc": "^0.28.1",
|
||||
"typescript": "^5.8.2",
|
||||
"typescript-eslint": "^8.28.0",
|
||||
"vite": "^6.2.0",
|
||||
"vite": "^6.3.4",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitest": "^3.0.9",
|
||||
"vitest-canvas-mock": "^0.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@material/material-color-utilities": "^0.2.7",
|
||||
"compare-versions": "^6.1.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"i18next": "^24.2.2",
|
||||
"i18next-browser-languagedetector": "^8.0.4",
|
||||
@ -62,10 +63,10 @@
|
||||
"i18next-korean-postposition-processor": "^1.0.0",
|
||||
"json-stable-stringify": "^1.2.0",
|
||||
"jszip": "^3.10.1",
|
||||
"phaser": "^3.70.0",
|
||||
"phaser3-rex-plugins": "^1.80.14"
|
||||
"phaser": "^3.88.2",
|
||||
"phaser3-rex-plugins": "^1.80.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -542,6 +542,79 @@
|
||||
"volume": 100,
|
||||
"pitch": 55,
|
||||
"eventType": "AnimTimedSoundEvent"
|
||||
},
|
||||
{
|
||||
"frameIndex": 0,
|
||||
"resourceName": "PRAS- Sandstorm",
|
||||
"bgX": -50,
|
||||
"bgY": 0,
|
||||
"opacity": 0,
|
||||
"duration": 5,
|
||||
"eventType": "AnimTimedAddBgEvent"
|
||||
},
|
||||
{
|
||||
"frameIndex": 0,
|
||||
"resourceName": "",
|
||||
"bgX": -50,
|
||||
"bgY": 0,
|
||||
"opacity": 96,
|
||||
"duration": 3,
|
||||
"eventType": "AnimTimedUpdateBgEvent"
|
||||
}
|
||||
],
|
||||
"3": [
|
||||
{
|
||||
"frameIndex": 3,
|
||||
"resourceName": "",
|
||||
"bgX": -25,
|
||||
"bgY": 0,
|
||||
"opacity": 128,
|
||||
"duration": 3,
|
||||
"eventType": "AnimTimedUpdateBgEvent"
|
||||
}
|
||||
],
|
||||
"6": [
|
||||
{
|
||||
"frameIndex": 6,
|
||||
"resourceName": "",
|
||||
"bgX": 0,
|
||||
"bgY": 0,
|
||||
"opacity": 192,
|
||||
"duration": 3,
|
||||
"eventType": "AnimTimedUpdateBgEvent"
|
||||
}
|
||||
],
|
||||
"9": [
|
||||
{
|
||||
"frameIndex": 9,
|
||||
"resourceName": "",
|
||||
"bgX": 25,
|
||||
"bgY": 0,
|
||||
"opacity": 128,
|
||||
"duration": 3,
|
||||
"eventType": "AnimTimedUpdateBgEvent"
|
||||
}
|
||||
],
|
||||
"12": [
|
||||
{
|
||||
"frameIndex": 12,
|
||||
"resourceName": "",
|
||||
"bgX": 50,
|
||||
"bgY": 0,
|
||||
"opacity": 96,
|
||||
"duration": 3,
|
||||
"eventType": "AnimTimedUpdateBgEvent"
|
||||
}
|
||||
],
|
||||
"15": [
|
||||
{
|
||||
"frameIndex": 15,
|
||||
"resourceName": "",
|
||||
"bgX": 50,
|
||||
"bgY": 0,
|
||||
"opacity": 0,
|
||||
"duration": 3,
|
||||
"eventType": "AnimTimedUpdateBgEvent"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": 94,
|
||||
"graphic": "PRAS- PsychicBG",
|
||||
"graphic": "PRAS- Psychic BG",
|
||||
"frames": [
|
||||
[
|
||||
{
|
||||
|
@ -179,8 +179,6 @@
|
||||
"483-origin",
|
||||
"484-origin",
|
||||
"484-origin",
|
||||
"487-origin",
|
||||
"487-origin",
|
||||
"531-mega",
|
||||
"531-mega",
|
||||
"569-gigantamax",
|
||||
@ -597,6 +595,20 @@
|
||||
"774-yellow",
|
||||
"774",
|
||||
"774",
|
||||
"774-blue-meteor",
|
||||
"774-blue-meteor",
|
||||
"774-green-meteor",
|
||||
"774-green-meteor",
|
||||
"774-indigo-meteor",
|
||||
"774-indigo-meteor",
|
||||
"774-orange-meteor",
|
||||
"774-orange-meteor",
|
||||
"774-red-meteor",
|
||||
"774-red-meteor",
|
||||
"774-violet-meteor",
|
||||
"774-violet-meteor",
|
||||
"774-yellow-meteor",
|
||||
"774-yellow-meteor",
|
||||
"775",
|
||||
"775",
|
||||
"776",
|
||||
@ -613,12 +625,6 @@
|
||||
"780",
|
||||
"781",
|
||||
"781",
|
||||
"782",
|
||||
"782",
|
||||
"783",
|
||||
"783",
|
||||
"784",
|
||||
"784",
|
||||
"785",
|
||||
"785",
|
||||
"786",
|
||||
@ -1299,8 +1305,6 @@
|
||||
"483b-origin",
|
||||
"484b-origin",
|
||||
"484b-origin",
|
||||
"487b-origin",
|
||||
"487b-origin",
|
||||
"531b-mega",
|
||||
"531b-mega",
|
||||
"569b-gigantamax",
|
||||
@ -1715,6 +1719,20 @@
|
||||
"774b-violet",
|
||||
"774b-yellow",
|
||||
"774b-yellow",
|
||||
"774b-blue-meteor",
|
||||
"774b-blue-meteor",
|
||||
"774b-green-meteor",
|
||||
"774b-green-meteor",
|
||||
"774b-indigo-meteor",
|
||||
"774b-indigo-meteor",
|
||||
"774b-orange-meteor",
|
||||
"774b-orange-meteor",
|
||||
"774b-red-meteor",
|
||||
"774b-red-meteor",
|
||||
"774b-violet-meteor",
|
||||
"774b-violet-meteor",
|
||||
"774b-yellow-meteor",
|
||||
"774b-yellow-meteor",
|
||||
"774b",
|
||||
"774b",
|
||||
"775b",
|
||||
@ -1733,12 +1751,6 @@
|
||||
"780b",
|
||||
"781b",
|
||||
"781b",
|
||||
"782b",
|
||||
"782b",
|
||||
"783b",
|
||||
"783b",
|
||||
"784b",
|
||||
"784b",
|
||||
"785b",
|
||||
"785b",
|
||||
"786b",
|
||||
@ -2419,8 +2431,6 @@
|
||||
"483sb-origin",
|
||||
"484sb-origin",
|
||||
"484sb-origin",
|
||||
"487sb-origin",
|
||||
"487sb-origin",
|
||||
"531sb-mega",
|
||||
"531sb-mega",
|
||||
"569sb-gigantamax",
|
||||
@ -2835,6 +2845,20 @@
|
||||
"774sb-violet",
|
||||
"774sb-yellow",
|
||||
"774sb-yellow",
|
||||
"774sb-blue-meteor",
|
||||
"774sb-blue-meteor",
|
||||
"774sb-green-meteor",
|
||||
"774sb-green-meteor",
|
||||
"774sb-indigo-meteor",
|
||||
"774sb-indigo-meteor",
|
||||
"774sb-orange-meteor",
|
||||
"774sb-orange-meteor",
|
||||
"774sb-red-meteor",
|
||||
"774sb-red-meteor",
|
||||
"774sb-violet-meteor",
|
||||
"774sb-violet-meteor",
|
||||
"774sb-yellow-meteor",
|
||||
"774sb-yellow-meteor",
|
||||
"774sb",
|
||||
"774sb",
|
||||
"775sb",
|
||||
@ -2853,12 +2877,6 @@
|
||||
"780sb",
|
||||
"781sb",
|
||||
"781sb",
|
||||
"782sb",
|
||||
"782sb",
|
||||
"783sb",
|
||||
"783sb",
|
||||
"784sb",
|
||||
"784sb",
|
||||
"785sb",
|
||||
"785sb",
|
||||
"786sb",
|
||||
@ -3544,8 +3562,6 @@
|
||||
"483s-origin",
|
||||
"484s-origin",
|
||||
"484s-origin",
|
||||
"487s-origin",
|
||||
"487s-origin",
|
||||
"531s-mega",
|
||||
"531s-mega",
|
||||
"569s-gigantamax",
|
||||
@ -3960,6 +3976,20 @@
|
||||
"774s-violet",
|
||||
"774s-yellow",
|
||||
"774s-yellow",
|
||||
"774s-blue-meteor",
|
||||
"774s-blue-meteor",
|
||||
"774s-green-meteor",
|
||||
"774s-green-meteor",
|
||||
"774s-indigo-meteor",
|
||||
"774s-indigo-meteor",
|
||||
"774s-orange-meteor",
|
||||
"774s-orange-meteor",
|
||||
"774s-red-meteor",
|
||||
"774s-red-meteor",
|
||||
"774s-violet-meteor",
|
||||
"774s-violet-meteor",
|
||||
"774s-yellow-meteor",
|
||||
"774s-yellow-meteor",
|
||||
"774s",
|
||||
"774s",
|
||||
"775s",
|
||||
@ -3978,12 +4008,6 @@
|
||||
"780s",
|
||||
"781s",
|
||||
"781s",
|
||||
"782s",
|
||||
"782s",
|
||||
"783s",
|
||||
"783s",
|
||||
"784s",
|
||||
"784s",
|
||||
"785s",
|
||||
"785s",
|
||||
"786s",
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 3.7 KiB |
BIN
public/images/events/pride2025-de.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
public/images/events/pride2025-en.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
public/images/events/pride2025-es-ES.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
public/images/events/pride2025-es-MX.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
public/images/events/pride2025-fr.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
public/images/events/pride2025-it.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
public/images/events/pride2025-ja.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
public/images/events/pride2025-ko.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
public/images/events/pride2025-pt-BR.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
public/images/events/pride2025-zh-CN.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
public/images/events/pride2025-zh-TW.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
public/images/events/spr25event-de.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/images/events/spr25event-en.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
public/images/events/spr25event-es-ES.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
public/images/events/spr25event-es-MX.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
public/images/events/spr25event-fr.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
public/images/events/spr25event-it.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
public/images/events/spr25event-ja.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
public/images/events/spr25event-ko.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/images/events/spr25event-pt-BR.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
public/images/events/spr25event-zh-CN.png
Normal file
After Width: | Height: | Size: 36 KiB |
@ -516,6 +516,34 @@
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 28, "h": 11 },
|
||||
"sourceSize": { "w": 28, "h": 11 }
|
||||
},
|
||||
"BACK_SLASH.png": {
|
||||
"frame": { "x": 147, "y": 66, "w": 12, "h": 11 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 12, "h": 11 },
|
||||
"sourceSize": { "w": 12, "h": 11 }
|
||||
},
|
||||
"FORWARD_SLASH.png": {
|
||||
"frame": { "x": 144, "y": 55, "w": 12, "h": 11 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 12, "h": 11 },
|
||||
"sourceSize": { "w": 12, "h": 11 }
|
||||
},
|
||||
"COMMA.png": {
|
||||
"frame": { "x": 144, "y": 44, "w": 12, "h": 11 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 12, "h": 11 },
|
||||
"sourceSize": { "w": 12, "h": 11 }
|
||||
},
|
||||
"PERIOD.png": {
|
||||
"frame": { "x": 143, "y": 22, "w": 11, "h": 11 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 11, "h": 11 },
|
||||
"sourceSize": { "w": 11, "h": 11 }
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.6 KiB |
16524
public/images/items.json
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 915 B After Width: | Height: | Size: 884 B |
Before Width: | Height: | Size: 601 B After Width: | Height: | Size: 653 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 121 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 131 KiB |