Merge branch 'beta' into bulkgacha

This commit is contained in:
David Yang 2025-05-04 22:33:23 +08:00 committed by GitHub
commit 5554c491ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1268 changed files with 52336 additions and 38888 deletions

View File

@ -65,7 +65,7 @@ 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? - [ ] The PR is self-contained and cannot be split into smaller PRs?
- [ ] Have I provided a clear explanation of the changes? - [ ] Have I provided a clear explanation of the changes?
- [ ] Have I tested the changes manually? - [ ] Have I tested the changes manually?
- [ ] Are all unit tests still passing? (`npm run test`) - [ ] Are all unit tests still passing? (`npm run test:silent`)
- [ ] Have I created new automated tests (`npm run create-test`) or updated existing tests related to the PR's changes? - [ ] Have I created new automated tests (`npm run create-test`) or updated existing tests related to the PR's changes?
- [ ] Have I provided screenshots/videos of the changes (if applicable)? - [ ] 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)? - [ ] Have I made sure that any UI change works for both UI themes (default and legacy)?

73
.github/workflows/create-release.yml vendored Normal file
View 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

View File

@ -4,18 +4,23 @@ on:
push: push:
branches: branches:
- beta - beta
- release
workflow_run:
types: completed
workflows: ["Post Release Deleted"]
jobs: jobs:
deploy: deploy:
if: github.repository == 'pagefaultgames/pokerogue' if: github.repository == 'pagefaultgames/pokerogue' && github.ref_name == ${{ vars.BETA_DEPLOY_BRANCH || 'beta' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
submodules: 'recursive' submodules: "recursive"
ref: ${{ vars.BETA_DEPLOY_BRANCH || 'beta'}}
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: "20" node-version-file: ".nvmrc"
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- name: Build - name: Build

View File

@ -18,7 +18,7 @@ jobs:
submodules: 'recursive' submodules: 'recursive'
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: "20" node-version-file: '.nvmrc'
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- name: Build - name: Build

View File

@ -24,7 +24,7 @@ jobs:
steps: steps:
- name: Checkout repository for Typedoc - name: Checkout repository for Typedoc
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
submodules: 'recursive' submodules: 'recursive'
path: pokerogue_docs path: pokerogue_docs
@ -34,14 +34,14 @@ jobs:
sudo apt update sudo apt update
sudo apt install -y git openssh-client sudo apt install -y git openssh-client
- name: Setup Node 20.13.1 - name: Setup Node 22.14.1
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version-file: "pokerogue_docs/.nvmrc"
- name: Checkout repository for Github Pages - name: Checkout repository for Github Pages
if: github.event_name == 'push' if: github.event_name == 'push'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
path: pokerogue_gh path: pokerogue_gh
ref: gh-pages ref: gh-pages

View 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"

View File

@ -29,6 +29,7 @@ jobs:
uses: actions/setup-node@v4 # Use the setup-node action version 4 uses: actions/setup-node@v4 # Use the setup-node action version 4
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'npm'
- name: Install Node.js dependencies # Step to install Node.js dependencies - name: Install Node.js dependencies # Step to install Node.js dependencies
run: npm ci # Use 'npm ci' to install dependencies run: npm ci # Use 'npm ci' to install dependencies

View File

@ -19,13 +19,14 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@v4 uses: actions/checkout@v4.2.2
with: with:
submodules: 'recursive' submodules: 'recursive'
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version-file: '.nvmrc'
cache: 'npm'
- name: Install Node.js dependencies - name: Install Node.js dependencies
run: npm ci run: npm ci
- name: Run tests - name: Run tests

View File

@ -7,10 +7,52 @@ on:
branches: branches:
- main # Trigger on push events to the main branch - main # Trigger on push events to the main branch
- beta # Trigger on push events to the beta branch - beta # Trigger on push events to the beta branch
- release # Trigger on push events to the release branch
# go upvote https://github.com/actions/runner/issues/1182 and yell at microsoft until they fix this or ditch yml for workflows
paths:
# src and test files
- "src/**"
- "test/**"
- "public/**"
# Workflows that can impact tests
- ".github/workflows/test*.yml"
# top-level files
- "package*.json"
- ".nvrmc" # Updates to node version can break tests
- "vite.*.ts" # vite.config.ts, vite.vitest.config.ts, vitest.workspace.ts
- "tsconfig*.json" # tsconfig.json tweaking can impact compilation
- "global.d.ts"
- ".env.*"
# Blanket negations for files that cannot impact tests
- "!**/*.py" # No .py files
- "!**/*.sh" # No .sh files
- "!**/*.md" # No .md files
- "!**/.git*" # .gitkeep and family
pull_request: pull_request:
branches: branches:
- main # Trigger on pull request events targeting the main branch - main # Trigger on pull request events targeting the main branch
- beta # Trigger on pull request events targeting the beta branch - beta # Trigger on pull request events targeting the beta branch
- release # Trigger on pull request events targeting the release branch
paths: # go upvote https://github.com/actions/runner/issues/1182 and yell at microsoft because until then we have to duplicate this
# src and test files
- "src/**"
- "test/**"
- "public/**"
# Workflows that can impact tests
- ".github/workflows/test*.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.*"
# Blanket negations for files that cannot impact tests
- "!**/*.py" # No .py files
- "!**/*.sh" # No .sh files
- "!**/*.md" # No .md files
- "!**/.git*" # .gitkeep and family
merge_group: merge_group:
types: [checks_requested] types: [checks_requested]

3
.gitignore vendored
View File

@ -13,7 +13,8 @@ dist-ssr
*.local *.local
# Editor directories and files # Editor directories and files
.vscode/* .vscode
*.code-workspace
.idea .idea
.DS_Store .DS_Store
*.suo *.suo

2
.nvmrc
View File

@ -1 +1 @@
v20.13.1 v22.14.0

View File

@ -12,7 +12,7 @@ If you have the motivation and experience with Typescript/Javascript (or are wil
#### Prerequisites #### Prerequisites
- node: 20.13.1 - node: 22.14.0
- npm: [how to install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - npm: [how to install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
#### Running Locally #### Running Locally

View File

@ -31,13 +31,16 @@
"src/overrides.ts", "src/overrides.ts",
// TODO: these files are too big and complex, ignore them until their respective refactors // TODO: these files are too big and complex, ignore them until their respective refactors
"src/data/moves/move.ts", "src/data/moves/move.ts",
"src/data/ability.ts", "src/data/abilities/ability.ts",
"src/field/pokemon.ts", "src/field/pokemon.ts",
// this file is just too big: // this file is just too big:
"src/data/balance/tms.ts" "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 }, "organizeImports": { "enabled": false },
"linter": { "linter": {
"ignore": [ "ignore": [
@ -55,31 +58,35 @@
}, },
"style": { "style": {
"noVar": "error", "noVar": "error",
"useEnumInitializers": "off", "useEnumInitializers": "off", // large enums like Moves/Species would make this cumbersome
"useBlockStatements": "error", "useBlockStatements": "error",
"useConst": "error", "useConst": "error",
"useImportType": "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", "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 "useDefaultParameterLast": "off", // TODO: Fix spots in the codebase where this flag would be triggered, and then enable
"useSingleVarDeclarator": "off", "useSingleVarDeclarator": "off",
"useNodejsImportProtocol": "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": { "suspicious": {
"noDoubleEquals": "error", "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", "noExplicitAny": "off",
"noAssignInExpressions": "off", "noAssignInExpressions": "off",
"noPrototypeBuiltins": "off", "noPrototypeBuiltins": "off",
"noFallthroughSwitchClause": "off", "noFallthroughSwitchClause": "error", // Prevents accidental automatic fallthroughs in switch cases (use disable comment if needed)
"noImplicitAnyLet": "info", // TODO: Refactor and make this an error "noImplicitAnyLet": "warn", // TODO: Refactor and make this an error
"noRedeclare": "off", // TODO: Refactor and make this an error "noRedeclare": "info", // TODO: Refactor and make this an error
"noGlobalIsNan": "off", "noGlobalIsNan": "off",
"noAsyncPromiseExecutor": "warn" // TODO: Refactor and make this an error "noAsyncPromiseExecutor": "warn" // TODO: Refactor and make this an error
}, },
"complexity": { "complexity": {
"noExcessiveCognitiveComplexity": "warn", "noExcessiveCognitiveComplexity": "warn", // TODO: Refactor and make this an error
"useLiteralKeys": "off", "useLiteralKeys": "off",
"noForEach": "off", // Foreach vs for of is not that simple. "noForEach": "off", // Foreach vs for of is not that simple.
"noUselessSwitchCase": "off", // Explicit > Implicit "noUselessSwitchCase": "off", // Explicit > Implicit
@ -98,7 +105,10 @@
"linter": { "linter": {
"rules": { "rules": {
"performance": { "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
} }
} }
} }

View File

@ -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 - 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** 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.
- Comments should not be repeating chunks of code or explaining what 'true' and 'false' means in typescript - 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 - 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. - 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.
- 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! [^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).
- 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 # 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
/** /**
* Changes the type-based weather modifier if this move's power would be reduced by it * Attribute to put in a {@link https://bulbapedia.bulbagarden.net/wiki/Substitute_(doll) | Substitute Doll} for the user.
* @param user {@linkcode Pokemon} using this move */
* @param target {@linkcode Pokemon} target of this move export class AddSubstituteAttr extends MoveEffectAttr {
* @param move {@linkcode Move} being used /** The ratio of the user's max HP that is required to apply this effect */
* @param args [0] {@linkcode Utils.NumberHolder} for arenaAttackTypeMultiplier private hpCost: number;
* @returns true if the function succeeds /** 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 { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
// code removed
} }
/** Set to true when experimental animated sprites from Gen6+ are used */ getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
public experimentalSprites: boolean = false; // code removed
}
getCondition(): MoveConditionFunc {
// code removed
}
/** /**
* Cures the user's party of non-volatile status conditions, ie. Heal Bell, Aromatherapy * Get the substitute-specific failure message if one should be displayed.
* @extends MoveAttr * @param user - The pokemon using the move.
* @see {@linkcode apply} * @returns The substitute-specific failure message if the conditions apply, otherwise `undefined`
*/ */
export class DontHealThePartyPlsAttr extends MoveAttr { 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: ### What not to do:
- Don't leave comments for code you don't understand - 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 - 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? ## 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. 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: ### 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. - 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 - Keep this in mind for functions that are not the `apply` function as they are usually sparse and mostly reused
- The class itself must be documented
- This must include the `@extends BaseClass` and `@see {@linkcode apply}` tags
- Class member variables must be documented - Class member variables must be documented
- You can use a single line documentation comment for these `/** i.e. a comment like this */` - You can use a single line documentation comment for these `/** i.e. a comment like this */`
- `args` parameters must be documented if used - `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 ```ts
/** /**
... ...
* @param args [0] {@linkcode Utils.NumberHolder} of arenaAttackTypeMultiplier * @param args -
* [1] {@linkcode Utils.BooleanHolder} of cancelled * `[0]` The {@linkcode Move} being used
* [2] {@linkcode Utils.BooleanHolder} of rWeDoneYet * `[1]` A {@linkcode BooleanHolder} used to track XYZ
* `[2]` {@linkcode BooleanHolder} `paramC` - paramC description here
... ...
*/ */
``` ```

View File

@ -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: 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. 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. 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. 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. 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)). 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: 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)"). - 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). - 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. - 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. 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. 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 ### 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).
![equation](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BTS%7D=%5Ctext%7BUBS%7D+%5Ctext%7BTBS%7D%5Ctimes%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D-1&%5Ctext%7Bif%20target%20is%20an%20opponent%7D%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) $$
\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: 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`: More specifically, the following steps are taken to compute the move's `attackScore`:
1. Compute a multiplier based on the move's type effectiveness: 1. Compute a multiplier based on the move's type effectiveness:
![typeMultEqn](https://latex.codecogs.com/png.image?%5Cdpi%7B110%7D%5Cbg%7Bwhite%7D%5Ctext%7BtypeMult%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D2&&%5Ctext%7Bif%20move%20is%20super%20effective(or%20better)%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: 2. Compute a multiplier based on the move's category and the user's offensive stats:
1. Compute the user's offensive stat ratio: 1. Compute the user's offensive stat ratio:
![statRatioEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BstatRatio%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D%5Cfrac%7B%5Ctext%7BuserSpAtk%7D%7D%7B%5Ctext%7BuserAtk%7D%7D&%5Ctext%7Bif%20move%20is%20physical%7D%5C%5C%5Cfrac%7B%5Ctext%7BuserAtk%7D%7D%7B%5Ctext%7BuserSpAtk%7D%7D&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) $$
\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: 2. Compute the stat-based multiplier:
![statMultEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BstatMult%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D2&%5Ctext%7Bif%20statRatio%7D%5Cle%200.75%5C%5C1.5&%5Ctext%7Bif%5C;%7D0.75%5Cle%5Ctext%7BstatRatio%7D%5Cle%200.875%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) $$
\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`: 3. Calculate the move's `attackScore`:
$\text{attackScore} = (\text{typeMult}\times \text{statMult})+\lfloor \frac{\text{power}}{5} \rfloor$ $\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: 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:
![TSSEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BTSS%7D=%5Ctext%7BTBS%7D%5Ctimes%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D-1&%5Ctext%7Bif%20target%20is%20an%20opponent%7D%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) $$
\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: 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. 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: 2. Normalize the weights. Let $w_n$ be the lowest-weighted target in the sorted list, then:
![normWeightEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7DW_i=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7Dw_i+%7Cw_n%7C&%5Ctext%7Bif%5C;%7Dw_n%5C;%5Ctext%7Bis%20negative%7D%5C%5Cw_i&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) $$
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}$ 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. 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)$, 5. For each target $(t_i, W_i)$,

View File

@ -1,40 +1,65 @@
# ESLint # Linting & Formatting
## Key Features
1. **Automation**: > "Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
- A pre-commit hook has been added to automatically run ESLint on the added or modified files, ensuring code quality before commits. >
> — Martin Fowler
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.
### 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.
# Using Biome
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.
## 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.
## 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.
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:
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 ```sh
npx eslint --fix . or npm run eslint npx biome check --[flags]
``` ```
- Running this command will lint all files in the repository.
3. **GitHub Action**: 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:
- A GitHub Action has been added to automatically run ESLint on every push and pull request, ensuring code quality in the CI/CD pipeline.
## Summary of ESLint Rules - `--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.
1. **General Rules**: ## Linting 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`).
2. **TypeScript-Specific 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].
- **Semicolons**:
- Enforce semicolons for TypeScript-specific syntax (`@typescript-eslint/semi`).
- Disallow unnecessary semicolons (`@typescript-eslint/no-extra-semi`).
## Benefits Some things to consider:
- **Consistency**: Ensures consistent coding style across the project. - We have disabled rules that prioritize style over performance, such as `useTemplate`.
- **Code Quality**: Helps catch potential errors and improve overall code quality. - 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.**
- **Readability**: Makes the codebase easier to read and maintain. - 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.

View File

@ -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 stylisticTs from "@stylistic/eslint-plugin-ts";
import parser from "@typescript-eslint/parser"; import parser from "@typescript-eslint/parser";
import importX from "eslint-plugin-import-x"; import importX from "eslint-plugin-import-x";
export default [ export default tseslint.config(
{ {
name: "eslint-config", name: "eslint-config",
files: ["src/**/*.{ts,tsx,js,jsx}", "test/**/*.{ts,tsx,js,jsx}"], files: ["src/**/*.{ts,tsx,js,jsx}", "test/**/*.{ts,tsx,js,jsx}"],
@ -14,12 +15,11 @@ export default [
plugins: { plugins: {
"import-x": importX, "import-x": importX,
"@stylistic/ts": stylisticTs, "@stylistic/ts": stylisticTs,
"@typescript-eslint": tseslint, "@typescript-eslint": tseslint.plugin,
}, },
rules: { 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-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 "import-x/extensions": ["error", "never", { json: "always" }], // Enforces no extension for imports unless json
}, },
}, },
@ -33,11 +33,11 @@ export default [
}, },
}, },
plugins: { plugins: {
"@typescript-eslint": tseslint, "@typescript-eslint": tseslint.plugin,
}, },
rules: { 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-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/ "@typescript-eslint/no-misused-promises": "error", // Disallow Promises in places not designed to handle them. - https://typescript-eslint.io/rules/no-misused-promises/
}, },
}, },
]; );

View File

@ -2,8 +2,7 @@ pre-commit:
parallel: true parallel: true
commands: commands:
biome-lint: biome-lint:
glob: "*.{js,jsx,ts,tsx}" run: npx biome check --write --reporter=summary --staged --no-errors-on-unmatched
run: npx @biomejs/biome check --write --reporter=summary {staged_files} --no-errors-on-unmatched
stage_fixed: true stage_fixed: true
skip: skip:
- merge - merge

258
package-lock.json generated
View File

@ -1,15 +1,16 @@
{ {
"name": "pokemon-rogue-battle", "name": "pokemon-rogue-battle",
"version": "1.8.4", "version": "1.9.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "pokemon-rogue-battle", "name": "pokemon-rogue-battle",
"version": "1.8.4", "version": "1.9.0",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@material/material-color-utilities": "^0.2.7", "@material/material-color-utilities": "^0.2.7",
"compare-versions": "^6.1.1",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"i18next": "^24.2.2", "i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.4", "i18next-browser-languagedetector": "^8.0.4",
@ -17,8 +18,8 @@
"i18next-korean-postposition-processor": "^1.0.0", "i18next-korean-postposition-processor": "^1.0.0",
"json-stable-stringify": "^1.2.0", "json-stable-stringify": "^1.2.0",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"phaser": "^3.70.0", "phaser": "^3.88.2",
"phaser3-rex-plugins": "^1.80.14" "phaser3-rex-plugins": "^1.80.15"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.9.4", "@biomejs/biome": "1.9.4",
@ -26,7 +27,7 @@
"@hpcc-js/wasm": "^2.22.4", "@hpcc-js/wasm": "^2.22.4",
"@stylistic/eslint-plugin-ts": "^4.1.0", "@stylistic/eslint-plugin-ts": "^4.1.0",
"@types/jsdom": "^21.1.7", "@types/jsdom": "^21.1.7",
"@types/node": "^20.12.13", "@types/node": "^22.13.14",
"@typescript-eslint/eslint-plugin": "^8.28.0", "@typescript-eslint/eslint-plugin": "^8.28.0",
"@typescript-eslint/parser": "^8.28.0", "@typescript-eslint/parser": "^8.28.0",
"@vitest/coverage-istanbul": "^3.0.9", "@vitest/coverage-istanbul": "^3.0.9",
@ -38,16 +39,17 @@
"lefthook": "^1.11.5", "lefthook": "^1.11.5",
"msw": "^2.7.3", "msw": "^2.7.3",
"phaser3spectorjs": "^0.0.8", "phaser3spectorjs": "^0.0.8",
"rollup": "^4.40.1",
"typedoc": "^0.28.1", "typedoc": "^0.28.1",
"typescript": "^5.8.2", "typescript": "^5.8.2",
"typescript-eslint": "^8.28.0", "typescript-eslint": "^8.28.0",
"vite": "^6.2.0", "vite": "^6.3.4",
"vite-tsconfig-paths": "^5.1.4", "vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.9", "vitest": "^3.0.9",
"vitest-canvas-mock": "^0.3.3" "vitest-canvas-mock": "^0.3.3"
}, },
"engines": { "engines": {
"node": ">=20.0.0" "node": ">=22.0.0"
} }
}, },
"node_modules/@ampproject/remapping": { "node_modules/@ampproject/remapping": {
@ -2160,9 +2162,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.1.tgz",
"integrity": "sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==", "integrity": "sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2174,9 +2176,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.1.tgz",
"integrity": "sha512-VUsgcy4GhhT7rokwzYQP+aV9XnSLkkhlEJ0St8pbasuWO/vwphhZQxYEKUP3ayeCYLhk6gEtacRpYP/cj3GjyQ==", "integrity": "sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2188,9 +2190,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.1.tgz",
"integrity": "sha512-buA17AYXlW9Rn091sWMq1xGUvWQFOH4N1rqUxGJtEQzhChxWjldGCCup7r/wUnaI6Au8sKXpoh0xg58a7cgcpg==", "integrity": "sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2202,9 +2204,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.1.tgz",
"integrity": "sha512-Mgcmc78AjunP1SKXl624vVBOF2bzwNWFPMP4fpOu05vS0amnLcX8gHIge7q/lDAHy3T2HeR0TqrriZDQS2Woeg==", "integrity": "sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2216,9 +2218,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.1.tgz",
"integrity": "sha512-zzJACgjLbQTsscxWqvrEQAEh28hqhebpRz5q/uUd1T7VTwUNZ4VIXQt5hE7ncs0GrF+s7d3S4on4TiXUY8KoQA==", "integrity": "sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2230,9 +2232,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.1.tgz",
"integrity": "sha512-hCY/KAeYMCyDpEE4pTETam0XZS4/5GXzlLgpi5f0IaPExw9kuB+PDTOTLuPtM10TlRG0U9OSmXJ+Wq9J39LvAg==", "integrity": "sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2244,9 +2246,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.1.tgz",
"integrity": "sha512-mimPH43mHl4JdOTD7bUMFhBdrg6f9HzMTOEnzRmXbOZqjijCw8LA5z8uL6LCjxSa67H2xiLFvvO67PT05PRKGg==", "integrity": "sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2258,9 +2260,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.1.tgz",
"integrity": "sha512-tPiJtiOoNuIH8XGG8sWoMMkAMm98PUwlriOFCCbZGc9WCax+GLeVRhmaxjJtz6WxrPKACgrwoZ5ia/uapq3ZVg==", "integrity": "sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2272,9 +2274,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.1.tgz",
"integrity": "sha512-wZco59rIVuB0tjQS0CSHTTUcEde+pXQWugZVxWaQFdQQ1VYub/sTrNdY76D1MKdN2NB48JDuGABP6o6fqos8mA==", "integrity": "sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2286,9 +2288,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.1.tgz",
"integrity": "sha512-fQgqwKmW0REM4LomQ+87PP8w8xvU9LZfeLBKybeli+0yHT7VKILINzFEuggvnV9M3x1Ed4gUBmGUzCo/ikmFbQ==", "integrity": "sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2300,9 +2302,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loongarch64-gnu": { "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.1.tgz",
"integrity": "sha512-hz5oqQLXTB3SbXpfkKHKXLdIp02/w3M+ajp8p4yWOWwQRtHWiEOCKtc9U+YXahrwdk+3qHdFMDWR5k+4dIlddg==", "integrity": "sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@ -2314,9 +2316,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.1.tgz",
"integrity": "sha512-NXqygK/dTSibQ+0pzxsL3r4Xl8oPqVoWbZV9niqOnIHV/J92fe65pOir0xjkUZDRSPyFRvu+4YOpJF9BZHQImw==", "integrity": "sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -2328,9 +2330,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.1.tgz",
"integrity": "sha512-GEAIabR1uFyvf/jW/5jfu8gjM06/4kZ1W+j1nWTSSB3w6moZEBm7iBtzwQ3a1Pxos2F7Gz+58aVEnZHU295QTg==", "integrity": "sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -2342,9 +2344,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-musl": { "node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.1.tgz",
"integrity": "sha512-9EYTX+Gus2EGPbfs+fh7l95wVADtSQyYw4DfSBcYdUEAmP2lqSZY0Y17yX/3m5VKGGJ4UmIH5LHLkMJft3bYoA==", "integrity": "sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -2356,9 +2358,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.1.tgz",
"integrity": "sha512-Mpp6+Z5VhB9VDk7RwZXoG2qMdERm3Jw07RNlXHE0bOnEeX+l7Fy4bg+NxfyN15ruuY3/7Vrbpm75J9QHFqj5+Q==", "integrity": "sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -2370,9 +2372,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.1.tgz",
"integrity": "sha512-vPvNgFlZRAgO7rwncMeE0+8c4Hmc+qixnp00/Uv3ht2x7KYrJ6ERVd3/R0nUtlE6/hu7/HiiNHJ/rP6knRFt1w==", "integrity": "sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2384,9 +2386,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.1.tgz",
"integrity": "sha512-q5Zv+goWvQUGCaL7fU8NuTw8aydIL/C9abAVGCzRReuj5h30TPx4LumBtAidrVOtXnlB+RZkBtExMsfqkMfb8g==", "integrity": "sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2398,9 +2400,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.1.tgz",
"integrity": "sha512-u/Jbm1BU89Vftqyqbmxdq14nBaQjQX1HhmsdBWqSdGClNaKwhjsg5TpW+5Ibs1mb8Es9wJiMdl86BcmtUVXNZg==", "integrity": "sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2412,9 +2414,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.1.tgz",
"integrity": "sha512-mqu4PzTrlpNHHbu5qleGvXJoGgHpChBlrBx/mEhTPpnAL1ZAYFlvHD7rLK839LLKQzqEQMFJfGrrOHItN4ZQqA==", "integrity": "sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -2426,9 +2428,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.1.tgz",
"integrity": "sha512-jjqy3uWlecfB98Psxb5cD6Fny9Fupv9LrDSPTQZUROqjvZmcCqNu4UMl7qqhlUUGpwiAkotj6GYu4SZdcr/nLw==", "integrity": "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2581,12 +2583,13 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.14.11", "version": "22.13.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz",
"integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", "integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~5.26.4" "undici-types": "~6.20.0"
} }
}, },
"node_modules/@types/statuses": { "node_modules/@types/statuses": {
@ -3605,6 +3608,12 @@
"node": ">=18" "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": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -4419,6 +4428,21 @@
"reusify": "^1.0.4" "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": { "node_modules/file-entry-cache": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
@ -6219,18 +6243,18 @@
} }
}, },
"node_modules/phaser": { "node_modules/phaser": {
"version": "3.80.1", "version": "3.88.2",
"resolved": "https://registry.npmjs.org/phaser/-/phaser-3.80.1.tgz", "resolved": "https://registry.npmjs.org/phaser/-/phaser-3.88.2.tgz",
"integrity": "sha512-VQGAWoDOkEpAWYkI+PUADv5Ql+SM0xpLuAMBJHz9tBcOLqjJ2wd8bUhxJgOqclQlLTg97NmMd9MhS75w16x1Cw==", "integrity": "sha512-UBgd2sAFuRJbF2xKaQ5jpMWB8oETncChLnymLGHcrnT53vaqiGrQWbUKUDBawKLm24sghjKo4Bf+/xfv8espZQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"eventemitter3": "^5.0.1" "eventemitter3": "^5.0.1"
} }
}, },
"node_modules/phaser3-rex-plugins": { "node_modules/phaser3-rex-plugins": {
"version": "1.80.14", "version": "1.80.15",
"resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.14.tgz", "resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.15.tgz",
"integrity": "sha512-eHi3VgryO9umNu6D1yQU5IS6tH4TyC2Y6RgJ495nNp37X2fdYnmYpBfgFg+YaumvtaoOvCkUVyi/YqWNPf2X2A==", "integrity": "sha512-Ur973N1W5st6XEYBcJko8eTcEbdDHMM+m7VqvT3j/EJeJwYyJ3bVb33JJDsFgefk3A2iAz2itP/UY7CzxJOJVA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"dagre": "^0.8.5", "dagre": "^0.8.5",
@ -6551,9 +6575,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.38.0", "version": "4.40.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.38.0.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.1.tgz",
"integrity": "sha512-5SsIRtJy9bf1ErAOiFMFzl64Ex9X5V7bnJ+WlFMb+zmP459OSWCEG7b0ERZ+PEU7xPt4OG3RHbrp1LJlXxYTrw==", "integrity": "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -6567,26 +6591,26 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.38.0", "@rollup/rollup-android-arm-eabi": "4.40.1",
"@rollup/rollup-android-arm64": "4.38.0", "@rollup/rollup-android-arm64": "4.40.1",
"@rollup/rollup-darwin-arm64": "4.38.0", "@rollup/rollup-darwin-arm64": "4.40.1",
"@rollup/rollup-darwin-x64": "4.38.0", "@rollup/rollup-darwin-x64": "4.40.1",
"@rollup/rollup-freebsd-arm64": "4.38.0", "@rollup/rollup-freebsd-arm64": "4.40.1",
"@rollup/rollup-freebsd-x64": "4.38.0", "@rollup/rollup-freebsd-x64": "4.40.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.38.0", "@rollup/rollup-linux-arm-gnueabihf": "4.40.1",
"@rollup/rollup-linux-arm-musleabihf": "4.38.0", "@rollup/rollup-linux-arm-musleabihf": "4.40.1",
"@rollup/rollup-linux-arm64-gnu": "4.38.0", "@rollup/rollup-linux-arm64-gnu": "4.40.1",
"@rollup/rollup-linux-arm64-musl": "4.38.0", "@rollup/rollup-linux-arm64-musl": "4.40.1",
"@rollup/rollup-linux-loongarch64-gnu": "4.38.0", "@rollup/rollup-linux-loongarch64-gnu": "4.40.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.38.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.40.1",
"@rollup/rollup-linux-riscv64-gnu": "4.38.0", "@rollup/rollup-linux-riscv64-gnu": "4.40.1",
"@rollup/rollup-linux-riscv64-musl": "4.38.0", "@rollup/rollup-linux-riscv64-musl": "4.40.1",
"@rollup/rollup-linux-s390x-gnu": "4.38.0", "@rollup/rollup-linux-s390x-gnu": "4.40.1",
"@rollup/rollup-linux-x64-gnu": "4.38.0", "@rollup/rollup-linux-x64-gnu": "4.40.1",
"@rollup/rollup-linux-x64-musl": "4.38.0", "@rollup/rollup-linux-x64-musl": "4.40.1",
"@rollup/rollup-win32-arm64-msvc": "4.38.0", "@rollup/rollup-win32-arm64-msvc": "4.40.1",
"@rollup/rollup-win32-ia32-msvc": "4.38.0", "@rollup/rollup-win32-ia32-msvc": "4.40.1",
"@rollup/rollup-win32-x64-msvc": "4.38.0", "@rollup/rollup-win32-x64-msvc": "4.40.1",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
@ -7035,6 +7059,23 @@
"dev": true, "dev": true,
"license": "MIT" "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": { "node_modules/tinypool": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz",
@ -7305,9 +7346,9 @@
"dev": true "dev": true
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "5.26.5", "version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -7405,15 +7446,18 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "6.2.4", "version": "6.3.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz",
"integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"fdir": "^6.4.4",
"picomatch": "^4.0.2",
"postcss": "^8.5.3", "postcss": "^8.5.3",
"rollup": "^4.30.1" "rollup": "^4.34.9",
"tinyglobby": "^0.2.13"
}, },
"bin": { "bin": {
"vite": "bin/vite.js" "vite": "bin/vite.js"

View File

@ -1,7 +1,7 @@
{ {
"name": "pokemon-rogue-battle", "name": "pokemon-rogue-battle",
"private": true, "private": true,
"version": "1.8.4", "version": "1.9.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "vite", "start": "vite",
@ -9,7 +9,7 @@
"build": "vite build", "build": "vite build",
"build:beta": "vite build --mode beta", "build:beta": "vite build --mode beta",
"preview": "vite preview", "preview": "vite preview",
"test": "vitest run", "test": "vitest run --no-isolate",
"test:cov": "vitest run --coverage --no-isolate", "test:cov": "vitest run --coverage --no-isolate",
"test:watch": "vitest watch --coverage --no-isolate", "test:watch": "vitest watch --coverage --no-isolate",
"test:silent": "vitest run --silent --no-isolate", "test:silent": "vitest run --silent --no-isolate",
@ -33,7 +33,7 @@
"@hpcc-js/wasm": "^2.22.4", "@hpcc-js/wasm": "^2.22.4",
"@stylistic/eslint-plugin-ts": "^4.1.0", "@stylistic/eslint-plugin-ts": "^4.1.0",
"@types/jsdom": "^21.1.7", "@types/jsdom": "^21.1.7",
"@types/node": "^20.12.13", "@types/node": "^22.13.14",
"@typescript-eslint/eslint-plugin": "^8.28.0", "@typescript-eslint/eslint-plugin": "^8.28.0",
"@typescript-eslint/parser": "^8.28.0", "@typescript-eslint/parser": "^8.28.0",
"@vitest/coverage-istanbul": "^3.0.9", "@vitest/coverage-istanbul": "^3.0.9",
@ -48,13 +48,14 @@
"typedoc": "^0.28.1", "typedoc": "^0.28.1",
"typescript": "^5.8.2", "typescript": "^5.8.2",
"typescript-eslint": "^8.28.0", "typescript-eslint": "^8.28.0",
"vite": "^6.2.0", "vite": "^6.3.4",
"vite-tsconfig-paths": "^5.1.4", "vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.9", "vitest": "^3.0.9",
"vitest-canvas-mock": "^0.3.3" "vitest-canvas-mock": "^0.3.3"
}, },
"dependencies": { "dependencies": {
"@material/material-color-utilities": "^0.2.7", "@material/material-color-utilities": "^0.2.7",
"compare-versions": "^6.1.1",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"i18next": "^24.2.2", "i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.4", "i18next-browser-languagedetector": "^8.0.4",
@ -62,10 +63,10 @@
"i18next-korean-postposition-processor": "^1.0.0", "i18next-korean-postposition-processor": "^1.0.0",
"json-stable-stringify": "^1.2.0", "json-stable-stringify": "^1.2.0",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"phaser": "^3.70.0", "phaser": "^3.88.2",
"phaser3-rex-plugins": "^1.80.14" "phaser3-rex-plugins": "^1.80.15"
}, },
"engines": { "engines": {
"node": ">=20.0.0" "node": ">=22.0.0"
} }
} }

View File

@ -613,12 +613,6 @@
"780", "780",
"781", "781",
"781", "781",
"782",
"782",
"783",
"783",
"784",
"784",
"785", "785",
"785", "785",
"786", "786",
@ -1733,12 +1727,6 @@
"780b", "780b",
"781b", "781b",
"781b", "781b",
"782b",
"782b",
"783b",
"783b",
"784b",
"784b",
"785b", "785b",
"785b", "785b",
"786b", "786b",
@ -2853,12 +2841,6 @@
"780sb", "780sb",
"781sb", "781sb",
"781sb", "781sb",
"782sb",
"782sb",
"783sb",
"783sb",
"784sb",
"784sb",
"785sb", "785sb",
"785sb", "785sb",
"786sb", "786sb",
@ -3978,12 +3960,6 @@
"780s", "780s",
"781s", "781s",
"781s", "781s",
"782s",
"782s",
"783s",
"783s",
"784s",
"784s",
"785s", "785s",
"785s", "785s",
"786s", "786s",

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -516,6 +516,34 @@
"trimmed": true, "trimmed": true,
"spriteSourceSize": { "x": 0, "y": 0, "w": 28, "h": 11 }, "spriteSourceSize": { "x": 0, "y": 0, "w": 28, "h": 11 },
"sourceSize": { "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": { "meta": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 B

After

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 B

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 B

After

Width:  |  Height:  |  Size: 409 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,41 +1,965 @@
{ { "frames": [
"textures": [
{
"image": "783.png",
"format": "RGBA8888",
"size": {
"w": 69,
"h": 69
},
"scale": 1,
"frames": [
{ {
"filename": "0001.png", "filename": "0001.png",
"frame": { "x": 66, "y": 214, "w": 61, "h": 69 },
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": true,
"sourceSize": { "spriteSourceSize": { "x": 5, "y": 2, "w": 61, "h": 69 },
"w": 61, "sourceSize": { "w": 76, "h": 71 },
"h": 69 "duration": 100
}, },
"spriteSourceSize": { {
"x": 0, "filename": "0002.png",
"y": 0, "frame": { "x": 336, "y": 146, "w": 62, "h": 69 },
"w": 61, "rotated": false,
"h": 69 "trimmed": true,
"spriteSourceSize": { "x": 6, "y": 2, "w": 62, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
}, },
"frame": { {
"x": 0, "filename": "0003.png",
"y": 0, "frame": { "x": 1, "y": 73, "w": 64, "h": 70 },
"w": 61, "rotated": false,
"h": 69 "trimmed": true,
} "spriteSourceSize": { "x": 7, "y": 1, "w": 64, "h": 70 },
} "sourceSize": { "w": 76, "h": 71 },
] "duration": 100
},
{
"filename": "0004.png",
"frame": { "x": 424, "y": 73, "w": 64, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 1, "w": 64, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0005.png",
"frame": { "x": 284, "y": 70, "w": 64, "h": 71 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 0, "w": 64, "h": 71 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0006.png",
"frame": { "x": 350, "y": 74, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0007.png",
"frame": { "x": 490, "y": 141, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0008.png",
"frame": { "x": 415, "y": 145, "w": 62, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 2, "w": 62, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0009.png",
"frame": { "x": 318, "y": 217, "w": 60, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 60, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0010.png",
"frame": { "x": 442, "y": 353, "w": 59, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 3, "w": 59, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0011.png",
"frame": { "x": 59, "y": 425, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0012.png",
"frame": { "x": 1, "y": 425, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0013.png",
"frame": { "x": 117, "y": 426, "w": 56, "h": 66 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 5, "w": 56, "h": 66 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0014.png",
"frame": { "x": 486, "y": 424, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0015.png",
"frame": { "x": 298, "y": 358, "w": 57, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 4, "w": 57, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0016.png",
"frame": { "x": 63, "y": 285, "w": 60, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 3, "w": 60, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0017.png",
"frame": { "x": 66, "y": 214, "w": 61, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 61, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0018.png",
"frame": { "x": 336, "y": 146, "w": 62, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 2, "w": 62, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0019.png",
"frame": { "x": 1, "y": 73, "w": 64, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 1, "w": 64, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0020.png",
"frame": { "x": 424, "y": 73, "w": 64, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 1, "w": 64, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0021.png",
"frame": { "x": 284, "y": 70, "w": 64, "h": 71 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 0, "w": 64, "h": 71 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0022.png",
"frame": { "x": 350, "y": 74, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0023.png",
"frame": { "x": 490, "y": 141, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0024.png",
"frame": { "x": 415, "y": 145, "w": 62, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 2, "w": 62, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0025.png",
"frame": { "x": 318, "y": 217, "w": 60, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 60, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0026.png",
"frame": { "x": 442, "y": 353, "w": 59, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 3, "w": 59, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0027.png",
"frame": { "x": 59, "y": 425, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0028.png",
"frame": { "x": 1, "y": 425, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0029.png",
"frame": { "x": 117, "y": 426, "w": 56, "h": 66 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 5, "w": 56, "h": 66 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0030.png",
"frame": { "x": 486, "y": 424, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0031.png",
"frame": { "x": 298, "y": 358, "w": 57, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 4, "w": 57, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0032.png",
"frame": { "x": 63, "y": 285, "w": 60, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 3, "w": 60, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0033.png",
"frame": { "x": 66, "y": 214, "w": 61, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 61, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0034.png",
"frame": { "x": 336, "y": 146, "w": 62, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 2, "w": 62, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0035.png",
"frame": { "x": 1, "y": 73, "w": 64, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 1, "w": 64, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0036.png",
"frame": { "x": 424, "y": 73, "w": 64, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 1, "w": 64, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0037.png",
"frame": { "x": 284, "y": 70, "w": 64, "h": 71 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 0, "w": 64, "h": 71 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0038.png",
"frame": { "x": 350, "y": 74, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0039.png",
"frame": { "x": 490, "y": 141, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0040.png",
"frame": { "x": 415, "y": 145, "w": 62, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 2, "w": 62, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0041.png",
"frame": { "x": 318, "y": 217, "w": 60, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 60, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0042.png",
"frame": { "x": 442, "y": 353, "w": 59, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 3, "w": 59, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0043.png",
"frame": { "x": 59, "y": 425, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0044.png",
"frame": { "x": 1, "y": 425, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0045.png",
"frame": { "x": 117, "y": 426, "w": 56, "h": 66 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 5, "w": 56, "h": 66 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0046.png",
"frame": { "x": 486, "y": 424, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0047.png",
"frame": { "x": 298, "y": 358, "w": 57, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 4, "w": 57, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0048.png",
"frame": { "x": 63, "y": 285, "w": 60, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 3, "w": 60, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0049.png",
"frame": { "x": 66, "y": 214, "w": 61, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 61, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0050.png",
"frame": { "x": 336, "y": 146, "w": 62, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 2, "w": 62, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0051.png",
"frame": { "x": 1, "y": 73, "w": 64, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 1, "w": 64, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0052.png",
"frame": { "x": 424, "y": 73, "w": 64, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 1, "w": 64, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0053.png",
"frame": { "x": 284, "y": 70, "w": 64, "h": 71 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 0, "w": 64, "h": 71 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0054.png",
"frame": { "x": 350, "y": 74, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0055.png",
"frame": { "x": 490, "y": 141, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0056.png",
"frame": { "x": 415, "y": 145, "w": 62, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 2, "w": 62, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0057.png",
"frame": { "x": 318, "y": 217, "w": 60, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 60, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0058.png",
"frame": { "x": 442, "y": 353, "w": 59, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 3, "w": 59, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0059.png",
"frame": { "x": 59, "y": 425, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0060.png",
"frame": { "x": 1, "y": 425, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0061.png",
"frame": { "x": 117, "y": 426, "w": 56, "h": 66 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 5, "w": 56, "h": 66 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0062.png",
"frame": { "x": 486, "y": 424, "w": 56, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 4, "w": 56, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0063.png",
"frame": { "x": 298, "y": 358, "w": 57, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 4, "w": 57, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0064.png",
"frame": { "x": 63, "y": 285, "w": 60, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 3, "w": 60, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0065.png",
"frame": { "x": 255, "y": 214, "w": 61, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 61, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0066.png",
"frame": { "x": 462, "y": 283, "w": 60, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 2, "w": 60, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0067.png",
"frame": { "x": 309, "y": 288, "w": 59, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 2, "w": 59, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0068.png",
"frame": { "x": 370, "y": 356, "w": 57, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 2, "w": 57, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0069.png",
"frame": { "x": 380, "y": 287, "w": 60, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 2, "w": 60, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0070.png",
"frame": { "x": 1, "y": 215, "w": 63, "h": 66 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 0, "y": 3, "w": 63, "h": 66 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0071.png",
"frame": { "x": 492, "y": 1, "w": 68, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 3, "w": 68, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0072.png",
"frame": { "x": 284, "y": 1, "w": 70, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 4, "w": 70, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0073.png",
"frame": { "x": 72, "y": 1, "w": 71, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 3, "w": 71, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0074.png",
"frame": { "x": 214, "y": 1, "w": 68, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 68, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0075.png",
"frame": { "x": 214, "y": 72, "w": 65, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 65, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0076.png",
"frame": { "x": 66, "y": 214, "w": 61, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 61, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0077.png",
"frame": { "x": 67, "y": 142, "w": 63, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 1, "w": 63, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0078.png",
"frame": { "x": 424, "y": 1, "w": 66, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 1, "w": 66, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0079.png",
"frame": { "x": 1, "y": 1, "w": 69, "h": 70 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 1, "w": 69, "h": 70 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0080.png",
"frame": { "x": 145, "y": 1, "w": 67, "h": 71 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 0, "w": 67, "h": 71 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0081.png",
"frame": { "x": 356, "y": 1, "w": 66, "h": 71 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 0, "w": 66, "h": 71 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0082.png",
"frame": { "x": 121, "y": 355, "w": 57, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 2, "w": 57, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0083.png",
"frame": { "x": 239, "y": 426, "w": 54, "h": 67 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 4, "w": 54, "h": 67 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0084.png",
"frame": { "x": 357, "y": 425, "w": 55, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 3, "w": 55, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0085.png",
"frame": { "x": 429, "y": 423, "w": 55, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 55, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0086.png",
"frame": { "x": 180, "y": 356, "w": 57, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 57, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0087.png",
"frame": { "x": 66, "y": 214, "w": 61, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 61, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0088.png",
"frame": { "x": 271, "y": 143, "w": 63, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 2, "w": 63, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0089.png",
"frame": { "x": 72, "y": 71, "w": 65, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 2, "w": 65, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0090.png",
"frame": { "x": 187, "y": 285, "w": 59, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 2, "w": 59, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0091.png",
"frame": { "x": 192, "y": 214, "w": 61, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 2, "w": 61, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0092.png",
"frame": { "x": 206, "y": 143, "w": 63, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 2, "w": 63, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0093.png",
"frame": { "x": 492, "y": 70, "w": 65, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 2, "w": 65, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0094.png",
"frame": { "x": 503, "y": 353, "w": 58, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 2, "w": 58, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0095.png",
"frame": { "x": 129, "y": 214, "w": 61, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 2, "w": 61, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0096.png",
"frame": { "x": 132, "y": 144, "w": 63, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 3, "w": 63, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0097.png",
"frame": { "x": 139, "y": 74, "w": 65, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 3, "w": 65, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0098.png",
"frame": { "x": 61, "y": 355, "w": 58, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 3, "w": 58, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0099.png",
"frame": { "x": 125, "y": 285, "w": 60, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 3, "w": 60, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0100.png",
"frame": { "x": 479, "y": 213, "w": 62, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 3, "w": 62, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0101.png",
"frame": { "x": 1, "y": 145, "w": 63, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 3, "w": 63, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0102.png",
"frame": { "x": 239, "y": 356, "w": 57, "h": 68 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 3, "w": 57, "h": 68 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0103.png",
"frame": { "x": 1, "y": 354, "w": 58, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 2, "w": 58, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0104.png",
"frame": { "x": 248, "y": 285, "w": 59, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 2, "w": 59, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0105.png",
"frame": { "x": 1, "y": 283, "w": 60, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 2, "w": 60, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
},
{
"filename": "0106.png",
"frame": { "x": 400, "y": 216, "w": 60, "h": 69 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 2, "w": 60, "h": 69 },
"sourceSize": { "w": 76, "h": 71 },
"duration": 100
} }
], ],
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.aseprite.org/",
"version": "3.0", "version": "1.3.13-x64",
"smartupdate": "$TexturePacker:SmartUpdate:a352518568888797dbb97bf40e2075df:76c85cf57217dd8c084dd2b2591b9bef:aab166e28c744865a0296041224dd01b$" "image": "783.png",
"format": "I8",
"size": { "w": 562, "h": 494 },
"scale": "1"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,41 +1,812 @@
{ { "frames": [
"textures": [
{
"image": "784.png",
"format": "RGBA8888",
"size": {
"w": 81,
"h": 81
},
"scale": 1,
"frames": [
{ {
"filename": "0001.png", "filename": "0001.png",
"frame": { "x": 260, "y": 244, "w": 80, "h": 81 },
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": true,
"sourceSize": { "spriteSourceSize": { "x": 11, "y": 4, "w": 80, "h": 81 },
"w": 79, "sourceSize": { "w": 108, "h": 88 },
"h": 81 "duration": 100
}, },
"spriteSourceSize": { {
"x": 0, "filename": "0002.png",
"y": 0, "frame": { "x": 381, "y": 166, "w": 84, "h": 81 },
"w": 79, "rotated": false,
"h": 81 "trimmed": true,
"spriteSourceSize": { "x": 9, "y": 4, "w": 84, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
}, },
"frame": { {
"x": 0, "filename": "0003.png",
"y": 0, "frame": { "x": 291, "y": 161, "w": 88, "h": 81 },
"w": 79, "rotated": false,
"h": 81 "trimmed": true,
} "spriteSourceSize": { "x": 8, "y": 4, "w": 88, "h": 81 },
} "sourceSize": { "w": 108, "h": 88 },
] "duration": 100
},
{
"filename": "0004.png",
"frame": { "x": 106, "y": 80, "w": 94, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 5, "w": 94, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0005.png",
"frame": { "x": 422, "y": 1, "w": 99, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 6, "w": 99, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0006.png",
"frame": { "x": 1, "y": 1, "w": 103, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 7, "w": 103, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0007.png",
"frame": { "x": 106, "y": 1, "w": 104, "h": 77 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 8, "w": 104, "h": 77 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0008.png",
"frame": { "x": 212, "y": 1, "w": 102, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 0, "y": 7, "w": 102, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0009.png",
"frame": { "x": 316, "y": 79, "w": 96, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 5, "w": 96, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0010.png",
"frame": { "x": 414, "y": 82, "w": 89, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 3, "w": 89, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0011.png",
"frame": { "x": 505, "y": 165, "w": 82, "h": 83 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 2, "w": 82, "h": 83 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0012.png",
"frame": { "x": 325, "y": 333, "w": 77, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 4, "w": 77, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0013.png",
"frame": { "x": 237, "y": 410, "w": 76, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 6, "w": 76, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0014.png",
"frame": { "x": 483, "y": 333, "w": 77, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 5, "w": 77, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0015.png",
"frame": { "x": 585, "y": 332, "w": 78, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 5, "w": 78, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0016.png",
"frame": { "x": 165, "y": 252, "w": 78, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 4, "w": 78, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0017.png",
"frame": { "x": 260, "y": 244, "w": 80, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 11, "y": 4, "w": 80, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0018.png",
"frame": { "x": 381, "y": 166, "w": 84, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 4, "w": 84, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0019.png",
"frame": { "x": 291, "y": 161, "w": 88, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 4, "w": 88, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0020.png",
"frame": { "x": 106, "y": 80, "w": 94, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 5, "w": 94, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0021.png",
"frame": { "x": 422, "y": 1, "w": 99, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 6, "w": 99, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0022.png",
"frame": { "x": 1, "y": 1, "w": 103, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 7, "w": 103, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0023.png",
"frame": { "x": 106, "y": 1, "w": 104, "h": 77 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 8, "w": 104, "h": 77 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0024.png",
"frame": { "x": 212, "y": 1, "w": 102, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 0, "y": 7, "w": 102, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0025.png",
"frame": { "x": 316, "y": 79, "w": 96, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 5, "w": 96, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0026.png",
"frame": { "x": 414, "y": 82, "w": 89, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 3, "w": 89, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0027.png",
"frame": { "x": 505, "y": 165, "w": 82, "h": 83 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 2, "w": 82, "h": 83 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0028.png",
"frame": { "x": 325, "y": 333, "w": 77, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 4, "w": 77, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0029.png",
"frame": { "x": 237, "y": 410, "w": 76, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 6, "w": 76, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0030.png",
"frame": { "x": 483, "y": 333, "w": 77, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 5, "w": 77, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0031.png",
"frame": { "x": 585, "y": 332, "w": 78, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 5, "w": 78, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0032.png",
"frame": { "x": 165, "y": 252, "w": 78, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 4, "w": 78, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0033.png",
"frame": { "x": 260, "y": 244, "w": 80, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 11, "y": 4, "w": 80, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0034.png",
"frame": { "x": 381, "y": 166, "w": 84, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 4, "w": 84, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0035.png",
"frame": { "x": 291, "y": 161, "w": 88, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 4, "w": 88, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0036.png",
"frame": { "x": 106, "y": 80, "w": 94, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 5, "w": 94, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0037.png",
"frame": { "x": 422, "y": 1, "w": 99, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 6, "w": 99, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0038.png",
"frame": { "x": 1, "y": 1, "w": 103, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 7, "w": 103, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0039.png",
"frame": { "x": 106, "y": 1, "w": 104, "h": 77 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 8, "w": 104, "h": 77 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0040.png",
"frame": { "x": 212, "y": 1, "w": 102, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 0, "y": 7, "w": 102, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0041.png",
"frame": { "x": 316, "y": 79, "w": 96, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 5, "w": 96, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0042.png",
"frame": { "x": 414, "y": 82, "w": 89, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 3, "w": 89, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0043.png",
"frame": { "x": 505, "y": 165, "w": 82, "h": 83 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 2, "w": 82, "h": 83 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0044.png",
"frame": { "x": 325, "y": 333, "w": 77, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 4, "w": 77, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0045.png",
"frame": { "x": 237, "y": 410, "w": 76, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 6, "w": 76, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0046.png",
"frame": { "x": 483, "y": 333, "w": 77, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 5, "w": 77, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0047.png",
"frame": { "x": 585, "y": 332, "w": 78, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 5, "w": 78, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0048.png",
"frame": { "x": 165, "y": 252, "w": 78, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 4, "w": 78, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0049.png",
"frame": { "x": 260, "y": 244, "w": 80, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 11, "y": 4, "w": 80, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0050.png",
"frame": { "x": 381, "y": 166, "w": 84, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 4, "w": 84, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0051.png",
"frame": { "x": 291, "y": 161, "w": 88, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 4, "w": 88, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0052.png",
"frame": { "x": 106, "y": 80, "w": 94, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 5, "w": 94, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0053.png",
"frame": { "x": 422, "y": 1, "w": 99, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 6, "w": 99, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0054.png",
"frame": { "x": 1, "y": 1, "w": 103, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 7, "w": 103, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0055.png",
"frame": { "x": 106, "y": 1, "w": 104, "h": 77 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 8, "w": 104, "h": 77 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0056.png",
"frame": { "x": 212, "y": 1, "w": 102, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 0, "y": 7, "w": 102, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0057.png",
"frame": { "x": 316, "y": 79, "w": 96, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 1, "y": 5, "w": 96, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0058.png",
"frame": { "x": 414, "y": 82, "w": 89, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 2, "y": 3, "w": 89, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0059.png",
"frame": { "x": 505, "y": 165, "w": 82, "h": 83 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 2, "w": 82, "h": 83 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0060.png",
"frame": { "x": 325, "y": 333, "w": 77, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 4, "w": 77, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0061.png",
"frame": { "x": 237, "y": 410, "w": 76, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 6, "w": 76, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0062.png",
"frame": { "x": 483, "y": 333, "w": 77, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 5, "w": 77, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0063.png",
"frame": { "x": 585, "y": 332, "w": 78, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 5, "w": 78, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0064.png",
"frame": { "x": 165, "y": 252, "w": 78, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 4, "w": 78, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0065.png",
"frame": { "x": 83, "y": 246, "w": 80, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 11, "y": 4, "w": 80, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0066.png",
"frame": { "x": 589, "y": 166, "w": 83, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 4, "w": 83, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0067.png",
"frame": { "x": 1, "y": 162, "w": 89, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 5, "w": 89, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0068.png",
"frame": { "x": 1, "y": 81, "w": 95, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 6, "w": 95, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0069.png",
"frame": { "x": 624, "y": 1, "w": 100, "h": 78 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 7, "w": 100, "h": 78 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0070.png",
"frame": { "x": 316, "y": 1, "w": 104, "h": 76 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 4, "y": 9, "w": 104, "h": 76 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0071.png",
"frame": { "x": 523, "y": 1, "w": 99, "h": 79 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 6, "w": 99, "h": 79 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0072.png",
"frame": { "x": 505, "y": 82, "w": 90, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 14, "y": 4, "w": 90, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0073.png",
"frame": { "x": 624, "y": 81, "w": 88, "h": 83 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 11, "y": 2, "w": 88, "h": 83 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0074.png",
"frame": { "x": 202, "y": 81, "w": 87, "h": 85 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 0, "w": 87, "h": 85 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0075.png",
"frame": { "x": 92, "y": 162, "w": 84, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 8, "y": 3, "w": 84, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0076.png",
"frame": { "x": 159, "y": 335, "w": 76, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 5, "w": 76, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0077.png",
"frame": { "x": 562, "y": 414, "w": 75, "h": 74 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 14, "w": 75, "h": 74 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0078.png",
"frame": { "x": 1, "y": 412, "w": 75, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 7, "w": 75, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0079.png",
"frame": { "x": 78, "y": 413, "w": 76, "h": 77 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 9, "w": 76, "h": 77 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0080.png",
"frame": { "x": 404, "y": 333, "w": 77, "h": 80 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 6, "w": 77, "h": 80 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0081.png",
"frame": { "x": 245, "y": 327, "w": 78, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 5, "w": 78, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0082.png",
"frame": { "x": 178, "y": 168, "w": 80, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 5, "y": 4, "w": 80, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0083.png",
"frame": { "x": 1, "y": 244, "w": 80, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 6, "y": 3, "w": 80, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0084.png",
"frame": { "x": 342, "y": 249, "w": 79, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 7, "y": 3, "w": 79, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0085.png",
"frame": { "x": 1, "y": 328, "w": 77, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 9, "y": 3, "w": 77, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0086.png",
"frame": { "x": 80, "y": 329, "w": 77, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 3, "w": 77, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0087.png",
"frame": { "x": 423, "y": 249, "w": 79, "h": 82 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 3, "w": 79, "h": 82 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0088.png",
"frame": { "x": 589, "y": 249, "w": 79, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 10, "y": 4, "w": 79, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
},
{
"filename": "0089.png",
"frame": { "x": 504, "y": 250, "w": 79, "h": 81 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 11, "y": 4, "w": 79, "h": 81 },
"sourceSize": { "w": 108, "h": 88 },
"duration": 100
} }
], ],
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.aseprite.org/",
"version": "3.0", "version": "1.3.13-x64",
"smartupdate": "$TexturePacker:SmartUpdate:dcfcb88e42dad35e57b259d31fbc6143:26fe93636d2b2e8c3da41c05f0648a08:c2f7ca3ab1075b8c824730653d891244$" "image": "784.png",
"format": "I8",
"size": { "w": 725, "h": 493 },
"scale": "1"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 B

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 902 B

After

Width:  |  Height:  |  Size: 936 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 659 B

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1022 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 B

After

Width:  |  Height:  |  Size: 922 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Some files were not shown because too many files have changed in this diff Show More