[
  {
    "path": ".eslintrc.json",
    "content": "{\n    \"root\": true,\n    \"parser\": \"@typescript-eslint/parser\",\n    \"parserOptions\": {\n        \"ecmaVersion\": 6,\n        \"sourceType\": \"module\",\n        \"project\": \"./tsconfig.json\"\n    },\n    \"plugins\": [\n        \"@typescript-eslint\",\n        \"prettier\",\n        \"unused-imports\"\n    ],\n    \"extends\": [\n        \"eslint:recommended\",\n        \"plugin:@typescript-eslint/recommended\",\n        \"plugin:prettier/recommended\"\n    ],\n    \"rules\": {\n        \"@typescript-eslint/naming-convention\": \"warn\",\n        \"@typescript-eslint/semi\": \"warn\",\n        \"curly\": \"warn\",\n        \"eqeqeq\": \"warn\",\n        \"no-throw-literal\": \"warn\",\n        \"semi\": \"off\",\n        \"@typescript-eslint/no-inferrable-types\": \"off\",\n        \"no-unused-vars\": \"error\",\n        \"no-var\": \"off\",\n        \"no-fallthrough\": \"warn\",\n        \"unused-imports/no-unused-imports\": \"error\",\n        \"prefer-const\": \"error\",\n        \"@typescript-eslint/no-non-null-assertion\": \"warn\",\n        \"@typescript-eslint/no-floating-promises\": \"warn\",\n        \"prettier/prettier\": [\n            \"error\",\n            {\n                \"endOfLine\": \"auto\"\n            }\n        ]\n    },\n    \"ignorePatterns\": [\n        \"out\",\n        \"dist\",\n        \"node_modules\",\n        \".vscode\",\n        \"src/test\"\n    ]\n}\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "The VS Code Pokémon project is dedicated to providing a respectful, harassment-free community for everyone. We do not tolerate harassment or bullying of any community member in any form. This does not only extend to members to local VS Code Pokémon communities, but to anyone who chooses to become involved in the larger VS Code Pokémon community of users, developers, and integrators through events or interactions.\n\nHarassment includes offensive verbal/electronic comments related to personal characteristics or choices, sexual images or comments in public or online spaces, deliberate intimidation, bullying, stalking, following, harassing photography or recording, sustained disruption of talks, IRC chats, electronic meetings, physical meetings or other events, inappropriate physical contact, or unwelcome sexual attention. Participants asked to stop any harassing or bullying behavior are expected to comply immediately.\n\nIf a participant engages in harassing behavior, representatives of the community may take reasonable action they deem appropriate, including warning the offender, expulsion from any VS Code Pokémon event, or expulsion from mailing lists, discussion boards, and other electronic communications channels to resolve the issue.\n\nIf you are being harassed, notice that someone else is being harassed, or have any other concerns, please act to intercede or ask for help from any member of the VS Code Pokémon community, or organizers/representatives of any physical events put on under the auspices of VS Code Pokémon.\n\nThis Code of Conduct has been adapted from the [Plone Foundation](http://plone.org/foundation/materials/foundation-resolutions/code-of-conduct) and is licensed under a [Creative Commons Attribution-Share Alike 3.0 Unported license](http://creativecommons.org/licenses/by-sa/3.0/)\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [jakobhoeg]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: 'bug'\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**Screenshots**\nPlease send screenshots of the developer console (Right-click > Inspect > Console) on the pages where the bug is occurring.\n\n**Additional context**\nAdd any other context about the problem here."
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for vscode-pokemon\ntitle: ''\nlabels: 'feature'\nassignees: ''\n\n---\n\n**Please describe your idea.**\nA clear and concise description of what the feature would do.\n\n**Describe how the idea would be helpful**\nA clear and concise description of how the feature would be helpful to users.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here."
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node\n# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions\n\nname: CI\n\non:\n    pull_request:\n        branches: [main]\n\njobs:\n    build:\n        runs-on: ubuntu-latest\n\n        strategy:\n            matrix:\n                node-version: [20.18.1]\n        steps:\n            - uses: actions/checkout@v4\n            - name: Use Node.js ${{ matrix.node-version }}\n              uses: actions/setup-node@v4\n              with:\n                  node-version: ${{ matrix.node-version }}\n            - run: npm ci\n            - run: npm run compile\n\n            - name: Package VSIX\n              run: npm install -g @vscode/vsce && vsce package\n            - uses: actions/upload-artifact@v4\n              with:\n                  path: '*.vsix'\n"
  },
  {
    "path": ".github/workflows/code-quality.yml",
    "content": "name: Code Quality\n\non:\n  pull_request:\n    branches:\n      - main\n\njobs:\n  lint-and-format:\n    runs-on: ubuntu-latest\n    name: Lint and Format Check - ${{ github.event.number }}\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Set up Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 20\n          cache: npm\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run ESLint\n        run: npm run lint\n\n      - name: Check formatting with Prettier\n        run: npm run format:check"
  },
  {
    "path": ".github/workflows/gifs.yml",
    "content": "name: Verify Gifs Filename\n\non:\n    pull_request:\n        branches: [main]\n\njobs:\n    build:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/checkout@v4\n            - name: Verify Gifs Filename\n              run: |\n                  npm install\n                  npm run compile:test\n                  npm run test:gifs\n"
  },
  {
    "path": ".gitignore",
    "content": "out\ndist\nnode_modules\n.vscode-test/\n*.vsix\n.build-out/\ncoverage/\n.nyc_output/\n.idea/\nmedia/main-bundle.js\n.DS_Store\n\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "npx lint-staged\n"
  },
  {
    "path": ".prettierignore",
    "content": "CHANGELOG.md\nREADME.md\nLICENSE\n.gitignore\n.eslintrc.json\nout\nmedia\n.vscode\n.dist\n.out\n.github\ntsconfig.json\ntsconfig.panel.json\ntsconfig.extension.json\ntsconfig.test.json\ntsconfig.web.json\nwebpack.config.js"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"semi\": true,\n  \"printWidth\": 80,\n  \"tabWidth\": 2,\n  \"useTabs\": false\n}\n"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n\t// See http://go.microsoft.com/fwlink/?LinkId=827846\n\t// for the documentation about the extensions.json format\n\t\"recommendations\": [\n\t\t\"dbaeumer.vscode-eslint\"\n\t]\n}\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "// A launch configuration that compiles the extension and then opens it inside a new window\n// Use IntelliSense to learn about possible attributes.\n// Hover to view descriptions of existing attributes.\n// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n{\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"name\": \"Run Extension\",\n\t\t\t\"type\": \"extensionHost\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"args\": [\n\t\t\t\t\"--extensionDevelopmentPath=${workspaceFolder}\"\n\t\t\t],\n\t\t\t\"outFiles\": [\n\t\t\t\t\"${workspaceFolder}/out/**/*.js\"\n\t\t\t],\n\t\t\t\"preLaunchTask\": \"${defaultBuildTask}\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Extension Tests\",\n\t\t\t\"type\": \"extensionHost\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"args\": [\n\t\t\t\t\"--extensionDevelopmentPath=${workspaceFolder}\",\n\t\t\t\t\"--extensionTestsPath=${workspaceFolder}/out/test/suite/index\"\n\t\t\t],\n\t\t\t\"outFiles\": [\n\t\t\t\t\"${workspaceFolder}/out/test/**/*.js\"\n\t\t\t],\n\t\t\t\"preLaunchTask\": \"${defaultBuildTask}\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Run Web Extension in VS Code\",\n\t\t\t\"type\": \"pwa-extensionHost\",\n\t\t\t\"debugWebWorkerHost\": true,\n\t\t\t\"request\": \"launch\",\n\t\t\t\"args\": [\n\t\t\t\t\"--extensionDevelopmentPath=${workspaceFolder}\",\n\t\t\t\t\"--extensionDevelopmentKind=web\"\n\t\t\t],\n\t\t\t\"outFiles\": [\n\t\t\t\t\"${workspaceFolder}/dist/web/**/*.js\"\n\t\t\t],\n\t\t\t\"preLaunchTask\": \"${defaultBuildTask}\"\n\t\t},\n\t]\n}"
  },
  {
    "path": ".vscode/settings.json",
    "content": "// Place your settings in this file to overwrite default and user settings.\n{\n    \"files.exclude\": {\n        \"out\": false // set this to true to hide the \"out\" folder with the compiled JS files\n    },\n    \"search.exclude\": {\n        \"out\": true // set this to false to include \"out\" folder in search results\n    },\n    // Turn off tsc task auto detection since we have the necessary tasks as npm scripts\n    \"typescript.tsc.autoDetect\": \"off\",\n    \"nuxt.isNuxtApp\": false\n}"
  },
  {
    "path": ".vscode/tasks.json",
    "content": "// See https://go.microsoft.com/fwlink/?LinkId=733558\n// for the documentation about the tasks.json format\n{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": [\n\t\t{\n\t\t\t\"type\": \"npm\",\n\t\t\t\"script\": \"watch\",\n\t\t\t\"problemMatcher\": \"$tsc-watch\",\n\t\t\t\"isBackground\": true,\n\t\t\t\"presentation\": {\n\t\t\t\t\"reveal\": \"never\"\n\t\t\t},\n\t\t\t\"group\": {\n\t\t\t\t\"kind\": \"build\",\n\t\t\t\t\"isDefault\": true\n\t\t\t}\n\t\t}\n\t]\n}\n"
  },
  {
    "path": ".vscodeignore",
    "content": ".vscode/**\n.vscode-test/**\nout/test/**\nsrc/**\n.gitignore\n.yarnrc\n**/tsconfig.json\n**/.eslintrc.json\n**/*.map\n**/*.ts\n.build-out/\ncoverage/\ndocs/\nnode_modules"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to the \"vscode-pokemon\" extension will be documented in this file.\n\n## [4.3.5]\n\n- fix: resolve delay when removing more than one pokemon quickly\n\n## [4.3.4]\n\n- feat: add shiny configuration option to default Pokemon settings\n- fix: prevent spawning empty Pokémon collection on session start\n\n## [4.3.3]\n\n- fix: improve session handling and normalize pokemon counter\n\n## [4.3.2]\n\n- fix: add back accidentally removed \"remove-all\" command\n\n## [4.3.1]\n\n- feat: add multi-language support\n- fix: add missing Nidoqueen & Rotom sprites\n\n## [4.2.0]\n\n- feat: add shiny sprites & spawn rate for gen 1-4\n\n## [4.1.1]\n\n- fix: optimize remove Pokemon method\n\n## [4.1.0]\n\n- feat: added code-quality GitHub Action\n- chore: formatted the whole codebase with Prettier\n- chore: enforced ESlint rules on commit\n\n## [4.0.1]\n\n- feat: change Pokémon speed depending on size\n\n## [4.0.0]\n\n- feat: added gen 4 pokemon\n- feat: add missing forms for Pichu, Heracross, and Wobbuffet\n\n## [3.5.0]\n\n- feat: Added Unown characters in Gen 2 \n- fix: Corphish in pokemon-data.ts \n- fix: Swipe state bug making everything stand still and not work anymore\n- fix: handle cancellation of Pokemon spawning when no name is entered\n\n## [3.4.0]\n\n- feat: Pokémon spawn animation via Pokéball \n\n## [3.3.0]\n\n- feat: add default pokemon configurable through settings.json\n\n## [3.2.2]\n\n- fix: issue when adding pokemon\n- fix: update keybindings to make \"remove all\" work\n\n## [3.2.1]\n\n- feat: add better search functionality\n- feat: add hotkeys\n\n## [3.1.1]\n\n- chore: update readme\n\n## [3.1.0]\n\n- fix: stop randomly and change direction\n- fix: make default size medium\n\n## [3.0.1]\n\n- fix: pixelate bubbles\n\n## [3.0.0]\n\n- feat: add generation 3 Pokémon\n\n## [2.0.3]\n\n- fix: add Celebi + fix Ho-Oh id\n\n## [2.0.2]\n\n- fix: use pixelate image rendering\n\n## [2.0.1]\n\n- fix: Entei typo\n\n## [2.0.0]\n\n- feat: add generation 2 Pokemon\n\n## [1.1.0]\n\n- feat: add functionality for adding a random Pokemon\n\n## [1.0.2]\n\n- fix: added missing Victreebel & Omastar\n\n## [1.0.1]\n\n- Bump version to reflex changes to readme\n\n## [1.0.0]\n\n- Added all 1st generation Pokémon.\n"
  },
  {
    "path": "LICENSE",
    "content": "All image contents within are Copyright The Pokémon Company.\n\nCreative Commons Legal Code\n\nCC0 1.0 Universal\n\n    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE\n    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN\n    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS\n    INFORMATION ON AN \"AS-IS\" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES\n    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS\n    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM\n    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED\n    HEREUNDER.\n\nStatement of Purpose\n\nThe laws of most jurisdictions throughout the world automatically confer\nexclusive Copyright and Related Rights (defined below) upon the creator\nand subsequent owner(s) (each and all, an \"owner\") of an original work of\nauthorship and/or a database (each, a \"Work\").\n\nCertain owners wish to permanently relinquish those rights to a Work for\nthe purpose of contributing to a commons of creative, cultural and\nscientific works (\"Commons\") that the public can reliably and without fear\nof later claims of infringement build upon, modify, incorporate in other\nworks, reuse and redistribute as freely as possible in any form whatsoever\nand for any purposes, including without limitation commercial purposes.\nThese owners may contribute to the Commons to promote the ideal of a free\nculture and the further production of creative, cultural and scientific\nworks, or to gain reputation or greater distribution for their Work in\npart through the use and efforts of others.\n\nFor these and/or other purposes and motivations, and without any\nexpectation of additional consideration or compensation, the person\nassociating CC0 with a Work (the \"Affirmer\"), to the extent that he or she\nis an owner of Copyright and Related Rights in the Work, voluntarily\nelects to apply CC0 to the Work and publicly distribute the Work under its\nterms, with knowledge of his or her Copyright and Related Rights in the\nWork and the meaning and intended legal effect of CC0 on those rights.\n\n1. Copyright and Related Rights. A Work made available under CC0 may be\nprotected by copyright and related or neighboring rights (\"Copyright and\nRelated Rights\"). Copyright and Related Rights include, but are not\nlimited to, the following:\n\n  i. the right to reproduce, adapt, distribute, perform, display,\n     communicate, and translate a Work;\n ii. moral rights retained by the original author(s) and/or performer(s);\niii. publicity and privacy rights pertaining to a person's image or\n     likeness depicted in a Work;\n iv. rights protecting against unfair competition in regards to a Work,\n     subject to the limitations in paragraph 4(a), below;\n  v. rights protecting the extraction, dissemination, use and reuse of data\n     in a Work;\n vi. database rights (such as those arising under Directive 96/9/EC of the\n     European Parliament and of the Council of 11 March 1996 on the legal\n     protection of databases, and under any national implementation\n     thereof, including any amended or successor version of such\n     directive); and\nvii. other similar, equivalent or corresponding rights throughout the\n     world based on applicable law or treaty, and any national\n     implementations thereof.\n\n2. Waiver. To the greatest extent permitted by, but not in contravention\nof, applicable law, Affirmer hereby overtly, fully, permanently,\nirrevocably and unconditionally waives, abandons, and surrenders all of\nAffirmer's Copyright and Related Rights and associated claims and causes\nof action, whether now known or unknown (including existing as well as\nfuture claims and causes of action), in the Work (i) in all territories\nworldwide, (ii) for the maximum duration provided by applicable law or\ntreaty (including future time extensions), (iii) in any current or future\nmedium and for any number of copies, and (iv) for any purpose whatsoever,\nincluding without limitation commercial, advertising or promotional\npurposes (the \"Waiver\"). Affirmer makes the Waiver for the benefit of each\nmember of the public at large and to the detriment of Affirmer's heirs and\nsuccessors, fully intending that such Waiver shall not be subject to\nrevocation, rescission, cancellation, termination, or any other legal or\nequitable action to disrupt the quiet enjoyment of the Work by the public\nas contemplated by Affirmer's express Statement of Purpose.\n\n3. Public License Fallback. Should any part of the Waiver for any reason\nbe judged legally invalid or ineffective under applicable law, then the\nWaiver shall be preserved to the maximum extent permitted taking into\naccount Affirmer's express Statement of Purpose. In addition, to the\nextent the Waiver is so judged Affirmer hereby grants to each affected\nperson a royalty-free, non transferable, non sublicensable, non exclusive,\nirrevocable and unconditional license to exercise Affirmer's Copyright and\nRelated Rights in the Work (i) in all territories worldwide, (ii) for the\nmaximum duration provided by applicable law or treaty (including future\ntime extensions), (iii) in any current or future medium and for any number\nof copies, and (iv) for any purpose whatsoever, including without\nlimitation commercial, advertising or promotional purposes (the\n\"License\"). The License shall be deemed effective as of the date CC0 was\napplied by Affirmer to the Work. Should any part of the License for any\nreason be judged legally invalid or ineffective under applicable law, such\npartial invalidity or ineffectiveness shall not invalidate the remainder\nof the License, and in such case Affirmer hereby affirms that he or she\nwill not (i) exercise any of his or her remaining Copyright and Related\nRights in the Work or (ii) assert any associated claims and causes of\naction with respect to the Work, in either case contrary to Affirmer's\nexpress Statement of Purpose.\n\n4. Limitations and Disclaimers.\n\n a. No trademark or patent rights held by Affirmer are waived, abandoned,\n    surrendered, licensed or otherwise affected by this document.\n b. Affirmer offers the Work as-is and makes no representations or\n    warranties of any kind concerning the Work, express, implied,\n    statutory or otherwise, including without limitation warranties of\n    title, merchantability, fitness for a particular purpose, non\n    infringement, or the absence of latent or other defects, accuracy, or\n    the present or absence of errors, whether or not discoverable, all to\n    the greatest extent permissible under applicable law.\n c. Affirmer disclaims responsibility for clearing rights of other persons\n    that may apply to the Work or any use thereof, including without\n    limitation any person's Copyright and Related Rights in the Work.\n    Further, Affirmer disclaims responsibility for obtaining any necessary\n    consents, permissions or other rights required for any use of the\n    Work.\n d. Affirmer understands and acknowledges that Creative Commons is not a\n    party to this document and has no duty or obligation with respect to\n    this CC0 or use of the Work.\n"
  },
  {
    "path": "README.md",
    "content": "<div align='center'>\n\n# VS Code Pokémon\n\n![icon](https://github.com/jakobhoeg/vscode-pokemon/raw/main/icon.png)\n</div>\n\n<p align=\"center\">\n    Puts cute Pokémon in your code editor to boost productivity ✨\n    <br>\n    <br>\n    <a href=\"https://github.com/jakobhoeg/vscode-pokemon/issues/new?assignees=&labels=feature&template=bug_report.md&title=\">Report a Bug</a>\n    ·\n    <a href=\"https://github.com/jakobhoeg/vscode-pokemon/issues/new?assignees=&labels=feature&template=feature_request.md&title=\">Request feature</a>\n</p>\n\n<div align=\"center\">\n\n![Visual Studio Marketplace Version](https://img.shields.io/visual-studio-marketplace/v/jakobhoeg.vscode-pokemon)\n![Visual Studio Marketplace Installs](https://img.shields.io/visual-studio-marketplace/i/jakobhoeg.vscode-pokemon)\n![Visual Studio Marketplace Downloads](https://img.shields.io/visual-studio-marketplace/d/jakobhoeg.vscode-pokemon)\n\n</div>\n\n<div align=\"center\">\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/jakobhoeg/vscode-pokemon/raw/main/vscode-pokemon.gif\">\n  <source media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/jakobhoeg/vscode-pokemon/raw/main/vscode-pokemon-light.gif\">\n  <img alt=\"Shows gif in dark or light mode\" src=\"https://github.com/jakobhoeg/vscode-pokemon/raw/main/vscode-pokemon-light.gif\">\n</picture>\n</div>\n\n<div align=\"center\">\n\nSeen used by engineers at [Microsoft](https://code.visualstudio.com/updates/v1_101#_chat-ux-improvements)!\n\n</div>\n\n## 💖 Support\n\nIf you enjoy this project, please consider supporting me.\nManually creating the `.gif` files for each sprite takes a lot of time and effort.\nYour sponsorship helps me dedicate more energy to improve and expand the project.\n\n[![GitHub Sponsor](https://img.shields.io/badge/Sponsor-❤-blue?style=flat&logo=github)](https://github.com/sponsors/jakobhoeg)\n\n## Installation\n\nInstall this extension from the [VS Code marketplace](https://marketplace.visualstudio.com/items?itemName=jakobhoeg.vscode-pokemon) or the [Open VSX Registry](https://open-vsx.org/extension/jakobhoeg/vscode-pokemon).\n\n![Default view](https://github.com/jakobhoeg/vscode-pokemon/raw/main/install.png)\n\nOR\n\nWith VS Code open, search for `vscode-pokemon` in the extension panel (`Ctrl+Shift+X` on Windows/Linux or `Cmd(⌘)+Shift+X` on MacOS) and click install.\n\nOR\n\nWith VS Code open, launch VS Code Quick Open (`Ctrl+P` on Windows/Linux or `Cmd(⌘)+P` on MacOS), paste the following command, and press enter.\n\n`ext install jakobhoeg.vscode-pokemon`\n\n## Using VS Code Pokémon\n\nAfter installing, open the command palette with `Ctrl+Shift+P` on Windows/Linux or `Cmd(⌘)+Shift+P` on MacOS.\n\nRun the \"Start Pokemon coding session\" command (`vscode-pokemon.start`) to see a Bulbasaur in VS Code:\n\n![Default view](https://github.com/jakobhoeg/vscode-pokemon/raw/main/usage.png)\n\nEnjoy interacting with your favourite Pokémon!\n\n## Keyboard Shortcuts\n\nVS Code Pokémon comes with default keyboard shortcuts to make managing your Pokémon quick and easy:\n\n![Keybindings](https://github.com/jakobhoeg/vscode-pokemon/raw/main/keybindings.png)\n\n### Configuring Keyboard Shortcuts\n\nYou can customize these shortcuts to match your preferences:\n\n1. Open the command palette (`Ctrl+Shift+P` on Windows/Linux or `Cmd(⌘)+Shift+P` on MacOS)\n2. Run the **`Pokemon Coding: Configure keybindings`** command\n3. Select the command you want to customize\n4. VS Code will open the Keyboard Shortcuts editor filtered to that command\n5. Click the pencil icon next to the command and press your desired key combination\n\n## Changing settings\n\nOpen the setting panel with Ctrl+, on Windows/Linux or Cmd(⌘)+, on MacOS. In the search bar, enter “vscode-pokemon\" to see all available options.\n\nSet the size and position of the extension.\n\n### Default Pokémon\n\nYou can configure specific Pokémon to automatically appear when you first start using the extension. This is useful for setting up your preferred team without having to manually spawn them when you open new windows.\n\nTo configure default Pokémon, add the following to your `settings.json`:\n\n```json\n{\n  \"vscode-pokemon.defaultPokemon\": [\n    {\n      \"type\": \"pikachu\",\n      \"name\": \"Sparky\"\n    },\n    {\n      \"type\": \"charizard\",\n      \"name\": \"Flame\"\n    },\n    {\n      \"type\": \"articuno\"\n    }\n  ]\n}\n```\n\n- **`type`** (required): The Pokémon species (e.g., `\"pikachu\"`, `\"charizard\"`, `\"mewtwo\"`)\n- **`name`** (optional): A custom name for your Pokémon. If not provided, a random name will be assigned\n- **`shiny`** (optional): Determines if the Pokémon is shiny, if not set will use `vscode-pokemon.shinyOdds` setting.\n\n**Note:** The extension automatically saves your current Pokémon between sessions. The `defaultPokemon` setting is only used when:\n- You start the extension for the first time\n- You open a new windows/repository\n- You have removed all Pokémon (no saved session exists)\n\nTo reset to your default Pokémon, use the \"Remove all pokemon\" command and restart VS Code.\n\n### Pokémon Language\n\nYou can customize the language used for Pokémon names. The extension supports official Pokémon languages: English (US), French, German, and Japanese.\n\n#### Using the Command\n\n1. Open the command palette (`Ctrl+Shift+P` on Windows/Linux or `Cmd(⌘)+Shift+P` on MacOS)\n2. Run the **`Pokemon Coding: Change Pokemon language`** command\n3. Select your preferred language from the list\n\n#### Using Settings\n\nYou can also configure the language directly in your `settings.json`:\n\n```json\n{\n  \"vscode-pokemon.pokemonLanguage\": \"fr-FR\"\n}\n```\n\nAvailable options:\n- **`auto`** (default): Automatically uses VS Code's language setting\n- **`en-US`**: English (US) names\n- **`fr-FR`**: French names (e.g., \"Bulbizarre\", \"Salamèche\", \"Dracaufeu\")\n- **`de-DE`**: German names (e.g., \"Bisasam\", \"Glumanda\", \"Glurak\")\n- **`ja-JP`**: Japanese names (e.g., \"フシギダネ\", \"ヒトカゲ\", \"リザードン\")\n\n**Note:** The language setting applies to all Pokémon names throughout the extension, including in the spawn selection menu, roll-call, and export features. Translations are available for all Pokémon from Generations 1, 2, 3, and 4.\n\n## Features\n\nExtracting and creating .gif files involves quite a bit of tedious manual work, but I’ll aim to add Gen 5 when possible.\n\n## Credits\n\n### Sprite Sources\n- Pokemon Sprites: © The Pokémon Company / Nintendo / Game Freak\n- The sprites are used for non-commercial, fan project purposes only\n- Original sprite artwork belongs to the respective copyright holders\n\n### Acknowledgments\n- All sprites are property of their original creators\n- This repository is a fan project and is not affiliated with Nintendo, The Pokémon Company, or Game Freak\n\nThis repository is inspired by and based on [vscode-pets](https://github.com/tonybaloney/vscode-pets) by [tonybaloney](https://github.com/tonybaloney).\n"
  },
  {
    "path": "l10n/bundle.l10n.de-DE.json",
    "content": "{\n  \"Spawn Pokemon\": \"Pokemon erscheinen lassen\",\n  \"Pokemon Panel\": \"Pokemon-Panel\",\n  \"Pokemon language changed to {0}. The change will persist after restart.\": \"Pokemon-Sprache wurde auf {0} geändert. Die Änderung bleibt nach dem Neustart erhalten.\",\n  \"Select a Pokemon\": \"Wähle ein Pokemon\",\n  \"Select a color\": \"Wähle eine Farbe\",\n  \"Select language for Pokemon names\": \"Sprache für Pokemon-Namen auswählen\",\n  \"Select a generation or start typing to search for a Pokemon...\": \"Wähle eine Generation oder tippe, um nach einem Pokemon zu suchen...\",\n  \"Select the Pokemon to remove.\": \"Wähle das Pokemon zum Entfernen.\",\n  \"Select a command to configure its keybinding\": \"Wähle einen Befehl, um seine Tastenkombination zu konfigurieren\",\n  \"Leave blank for a random name\": \"Leer lassen für einen zufälligen Namen\",\n  \"Name your Pokemon\": \"Benenne dein Pokemon\",\n  \"Cancelled Spawning Pokemon\": \"Pokemon-Erscheinen abgebrochen\",\n  \"A Pokemon Playground has been created. You can now use the \\\"Spawn Additional Pokemon\\\" Command to add more Pokemon.\": \"Ein Pokemon-Center wurde erstellt. Du kannst jetzt den Befehl \\\"Zusätzliches Pokemon erscheinen lassen\\\" verwenden, um weitere Pokemon hinzuzufügen.\",\n  \"A Pokemon Playground has been created. You can now use the \\\"Remove All Pokemon\\\" Command to remove all Pokemon.\": \"Ein Pokemon-Center wurde erstellt. Du kannst jetzt den Befehl \\\"Alle Pokemon entfernen\\\" verwenden, um alle Pokemon zu entfernen.\",\n  \"Generation {0}\": \"Generation {0}\",\n  \"Browse Gen {0} Pokemon\": \"Gen {0} Pokemon durchsuchen\",\n  \"Generations\": \"Generationen\",\n  \"Results\": \"Ergebnisse\",\n  \"Current\": \"Aktuell\",\n  \"Use VS Code language\": \"VS Code-Sprache verwenden\",\n  \"English names\": \"Englische Namen\",\n  \"French names\": \"Französische Namen\",\n  \"German names\": \"Deutsche Namen\",\n  \"Japanese names\": \"Japanische Namen\",\n  \"Spawn additional pokemon\": \"Zusätzliches Pokemon erscheinen lassen\",\n  \"Spawn random pokemon\": \"Zufälliges Pokemon erscheinen lassen\",\n  \"Remove pokemon\": \"Pokemon entfernen\",\n  \"Remove all pokemon\": \"Alle Pokemon entfernen\",\n  \"There are no pokemon to remove.\": \"Es gibt keine Pokemon zum Entfernen.\",\n  \"You must have a folder or workspace open to export pokemonCollection.\": \"Du musst einen Ordner oder Arbeitsbereich geöffnet haben, um die Pokemon-Sammlung zu exportieren.\",\n  \"Failed to import pokemon: {0}\": \"Fehler beim Importieren von Pokemon: {0}\",\n  \"default\": \"Standard\",\n  \"shiny\": \"Schillernd\"\n}\n"
  },
  {
    "path": "l10n/bundle.l10n.en-GB.json",
    "content": "{\n  \"Spawn Pokemon\": \"Spawn Pokemon\",\n  \"Pokemon Panel\": \"Pokemon Panel\",\n  \"Pokemon language changed to {0}. The change will persist after restart.\": \"Pokemon language changed to {0}. The change will persist after restart.\",\n  \"Select a Pokemon\": \"Select a Pokemon\",\n  \"Select a color\": \"Select a colour\",\n  \"Select language for Pokemon names\": \"Select language for Pokemon names\",\n  \"Select a generation or start typing to search for a Pokemon...\": \"Select a generation or start typing to search for a Pokemon...\",\n  \"Select the Pokemon to remove.\": \"Select the Pokemon to remove.\",\n  \"Select a command to configure its keybinding\": \"Select a command to configure its keybinding\",\n  \"Leave blank for a random name\": \"Leave blank for a random name\",\n  \"Name your Pokemon\": \"Name your Pokemon\",\n  \"Cancelled Spawning Pokemon\": \"Cancelled Spawning Pokemon\",\n  \"A Pokemon Playground has been created. You can now use the \\\"Spawn Additional Pokemon\\\" Command to add more Pokemon.\": \"A Pokemon Center has been created. You can now use the \\\"Spawn Additional Pokemon\\\" command to add more Pokemon.\",\n  \"A Pokemon Playground has been created. You can now use the \\\"Remove All Pokemon\\\" Command to remove all Pokemon.\": \"A Pokemon Center has been created. You can now use the \\\"Remove All Pokemon\\\" command to remove all Pokemon.\",\n  \"Generation {0}\": \"Generation {0}\",\n  \"Browse Gen {0} Pokemon\": \"Browse Gen {0} Pokemon\",\n  \"Generations\": \"Generations\",\n  \"Results\": \"Results\",\n  \"Current\": \"Current\",\n  \"Use VS Code language\": \"Use VS Code language\",\n  \"English names\": \"English names\",\n  \"French names\": \"French names\",\n  \"German names\": \"German names\",\n  \"Japanese names\": \"Japanese names\",\n  \"Spawn additional pokemon\": \"Spawn additional pokemon\",\n  \"Spawn random pokemon\": \"Spawn random pokemon\",\n  \"Remove pokemon\": \"Remove pokemon\",\n  \"Remove all pokemon\": \"Remove all pokemon\",\n  \"There are no pokemon to remove.\": \"There are no pokemon to remove.\",\n  \"You must have a folder or workspace open to export pokemonCollection.\": \"You must have a folder or workspace open to export pokemonCollection.\",\n  \"Failed to import pokemon: {0}\": \"Failed to import pokemon: {0}\",\n  \"default\": \"Default\",\n  \"shiny\": \"Shiny\"\n}\n"
  },
  {
    "path": "l10n/bundle.l10n.en-US.json",
    "content": "{\n  \"Spawn Pokemon\": \"Spawn Pokemon\",\n  \"Pokemon Panel\": \"Pokemon Panel\",\n  \"Pokemon language changed to {0}. The change will persist after restart.\": \"Pokemon language changed to {0}. The change will persist after restart.\",\n  \"Select a Pokemon\": \"Select a Pokemon\",\n  \"Select a color\": \"Select a color\",\n  \"Select language for Pokemon names\": \"Select language for Pokemon names\",\n  \"Select a generation or start typing to search for a Pokemon...\": \"Select a generation or start typing to search for a Pokemon...\",\n  \"Select the Pokemon to remove.\": \"Select the Pokemon to remove.\",\n  \"Select a command to configure its keybinding\": \"Select a command to configure its keybinding\",\n  \"Leave blank for a random name\": \"Leave blank for a random name\",\n  \"Name your Pokemon\": \"Name your Pokemon\",\n  \"Cancelled Spawning Pokemon\": \"Cancelled Spawning Pokemon\",\n  \"A Pokemon Playground has been created. You can now use the \\\"Spawn Additional Pokemon\\\" Command to add more Pokemon.\": \"A Pokemon Center has been created. You can now use the \\\"Spawn Additional Pokemon\\\" command to add more Pokemon.\",\n  \"A Pokemon Playground has been created. You can now use the \\\"Remove All Pokemon\\\" Command to remove all Pokemon.\": \"A Pokemon Center has been created. You can now use the \\\"Remove All Pokemon\\\" command to remove all Pokemon.\",\n  \"Generation {0}\": \"Generation {0}\",\n  \"Browse Gen {0} Pokemon\": \"Browse Gen {0} Pokemon\",\n  \"Generations\": \"Generations\",\n  \"Results\": \"Results\",\n  \"Current\": \"Current\",\n  \"Use VS Code language\": \"Use VS Code language\",\n  \"English names\": \"English names\",\n  \"French names\": \"French names\",\n  \"German names\": \"German names\",\n  \"Japanese names\": \"Japanese names\",\n  \"Spawn additional pokemon\": \"Spawn additional pokemon\",\n  \"Spawn random pokemon\": \"Spawn random pokemon\",\n  \"Remove pokemon\": \"Remove pokemon\",\n  \"Remove all pokemon\": \"Remove all pokemon\",\n  \"There are no pokemon to remove.\": \"There are no pokemon to remove.\",\n  \"You must have a folder or workspace open to export pokemonCollection.\": \"You must have a folder or workspace open to export pokemonCollection.\",\n  \"Failed to import pokemon: {0}\": \"Failed to import pokemon: {0}\",\n  \"default\": \"Default\",\n  \"shiny\": \"Shiny\"\n}\n"
  },
  {
    "path": "l10n/bundle.l10n.fr-FR.json",
    "content": "{\n\t\"A Pokemon Playground has been created. You can now use the \\\"Remove All Pokemon\\\" Command to remove all Pokemon.\": \"Un Centre Pokémon a été créé. Vous pouvez maintenant utiliser la commande \\\"Retirer tous les Pokémon\\\" pour retirer tous les Pokémon.\",\n\t\"A Pokemon Playground has been created. You can now use the \\\"Spawn Additional Pokemon\\\" Command to add more Pokemon.\": \"Un Centre Pokémon a été créé. Vous pouvez maintenant utiliser la commande \\\"Faire apparaître un Pokémon supplémentaire\\\" pour ajouter plus de Pokémon.\",\n\t\"Browse Gen {0} Pokémon\": \"Parcourir les Pokémon de Gen {0}\",\n\t\"Cancelled Spawning Pokemon\": \"Apparition de Pokémon annulée\",\n\t\"Current\": \"Actuel\",\n\t\"English names\": \"Noms anglais\",\n\t\"Failed to import pokemon: {0}\": \"Échec de l'importation du Pokémon : {0}\",\n\t\"French names\": \"Noms français\",\n\t\"Generation {0}\": \"Génération {0}\",\n\t\"Generations\": \"Générations\",\n\t\"German names\": \"Noms allemands\",\n\t\"Japanese names\": \"Noms japonais\",\n\t\"Leave blank for a random name\": \"Laisser vide pour un nom aléatoire\",\n\t\"Name your Pokemon\": \"Nommer votre Pokémon\",\n\t\"Name your Pokémon\": \"Nommer votre Pokémon\",\n\t\"Pokemon Panel\": \"Panneau Pokémon\",\n\t\"Pokemon language changed to {0}. The change will persist after restart.\": \"Langue des Pokémon changée en {0}. Le changement persistera après redémarrage.\",\n\t\"Remove all pokemon\": \"Retirer tous les Pokémon\",\n\t\"Remove pokemon\": \"Retirer un Pokémon\",\n\t\"Results\": \"Résultats\",\n\t\"Select a Pokemon\": \"Sélectionner un Pokémon\",\n\t\"Select a Pokémon\": \"Sélectionner un Pokémon\",\n\t\"Select a color\": \"Sélectionner une couleur\",\n\t\"Select a command to configure its keybinding\": \"Sélectionner une commande pour configurer son raccourci clavier\",\n\t\"Select a generation or start typing to search for a Pokémon...\": \"Sélectionner une génération ou commencer à taper pour rechercher un Pokémon...\",\n\t\"Select language for Pokemon names\": \"Sélectionner la langue pour les noms de Pokémon\",\n\t\"Select the Pokemon to remove.\": \"Sélectionner le Pokémon à retirer.\",\n\t\"Spawn Pokemon\": \"Apparition d'un Pokémon\",\n\t\"Spawn additional pokemon\": \"Faire apparaître un Pokémon supplémentaire\",\n\t\"Spawn random pokemon\": \"Faire apparaître un Pokémon aléatoire\",\n\t\"There are no pokemon to remove.\": \"Il n'y a aucun Pokémon à retirer.\",\n\t\"Use VS Code language\": \"Utiliser la langue de VS Code\",\n\t\"You must have a folder or workspace open to export pokemonCollection.\": \"Vous devez avoir un dossier ou un espace de travail ouvert pour exporter la collection de Pokémon.\",\n\t\"default\": \"Par défaut\",\n\t\"shiny\": \"Chromatique\"\n}\n"
  },
  {
    "path": "l10n/bundle.l10n.ja-JP.json",
    "content": "{\n  \"Spawn Pokemon\": \"ポケモンを出現させる\",\n  \"Pokemon Panel\": \"ポケモンパネル\",\n  \"Pokemon language changed to {0}. The change will persist after restart.\": \"ポケモンの言語が{0}に変更されました。この変更は再起動後も保持されます。\",\n  \"Select a Pokemon\": \"ポケモンを選択\",\n  \"Select a color\": \"色を選択\",\n  \"Select language for Pokemon names\": \"ポケモン名の言語を選択\",\n  \"Select a generation or start typing to search for a Pokemon...\": \"世代を選択するか、ポケモンを検索するために入力を開始してください...\",\n  \"Select the Pokemon to remove.\": \"削除するポケモンを選択してください。\",\n  \"Select a command to configure its keybinding\": \"キーバインドを設定するコマンドを選択\",\n  \"Leave blank for a random name\": \"ランダムな名前の場合は空白のまま\",\n  \"Name your Pokemon\": \"ポケモンに名前を付ける\",\n  \"Cancelled Spawning Pokemon\": \"ポケモンの出現をキャンセルしました\",\n  \"A Pokemon Playground has been created. You can now use the \\\"Spawn Additional Pokemon\\\" Command to add more Pokemon.\": \"ポケモンセンターが作成されました。これで「追加のポケモンを出現させる」コマンドを使用して、さらにポケモンを追加できます。\",\n  \"A Pokemon Playground has been created. You can now use the \\\"Remove All Pokemon\\\" Command to remove all Pokemon.\": \"ポケモンセンターが作成されました。これで「すべてのポケモンを削除」コマンドを使用して、すべてのポケモンを削除できます。\",\n  \"Generation {0}\": \"第{0}世代\",\n  \"Browse Gen {0} Pokemon\": \"第{0}世代のポケモンを閲覧\",\n  \"Generations\": \"世代\",\n  \"Results\": \"結果\",\n  \"Current\": \"現在\",\n  \"Use VS Code language\": \"VS Codeの言語を使用\",\n  \"English names\": \"英語名\",\n  \"French names\": \"フランス語名\",\n  \"German names\": \"ドイツ語名\",\n  \"Japanese names\": \"日本語名\",\n  \"Spawn additional pokemon\": \"追加のポケモンを出現させる\",\n  \"Spawn random pokemon\": \"ランダムなポケモンを出現させる\",\n  \"Remove pokemon\": \"ポケモンを削除\",\n  \"Remove all pokemon\": \"すべてのポケモンを削除\",\n  \"There are no pokemon to remove.\": \"削除するポケモンがありません。\",\n  \"You must have a folder or workspace open to export pokemonCollection.\": \"ポケモンコレクションをエクスポートするには、フォルダーまたはワークスペースを開いている必要があります。\",\n  \"Failed to import pokemon: {0}\": \"ポケモンのインポートに失敗しました：{0}\",\n  \"default\": \"デフォルト\",\n  \"shiny\": \"色違い\"\n}\n"
  },
  {
    "path": "l10n/pokemon/de-DE/gen1.json",
    "content": "{\n\t\"abra\": \"Abra\",\n\t\"aerodactyl\": \"Aerodactyl\",\n\t\"alakazam\": \"Simsala\",\n\t\"arbok\": \"Arbok\",\n\t\"arcanine\": \"Arkani\",\n\t\"articuno\": \"Arktos\",\n\t\"beedrill\": \"Bibor\",\n\t\"bellsprout\": \"Knofensa\",\n\t\"blastoise\": \"Turtok\",\n\t\"bulbasaur\": \"Bisasam\",\n\t\"butterfree\": \"Smettbo\",\n\t\"caterpie\": \"Raupy\",\n\t\"chansey\": \"Chaneira\",\n\t\"charizard\": \"Glurak\",\n\t\"charmander\": \"Glumanda\",\n\t\"charmeleon\": \"Glutexo\",\n\t\"clefable\": \"Pixi\",\n\t\"clefairy\": \"Piepi\",\n\t\"cloyster\": \"Austos\",\n\t\"cubone\": \"Tragosso\",\n\t\"dewgong\": \"Jugong\",\n\t\"diglett\": \"Digda\",\n\t\"ditto\": \"Ditto\",\n\t\"dodrio\": \"Dodri\",\n\t\"doduo\": \"Dodu\",\n\t\"dragonair\": \"Dragonir\",\n\t\"dragonite\": \"Dragoran\",\n\t\"dratini\": \"Dratini\",\n\t\"drowzee\": \"Traumato\",\n\t\"dugtrio\": \"Digdri\",\n\t\"eevee\": \"Evoli\",\n\t\"ekans\": \"Rettan\",\n\t\"electabuzz\": \"Elektek\",\n\t\"electrode\": \"Lektrobal\",\n\t\"exeggcute\": \"Owei\",\n\t\"exeggutor\": \"Kokowei\",\n\t\"farfetchd\": \"Porenta\",\n\t\"fearow\": \"Iarbok\",\n\t\"flareon\": \"Flamara\",\n\t\"gastly\": \"Nebulak\",\n\t\"gengar\": \"Gengar\",\n\t\"geodude\": \"Kleinstein\",\n\t\"gloom\": \"Duflor\",\n\t\"golbat\": \"Golbat\",\n\t\"goldeen\": \"Goldini\",\n\t\"golduck\": \"Entoron\",\n\t\"golem\": \"Geowaz\",\n\t\"graveler\": \"Georok\",\n\t\"grimer\": \"Sleima\",\n\t\"growlithe\": \"Fukano\",\n\t\"gyarados\": \"Garados\",\n\t\"haunter\": \"Alpollo\",\n\t\"hitmonchan\": \"Nockchan\",\n\t\"hitmonlee\": \"Kicklee\",\n\t\"horsea\": \"Seeper\",\n\t\"hypno\": \"Hypno\",\n\t\"ivysaur\": \"Bisaknosp\",\n\t\"jigglypuff\": \"Pummeluff\",\n\t\"jolteon\": \"Blitza\",\n\t\"jynx\": \"Rossana\",\n\t\"kabuto\": \"Kabuto\",\n\t\"kabutops\": \"Kabutops\",\n\t\"kadabra\": \"Kadabra\",\n\t\"kakuna\": \"Kokuna\",\n\t\"kangaskhan\": \"Kangama\",\n\t\"kingler\": \"Kingler\",\n\t\"koffing\": \"Smogon\",\n\t\"krabby\": \"Krabby\",\n\t\"lapras\": \"Lapras\",\n\t\"lickitung\": \"Schlurp\",\n\t\"machamp\": \"Machomei\",\n\t\"machoke\": \"Maschock\",\n\t\"machop\": \"Machollo\",\n\t\"magikarp\": \"Karpador\",\n\t\"magmar\": \"Magmar\",\n\t\"magnemite\": \"Magnetilo\",\n\t\"magneton\": \"Magneton\",\n\t\"mankey\": \"Menki\",\n\t\"marowak\": \"Knogga\",\n\t\"meowth\": \"Mauzi\",\n\t\"metapod\": \"Safcon\",\n\t\"mew\": \"Mew\",\n\t\"mewtwo\": \"Mewtu\",\n\t\"moltres\": \"Lavados\",\n\t\"mrmime\": \"Pantimos\",\n\t\"muk\": \"Sleimok\",\n\t\"nidoking\": \"Nidoking\",\n\t\"nidoqueen\": \"Nidoqueen\",\n\t\"nidoran_female\": \"Nidoran♀\",\n\t\"nidoran_male\": \"Nidoran♂\",\n\t\"nidorina\": \"Nidorina\",\n\t\"nidorino\": \"Nidorino\",\n\t\"ninetales\": \"Vulnona\",\n\t\"oddish\": \"Myrapla\",\n\t\"omanyte\": \"Amonitas\",\n\t\"omastar\": \"Amoroso\",\n\t\"onix\": \"Onix\",\n\t\"paras\": \"Paras\",\n\t\"parasect\": \"Parasek\",\n\t\"persian\": \"Snobilikat\",\n\t\"pidgeot\": \"Tauboss\",\n\t\"pidgeotto\": \"Tauboga\",\n\t\"pidgey\": \"Taubsi\",\n\t\"pikachu\": \"Pikachu\",\n\t\"pikachu_female\": \"Pikachu (Weiblich)\",\n\t\"pinsir\": \"Pinsir\",\n\t\"poliwag\": \"Quapsel\",\n\t\"poliwhirl\": \"Quaputzi\",\n\t\"poliwrath\": \"Quappo\",\n\t\"ponyta\": \"Ponita\",\n\t\"porygon\": \"Porygon\",\n\t\"primeape\": \"Rasaff\",\n\t\"psyduck\": \"Enton\",\n\t\"raichu\": \"Raichu\",\n\t\"rapidash\": \"Gallopa\",\n\t\"raticate\": \"Rattikarl\",\n\t\"rattata\": \"Rattfratz\",\n\t\"rhydon\": \"Rizeros\",\n\t\"rhyhorn\": \"Rihorn\",\n\t\"sandshrew\": \"Sandan\",\n\t\"sandslash\": \"Sandamer\",\n\t\"scyther\": \"Sichlor\",\n\t\"seadra\": \"Seemon\",\n\t\"seaking\": \"Golking\",\n\t\"seel\": \"Jurob\",\n\t\"shellder\": \"Muschas\",\n\t\"slowbro\": \"Lahmus\",\n\t\"slowpoke\": \"Flegmon\",\n\t\"snorlax\": \"Relaxo\",\n\t\"spearow\": \"Habitak\",\n\t\"squirtle\": \"Schiggy\",\n\t\"starmie\": \"Starmie\",\n\t\"staryu\": \"Sterndu\",\n\t\"tangela\": \"Tangela\",\n\t\"tauros\": \"Tauros\",\n\t\"tentacool\": \"Tentacha\",\n\t\"tentacruel\": \"Tentoxa\",\n\t\"vaporeon\": \"Aquana\",\n\t\"venomoth\": \"Omot\",\n\t\"venonat\": \"Bluzuk\",\n\t\"venusaur\": \"Bisaflor\",\n\t\"venusaur_female\": \"Bisaflor (Weiblich)\",\n\t\"victreebel\": \"Sarzenia\",\n\t\"vileplume\": \"Giflor\",\n\t\"voltorb\": \"Voltobal\",\n\t\"vulpix\": \"Vulpix\",\n\t\"wartortle\": \"Schillok\",\n\t\"weedle\": \"Hornliu\",\n\t\"weepinbell\": \"Ultrigaria\",\n\t\"weezing\": \"Smogmog\",\n\t\"wigglytuff\": \"Knuddeluff\",\n\t\"zapdos\": \"Zapdos\",\n\t\"zubat\": \"Zubat\"\n}\n\n"
  },
  {
    "path": "l10n/pokemon/de-DE/gen2.json",
    "content": "{\n\t\"aipom\": \"Griffel\",\n\t\"ampharos\": \"Ampharos\",\n\t\"ariados\": \"Ariados\",\n\t\"azumarill\": \"Azumarill\",\n\t\"bayleef\": \"Lorblatt\",\n\t\"bellossom\": \"Blubella\",\n\t\"blissey\": \"Heiteira\",\n\t\"celebi\": \"Celebi\",\n\t\"chikorita\": \"Endivie\",\n\t\"chinchou\": \"Lampi\",\n\t\"cleffa\": \"Pii\",\n\t\"corsola\": \"Corasonn\",\n\t\"crobat\": \"Iksbat\",\n\t\"croconaw\": \"Tyracroc\",\n\t\"cyndaquil\": \"Feurigel\",\n\t\"delibird\": \"Botogel\",\n\t\"donphan\": \"Donphan\",\n\t\"dunsparce\": \"Dummisel\",\n\t\"elekid\": \"Elekid\",\n\t\"entei\": \"Entei\",\n\t\"espeon\": \"Psiana\",\n\t\"feraligatr\": \"Impergator\",\n\t\"flaaffy\": \"Waaty\",\n\t\"forretress\": \"Forstellka\",\n\t\"furret\": \"Wiesenior\",\n\t\"girafarig\": \"Girafarig\",\n\t\"gligar\": \"Skorgla\",\n\t\"granbull\": \"Granbull\",\n\t\"heracross\": \"Skaraborn\",\n\t\"heracross_male\": \"Skaraborn (Männlich)\",\n\t\"heracross_female\": \"Skaraborn (Weiblich)\",\n\t\"hitmontop\": \"Kapoera\",\n\t\"hooh\": \"Ho-Oh\",\n\t\"hoothoot\": \"Hoothoot\",\n\t\"hoppip\": \"Hoppspross\",\n\t\"houndoom\": \"Hundemon\",\n\t\"houndour\": \"Hunduster\",\n\t\"igglybuff\": \"Fluffeluff\",\n\t\"jumpluff\": \"Papungha\",\n\t\"kingdra\": \"Seedraking\",\n\t\"lanturn\": \"Lanturn\",\n\t\"larvitar\": \"Larvitar\",\n\t\"ledian\": \"Ledian\",\n\t\"ledyba\": \"Ledyba\",\n\t\"lugia\": \"Lugia\",\n\t\"magby\": \"Magby\",\n\t\"magcargo\": \"Magcargo\",\n\t\"mantine\": \"Mantax\",\n\t\"mareep\": \"Voltilamm\",\n\t\"marill\": \"Marill\",\n\t\"meganium\": \"Meganie\",\n\t\"meganium_female\": \"Meganie (Weiblich)\",\n\t\"miltank\": \"Miltank\",\n\t\"misdreavus\": \"Traunfugil\",\n\t\"murkrow\": \"Kramurx\",\n\t\"natu\": \"Natu\",\n\t\"noctowl\": \"Noctuh\",\n\t\"octillery\": \"Octillery\",\n\t\"phanpy\": \"Phanpy\",\n\t\"pichu\": \"Pichu\",\n\t\"piloswine\": \"Keifel\",\n\t\"pineco\": \"Tannza\",\n\t\"politoed\": \"Quaxo\",\n\t\"porygon2\": \"Porygon2\",\n\t\"pupitar\": \"Pupitar\",\n\t\"quagsire\": \"Morlord\",\n\t\"quilava\": \"Igelavar\",\n\t\"qwilfish\": \"Baldorfish\",\n\t\"raikou\": \"Raikou\",\n\t\"remoraid\": \"Remoraid\",\n\t\"scizor\": \"Scherox\",\n\t\"sentret\": \"Wiesor\",\n\t\"shuckle\": \"Pottrott\",\n\t\"skarmory\": \"Panzaeron\",\n\t\"skiploom\": \"Hubelupf\",\n\t\"slowking\": \"Laschoking\",\n\t\"slugma\": \"Schneckmag\",\n\t\"smeargle\": \"Farbeagle\",\n\t\"smoochum\": \"Rossana\",\n\t\"sneasel\": \"Sniebel\",\n\t\"snubbull\": \"Snubbull\",\n\t\"spinarak\": \"Webarak\",\n\t\"stantler\": \"Damhirplex\",\n\t\"steelix\": \"Stahlos\",\n\t\"steelix_female\": \"Stahlos (Weiblich)\",\n\t\"sudowoodo\": \"Mogelbaum\",\n\t\"suicune\": \"Suicune\",\n\t\"sunflora\": \"Sonnflora\",\n\t\"sunkern\": \"Sonnkern\",\n\t\"swinub\": \"Quiekel\",\n\t\"teddiursa\": \"Teddiursa\",\n\t\"togepi\": \"Togepi\",\n\t\"togetic\": \"Togetic\",\n\t\"totodile\": \"Karnimani\",\n\t\"typhlosion\": \"Tornupto\",\n\t\"tyranitar\": \"Despotar\",\n\t\"tyrogue\": \"Rabauz\",\n\t\"umbreon\": \"Nachtara\",\n\t\"ursaring\": \"Ursaring\",\n\t\"wobbuffet\": \"Woingenau\",\n\t\"wobbuffet_male\": \"Woingenau (Männlich)\",\n\t\"wobbuffet_female\": \"Woingenau (Weiblich)\",\n\t\"wooper\": \"Felino\",\n\t\"xatu\": \"Xatu\",\n\t\"yanma\": \"Yanma\"\n}\n"
  },
  {
    "path": "l10n/pokemon/de-DE/gen3.json",
    "content": "{\n\t\"absol\": \"Absol\",\n\t\"aggron\": \"Stolloss\",\n\t\"altaria\": \"Altaria\",\n\t\"anorith\": \"Anorith\",\n\t\"armaldo\": \"Armaldo\",\n\t\"aron\": \"Stollunior\",\n\t\"azurill\": \"Azurill\",\n\t\"bagon\": \"Kindwurm\",\n\t\"baltoy\": \"Puppance\",\n\t\"banette\": \"Zuppetta\",\n\t\"barboach\": \"Schmerbe\",\n\t\"beautifly\": \"Papinella\",\n\t\"beldum\": \"Tanhel\",\n\t\"blaziken\": \"Lohgock\",\n\t\"breloom\": \"Kapilz\",\n\t\"cacnea\": \"Tuska\",\n\t\"cacturne\": \"Noktuska\",\n\t\"camerupt\": \"Camerupt\",\n\t\"carvanha\": \"Kanivanha\",\n\t\"cascoon\": \"Panekon\",\n\t\"castform\": \"Formeo\",\n\t\"chimecho\": \"Palimpalim\",\n\t\"clamperl\": \"Perlu\",\n\t\"claydol\": \"Lepumentas\",\n\t\"combusken\": \"Jungglut\",\n\t\"corpish\": \"Krebscorps\",\n\t\"cradily\": \"Wielie\",\n\t\"crawdaunt\": \"Krebutack\",\n\t\"delcatty\": \"Enekoro\",\n\t\"deoxys\": \"Deoxys\",\n\t\"deoxys_attack\": \"Deoxys (Angriff)\",\n\t\"deoxys_defense\": \"Deoxys (Verteidigung)\",\n\t\"deoxys_speed\": \"Deoxys (Initiative)\",\n\t\"dusclops\": \"Zwirrklop\",\n\t\"duskull\": \"Zwirrlicht\",\n\t\"dustox\": \"Pudox\",\n\t\"electrike\": \"Frizelbliz\",\n\t\"exploud\": \"Krawumms\",\n\t\"feebas\": \"Barschwa\",\n\t\"flygon\": \"Libelldra\",\n\t\"gardevoir\": \"Guardevoir\",\n\t\"glalie\": \"Firnontor\",\n\t\"gorebyss\": \"Saganabyss\",\n\t\"groudon\": \"Groudon\",\n\t\"grovyle\": \"Reptain\",\n\t\"grumpig\": \"Groink\",\n\t\"gulpin\": \"Schluppuck\",\n\t\"hariyama\": \"Hariyama\",\n\t\"huntail\": \"Aalabyss\",\n\t\"illumise\": \"Illumise\",\n\t\"jirachi\": \"Jirachi\",\n\t\"kecleon\": \"Kecleon\",\n\t\"kirlia\": \"Kirlia\",\n\t\"kyogre\": \"Kyogre\",\n\t\"lairon\": \"Stollrak\",\n\t\"latias\": \"Latias\",\n\t\"latios\": \"Latios\",\n\t\"lileep\": \"Liliep\",\n\t\"linoone\": \"Geradaks\",\n\t\"lombre\": \"Lombrero\",\n\t\"lotad\": \"Loturzel\",\n\t\"loudred\": \"Krakeelo\",\n\t\"ludicolo\": \"Kappalores\",\n\t\"lunatone\": \"Lunastein\",\n\t\"luvdisc\": \"Liebiskus\",\n\t\"makuhita\": \"Makuhita\",\n\t\"manectric\": \"Voltenso\",\n\t\"marshtomp\": \"Moorabbel\",\n\t\"masquerain\": \"Maskeregen\",\n\t\"mawile\": \"Flunkifer\",\n\t\"medicham\": \"Meditalis\",\n\t\"meditite\": \"Meditie\",\n\t\"metagross\": \"Metagross\",\n\t\"metang\": \"Metang\",\n\t\"mightyena\": \"Mightyena\",\n\t\"milotic\": \"Milotic\",\n\t\"minun\": \"Minun\",\n\t\"mudkip\": \"Hydropi\",\n\t\"nincada\": \"Nincada\",\n\t\"ninjask\": \"Ninjask\",\n\t\"nosepass\": \"Nasgnet\",\n\t\"numel\": \"Camaub\",\n\t\"nuzleaf\": \"Blanas\",\n\t\"pelipper\": \"Pelipper\",\n\t\"plusle\": \"Plusle\",\n\t\"poochyena\": \"Fiffyen\",\n\t\"ralts\": \"Trasla\",\n\t\"rayquaza\": \"Rayquaza\",\n\t\"regice\": \"Regice\",\n\t\"regirock\": \"Regirock\",\n\t\"registeel\": \"Registeel\",\n\t\"relicanth\": \"Relicanth\",\n\t\"roselia\": \"Roselia\",\n\t\"sableye\": \"Zobiris\",\n\t\"salamence\": \"Brutalanda\",\n\t\"sceptile\": \"Gewaldro\",\n\t\"sealeo\": \"Seejong\",\n\t\"seedot\": \"Samurzel\",\n\t\"seviper\": \"Vipitis\",\n\t\"sharpedo\": \"Tohaido\",\n\t\"shedinja\": \"Ninjatom\",\n\t\"shelgon\": \"Draschel\",\n\t\"shiftry\": \"Tengulist\",\n\t\"shroomish\": \"Knilz\",\n\t\"shuppet\": \"Shuppet\",\n\t\"silcoon\": \"Schaloko\",\n\t\"skitty\": \"Eneco\",\n\t\"slaking\": \"Letarking\",\n\t\"slakoth\": \"Bummelz\",\n\t\"snorunt\": \"Schneppke\",\n\t\"solrock\": \"Sonnfel\",\n\t\"spheal\": \"Seemops\",\n\t\"spinda\": \"Pandir\",\n\t\"spoink\": \"Spoink\",\n\t\"surskit\": \"Gehweiher\",\n\t\"swablu\": \"Wablu\",\n\t\"swalot\": \"Schlukwech\",\n\t\"swampert\": \"Sumpex\",\n\t\"swellow\": \"Schwalboss\",\n\t\"taillow\": \"Schwalbini\",\n\t\"torchic\": \"Flemmli\",\n\t\"torkoal\": \"Qurtel\",\n\t\"trapinch\": \"Knacklion\",\n\t\"treecko\": \"Geckarbor\",\n\t\"tropius\": \"Tropius\",\n\t\"vibrava\": \"Vibrava\",\n\t\"vigoroth\": \"Muntier\",\n\t\"volbeat\": \"Volbeat\",\n\t\"wailmer\": \"Wailmer\",\n\t\"wailord\": \"Wailord\",\n\t\"walrein\": \"Walraisa\",\n\t\"whiscash\": \"Welsar\",\n\t\"whismur\": \"Flurmel\",\n\t\"wingull\": \"Wingull\",\n\t\"wurmple\": \"Waumpel\",\n\t\"wynaut\": \"Isso\",\n\t\"zangoose\": \"Zangoose\",\n\t\"zigzagoon\": \"Zigzachs\"\n}\n"
  },
  {
    "path": "l10n/pokemon/de-DE/gen4.json",
    "content": "{\n\t\"turtwig\": \"Chelast\",\n\t\"grotle\": \"Chelcarain\",\n\t\"torterra\": \"Chelterrar\",\n\t\"chimchar\": \"Panflam\",\n\t\"monferno\": \"Panpyro\",\n\t\"infernape\": \"Panferno\",\n\t\"piplup\": \"Plinfa\",\n\t\"prinplup\": \"Pliprin\",\n\t\"empoleon\": \"Impoleon\",\n\t\"starly\": \"Staralili\",\n\t\"staravia\": \"Staravia\",\n\t\"staraptor\": \"Staraptor\",\n\t\"bidoof\": \"Bidiza\",\n\t\"bibarel\": \"Bidifas\",\n\t\"kricketot\": \"Zirpurze\",\n\t\"kricketune\": \"Zirpeise\",\n\t\"shinx\": \"Sheinux\",\n\t\"luxio\": \"Luxio\",\n\t\"luxray\": \"Luxtra\",\n\t\"budew\": \"Knospi\",\n\t\"roserade\": \"Roserade\",\n\t\"cranidos\": \"Koknodon\",\n\t\"rampardos\": \"Rameidon\",\n\t\"shieldon\": \"Schilterus\",\n\t\"bastiodon\": \"Bollterus\",\n\t\"burmy_plant\": \"Burmy (Pflanze)\",\n\t\"burmy_sandy\": \"Burmy (Sand)\",\n\t\"burmy_trash\": \"Burmy (Müll)\",\n\t\"wormadam_plant\": \"Burmadame (Pflanze)\",\n\t\"wormadam_sandy\": \"Burmadame (Sand)\",\n\t\"wormadam_trash\": \"Burmadame (Müll)\",\n\t\"mothim\": \"Moterpel\",\n\t\"combee_male\": \"Wadribie (Männlich)\",\n\t\"combee_female\": \"Wadribie (Weiblich)\",\n\t\"vespiquen\": \"Honweisel\",\n\t\"pachirisu\": \"Pachirisu\",\n\t\"buizel\": \"Bamelin\",\n\t\"floatzel\": \"Bojelin\",\n\t\"cherubi\": \"Kikugi\",\n\t\"cherrim\": \"Kinoso\",\n\t\"shellos_west\": \"Schalellos (West)\",\n\t\"shellos_east\": \"Schalellos (Ost)\",\n\t\"gastrodon_west\": \"Gastrodon (West)\",\n\t\"gastrodon_east\": \"Gastrodon (Ost)\",\n\t\"ambipom\": \"Ambidiffel\",\n\t\"drifloon\": \"Driftlon\",\n\t\"drifblim\": \"Drifzepeli\",\n\t\"buneary\": \"Haspiror\",\n\t\"lopunny\": \"Schlapor\",\n\t\"mismagius\": \"Traunmagil\",\n\t\"honchkrow\": \"Kramshef\",\n\t\"glameow\": \"Charmian\",\n\t\"purugly\": \"Shnurgarst\",\n\t\"chingling\": \"Klingplim\",\n\t\"stunky\": \"Skunkapuh\",\n\t\"skuntank\": \"Skuntank\",\n\t\"bronzor\": \"Bronzel\",\n\t\"bronzong\": \"Bronzong\",\n\t\"bonsly\": \"Mobai\",\n\t\"mrmime\": \"Pantimos\",\n\t\"happiny\": \"Wonneira\",\n\t\"chatot\": \"Plaudagei\",\n\t\"spiritomb\": \"Kryppuk\",\n\t\"gible\": \"Kaumalat\",\n\t\"gible_female\": \"Kaumalat (Weiblich)\",\n\t\"gabite\": \"Knarksel\",\n\t\"gabite_female\": \"Knarksel (Weiblich)\",\n\t\"garchomp\": \"Knakrack\",\n\t\"garchomp_female\": \"Knakrack (Weiblich)\",\n\t\"munchlax\": \"Mampfaxo\",\n\t\"riolu\": \"Riolu\",\n\t\"lucario\": \"Lucario\",\n\t\"hippopotas_male\": \"Hippopotas (Männlich)\",\n\t\"hippopotas_female\": \"Hippopotas (Weiblich)\",\n\t\"hippowdon_male\": \"Hippoterus (Männlich)\",\n\t\"hippowdon_female\": \"Hippoterus (Weiblich)\",\n\t\"skorupi\": \"Pionskora\",\n\t\"drapion\": \"Piondragi\",\n\t\"croagunk\": \"Glibunkel\",\n\t\"toxicroak\": \"Toxiquak\",\n\t\"carnivine\": \"Venuflibis\",\n\t\"finneon\": \"Finneon\",\n\t\"lumineon\": \"Lumineon\",\n\t\"mantyke\": \"Mantirps\",\n\t\"snover\": \"Shnebedeck\",\n\t\"abomasnow\": \"Rexblisar\",\n\t\"weavile\": \"Snibunna\",\n\t\"magnezone\": \"Magnezone\",\n\t\"lickilicky\": \"Schlurplek\",\n\t\"rhyperior\": \"Rihornior\",\n\t\"tangrowth\": \"Tangoloss\",\n\t\"electivire\": \"Elevoltek\",\n\t\"magmortar\": \"Magbrant\",\n\t\"togekiss\": \"Togekiss\",\n\t\"yanmega\": \"Yanmega\",\n\t\"leafeon\": \"Folipurba\",\n\t\"glaceon\": \"Glaziola\",\n\t\"gliscor\": \"Skorgro\",\n\t\"mamoswine\": \"Mamutel\",\n\t\"porygon_z\": \"Porygon-Z\",\n\t\"gallade\": \"Galagladi\",\n\t\"probopass\": \"Voluminas\",\n\t\"dusknoir\": \"Zwirrfinst\",\n\t\"froslass\": \"Frosdedje\",\n\t\"rotom\": \"Rotom\",\n\t\"rotom_heat\": \"Rotom (Hitze)\",\n\t\"rotom_wash\": \"Rotom (Wasch)\",\n\t\"rotom_frost\": \"Rotom (Frost)\",\n\t\"rotom_fan\": \"Rotom (Wirbel)\",\n\t\"rotom_mow\": \"Rotom (Schneid)\",\n\t\"uxie\": \"Selfe\",\n\t\"mesprit\": \"Vesprit\",\n\t\"azelf\": \"Tobutz\",\n\t\"dialga\": \"Dialga\",\n\t\"palkia\": \"Palkia\",\n\t\"heatran\": \"Heatran\",\n\t\"regigigas\": \"Regigigas\",\n\t\"giratina\": \"Giratina\",\n\t\"giratina_origin\": \"Giratina (Urform)\",\n\t\"cresselia\": \"Cresselia\",\n\t\"phione\": \"Phione\",\n\t\"manaphy\": \"Manaphy\",\n\t\"darkrai\": \"Darkrai\",\n\t\"shaymin\": \"Shaymin\",\n\t\"shaymin_sky\": \"Shaymin (Zenitform)\",\n\t\"arceus\": \"Arceus\",\n\t\"arceus_bug\": \"Arceus (Käfer)\",\n\t\"arceus_dark\": \"Arceus (Unlicht)\",\n\t\"arceus_dragon\": \"Arceus (Drache)\",\n\t\"arceus_electric\": \"Arceus (Elektro)\",\n\t\"arceus_fighting\": \"Arceus (Kampf)\",\n\t\"arceus_fire\": \"Arceus (Feuer)\",\n\t\"arceus_flying\": \"Arceus (Flug)\",\n\t\"arceus_ghost\": \"Arceus (Geist)\",\n\t\"arceus_grass\": \"Arceus (Pflanze)\",\n\t\"arceus_ground\": \"Arceus (Boden)\",\n\t\"arceus_ice\": \"Arceus (Eis)\",\n\t\"arceus_poison\": \"Arceus (Gift)\",\n\t\"arceus_psychic\": \"Arceus (Psycho)\",\n\t\"arceus_rock\": \"Arceus (Gestein)\",\n\t\"arceus_steel\": \"Arceus (Stahl)\",\n\t\"arceus_water\": \"Arceus (Wasser)\"\n}\n"
  },
  {
    "path": "l10n/pokemon/fr-FR/gen1.json",
    "content": "{\n\t\"bulbasaur\": \"Bulbizarre\",\n\t\"ivysaur\": \"Herbizarre\",\n\t\"venusaur\": \"Florizarre\",\n\t\"venusaur_female\": \"Florizarre (Femelle)\",\n\t\"charmander\": \"Salamèche\",\n\t\"charmeleon\": \"Reptincel\",\n\t\"charizard\": \"Dracaufeu\",\n\t\"squirtle\": \"Carapuce\",\n\t\"wartortle\": \"Carabaffe\",\n\t\"blastoise\": \"Tortank\",\n\t\"caterpie\": \"Chenipan\",\n\t\"metapod\": \"Chrysacier\",\n\t\"butterfree\": \"Papilusion\",\n\t\"weedle\": \"Aspicot\",\n\t\"kakuna\": \"Coconfort\",\n\t\"beedrill\": \"Dardargnan\",\n\t\"pidgey\": \"Roucool\",\n\t\"pidgeotto\": \"Roucoups\",\n\t\"pidgeot\": \"Roucarnage\",\n\t\"rattata\": \"Rattata\",\n\t\"raticate\": \"Rattatac\",\n\t\"spearow\": \"Piafabec\",\n\t\"fearow\": \"Rapasdepic\",\n\t\"ekans\": \"Abo\",\n\t\"arbok\": \"Arbok\",\n\t\"pikachu\": \"Pikachu\",\n\t\"pikachu_female\": \"Pikachu (Femelle)\",\n\t\"raichu\": \"Raichu\",\n\t\"sandshrew\": \"Sabelette\",\n\t\"sandslash\": \"Sablaireau\",\n\t\"nidoran_female\": \"Nidoran♀\",\n\t\"nidorina\": \"Nidorina\",\n\t\"nidoqueen\": \"Nidoqueen\",\n\t\"nidoran_male\": \"Nidoran♂\",\n\t\"nidorino\": \"Nidorino\",\n\t\"nidoking\": \"Nidoking\",\n\t\"clefairy\": \"Mélofée\",\n\t\"clefable\": \"Mélodelfe\",\n\t\"vulpix\": \"Goupix\",\n\t\"ninetales\": \"Feunard\",\n\t\"jigglypuff\": \"Rondoudou\",\n\t\"wigglytuff\": \"Grodoudou\",\n\t\"zubat\": \"Nosferapti\",\n\t\"golbat\": \"Nosferalto\",\n\t\"oddish\": \"Mystherbe\",\n\t\"gloom\": \"Ortide\",\n\t\"vileplume\": \"Rafflesia\",\n\t\"paras\": \"Paras\",\n\t\"parasect\": \"Parasect\",\n\t\"venonat\": \"Mimitoss\",\n\t\"venomoth\": \"Aéromite\",\n\t\"diglett\": \"Taupiqueur\",\n\t\"dugtrio\": \"Triopikeur\",\n\t\"meowth\": \"Miaouss\",\n\t\"persian\": \"Persian\",\n\t\"psyduck\": \"Psykokwak\",\n\t\"golduck\": \"Akwakwak\",\n\t\"mankey\": \"Férosinge\",\n\t\"primeape\": \"Colossinge\",\n\t\"growlithe\": \"Caninos\",\n\t\"arcanine\": \"Arcanin\",\n\t\"poliwag\": \"Ptitard\",\n\t\"poliwhirl\": \"Têtarte\",\n\t\"poliwrath\": \"Tartard\",\n\t\"abra\": \"Abra\",\n\t\"kadabra\": \"Kadabra\",\n\t\"alakazam\": \"Alakazam\",\n\t\"machop\": \"Machoc\",\n\t\"machoke\": \"Machopeur\",\n\t\"machamp\": \"Mackogneur\",\n\t\"bellsprout\": \"Chétiflor\",\n\t\"weepinbell\": \"Boustiflor\",\n\t\"victreebel\": \"Empiflor\",\n\t\"tentacool\": \"Tentacool\",\n\t\"tentacruel\": \"Tentacruel\",\n\t\"geodude\": \"Racaillou\",\n\t\"graveler\": \"Gravalanch\",\n\t\"golem\": \"Grolem\",\n\t\"ponyta\": \"Ponyta\",\n\t\"rapidash\": \"Galopa\",\n\t\"slowpoke\": \"Ramoloss\",\n\t\"slowbro\": \"Flagadoss\",\n\t\"magnemite\": \"Magnéti\",\n\t\"magneton\": \"Magnéton\",\n\t\"farfetchd\": \"Canarticho\",\n\t\"doduo\": \"Doduo\",\n\t\"dodrio\": \"Dodrio\",\n\t\"seel\": \"Otaria\",\n\t\"dewgong\": \"Lamantine\",\n\t\"grimer\": \"Tadmorv\",\n\t\"muk\": \"Grotadmorv\",\n\t\"shellder\": \"Kokiyas\",\n\t\"cloyster\": \"Crustabri\",\n\t\"gastly\": \"Fantominus\",\n\t\"haunter\": \"Spectrum\",\n\t\"gengar\": \"Ectoplasma\",\n\t\"onix\": \"Onix\",\n\t\"drowzee\": \"Soporifik\",\n\t\"hypno\": \"Hypnomade\",\n\t\"krabby\": \"Krabby\",\n\t\"kingler\": \"Krabboss\",\n\t\"voltorb\": \"Voltorbe\",\n\t\"electrode\": \"Électrode\",\n\t\"exeggcute\": \"Noeunoeuf\",\n\t\"exeggutor\": \"Noadkoko\",\n\t\"cubone\": \"Osselait\",\n\t\"marowak\": \"Ossatueur\",\n\t\"hitmonlee\": \"Kicklee\",\n\t\"hitmonchan\": \"Tygnon\",\n\t\"lickitung\": \"Excelangue\",\n\t\"koffing\": \"Smogo\",\n\t\"weezing\": \"Smogogo\",\n\t\"rhyhorn\": \"Rhinocorne\",\n\t\"rhydon\": \"Rhinoféros\",\n\t\"chansey\": \"Leveinard\",\n\t\"tangela\": \"Saquedeneu\",\n\t\"kangaskhan\": \"Kangourex\",\n\t\"horsea\": \"Hypotrempe\",\n\t\"seadra\": \"Hypocéan\",\n\t\"goldeen\": \"Poissirène\",\n\t\"seaking\": \"Poissoroy\",\n\t\"staryu\": \"Stari\",\n\t\"starmie\": \"Staross\",\n\t\"mrmime\": \"M. Mime\",\n\t\"scyther\": \"Insécateur\",\n\t\"jynx\": \"Lippoutou\",\n\t\"electabuzz\": \"Élektek\",\n\t\"magmar\": \"Magmar\",\n\t\"pinsir\": \"Scarabrute\",\n\t\"tauros\": \"Tauros\",\n\t\"magikarp\": \"Magicarpe\",\n\t\"gyarados\": \"Léviator\",\n\t\"lapras\": \"Lokhlass\",\n\t\"ditto\": \"Métamorph\",\n\t\"eevee\": \"Évoli\",\n\t\"vaporeon\": \"Aquali\",\n\t\"jolteon\": \"Voltali\",\n\t\"flareon\": \"Pyroli\",\n\t\"porygon\": \"Porygon\",\n\t\"omanyte\": \"Amonita\",\n\t\"omastar\": \"Amonistar\",\n\t\"kabuto\": \"Kabuto\",\n\t\"kabutops\": \"Kabutops\",\n\t\"aerodactyl\": \"Ptéra\",\n\t\"snorlax\": \"Ronflex\",\n\t\"articuno\": \"Artikodin\",\n\t\"zapdos\": \"Électhor\",\n\t\"moltres\": \"Sulfura\",\n\t\"dratini\": \"Minidraco\",\n\t\"dragonair\": \"Draco\",\n\t\"dragonite\": \"Dracolosse\",\n\t\"mewtwo\": \"Mewtwo\",\n\t\"mew\": \"Mew\"\n}"
  },
  {
    "path": "l10n/pokemon/fr-FR/gen2.json",
    "content": "{\n\t\"chikorita\": \"Germignon\",\n\t\"bayleef\": \"Macronium\",\n\t\"meganium\": \"Méganium\",\n\t\"meganium_female\": \"Méganium (Femelle)\",\n\t\"cyndaquil\": \"Héricendre\",\n\t\"quilava\": \"Feurisson\",\n\t\"typhlosion\": \"Typhlosion\",\n\t\"totodile\": \"Kaiminus\",\n\t\"croconaw\": \"Crocodil\",\n\t\"feraligatr\": \"Aligatueur\",\n\t\"sentret\": \"Fouinette\",\n\t\"furret\": \"Fouinar\",\n\t\"hoothoot\": \"Hoothoot\",\n\t\"noctowl\": \"Noarfang\",\n\t\"ledyba\": \"Coxy\",\n\t\"ledian\": \"Coxyclaque\",\n\t\"spinarak\": \"Mimigal\",\n\t\"ariados\": \"Migalos\",\n\t\"crobat\": \"Nostenfer\",\n\t\"chinchou\": \"Loupio\",\n\t\"lanturn\": \"Lanturn\",\n\t\"pichu\": \"Pichu\",\n\t\"cleffa\": \"Mélo\",\n\t\"igglybuff\": \"Toudoudou\",\n\t\"togepi\": \"Togepi\",\n\t\"togetic\": \"Togetic\",\n\t\"natu\": \"Natu\",\n\t\"xatu\": \"Xatu\",\n\t\"mareep\": \"Wattouat\",\n\t\"flaaffy\": \"Lainergie\",\n\t\"ampharos\": \"Pharamp\",\n\t\"bellossom\": \"Joliflor\",\n\t\"marill\": \"Marill\",\n\t\"azumarill\": \"Azumarill\",\n\t\"sudowoodo\": \"Simularbre\",\n\t\"politoed\": \"Tarpaud\",\n\t\"hoppip\": \"Granivol\",\n\t\"skiploom\": \"Floravol\",\n\t\"jumpluff\": \"Cotovol\",\n\t\"aipom\": \"Capumain\",\n\t\"sunkern\": \"Tournegrin\",\n\t\"sunflora\": \"Héliatronc\",\n\t\"yanma\": \"Yanma\",\n\t\"wooper\": \"Axoloto\",\n\t\"quagsire\": \"Maraiste\",\n\t\"espeon\": \"Mentali\",\n\t\"umbreon\": \"Noctali\",\n\t\"murkrow\": \"Cornèbre\",\n\t\"slowking\": \"Roigada\",\n\t\"misdreavus\": \"Feuforêve\",\n\t\"wobbuffet\": \"Qulbutoké\",\n\t\"wobbuffet_male\": \"Qulbutoké (Mâle)\",\n\t\"wobbuffet_female\": \"Qulbutoké (Femelle)\",\n\t\"girafarig\": \"Girafarig\",\n\t\"pineco\": \"Pomdepik\",\n\t\"forretress\": \"Foretress\",\n\t\"dunsparce\": \"Insolourdo\",\n\t\"gligar\": \"Scorplane\",\n\t\"steelix\": \"Steelix\",\n\t\"steelix_female\": \"Steelix (Femelle)\",\n\t\"snubbull\": \"Snubbull\",\n\t\"granbull\": \"Granbull\",\n\t\"qwilfish\": \"Qwilfish\",\n\t\"scizor\": \"Cizayox\",\n\t\"shuckle\": \"Caratroc\",\n\t\"heracross\": \"Scarhino\",\n\t\"heracross_male\": \"Scarhino (Mâle)\",\n\t\"heracross_female\": \"Scarhino (Femelle)\",\n\t\"sneasel\": \"Farfuret\",\n\t\"teddiursa\": \"Teddiursa\",\n\t\"ursaring\": \"Ursaring\",\n\t\"slugma\": \"Limagma\",\n\t\"magcargo\": \"Volcaropod\",\n\t\"swinub\": \"Marcacrin\",\n\t\"piloswine\": \"Cochignon\",\n\t\"corsola\": \"Corayon\",\n\t\"remoraid\": \"Rémoraid\",\n\t\"octillery\": \"Octillery\",\n\t\"delibird\": \"Cadoizo\",\n\t\"mantine\": \"Démanta\",\n\t\"skarmory\": \"Airmure\",\n\t\"houndour\": \"Malosse\",\n\t\"houndoom\": \"Démolosse\",\n\t\"kingdra\": \"Hyporoi\",\n\t\"phanpy\": \"Phanpy\",\n\t\"donphan\": \"Donphan\",\n\t\"porygon2\": \"Porygon2\",\n\t\"stantler\": \"Cerfrousse\",\n\t\"smeargle\": \"Queulorior\",\n\t\"tyrogue\": \"Debugant\",\n\t\"hitmontop\": \"Kapoera\",\n\t\"smoochum\": \"Lippouti\",\n\t\"elekid\": \"Élekid\",\n\t\"magby\": \"Magby\",\n\t\"miltank\": \"Écrémeuh\",\n\t\"blissey\": \"Leuphorie\",\n\t\"raikou\": \"Raikou\",\n\t\"entei\": \"Entei\",\n\t\"suicune\": \"Suicune\",\n\t\"larvitar\": \"Embrylex\",\n\t\"pupitar\": \"Ymphect\",\n\t\"tyranitar\": \"Tyranocif\",\n\t\"lugia\": \"Lugia\",\n\t\"hooh\": \"Ho-Oh\",\n\t\"celebi\": \"Celebi\"\n}"
  },
  {
    "path": "l10n/pokemon/fr-FR/gen3.json",
    "content": "{\n\t\"treecko\": \"Arcko\",\n\t\"grovyle\": \"Massko\",\n\t\"sceptile\": \"Jungko\",\n\t\"torchic\": \"Poussifeu\",\n\t\"combusken\": \"Galégon\",\n\t\"blaziken\": \"Braségali\",\n\t\"mudkip\": \"Gobou\",\n\t\"marshtomp\": \"Flobio\",\n\t\"swampert\": \"Laggron\",\n\t\"poochyena\": \"Medhyèna\",\n\t\"mightyena\": \"Grahyèna\",\n\t\"zigzagoon\": \"Zigzaton\",\n\t\"linoone\": \"Linéon\",\n\t\"wurmple\": \"Chenipotte\",\n\t\"silcoon\": \"Armulys\",\n\t\"beautifly\": \"Charmillon\",\n\t\"cascoon\": \"Blindalys\",\n\t\"dustox\": \"Papinox\",\n\t\"lotad\": \"Nénupiot\",\n\t\"lombre\": \"Lombre\",\n\t\"ludicolo\": \"Ludicolo\",\n\t\"seedot\": \"Grainipiot\",\n\t\"nuzleaf\": \"Pifeuil\",\n\t\"shiftry\": \"Tengalice\",\n\t\"taillow\": \"Nirondelle\",\n\t\"swellow\": \"Hélédelle\",\n\t\"wingull\": \"Goélise\",\n\t\"pelipper\": \"Bekipan\",\n\t\"ralts\": \"Tarsal\",\n\t\"kirlia\": \"Kirlia\",\n\t\"gardevoir\": \"Gardevoir\",\n\t\"surskit\": \"Arakdo\",\n\t\"masquerain\": \"Maskadra\",\n\t\"shroomish\": \"Balignon\",\n\t\"breloom\": \"Chapignon\",\n\t\"slakoth\": \"Parecool\",\n\t\"vigoroth\": \"Vigoroth\",\n\t\"slaking\": \"Monaflèmit\",\n\t\"nincada\": \"Ningale\",\n\t\"ninjask\": \"Ninjask\",\n\t\"shedinja\": \"Munja\",\n\t\"whismur\": \"Chuchmur\",\n\t\"loudred\": \"Ramboum\",\n\t\"exploud\": \"Brouhabam\",\n\t\"makuhita\": \"Makuhita\",\n\t\"hariyama\": \"Hariyama\",\n\t\"azurill\": \"Azurill\",\n\t\"nosepass\": \"Tarinor\",\n\t\"skitty\": \"Skitty\",\n\t\"delcatty\": \"Delcatty\",\n\t\"sableye\": \"Ténéfix\",\n\t\"mawile\": \"Mysdibule\",\n\t\"aron\": \"Galekid\",\n\t\"lairon\": \"Galegon\",\n\t\"aggron\": \"Galeking\",\n\t\"meditite\": \"Méditikka\",\n\t\"medicham\": \"Charmina\",\n\t\"electrike\": \"Dynavolt\",\n\t\"manectric\": \"Élecsprint\",\n\t\"plusle\": \"Posipi\",\n\t\"minun\": \"Négapi\",\n\t\"volbeat\": \"Muciole\",\n\t\"illumise\": \"Lumivole\",\n\t\"roselia\": \"Rosélia\",\n\t\"gulpin\": \"Gloupti\",\n\t\"swalot\": \"Avaltout\",\n\t\"carvanha\": \"Carvanha\",\n\t\"sharpedo\": \"Sharpedo\",\n\t\"wailmer\": \"Wailmer\",\n\t\"wailord\": \"Wailord\",\n\t\"numel\": \"Chamallot\",\n\t\"camerupt\": \"Camérupt\",\n\t\"torkoal\": \"Chartor\",\n\t\"spoink\": \"Spoink\",\n\t\"grumpig\": \"Groret\",\n\t\"spinda\": \"Spinda\",\n\t\"trapinch\": \"Kraknoix\",\n\t\"vibrava\": \"Vibraninf\",\n\t\"flygon\": \"Libégon\",\n\t\"cacnea\": \"Cacnea\",\n\t\"cacturne\": \"Cacturne\",\n\t\"swablu\": \"Tylton\",\n\t\"altaria\": \"Altaria\",\n\t\"zangoose\": \"Mangriff\",\n\t\"seviper\": \"Séviper\",\n\t\"lunatone\": \"Séléroc\",\n\t\"solrock\": \"Solaroc\",\n\t\"barboach\": \"Barloche\",\n\t\"whiscash\": \"Barbicha\",\n\t\"corpish\": \"Écrapince\",\n\t\"crawdaunt\": \"Colhomard\",\n\t\"baltoy\": \"Balbuto\",\n\t\"claydol\": \"Kaorine\",\n\t\"lileep\": \"Lilia\",\n\t\"cradily\": \"Vacilys\",\n\t\"anorith\": \"Anorith\",\n\t\"armaldo\": \"Armaldo\",\n\t\"feebas\": \"Barpau\",\n\t\"milotic\": \"Milobellus\",\n\t\"castform\": \"Morphéo\",\n\t\"kecleon\": \"Kecleon\",\n\t\"shuppet\": \"Polichombr\",\n\t\"banette\": \"Branette\",\n\t\"duskull\": \"Skelénox\",\n\t\"dusclops\": \"Téraclope\",\n\t\"tropius\": \"Tropius\",\n\t\"chimecho\": \"Éoko\",\n\t\"absol\": \"Absol\",\n\t\"wynaut\": \"Okéoké\",\n\t\"snorunt\": \"Stalgamin\",\n\t\"glalie\": \"Oniglali\",\n\t\"spheal\": \"Obalie\",\n\t\"sealeo\": \"Phogleur\",\n\t\"walrein\": \"Kaimorse\",\n\t\"clamperl\": \"Coquiperl\",\n\t\"huntail\": \"Serpang\",\n\t\"gorebyss\": \"Rosabyss\",\n\t\"relicanth\": \"Relicanth\",\n\t\"luvdisc\": \"Lovdisc\",\n\t\"bagon\": \"Draby\",\n\t\"shelgon\": \"Drackhaus\",\n\t\"salamence\": \"Drattak\",\n\t\"beldum\": \"Terhal\",\n\t\"metang\": \"Métang\",\n\t\"metagross\": \"Métalosse\",\n\t\"regirock\": \"Regirock\",\n\t\"regice\": \"Regice\",\n\t\"registeel\": \"Registeel\",\n\t\"latias\": \"Latias\",\n\t\"latios\": \"Latios\",\n\t\"kyogre\": \"Kyogre\",\n\t\"groudon\": \"Groudon\",\n\t\"rayquaza\": \"Rayquaza\",\n\t\"jirachi\": \"Jirachi\",\n\t\"deoxys\": \"Deoxys\",\n\t\"deoxys_speed\": \"Deoxys (Vitesse)\",\n\t\"deoxys_attack\": \"Deoxys (Attaque)\",\n\t\"deoxys_defense\": \"Deoxys (Défense)\"\n}"
  },
  {
    "path": "l10n/pokemon/fr-FR/gen4.json",
    "content": "{\n\t\"turtwig\": \"Tortipouss\",\n\t\"grotle\": \"Boskara\",\n\t\"torterra\": \"Torterra\",\n\t\"chimchar\": \"Ouisticram\",\n\t\"monferno\": \"Chimpenfeu\",\n\t\"infernape\": \"Simiabraz\",\n\t\"piplup\": \"Tiplouf\",\n\t\"prinplup\": \"Prinplouf\",\n\t\"empoleon\": \"Pingoléon\",\n\t\"starly\": \"Étourmi\",\n\t\"staravia\": \"Étourvol\",\n\t\"staraptor\": \"Étouraptor\",\n\t\"bidoof\": \"Keunotor\",\n\t\"bibarel\": \"Castorno\",\n\t\"kricketot\": \"Crikzik\",\n\t\"kricketune\": \"Mélokrik\",\n\t\"shinx\": \"Lixy\",\n\t\"luxio\": \"Luxio\",\n\t\"luxray\": \"Luxray\",\n\t\"budew\": \"Rozbouton\",\n\t\"roserade\": \"Roserade\",\n\t\"cranidos\": \"Kranidos\",\n\t\"rampardos\": \"Charkos\",\n\t\"shieldon\": \"Dinoclier\",\n\t\"bastiodon\": \"Bastiodon\",\n\t\"burmy_plant\": \"Cheniti (Plante)\",\n\t\"burmy_sandy\": \"Cheniti (Sable)\",\n\t\"burmy_trash\": \"Cheniti (Déchet)\",\n\t\"wormadam_plant\": \"Cheniselle (Plante)\",\n\t\"wormadam_sandy\": \"Cheniselle (Sable)\",\n\t\"wormadam_trash\": \"Cheniselle (Déchet)\",\n\t\"mothim\": \"Papilord\",\n\t\"combee_male\": \"Apitrini (Mâle)\",\n\t\"combee_female\": \"Apitrini (Femelle)\",\n\t\"vespiquen\": \"Apireine\",\n\t\"pachirisu\": \"Pachirisu\",\n\t\"buizel\": \"Mustébouée\",\n\t\"floatzel\": \"Mustéflott\",\n\t\"cherubi\": \"Ceribou\",\n\t\"cherrim\": \"Ceriflor\",\n\t\"shellos_west\": \"Sancoki (Ouest)\",\n\t\"shellos_east\": \"Sancoki (Est)\",\n\t\"gastrodon_west\": \"Tritosor (Ouest)\",\n\t\"gastrodon_east\": \"Tritosor (Est)\",\n\t\"ambipom\": \"Capidextre\",\n\t\"drifloon\": \"Baudrive\",\n\t\"drifblim\": \"Grodrive\",\n\t\"buneary\": \"Laporeille\",\n\t\"lopunny\": \"Lockpin\",\n\t\"mismagius\": \"Magirêve\",\n\t\"honchkrow\": \"Corboss\",\n\t\"glameow\": \"Chaglam\",\n\t\"purugly\": \"Chaffreux\",\n\t\"chingling\": \"Korillon\",\n\t\"stunky\": \"Moufouette\",\n\t\"skuntank\": \"Moufflair\",\n\t\"bronzor\": \"Archéomire\",\n\t\"bronzong\": \"Archéodong\",\n\t\"bonsly\": \"Manzaï\",\n\t\"mrmime\": \"M. Mime\",\n\t\"happiny\": \"Ptiravi\",\n\t\"chatot\": \"Pijako\",\n\t\"spiritomb\": \"Spiritomb\",\n\t\"gible\": \"Griknot\",\n\t\"gible_female\": \"Griknot (Femelle)\",\n\t\"gabite\": \"Carmache\",\n\t\"gabite_female\": \"Carmache (Femelle)\",\n\t\"garchomp\": \"Carchacrok\",\n\t\"garchomp_female\": \"Carchacrok (Femelle)\",\n\t\"munchlax\": \"Goinfrex\",\n\t\"riolu\": \"Riolu\",\n\t\"lucario\": \"Lucario\",\n\t\"hippopotas_male\": \"Hippopotas (Mâle)\",\n\t\"hippopotas_female\": \"Hippopotas (Femelle)\",\n\t\"hippowdon_male\": \"Hippodocus (Mâle)\",\n\t\"hippowdon_female\": \"Hippodocus (Femelle)\",\n\t\"skorupi\": \"Rapion\",\n\t\"drapion\": \"Drascore\",\n\t\"croagunk\": \"Cradopaud\",\n\t\"toxicroak\": \"Coatox\",\n\t\"carnivine\": \"Vortente\",\n\t\"finneon\": \"Écayon\",\n\t\"lumineon\": \"Luminéon\",\n\t\"mantyke\": \"Babimanta\",\n\t\"snover\": \"Blizzi\",\n\t\"abomasnow\": \"Blizzaroi\",\n\t\"weavile\": \"Dimoret\",\n\t\"magnezone\": \"Magnézone\",\n\t\"lickilicky\": \"Coudlangue\",\n\t\"rhyperior\": \"Rhinastoc\",\n\t\"tangrowth\": \"Bouldeneu\",\n\t\"electivire\": \"Élekable\",\n\t\"magmortar\": \"Maganon\",\n\t\"togekiss\": \"Togekiss\",\n\t\"yanmega\": \"Yanmega\",\n\t\"leafeon\": \"Phyllali\",\n\t\"glaceon\": \"Givrali\",\n\t\"gliscor\": \"Scorvol\",\n\t\"mamoswine\": \"Mammochon\",\n\t\"porygon_z\": \"Porygon-Z\",\n\t\"gallade\": \"Gallame\",\n\t\"probopass\": \"Tarinorme\",\n\t\"dusknoir\": \"Noctunoir\",\n\t\"froslass\": \"Momartik\",\n\t\"rotom\": \"Motisma\",\n\t\"rotom_heat\": \"Motisma (Chaleur)\",\n\t\"rotom_wash\": \"Motisma (Lavage)\",\n\t\"rotom_frost\": \"Motisma (Froid)\",\n\t\"rotom_fan\": \"Motisma (Hélice)\",\n\t\"rotom_mow\": \"Motisma (Tonte)\",\n\t\"uxie\": \"Créhelf\",\n\t\"mesprit\": \"Créfollet\",\n\t\"azelf\": \"Créfadet\",\n\t\"dialga\": \"Dialga\",\n\t\"palkia\": \"Palkia\",\n\t\"heatran\": \"Heatran\",\n\t\"regigigas\": \"Regigigas\",\n\t\"giratina\": \"Giratina\",\n\t\"giratina_origin\": \"Giratina (Origine)\",\n\t\"cresselia\": \"Cresselia\",\n\t\"phione\": \"Phione\",\n\t\"manaphy\": \"Manaphy\",\n\t\"darkrai\": \"Darkrai\",\n\t\"shaymin\": \"Shaymin\",\n\t\"shaymin_sky\": \"Shaymin (Ciel)\",\n\t\"arceus\": \"Arceus\",\n\t\"arceus_bug\": \"Arceus (Insecte)\",\n\t\"arceus_dark\": \"Arceus (Ténèbres)\",\n\t\"arceus_dragon\": \"Arceus (Dragon)\",\n\t\"arceus_electric\": \"Arceus (Électrik)\",\n\t\"arceus_fighting\": \"Arceus (Combat)\",\n\t\"arceus_fire\": \"Arceus (Feu)\",\n\t\"arceus_flying\": \"Arceus (Vol)\",\n\t\"arceus_ghost\": \"Arceus (Spectre)\",\n\t\"arceus_grass\": \"Arceus (Plante)\",\n\t\"arceus_ground\": \"Arceus (Sol)\",\n\t\"arceus_ice\": \"Arceus (Glace)\",\n\t\"arceus_poison\": \"Arceus (Poison)\",\n\t\"arceus_psychic\": \"Arceus (Psy)\",\n\t\"arceus_rock\": \"Arceus (Roche)\",\n\t\"arceus_steel\": \"Arceus (Acier)\",\n\t\"arceus_water\": \"Arceus (Eau)\"\n}\n"
  },
  {
    "path": "l10n/pokemon/ja-JP/gen1.json",
    "content": "{\n\t\"abra\": \"ケーシィ\",\n\t\"aerodactyl\": \"プテラ\",\n\t\"alakazam\": \"フーディン\",\n\t\"arbok\": \"アーボック\",\n\t\"arcanine\": \"ウインディ\",\n\t\"articuno\": \"フリーザー\",\n\t\"beedrill\": \"スピアー\",\n\t\"bellsprout\": \"マダツボミ\",\n\t\"blastoise\": \"カメックス\",\n\t\"bulbasaur\": \"フシギダネ\",\n\t\"butterfree\": \"バタフリー\",\n\t\"caterpie\": \"キャタピー\",\n\t\"chansey\": \"ラッキー\",\n\t\"charizard\": \"リザードン\",\n\t\"charmander\": \"ヒトカゲ\",\n\t\"charmeleon\": \"リザード\",\n\t\"clefable\": \"ピクシー\",\n\t\"clefairy\": \"ピッピ\",\n\t\"cloyster\": \"パルシェン\",\n\t\"cubone\": \"カラカラ\",\n\t\"dewgong\": \"ジュゴン\",\n\t\"diglett\": \"ディグダ\",\n\t\"ditto\": \"メタモン\",\n\t\"dodrio\": \"ドードリオ\",\n\t\"doduo\": \"ドードー\",\n\t\"dragonair\": \"ハクリュー\",\n\t\"dragonite\": \"カイリュー\",\n\t\"dratini\": \"ミニリュウ\",\n\t\"drowzee\": \"スリープ\",\n\t\"dugtrio\": \"ダグトリオ\",\n\t\"eevee\": \"イーブイ\",\n\t\"ekans\": \"アーボ\",\n\t\"electabuzz\": \"エレブー\",\n\t\"electrode\": \"マルマイン\",\n\t\"exeggcute\": \"タマタマ\",\n\t\"exeggutor\": \"ナッシー\",\n\t\"farfetchd\": \"カモネギ\",\n\t\"fearow\": \"オニドリル\",\n\t\"flareon\": \"ブースター\",\n\t\"gastly\": \"ゴース\",\n\t\"gengar\": \"ゲンガー\",\n\t\"geodude\": \"イシツブテ\",\n\t\"gloom\": \"クサイハナ\",\n\t\"golbat\": \"ゴルバット\",\n\t\"goldeen\": \"トサキント\",\n\t\"golduck\": \"ゴルダック\",\n\t\"golem\": \"ゴローニャ\",\n\t\"graveler\": \"ゴローン\",\n\t\"grimer\": \"ベトベター\",\n\t\"growlithe\": \"ガーディ\",\n\t\"gyarados\": \"ギャラドス\",\n\t\"haunter\": \"ゴースト\",\n\t\"hitmonchan\": \"エビワラー\",\n\t\"hitmonlee\": \"サワムラー\",\n\t\"horsea\": \"タッツー\",\n\t\"hypno\": \"スリーパー\",\n\t\"ivysaur\": \"フシギソウ\",\n\t\"jigglypuff\": \"プリン\",\n\t\"jolteon\": \"サンダース\",\n\t\"jynx\": \"ルージュラ\",\n\t\"kabuto\": \"カブト\",\n\t\"kabutops\": \"カブトプス\",\n\t\"kadabra\": \"ユンゲラー\",\n\t\"kakuna\": \"コクーン\",\n\t\"kangaskhan\": \"ガルーラ\",\n\t\"kingler\": \"キングラー\",\n\t\"koffing\": \"ドガース\",\n\t\"krabby\": \"クラブ\",\n\t\"lapras\": \"ラプラス\",\n\t\"lickitung\": \"ベロリンガ\",\n\t\"machamp\": \"カイリキー\",\n\t\"machoke\": \"ゴーリキー\",\n\t\"machop\": \"ワンリキー\",\n\t\"magikarp\": \"コイキング\",\n\t\"magmar\": \"ブーバー\",\n\t\"magnemite\": \"コイル\",\n\t\"magneton\": \"レアコイル\",\n\t\"mankey\": \"マンキー\",\n\t\"marowak\": \"ガラガラ\",\n\t\"meowth\": \"ニャース\",\n\t\"metapod\": \"トランセル\",\n\t\"mew\": \"ミュウ\",\n\t\"mewtwo\": \"ミュウツー\",\n\t\"moltres\": \"ファイヤー\",\n\t\"mrmime\": \"バリヤード\",\n\t\"muk\": \"ベトベトン\",\n\t\"nidoking\": \"ニドキング\",\n\t\"nidoqueen\": \"ニドクイン\",\n\t\"nidoran_female\": \"ニドラン♀\",\n\t\"nidoran_male\": \"ニドラン♂\",\n\t\"nidorina\": \"ニドリーナ\",\n\t\"nidorino\": \"ニドリーノ\",\n\t\"ninetales\": \"キュウコン\",\n\t\"oddish\": \"ナゾノクサ\",\n\t\"omanyte\": \"オムナイト\",\n\t\"omastar\": \"オムスター\",\n\t\"onix\": \"イワーク\",\n\t\"paras\": \"パラス\",\n\t\"parasect\": \"パラセクト\",\n\t\"persian\": \"ペルシアン\",\n\t\"pidgeot\": \"ピジョット\",\n\t\"pidgeotto\": \"ピジョン\",\n\t\"pidgey\": \"ポッポ\",\n\t\"pikachu\": \"ピカチュウ\",\n\t\"pikachu_female\": \"ピカチュウ（メス）\",\n\t\"pinsir\": \"カイロス\",\n\t\"poliwag\": \"ニョロモ\",\n\t\"poliwhirl\": \"ニョロゾ\",\n\t\"poliwrath\": \"ニョロボン\",\n\t\"ponyta\": \"ポニータ\",\n\t\"porygon\": \"ポリゴン\",\n\t\"primeape\": \"オコリザル\",\n\t\"psyduck\": \"コダック\",\n\t\"raichu\": \"ライチュウ\",\n\t\"rapidash\": \"ギャロップ\",\n\t\"raticate\": \"ラッタ\",\n\t\"rattata\": \"コラッタ\",\n\t\"rhydon\": \"サイドン\",\n\t\"rhyhorn\": \"サイホーン\",\n\t\"sandshrew\": \"サンド\",\n\t\"sandslash\": \"サンドパン\",\n\t\"scyther\": \"ストライク\",\n\t\"seadra\": \"シードラ\",\n\t\"seaking\": \"アズマオウ\",\n\t\"seel\": \"パウワウ\",\n\t\"shellder\": \"シェルダー\",\n\t\"slowbro\": \"ヤドラン\",\n\t\"slowpoke\": \"ヤドン\",\n\t\"snorlax\": \"カビゴン\",\n\t\"spearow\": \"オニスズメ\",\n\t\"squirtle\": \"ゼニガメ\",\n\t\"starmie\": \"スターミー\",\n\t\"staryu\": \"ヒトデマン\",\n\t\"tangela\": \"モンジャラ\",\n\t\"tauros\": \"ケンタロス\",\n\t\"tentacool\": \"メノクラゲ\",\n\t\"tentacruel\": \"ドククラゲ\",\n\t\"vaporeon\": \"シャワーズ\",\n\t\"venomoth\": \"モルフォン\",\n\t\"venonat\": \"コンパン\",\n\t\"venusaur\": \"フシギバナ\",\n\t\"venusaur_female\": \"フシギバナ（メス）\",\n\t\"victreebel\": \"ウツボット\",\n\t\"vileplume\": \"ラフレシア\",\n\t\"voltorb\": \"ビリリダマ\",\n\t\"vulpix\": \"ロコン\",\n\t\"wartortle\": \"カメール\",\n\t\"weedle\": \"ビードル\",\n\t\"weepinbell\": \"ウツドン\",\n\t\"weezing\": \"マタドガス\",\n\t\"wigglytuff\": \"プクリン\",\n\t\"zapdos\": \"サンダー\",\n\t\"zubat\": \"ズバット\"\n}\n"
  },
  {
    "path": "l10n/pokemon/ja-JP/gen2.json",
    "content": "{\n\t\"aipom\": \"エイパム\",\n\t\"ampharos\": \"デンリュウ\",\n\t\"ariados\": \"アリアドス\",\n\t\"azumarill\": \"マリルリ\",\n\t\"bayleef\": \"ベイリーフ\",\n\t\"bellossom\": \"キレイハナ\",\n\t\"blissey\": \"ハピナス\",\n\t\"celebi\": \"セレビィ\",\n\t\"chikorita\": \"チコリータ\",\n\t\"chinchou\": \"チョンチー\",\n\t\"cleffa\": \"ピィ\",\n\t\"corsola\": \"サニーゴ\",\n\t\"crobat\": \"クロバット\",\n\t\"croconaw\": \"アリゲイツ\",\n\t\"cyndaquil\": \"ヒノアラシ\",\n\t\"delibird\": \"デリバード\",\n\t\"donphan\": \"ドンファン\",\n\t\"dunsparce\": \"ノコッチ\",\n\t\"elekid\": \"エレキッド\",\n\t\"entei\": \"エンテイ\",\n\t\"espeon\": \"エーフィ\",\n\t\"feraligatr\": \"オーダイル\",\n\t\"flaaffy\": \"モココ\",\n\t\"forretress\": \"フォレトス\",\n\t\"furret\": \"オオタチ\",\n\t\"girafarig\": \"キリンリキ\",\n\t\"gligar\": \"グライガー\",\n\t\"granbull\": \"グランブル\",\n\t\"heracross\": \"ヘラクロス\",\n\t\"heracross_male\": \"ヘラクロス（オス）\",\n\t\"heracross_female\": \"ヘラクロス（メス）\",\n\t\"hitmontop\": \"カポエラー\",\n\t\"hooh\": \"ホウオウ\",\n\t\"hoothoot\": \"ホーホー\",\n\t\"hoppip\": \"ハネッコ\",\n\t\"houndoom\": \"ヘルガー\",\n\t\"houndour\": \"デルビル\",\n\t\"igglybuff\": \"ププリン\",\n\t\"jumpluff\": \"ワタッコ\",\n\t\"kingdra\": \"キングドラ\",\n\t\"lanturn\": \"ランターン\",\n\t\"larvitar\": \"ヨーギラス\",\n\t\"ledian\": \"レディアン\",\n\t\"ledyba\": \"レディバ\",\n\t\"lugia\": \"ルギア\",\n\t\"magby\": \"ブビィ\",\n\t\"magcargo\": \"マグカルゴ\",\n\t\"mantine\": \"マンタイン\",\n\t\"mareep\": \"メリープ\",\n\t\"marill\": \"マリル\",\n\t\"meganium\": \"メガニウム\",\n\t\"meganium_female\": \"メガニウム（メス）\",\n\t\"miltank\": \"ミルタンク\",\n\t\"misdreavus\": \"ムウマ\",\n\t\"murkrow\": \"ヤミカラス\",\n\t\"natu\": \"ネイティ\",\n\t\"noctowl\": \"ヨルノズク\",\n\t\"octillery\": \"オクタン\",\n\t\"phanpy\": \"ゴマゾウ\",\n\t\"pichu\": \"ピチュー\",\n\t\"piloswine\": \"イノムー\",\n\t\"pineco\": \"クヌギダマ\",\n\t\"politoed\": \"ニョロトノ\",\n\t\"porygon2\": \"ポリゴン2\",\n\t\"pupitar\": \"サナギラス\",\n\t\"quagsire\": \"ヌオー\",\n\t\"quilava\": \"マグマラシ\",\n\t\"qwilfish\": \"ハリーセン\",\n\t\"raikou\": \"ライコウ\",\n\t\"remoraid\": \"テッポウオ\",\n\t\"scizor\": \"ハッサム\",\n\t\"sentret\": \"オタチ\",\n\t\"shuckle\": \"ツボツボ\",\n\t\"skarmory\": \"エアームド\",\n\t\"skiploom\": \"ポポッコ\",\n\t\"slowking\": \"ヤドキング\",\n\t\"slugma\": \"マグマッグ\",\n\t\"smeargle\": \"ドーブル\",\n\t\"smoochum\": \"ムチュール\",\n\t\"sneasel\": \"ニューラ\",\n\t\"snubbull\": \"ブルー\",\n\t\"spinarak\": \"イトマル\",\n\t\"stantler\": \"オドシシ\",\n\t\"steelix\": \"ハガネール\",\n\t\"steelix_female\": \"ハガネール（メス）\",\n\t\"sudowoodo\": \"ウソッキー\",\n\t\"suicune\": \"スイクン\",\n\t\"sunflora\": \"キマワリ\",\n\t\"sunkern\": \"ヒマナッツ\",\n\t\"swinub\": \"ウリムー\",\n\t\"teddiursa\": \"ヒメグマ\",\n\t\"togepi\": \"トゲピー\",\n\t\"togetic\": \"トゲチック\",\n\t\"totodile\": \"ワニノコ\",\n\t\"typhlosion\": \"バクフーン\",\n\t\"tyranitar\": \"バンギラス\",\n\t\"tyrogue\": \"バルキー\",\n\t\"umbreon\": \"ブラッキー\",\n\t\"ursaring\": \"リングマ\",\n\t\"wobbuffet\": \"ソーナノ\",\n\t\"wobbuffet_male\": \"ソーナノ（オス）\",\n\t\"wobbuffet_female\": \"ソーナノ（メス）\",\n\t\"wooper\": \"ウパー\",\n\t\"xatu\": \"ネイティオ\",\n\t\"yanma\": \"ヤンヤンマ\"\n}\n"
  },
  {
    "path": "l10n/pokemon/ja-JP/gen3.json",
    "content": "{\n\t\"absol\": \"アブソル\",\n\t\"aggron\": \"ボスゴドラ\",\n\t\"altaria\": \"チルタリス\",\n\t\"anorith\": \"アノプス\",\n\t\"armaldo\": \"アーマルド\",\n\t\"aron\": \"ココドラ\",\n\t\"azurill\": \"ルリリ\",\n\t\"bagon\": \"タツベイ\",\n\t\"baltoy\": \"ヤジロン\",\n\t\"banette\": \"ジュペッタ\",\n\t\"barboach\": \"ドジョッチ\",\n\t\"beautifly\": \"アゲハント\",\n\t\"beldum\": \"ダンバル\",\n\t\"blaziken\": \"バシャーモ\",\n\t\"breloom\": \"キノガッサ\",\n\t\"cacnea\": \"サボネア\",\n\t\"cacturne\": \"ノクタス\",\n\t\"camerupt\": \"バクーダ\",\n\t\"carvanha\": \"キバニア\",\n\t\"cascoon\": \"マユルド\",\n\t\"castform\": \"ポワルン\",\n\t\"chimecho\": \"チリーン\",\n\t\"clamperl\": \"パールル\",\n\t\"claydol\": \"ネンドール\",\n\t\"combusken\": \"ワカシャモ\",\n\t\"corpish\": \"ヘイガニ\",\n\t\"cradily\": \"ユレイドル\",\n\t\"crawdaunt\": \"シザリガー\",\n\t\"delcatty\": \"エネコロロ\",\n\t\"deoxys\": \"デオキシス\",\n\t\"deoxys_attack\": \"デオキシス（攻撃）\",\n\t\"deoxys_defense\": \"デオキシス（防御）\",\n\t\"deoxys_speed\": \"デオキシス（速度）\",\n\t\"dusclops\": \"サマヨール\",\n\t\"duskull\": \"ヨマワル\",\n\t\"dustox\": \"ドクケイル\",\n\t\"electrike\": \"ラクライ\",\n\t\"exploud\": \"バクオング\",\n\t\"feebas\": \"ヒンバス\",\n\t\"flygon\": \"フライゴン\",\n\t\"gardevoir\": \"サーナイト\",\n\t\"glalie\": \"オニゴーリ\",\n\t\"gorebyss\": \"サクラビス\",\n\t\"groudon\": \"グラードン\",\n\t\"grovyle\": \"ジュプトル\",\n\t\"grumpig\": \"ブーピッグ\",\n\t\"gulpin\": \"ゴクリン\",\n\t\"hariyama\": \"ハリテヤマ\",\n\t\"huntail\": \"ハンテール\",\n\t\"illumise\": \"イルミーゼ\",\n\t\"jirachi\": \"ジラーチ\",\n\t\"kecleon\": \"カクレオン\",\n\t\"kirlia\": \"キルリア\",\n\t\"kyogre\": \"カイオーガ\",\n\t\"lairon\": \"コドラ\",\n\t\"latias\": \"ラティアス\",\n\t\"latios\": \"ラティオス\",\n\t\"lileep\": \"リリーラ\",\n\t\"linoone\": \"マッスグマ\",\n\t\"lombre\": \"ハスブレロ\",\n\t\"lotad\": \"ハスボー\",\n\t\"loudred\": \"ドゴーム\",\n\t\"ludicolo\": \"ルンパッパ\",\n\t\"lunatone\": \"ルナトーン\",\n\t\"luvdisc\": \"ラブカス\",\n\t\"makuhita\": \"マクノシタ\",\n\t\"manectric\": \"ライボルト\",\n\t\"marshtomp\": \"ヌマクロー\",\n\t\"masquerain\": \"アメモース\",\n\t\"mawile\": \"クチート\",\n\t\"medicham\": \"チャーレム\",\n\t\"meditite\": \"アサナン\",\n\t\"metagross\": \"メタグロス\",\n\t\"metang\": \"メタング\",\n\t\"mightyena\": \"グラエナ\",\n\t\"milotic\": \"ミロカロス\",\n\t\"minun\": \"マイナン\",\n\t\"mudkip\": \"ミズゴロウ\",\n\t\"nincada\": \"ツチニン\",\n\t\"ninjask\": \"テッカニン\",\n\t\"nosepass\": \"ノズパス\",\n\t\"numel\": \"ドンメル\",\n\t\"nuzleaf\": \"コノハナ\",\n\t\"pelipper\": \"ペリッパー\",\n\t\"plusle\": \"プラスル\",\n\t\"poochyena\": \"ポチエナ\",\n\t\"ralts\": \"ラルトス\",\n\t\"rayquaza\": \"レックウザ\",\n\t\"regice\": \"レジアイス\",\n\t\"regirock\": \"レジロック\",\n\t\"registeel\": \"レジスチル\",\n\t\"relicanth\": \"ジーランス\",\n\t\"roselia\": \"ロゼリア\",\n\t\"sableye\": \"ヤミラミ\",\n\t\"salamence\": \"ボーマンダ\",\n\t\"sceptile\": \"ジュカイン\",\n\t\"sealeo\": \"トドグラー\",\n\t\"seedot\": \"タネボー\",\n\t\"seviper\": \"ハブネーク\",\n\t\"sharpedo\": \"サメハダー\",\n\t\"shedinja\": \"ヌケニン\",\n\t\"shelgon\": \"コモルー\",\n\t\"shiftry\": \"ダーテング\",\n\t\"shroomish\": \"キノココ\",\n\t\"shuppet\": \"カゲボウズ\",\n\t\"silcoon\": \"カラサリス\",\n\t\"skitty\": \"エネコ\",\n\t\"slaking\": \"ケッキング\",\n\t\"slakoth\": \"ナマケロ\",\n\t\"snorunt\": \"ユキワラシ\",\n\t\"solrock\": \"ソルロック\",\n\t\"spheal\": \"タマザラシ\",\n\t\"spinda\": \"パッチール\",\n\t\"spoink\": \"バネブー\",\n\t\"surskit\": \"アメタマ\",\n\t\"swablu\": \"チルット\",\n\t\"swalot\": \"マルノーム\",\n\t\"swampert\": \"ラグラージ\",\n\t\"swellow\": \"オオスバメ\",\n\t\"taillow\": \"スバメ\",\n\t\"torchic\": \"アチャモ\",\n\t\"torkoal\": \"コータス\",\n\t\"trapinch\": \"ナックラー\",\n\t\"treecko\": \"キモリ\",\n\t\"tropius\": \"トロピウス\",\n\t\"vibrava\": \"ビブラーバ\",\n\t\"vigoroth\": \"ヤルキモノ\",\n\t\"volbeat\": \"バルビート\",\n\t\"wailmer\": \"ホエルコ\",\n\t\"wailord\": \"ホエルオー\",\n\t\"walrein\": \"トドゼルガ\",\n\t\"whiscash\": \"ナマズン\",\n\t\"whismur\": \"ゴニョニョ\",\n\t\"wingull\": \"キャモメ\",\n\t\"wurmple\": \"ケムッソ\",\n\t\"wynaut\": \"ソーナノ\",\n\t\"zangoose\": \"ザングース\",\n\t\"zigzagoon\": \"ジグザグマ\"\n}\n"
  },
  {
    "path": "l10n/pokemon/ja-JP/gen4.json",
    "content": "{\n\t\"turtwig\": \"ナエトル\",\n\t\"grotle\": \"ハヤシガメ\",\n\t\"torterra\": \"ドダイトス\",\n\t\"chimchar\": \"ヒコザル\",\n\t\"monferno\": \"モウカザル\",\n\t\"infernape\": \"ゴウカザル\",\n\t\"piplup\": \"ポッチャマ\",\n\t\"prinplup\": \"ポッタイシ\",\n\t\"empoleon\": \"エンペルト\",\n\t\"starly\": \"ムックル\",\n\t\"staravia\": \"ムクバード\",\n\t\"staraptor\": \"ムクホーク\",\n\t\"bidoof\": \"ビッパ\",\n\t\"bibarel\": \"ビーダル\",\n\t\"kricketot\": \"コロボーシ\",\n\t\"kricketune\": \"コロトック\",\n\t\"shinx\": \"コリンク\",\n\t\"luxio\": \"ルクシオ\",\n\t\"luxray\": \"レントラー\",\n\t\"budew\": \"スボミー\",\n\t\"roserade\": \"ロズレイド\",\n\t\"cranidos\": \"ズガイドス\",\n\t\"rampardos\": \"ラムパルド\",\n\t\"shieldon\": \"タテトプス\",\n\t\"bastiodon\": \"トリデプス\",\n\t\"burmy_plant\": \"ミノムッチ（くさきのミノ）\",\n\t\"burmy_sandy\": \"ミノムッチ（すなちのミノ）\",\n\t\"burmy_trash\": \"ミノムッチ（ゴミのミノ）\",\n\t\"wormadam_plant\": \"ミノマダム（くさきのミノ）\",\n\t\"wormadam_sandy\": \"ミノマダム（すなちのミノ）\",\n\t\"wormadam_trash\": \"ミノマダム（ゴミのミノ）\",\n\t\"mothim\": \"ガーメイル\",\n\t\"combee_male\": \"ミツハニー（オス）\",\n\t\"combee_female\": \"ミツハニー（メス）\",\n\t\"vespiquen\": \"ビークイン\",\n\t\"pachirisu\": \"パチリス\",\n\t\"buizel\": \"ブイゼル\",\n\t\"floatzel\": \"フローゼル\",\n\t\"cherubi\": \"チェリンボ\",\n\t\"cherrim\": \"チェリム\",\n\t\"shellos_west\": \"カラナクシ（にしのうみ）\",\n\t\"shellos_east\": \"カラナクシ（ひがしのうみ）\",\n\t\"gastrodon_west\": \"トリトドン（にしのうみ）\",\n\t\"gastrodon_east\": \"トリトドン（ひがしのうみ）\",\n\t\"ambipom\": \"エテボース\",\n\t\"drifloon\": \"フワンテ\",\n\t\"drifblim\": \"フワライド\",\n\t\"buneary\": \"ミミロル\",\n\t\"lopunny\": \"ミミロップ\",\n\t\"mismagius\": \"ムウマージ\",\n\t\"honchkrow\": \"ドンカラス\",\n\t\"glameow\": \"ニャルマー\",\n\t\"purugly\": \"ブニャット\",\n\t\"chingling\": \"リーシャン\",\n\t\"stunky\": \"スカンプー\",\n\t\"skuntank\": \"スカタンク\",\n\t\"bronzor\": \"ドーミラー\",\n\t\"bronzong\": \"ドータクン\",\n\t\"bonsly\": \"ウソハチ\",\n\t\"mrmime\": \"バリヤード\",\n\t\"happiny\": \"ピンプク\",\n\t\"chatot\": \"ペラップ\",\n\t\"spiritomb\": \"ミカルゲ\",\n\t\"gible\": \"フカマル\",\n\t\"gible_female\": \"フカマル（メス）\",\n\t\"gabite\": \"ガバイト\",\n\t\"gabite_female\": \"ガバイト（メス）\",\n\t\"garchomp\": \"ガブリアス\",\n\t\"garchomp_female\": \"ガブリアス（メス）\",\n\t\"munchlax\": \"ゴンベ\",\n\t\"riolu\": \"リオル\",\n\t\"lucario\": \"ルカリオ\",\n\t\"hippopotas_male\": \"ヒポポタス（オス）\",\n\t\"hippopotas_female\": \"ヒポポタス（メス）\",\n\t\"hippowdon_male\": \"カバルドン（オス）\",\n\t\"hippowdon_female\": \"カバルドン（メス）\",\n\t\"skorupi\": \"スコルピ\",\n\t\"drapion\": \"ドラピオン\",\n\t\"croagunk\": \"グレッグル\",\n\t\"toxicroak\": \"ドクロッグ\",\n\t\"carnivine\": \"マスキッパ\",\n\t\"finneon\": \"ケイコウオ\",\n\t\"lumineon\": \"ネオラント\",\n\t\"mantyke\": \"タマンタ\",\n\t\"snover\": \"ユキカブリ\",\n\t\"abomasnow\": \"ユキノオー\",\n\t\"weavile\": \"マニューラ\",\n\t\"magnezone\": \"ジバコイル\",\n\t\"lickilicky\": \"ベロベルト\",\n\t\"rhyperior\": \"ドサイドン\",\n\t\"tangrowth\": \"モジャンボ\",\n\t\"electivire\": \"エレキブル\",\n\t\"magmortar\": \"ブーバーン\",\n\t\"togekiss\": \"トゲキッス\",\n\t\"yanmega\": \"メガヤンマ\",\n\t\"leafeon\": \"リーフィア\",\n\t\"glaceon\": \"グレイシア\",\n\t\"gliscor\": \"グライオン\",\n\t\"mamoswine\": \"マンムー\",\n\t\"porygon_z\": \"ポリゴンZ\",\n\t\"gallade\": \"エルレイド\",\n\t\"probopass\": \"ダイノーズ\",\n\t\"dusknoir\": \"ヨノワール\",\n\t\"froslass\": \"ユキメノコ\",\n\t\"rotom\": \"ロトム\",\n\t\"rotom_heat\": \"ロトム（ヒート）\",\n\t\"rotom_wash\": \"ロトム（ウォッシュ）\",\n\t\"rotom_frost\": \"ロトム（フロスト）\",\n\t\"rotom_fan\": \"ロトム（スピン）\",\n\t\"rotom_mow\": \"ロトム（カット）\",\n\t\"uxie\": \"ユクシー\",\n\t\"mesprit\": \"エムリット\",\n\t\"azelf\": \"アグノム\",\n\t\"dialga\": \"ディアルガ\",\n\t\"palkia\": \"パルキア\",\n\t\"heatran\": \"ヒードラン\",\n\t\"regigigas\": \"レジギガス\",\n\t\"giratina\": \"ギラティナ\",\n\t\"giratina_origin\": \"ギラティナ（オリジンフォルム）\",\n\t\"cresselia\": \"クレセリア\",\n\t\"phione\": \"フィオネ\",\n\t\"manaphy\": \"マナフィ\",\n\t\"darkrai\": \"ダークライ\",\n\t\"shaymin\": \"シェイミ\",\n\t\"shaymin_sky\": \"シェイミ（スカイフォルム）\",\n\t\"arceus\": \"アルセウス\",\n\t\"arceus_bug\": \"アルセウス（むし）\",\n\t\"arceus_dark\": \"アルセウス（あく）\",\n\t\"arceus_dragon\": \"アルセウス（ドラゴン）\",\n\t\"arceus_electric\": \"アルセウス（でんき）\",\n\t\"arceus_fighting\": \"アルセウス（かくとう）\",\n\t\"arceus_fire\": \"アルセウス（ほのお）\",\n\t\"arceus_flying\": \"アルセウス（ひこう）\",\n\t\"arceus_ghost\": \"アルセウス（ゴースト）\",\n\t\"arceus_grass\": \"アルセウス（くさ）\",\n\t\"arceus_ground\": \"アルセウス（じめん）\",\n\t\"arceus_ice\": \"アルセウス（こおり）\",\n\t\"arceus_poison\": \"アルセウス（どく）\",\n\t\"arceus_psychic\": \"アルセウス（エスパー）\",\n\t\"arceus_rock\": \"アルセウス（いわ）\",\n\t\"arceus_steel\": \"アルセウス（はがね）\",\n\t\"arceus_water\": \"アルセウス（みず）\"\n}\n"
  },
  {
    "path": "media/.gitignore",
    "content": "unused/"
  },
  {
    "path": "media/pokemon.css",
    "content": ":root {\n\t--container-paddding: 20px;\n\t--input-padding-vertical: 6px;\n\t--input-padding-horizontal: 4px;\n\t--input-margin-vertical: 4px;\n\t--input-margin-horizontal: 0;\n}\n\n* {\n\tuser-select: none;\n}\n\nbody {\n\tpadding: 0 var(--container-paddding);\n\tcolor: var(--vscode-foreground);\n\tfont-size: var(--vscode-font-size);\n\tfont-weight: var(--vscode-font-weight);\n\tfont-family: var(--vscode-font-family);\n\tbackground-color: var(--vscode-editor-background);\n\tbackground-attachment: fixed;\n\tbackground-repeat: repeat-x;\n\tbackground-position: bottom left;\n\toverflow: hidden;\n\t/* Hide scrollbars */\n}\n\n#foreground {\n\twidth: 100%;\n\theight: 100%;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tz-index: 5;\n\tbackground-attachment: fixed;\n\tbackground-repeat: repeat-x;\n\tbackground-position: bottom left;\n}\n\nol,\nul {\n\tpadding-left: var(--container-paddding);\n}\n\nbody>*,\nform>* {\n\tmargin-block-start: var(--input-margin-vertical);\n\tmargin-block-end: var(--input-margin-vertical);\n}\n\n*:focus {\n\toutline-color: var(--vscode-focusBorder) !important;\n}\n\na {\n\tcolor: var(--vscode-textLink-foreground);\n}\n\na:hover,\na:active {\n\tcolor: var(--vscode-textLink-activeForeground);\n}\n\ncode {\n\tfont-size: var(--vscode-editor-font-size);\n\tfont-family: var(--vscode-editor-font-family);\n}\n\nbutton {\n\tborder: none;\n\tpadding: var(--input-padding-vertical) var(--input-padding-horizontal);\n\twidth: 100%;\n\ttext-align: center;\n\toutline: 1px solid transparent;\n\toutline-offset: 2px !important;\n\tcolor: var(--vscode-button-foreground);\n\tbackground: var(--vscode-button-background);\n}\n\nbutton:hover {\n\tcursor: pointer;\n\tbackground: var(--vscode-button-hoverBackground);\n}\n\nbutton:focus {\n\toutline-color: var(--vscode-focusBorder);\n}\n\nbutton.secondary {\n\tcolor: var(--vscode-button-secondaryForeground);\n\tbackground: var(--vscode-button-secondaryBackground);\n}\n\nbutton.secondary:hover {\n\tbackground: var(--vscode-button-secondaryHoverBackground);\n}\n\ninput:not([type='checkbox']),\ntextarea {\n\tdisplay: block;\n\twidth: 100%;\n\tborder: none;\n\tfont-family: var(--vscode-font-family);\n\tpadding: var(--input-padding-vertical) var(--input-padding-horizontal);\n\tcolor: var(--vscode-input-foreground);\n\toutline-color: var(--vscode-input-border);\n\tbackground-color: var(--vscode-input-background);\n}\n\ninput::placeholder,\ntextarea::placeholder {\n\tcolor: var(--vscode-input-placeholderForeground);\n}\n\n#pokemonCanvas {\n\tposition: fixed;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 3;\n}\n\nimg.pokemon {\n\t-webkit-transform: scaleX(-1);\n\ttransform: scaleX(-1);\n\tposition: absolute;\n\timage-rendering: pixelated;\n\tleft: 0px;\n\tright: 0px;\n\tbottom: 0px;\n\tz-index: 2;\n}\n\n.collision {\n\tposition: absolute;\n\tleft: 0px;\n\tright: 0px;\n\tbottom: 0px;\n\tz-index: 999;\n}\n\n.bubble {\n\timage-rendering: pixelated;\n\tposition: absolute;\n\ttext-align: center;\n\tmargin: auto;\n\topacity: 0;\n\tanimation: fadeIn 0.2s forwards;\n}\n\n@keyframes fadeIn {\n\t0% {\n\t\topacity: 0;\n\t\ttransform: translateX(50%) translateY(10px);\n\t}\n\n\t100% {\n\t\topacity: 1;\n\t\ttransform: translateX(50%) translateY(0);\n\t}\n}\n\n.bubble-nano {\n\twidth: 15px;\n}\n\n.bubble-small {\n\twidth: 22.5px;\n}\n\n.bubble-medium {\n\twidth: 30px;\n}\n\n.bubble-large {\n\twidth: 37.5px;\n}\n\n/* Manually adjust the size teh bubble on 64x64px pokemon. Quick fix for now, TODO */\n.bubble-nano.b-64 {\n\tmargin-left: 15px;\n}\n\n.bubble-small.b-64 {\n\tmargin-left: 22.5px;\n}\n\n.bubble-medium.b-64 {\n\tmargin-left: 30px;\n}\n\n\n.bubble-large.b-64 {\n\tmargin-left: 37.5px;\n}\n\n.pokeball-sprite {\n  --frame-size: 64px;\n  --frames: 6;\n\n  position: absolute;\n  width: var(--frame-size);\n  height: var(--frame-size);\n\n  background-image: url('pokeball_sprite_sheet.png');\n  background-repeat: no-repeat;\n  background-position: 0 0;\n  background-size: var(--frame-size)\n                   calc(var(--frame-size) * var(--frames));\n\n  image-rendering: pixelated;\n  z-index: 0;\n}\n.pokeball-sprite.pokeball-open {\n  animation: pokeball-open 0.45s steps(var(--frames)) forwards;\n}\n@keyframes pokeball-open {\n  to {\n    background-position-y: calc(-1 * var(--frame-size) * (var(--frames)));\n  }\n}\n\n.pokeball-sprite.pokeball-close {\n  animation: pokeball-close 0.6s steps(var(--frames)) backwards;\n}\n\n@keyframes pokeball-close {\n  from { background-position-y: calc(-1 * var(--frame-size) * (var(--frames)));}\n  to   { background-position-y: 0; }\n}\n\n.pokemon.spawn-pop {\n  animation: pokemon-pop 150ms ease-out;\n  opacity: 1 !important;\n  will-change: transform, opacity, filter;\n}\n\n@keyframes pokemon-pop {\n  0% {\n    transform: scale(0.4);\n    opacity: 0;\n    filter: saturate(0) brightness(3) contrast(1);\n  }\n  40% {\n    filter: saturate(0.3) brightness(1.8) contrast(1.05);\n  }\n  60% {\n    transform: scale(1.15);\n    opacity: 1;\n    filter: saturate(0.8) brightness(1.1) contrast(1);\n  }\n  100% {\n    transform: scale(1);\n    opacity: 1;\n    filter: none;\n  }\n}\n\n.shiny-overlay {\n  position: absolute;\n  image-rendering: pixelated;\n  z-index: 9999;\n  pointer-events: none;\n  mix-blend-mode: screen;\n  margin-bottom: -5px;\n  animation: shiny-sparkle 1s ease-out forwards;\n}\n\n@keyframes shiny-sparkle {\n  0% {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  15% {\n    opacity: 1;\n    transform: scale(1.2);\n  }\n  30% {\n    transform: scale(1);\n  }\n  80% {\n    opacity: 1;\n  }\n  100% {\n    opacity: 0;\n  }\n}\n\n.pokemon.fade-out {\n  animation: pokemon-fade-out 220ms ease-out;\n}\n\n@keyframes pokemon-fade-out {\n  0% {\n\topacity: 1;\n\tfilter: none;\n  }\n  40% {\n\ttransform: scale(1.15);\n\tfilter: saturate(0.8) brightness(1.1) contrast(1);\n  }\n  60% {\n\topacity: 0.4;\n\tfilter: saturate(0.3) brightness(1.8) contrast(1.05);\n  }\n  100% {\n\ttransform: scale(0.4);\n\topacity: 0;\n\tfilter: saturate(0) brightness(3) contrast(1);\n  }\n}"
  },
  {
    "path": "media/reset.css",
    "content": "html {\n\tbox-sizing: border-box;\n\tfont-size: 13px;\n}\n\n*,\n*:before,\n*:after {\n\tbox-sizing: inherit;\n}\n\nbody,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np,\nol,\nul {\n\tmargin: 0;\n\tpadding: 0;\n\tfont-weight: normal;\n}\n\nimg {\n\tmax-width: 100%;\n\theight: auto;\n}"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"vscode-pokemon\",\n    \"displayName\": \"vscode-pokemon\",\n    \"description\": \"Pokémon for your VS Code\",\n    \"version\": \"4.3.5\",\n    \"engines\": {\n        \"vscode\": \"^1.73.0\"\n    },\n    \"l10n\": \"./l10n\",\n    \"repository\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/jakobhoeg/vscode-pokemon\"\n    },\n    \"homepage\": \"https://github.com/jakobhoeg/vscode-pokemon\",\n    \"bugs\": \"https://github.com/jakobhoeg/vscode-pokemon/issues\",\n    \"publisher\": \"jakobhoeg\",\n    \"pricing\": \"Free\",\n    \"categories\": [\n        \"Other\"\n    ],\n    \"keywords\": [\n        \"pokemon\",\n        \"pets\",\n        \"pokémon\",\n        \"pixelart\",\n        \"pixel\",\n        \"pixel\",\n        \"vscode\"\n    ],\n    \"license\": \"MIT\",\n    \"icon\": \"icon.png\",\n    \"activationEvents\": [\n        \"onCommand:vscode-pokemon.start\",\n        \"onCommand:vscode-pokemon.spawn-pokemon\",\n        \"onCommand:vscode-pokemon.spawn-random-pokemon\",\n        \"onCommand:vscode-pokemon.delete-pokemon\",\n        \"onCommand:vscode-pokemon.remove-all-pokemon\",\n        \"onCommand:vscode-pokemon.roll-call\",\n        \"onCommand:vscode-pokemon.export-pokemon-list\",\n        \"onCommand:vscode-pokemon.import-pokemon-list\",\n        \"onCommand:vscode-pokemon.configure-keybindings\",\n        \"onCommand:vscode-pokemon.change-pokemon-language\",\n        \"onWebviewPanel:pokemonCoding\",\n        \"onView:explorer\",\n        \"onView:pokemonView\",\n        \"onStartupFinished\"\n    ],\n    \"main\": \"./out/extension/extension.js\",\n    \"browser\": \"./dist/web/extension-web.js\",\n    \"contributes\": {\n        \"views\": {\n            \"explorer\": [\n                {\n                    \"type\": \"webview\",\n                    \"id\": \"pokemonView\",\n                    \"name\": \"VS Code Pokémon\",\n                    \"when\": \"vscode-pokemon.position == 'explorer'\",\n                    \"icon\": \"media/icon/dark-add.svg\"\n                }\n            ]\n        },\n        \"menus\": {\n            \"view/title\": [\n                {\n                    \"command\": \"vscode-pokemon.spawn-pokemon\",\n                    \"when\": \"view == pokemonView\",\n                    \"group\": \"navigation@1\"\n                },\n                {\n                    \"command\": \"vscode-pokemon.spawn-random-pokemon\",\n                    \"when\": \"view == pokemonView\",\n                    \"group\": \"navigation@2\"\n                },\n                {\n                    \"command\": \"vscode-pokemon.delete-pokemon\",\n                    \"when\": \"view == pokemonView\",\n                    \"group\": \"navigation@3\"\n                }\n            ]\n        },\n        \"commands\": [\n            {\n                \"command\": \"vscode-pokemon.start\",\n                \"title\": \"Start pokemon coding session\",\n                \"category\": \"Pokemon Coding\"\n            },\n            {\n                \"command\": \"vscode-pokemon.export-pokemon-list\",\n                \"title\": \"Export pokemon list\",\n                \"category\": \"Pokemon Coding\"\n            },\n            {\n                \"command\": \"vscode-pokemon.import-pokemon-list\",\n                \"title\": \"Import pokemon list\",\n                \"category\": \"Pokemon Coding\"\n            },\n            {\n                \"command\": \"vscode-pokemon.spawn-pokemon\",\n                \"title\": \"Spawn additional pokemon\",\n                \"category\": \"Pokemon Coding\",\n                \"icon\": {\n                    \"dark\": \"media/icon/dark-add.svg\",\n                    \"light\": \"media/icon/light-add.svg\"\n                }\n            },\n            {\n                \"command\": \"vscode-pokemon.spawn-random-pokemon\",\n                \"title\": \"Spawn random additional pokemon\",\n                \"category\": \"Pokemon Coding\",\n                \"icon\": {\n                    \"dark\": \"media/icon/dark-random.svg\",\n                    \"light\": \"media/icon/light-random.svg\"\n                }\n            },\n            {\n                \"command\": \"vscode-pokemon.delete-pokemon\",\n                \"title\": \"Remove pokemon\",\n                \"category\": \"Pokemon Coding\",\n                \"icon\": {\n                    \"dark\": \"media/icon/dark-trash.svg\",\n                    \"light\": \"media/icon/light-trash.svg\"\n                }\n            },\n            {\n                \"command\": \"vscode-pokemon.remove-all-pokemon\",\n                \"title\": \"Remove all pokemon\",\n                \"category\": \"Pokemon Coding\",\n                \"icon\": {\n                    \"dark\": \"media/icon/dark-trash.svg\",\n                    \"light\": \"media/icon/light-trash.svg\"\n                }\n            },\n            {\n                \"command\": \"vscode-pokemon.roll-call\",\n                \"title\": \"Roll-call\",\n                \"category\": \"Pokemon Coding\"\n            },\n            {\n                \"command\": \"vscode-pokemon.configure-keybindings\",\n                \"title\": \"Configure keybindings\",\n                \"category\": \"Pokemon Coding\"\n            },\n            {\n                \"command\": \"vscode-pokemon.change-pokemon-language\",\n                \"title\": \"Change Pokemon language\",\n                \"category\": \"Pokemon Coding\"\n            }\n        ],\n        \"keybindings\": [\n            {\n                \"command\": \"vscode-pokemon.spawn-pokemon\",\n                \"key\": \"alt+shift+w\",\n                \"mac\": \"alt+shift+w\"\n            },\n            {\n                \"command\": \"vscode-pokemon.spawn-random-pokemon\",\n                \"key\": \"alt+shift+q\",\n                \"mac\": \"alt+shift+q\"\n            },\n            {\n                \"command\": \"vscode-pokemon.delete-pokemon\",\n                \"key\": \"alt+shift+d\",\n                \"mac\": \"alt+shift+d\"\n            },\n            {\n                \"command\": \"vscode-pokemon.remove-all-pokemon\",\n                \"key\": \"alt+shift+backspace\",\n                \"mac\": \"alt+shift+backspace\"\n            }\n        ],\n        \"configuration\": [\n            {\n                \"title\": \"VS Code Pokemon\",\n                \"properties\": {\n                    \"vscode-pokemon.pokemonSize\": {\n                        \"type\": \"string\",\n                        \"enum\": [\n                            \"nano\",\n                            \"small\",\n                            \"medium\",\n                            \"large\"\n                        ],\n                        \"default\": \"medium\",\n                        \"description\": \"Pokemon size\"\n                    },\n                    \"vscode-pokemon.position\": {\n                        \"type\": \"string\",\n                        \"enum\": [\n                            \"panel\",\n                            \"explorer\"\n                        ],\n                        \"default\": \"explorer\",\n                        \"description\": \"VSCode pokemon webview position\"\n                    },\n                    \"vscode-pokemon.theme\": {\n                        \"type\": \"string\",\n                        \"enum\": [\n                            \"none\",\n                            \"forest\",\n                            \"castle\",\n                            \"beach\"\n                        ],\n                        \"default\": \"none\",\n                        \"description\": \"Background theme assets for your pokemon\"\n                    },\n                    \"vscode-pokemon.defaultPokemon\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                            \"type\": \"object\",\n                            \"properties\": {\n                                \"type\": {\n                                    \"type\": \"string\",\n                                    \"description\": \"Pokemon type (e.g., 'pikachu', 'charizard', 'bulbasaur')\"\n                                },\n                                \"name\": {\n                                    \"type\": \"string\",\n                                    \"description\": \"Custom name for the pokemon (optional)\"\n                                }\n                            },\n                            \"required\": [\n                                \"type\"\n                            ]\n                        },\n                        \"default\": [],\n                        \"description\": \"List of default pokemon to automatically spawn on startup. Each pokemon should have a 'type' (required), and optionally 'name'. Example: [{\\\"type\\\": \\\"pikachu\\\", \\\"name\\\": \\\"Sparky\\\"}, {\\\"type\\\": \\\"charizard\\\"}]\"\n                    },\n                    \"vscode-pokemon.shinyOdds\": {\n                        \"type\": \"number\",\n                        \"default\": 8192,\n                        \"minimum\": 1,\n                        \"description\": \"Odds (1 in N) for a Pokémon to be shiny. Lower = more shinies. Default is 8192.\"\n                    },\n                    \"vscode-pokemon.pokemonLanguage\": {\n                        \"type\": \"string\",\n                        \"enum\": [\n                            \"auto\",\n                            \"en-US\",\n                            \"fr-FR\",\n                            \"de-DE\",\n                            \"ja-JP\"\n                        ],\n                        \"default\": \"auto\",\n                        \"description\": \"Language for Pokemon names. 'auto' uses VS Code's language, or you can choose a specific language (e.g., 'fr-FR' for French, 'en-US' for English, 'de-DE' for German, 'ja-JP' for Japanese). Only official Pokemon languages are supported.\"\n                    }\n                }\n            }\n        ]\n    },\n    \"scripts\": {\n        \"vscode:prepublish\": \"npm run compile\",\n        \"compile:panel\": \"webpack\",\n        \"compile:extension\": \"tsc -p ./tsconfig.extension.json\",\n        \"compile:test\": \"tsc -p ./tsconfig.test.json\",\n        \"compile:web\": \"webpack\",\n        \"compile\": \"npm run compile:panel && npm run compile:extension && npm run compile:test && npm run compile:web\",\n        \"watch\": \"webpack && tsc -watch -p ./tsconfig.extension.json\",\n        \"watch:web\": \"webpack --watch\",\n        \"pretest\": \"npm run compile && npm run lint\",\n        \"lint\": \"eslint src --ext ts\",\n        \"lint:fix\": \"eslint src --ext ts --fix\",\n        \"format:check\": \"prettier --check src\",\n        \"format\": \"prettier --write src\",\n        \"test\": \"node ./out/test/runTest.js\",\n        \"test:coverage\": \"COVERAGE=1 node ./out/test/runTest.js\",\n        \"test:web\": \"vscode-test-web --browserType=chromium --extensionDevelopmentPath=. --extensionTestsPath=dist/web/test/suite/index.js\",\n        \"test:gifs\": \"node ./out/test/gifs.js\",\n        \"prepare\": \"husky\"\n    },\n    \"devDependencies\": {\n        \"@rbarilani/remove-source-map-url-webpack-plugin\": \"^1.1.0\",\n        \"@types/glob\": \"^7.1.3\",\n        \"@types/jsdom\": \"^20.0.0\",\n        \"@types/mocha\": \"^9.1.1\",\n        \"@types/node\": \"^18.0.0\",\n        \"@types/vscode\": \"^1.73.0\",\n        \"@typescript-eslint/eslint-plugin\": \"^5.29.0\",\n        \"@typescript-eslint/parser\": \"^5.29.0\",\n        \"@vscode/l10n-dev\": \"^0.0.29\",\n        \"@vscode/test-web\": \"^0.0.50\",\n        \"eslint\": \"^8.18.0\",\n        \"eslint-config-prettier\": \"^9.1.2\",\n        \"eslint-plugin-prettier\": \"^5.5.4\",\n        \"eslint-plugin-unused-imports\": \"^2.0.0\",\n        \"glob\": \"^8.0.3\",\n        \"gulp\": \"^5.0.0\",\n        \"husky\": \"^9.1.7\",\n        \"jsdom\": \"^20.0.0\",\n        \"jsdom-global\": \"^3.0.2\",\n        \"mocha\": \"^10.0.0\",\n        \"nyc\": \"^15.1.0\",\n        \"path-browserify\": \"^1.0.1\",\n        \"prettier\": \"^3.3.3\",\n        \"process\": \"^0.11.10\",\n        \"ts-loader\": \"^9.3.0\",\n        \"typescript\": \"^4.7.4\",\n        \"typescript-eslint\": \"^0.0.1-alpha.0\",\n        \"vscode-test\": \"^1.4.0\",\n        \"webpack\": \"5.95.0\",\n        \"webpack-cli\": \"^4.10.0\"\n    },\n    \"dependencies\": {\n        \"@vscode/l10n\": \"^0.0.10\"\n    },\n    \"lint-staged\": {\n        \"*.ts\": [\n            \"eslint --fix\",\n            \"prettier --write\"\n        ]\n    }\n}\n"
  },
  {
    "path": "src/common/localize.ts",
    "content": "import * as fs from 'fs';\nimport * as path from 'path';\nimport * as vscode from 'vscode';\nimport { POKEMON_DATA } from './pokemon-data';\nimport { PokemonType } from './types';\n\n/**\n * Cache for loaded Pokemon translations\n * Key: locale (e.g., 'fr-FR'), Value: translations map (pokemon key -> translated name)\n */\nlet pokemonTranslationsCache: { [locale: string]: { [key: string]: string } } =\n  {};\n\n/**\n * Supported Pokemon translation locales\n * These correspond to the folders in l10n/pokemon/\n */\nexport const SUPPORTED_LOCALES = ['en-US', 'fr-FR', 'de-DE', 'ja-JP'] as const;\n\nexport type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];\n\nconst GENERATIONS = ['gen1', 'gen2', 'gen3', 'gen4'] as const;\nconst FALLBACK_LOCALE = 'en-US';\n\n/**\n * Resets the Pokemon translations cache\n * Useful when the language configuration changes\n */\nexport function resetPokemonTranslationsCache(): void {\n  pokemonTranslationsCache = {};\n}\n\n/**\n * Gets the configured locale for Pokemon names\n * Uses vscode-pokemon.pokemonLanguage configuration if set,\n * otherwise falls back to VS Code's language\n * @returns The locale string (e.g., 'fr-FR', 'en-US')\n */\nfunction getPokemonLocale(): string {\n  const config = vscode.workspace.getConfiguration('vscode-pokemon');\n  const configuredLocale = config.get<string>('pokemonLanguage', 'auto');\n\n  // If a specific language is configured and different from 'auto'\n  if (configuredLocale && configuredLocale !== 'auto') {\n    return configuredLocale.toLowerCase().replace(/_/g, '-');\n  }\n\n  // Default: use VS Code's language\n  return vscode.env.language.toLowerCase().replace(/_/g, '-');\n}\n\n/**\n * Gets the extension path, with caching\n */\nfunction getExtensionPath(): string | undefined {\n  const extension = vscode.extensions.getExtension('jakobhoeg.vscode-pokemon');\n  return extension?.extensionPath;\n}\n\n/**\n * Resolves the path to Pokemon translation files for a given locale\n */\nfunction resolvePokemonL10nPath(locale: string): string | undefined {\n  const extensionPath = getExtensionPath();\n  const basePath = extensionPath\n    ? path.join(extensionPath, 'l10n', 'pokemon')\n    : path.join(__dirname, '../../l10n/pokemon');\n\n  const localePath = path.join(basePath, locale);\n  if (fs.existsSync(localePath)) {\n    return localePath;\n  }\n\n  // Fallback to en-US\n  const fallbackPath = path.join(basePath, FALLBACK_LOCALE);\n  return fs.existsSync(fallbackPath) ? fallbackPath : undefined;\n}\n\n/**\n * Loads Pokemon translations from generation files (gen1.json, gen2.json, gen3.json)\n * Translations are stored in l10n/pokemon/{locale}/gen*.json\n *\n * Note: English names are the default source of truth defined in\n * src/common/pokemon-generations/gen*.ts files. Translation files are optional\n * and missing translations will fall back to English names.\n *\n * @param locale The locale to load (e.g., 'fr-FR', 'en-US'). Uses configured locale if not provided\n * @returns Map of Pokemon keys to translated names\n */\nfunction loadPokemonTranslations(locale?: string): { [key: string]: string } {\n  // Use provided locale or get from configuration\n  const targetLocale = locale || getPokemonLocale();\n\n  // Return cached translations if available\n  if (pokemonTranslationsCache[targetLocale]) {\n    return pokemonTranslationsCache[targetLocale];\n  }\n\n  // Initialize cache for this locale\n  const cache: { [key: string]: string } = {};\n  pokemonTranslationsCache[targetLocale] = cache;\n\n  try {\n    const pokemonL10nPath = resolvePokemonL10nPath(targetLocale);\n\n    if (!pokemonL10nPath) {\n      console.warn(\n        `[Pokemon Translations] Directory not found for locale: ${targetLocale}`,\n      );\n      return cache;\n    }\n\n    let totalLoaded = 0;\n\n    for (const gen of GENERATIONS) {\n      const genFile = path.join(pokemonL10nPath, `${gen}.json`);\n      if (!fs.existsSync(genFile)) {\n        continue;\n      }\n\n      try {\n        const genData = JSON.parse(fs.readFileSync(genFile, 'utf8'));\n        Object.assign(cache, genData);\n        totalLoaded += Object.keys(genData).length;\n      } catch (error) {\n        console.warn(`[Pokemon Translations] Error loading ${genFile}:`, error);\n      }\n    }\n\n    if (totalLoaded > 0) {\n      console.log(\n        `[Pokemon Translations] Loaded ${totalLoaded} translations from ${pokemonL10nPath}`,\n      );\n    } else {\n      console.warn(\n        `[Pokemon Translations] No translations found in ${pokemonL10nPath}`,\n      );\n    }\n  } catch (error) {\n    console.error('[Pokemon Translations] Error loading translations:', error);\n  }\n\n  return cache;\n}\n\nexport class TranslatedQuickPickItem<T> implements vscode.QuickPickItem {\n  label: string;\n  value: T;\n\n  constructor(label: string, value: T) {\n    this.label = label;\n    this.value = value;\n  }\n}\n\nexport function stringListAsQuickPickItemList<T>(\n  collection: Array<T>,\n): TranslatedQuickPickItem<T>[] {\n  return collection.map<TranslatedQuickPickItem<T>>((el) => {\n    return { label: vscode.l10n.t(String(el)), value: el };\n  });\n}\n\n/**\n * Gets the localized name of a Pokemon.\n * Loads translations from l10n/pokemon/{locale}/gen*.json files.\n * Falls back to the English name from POKEMON_DATA if no translation is available.\n *\n * @param pokemonType The Pokemon type (e.g., 'pikachu', 'charizard')\n * @returns The localized Pokemon name, or English name if translation not found\n */\nexport function getLocalizedPokemonName(pokemonType: PokemonType): string {\n  const translations = loadPokemonTranslations();\n  return (\n    translations[pokemonType] || POKEMON_DATA[pokemonType]?.name || pokemonType\n  );\n}\n"
  },
  {
    "path": "src/common/names.ts",
    "content": "import { POKEMON_NAMES } from '../panel/pokemon';\n\nexport function randomName(): string {\n  const collection: ReadonlyArray<string> = POKEMON_NAMES;\n\n  return collection[Math.floor(Math.random() * collection.length)] ?? 'Unknown';\n}\n"
  },
  {
    "path": "src/common/pokemon-data.ts",
    "content": "/* eslint-disable no-unused-vars */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport {\n  PokemonColor,\n  PokemonConfig,\n  PokemonExtraSprite,\n  PokemonGeneration,\n  PokemonType,\n} from './types';\n\nexport const POKEMON_DATA: { [key: string]: PokemonConfig } = {\n  // Generation 1\n  bulbasaur: {\n    id: 1,\n    name: 'Bulbasaur',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Bulbasaur!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ivysaur: {\n    id: 2,\n    name: 'Ivysaur',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Ivysaur!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  venusaur: {\n    id: 3,\n    name: 'Venusaur',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Venusaur!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  venusaur_female: {\n    id: 3,\n    name: 'Venusaur (Female)',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Venusaur!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  charmander: {\n    id: 4,\n    name: 'Charmander',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Charmander!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  charmeleon: {\n    id: 5,\n    name: 'Charmeleon',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Charmeleon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  charizard: {\n    id: 6,\n    name: 'Charizard',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Charizard!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  squirtle: {\n    id: 7,\n    name: 'Squirtle',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Squritle!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wartortle: {\n    id: 8,\n    name: 'Wartortle',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Wartortle!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  blastoise: {\n    id: 9,\n    name: 'Blastoise',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Blastoise!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  caterpie: {\n    id: 10,\n    name: 'Caterpie',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Caterpie!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  metapod: {\n    id: 11,\n    name: 'Metapod',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Metapod!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  butterfree: {\n    id: 12,\n    name: 'Butterfree',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Butterfree!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  weedle: {\n    id: 13,\n    name: 'Weedle',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Weedle!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kakuna: {\n    id: 14,\n    name: 'Kakuna',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Kakuna!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  beedrill: {\n    id: 15,\n    name: 'Beedrill',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Beedrill!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pidgey: {\n    id: 16,\n    name: 'Pidgey',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Pidgey!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pidgeotto: {\n    id: 17,\n    name: 'Pidgeotto',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Pidgeotto!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pidgeot: {\n    id: 18,\n    name: 'Pidgeot',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Pidgeot!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rattata: {\n    id: 19,\n    name: 'Rattata',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Rattata!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  raticate: {\n    id: 20,\n    name: 'Raticate',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Raticate!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  spearow: {\n    id: 21,\n    name: 'Spearow',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Spearow!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  fearow: {\n    id: 22,\n    name: 'Fearow',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Fearow!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ekans: {\n    id: 23,\n    name: 'Ekans',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Ekans!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  arbok: {\n    id: 24,\n    name: 'Arbok',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Arbok!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pikachu: {\n    id: 25,\n    name: 'Pikachu',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Pikachu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pikachu_female: {\n    id: 25,\n    name: 'Pikachu (Female)',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Pikachu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  raichu: {\n    id: 26,\n    name: 'Raichu',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Raichu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sandshrew: {\n    id: 27,\n    name: 'Sandshrew',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Sandshrew!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sandslash: {\n    id: 28,\n    name: 'Sandslash',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Sandslash!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nidoran_female: {\n    id: 29,\n    name: 'Nidoran♀',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Nidoran!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nidorina: {\n    id: 30,\n    name: 'Nidorina',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Nidorina!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nidoqueen: {\n    id: 31,\n    name: 'Nidoqueen',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Nidoqueen!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nidoran_male: {\n    id: 32,\n    name: 'Nidoran♂',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Nidoran!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nidorino: {\n    id: 33,\n    name: 'Nidorino',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Nidorino!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nidoking: {\n    id: 34,\n    name: 'Nidoking',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Nidoking!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  clefairy: {\n    id: 35,\n    name: 'Clefairy',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Clefairy!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  clefable: {\n    id: 36,\n    name: 'Clefable',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Clefable!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  vulpix: {\n    id: 37,\n    name: 'Vulpix',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Vulpix!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ninetales: {\n    id: 38,\n    name: 'Ninetales',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Ninetales!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  jigglypuff: {\n    id: 39,\n    name: 'Jigglypuff',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Jigglypuff!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wigglytuff: {\n    id: 40,\n    name: 'Wigglytuff',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Wigglytuff!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  zubat: {\n    id: 41,\n    name: 'Zubat',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Zubat!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  golbat: {\n    id: 42,\n    name: 'Golbat',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Golbat!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  oddish: {\n    id: 43,\n    name: 'Oddish',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Oddish!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gloom: {\n    id: 44,\n    name: 'Gloom',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Gloom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  vileplume: {\n    id: 45,\n    name: 'Vileplume',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Vileplume!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  paras: {\n    id: 46,\n    name: 'Paras',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Paras!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  parasect: {\n    id: 47,\n    name: 'Parasect',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Parasect!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  venonat: {\n    id: 48,\n    name: 'Venonat',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Venonat!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  venomoth: {\n    id: 49,\n    name: 'Venomoth',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Venomoth!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  diglett: {\n    id: 50,\n    name: 'Diglett',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Diglett!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dugtrio: {\n    id: 51,\n    name: 'Dugtrio',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Dugtrio!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  meowth: {\n    id: 52,\n    name: 'Meowth',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Meowth!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  persian: {\n    id: 53,\n    name: 'Persian',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Persian!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  psyduck: {\n    id: 54,\n    name: 'Psyduck',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Psyduck!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  golduck: {\n    id: 55,\n    name: 'Golduck',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Golduck!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mankey: {\n    id: 56,\n    name: 'Mankey',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Mankey!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  primeape: {\n    id: 57,\n    name: 'Primeape',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Primeape!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  growlithe: {\n    id: 58,\n    name: 'Growlithe',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Growlithe!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  arcanine: {\n    id: 59,\n    name: 'Arcanine',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Arcanine!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  poliwag: {\n    id: 60,\n    name: 'Poliwag',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Poliwag!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  poliwhirl: {\n    id: 61,\n    name: 'Poliwhirl',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Poliwhirl!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  poliwrath: {\n    id: 62,\n    name: 'Poliwrath',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Poliwrath!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  abra: {\n    id: 63,\n    name: 'Abra',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Abra!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kadabra: {\n    id: 64,\n    name: 'Kadabra',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Kadabra!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  alakazam: {\n    id: 65,\n    name: 'Alakazam',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Alakazam!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  machop: {\n    id: 66,\n    name: 'Machop',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Machop!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  machoke: {\n    id: 67,\n    name: 'Machoke',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Machoke!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  machamp: {\n    id: 68,\n    name: 'Machamp',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Alakazam!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bellsprout: {\n    id: 69,\n    name: 'Bellsprout',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Bellsprout!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  weepinbell: {\n    id: 70,\n    name: 'Weepinbell',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Weepinbell!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  victreebel: {\n    id: 71,\n    name: 'Victreebel',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Victreebel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  tentacool: {\n    id: 72,\n    name: 'Tentacool',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Tentacool!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  tentacruel: {\n    id: 73,\n    name: 'Tentacruel',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Tentacruel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  geodude: {\n    id: 74,\n    name: 'Geodude',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Geodude!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  graveler: {\n    id: 75,\n    name: 'Graveler',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Graveler!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  golem: {\n    id: 76,\n    name: 'Golem',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Golem!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ponyta: {\n    id: 77,\n    name: 'Ponyta',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Ponyta!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rapidash: {\n    id: 78,\n    name: 'Rapidash',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Rapidash!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  slowpoke: {\n    id: 79,\n    name: 'Slowpoke',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Slowpoke!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  slowbro: {\n    id: 80,\n    name: 'Slowbro',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Slowbro!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  magnemite: {\n    id: 81,\n    name: 'Magnemite',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Magnemite!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  magneton: {\n    id: 82,\n    name: 'Magneton',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Magneton!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  farfetchd: {\n    id: 83,\n    name: \"Farfetch'd\",\n    generation: PokemonGeneration.Gen1,\n    cry: \"Farfetch'd!\",\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  doduo: {\n    id: 84,\n    name: 'Doduo',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Doduo!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dodrio: {\n    id: 85,\n    name: 'Dodrio',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Dodrio!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  seel: {\n    id: 86,\n    name: 'Seel',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Seel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dewgong: {\n    id: 87,\n    name: 'Dewgong',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Dewgong!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  grimer: {\n    id: 88,\n    name: 'Grimer',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Grimer!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  muk: {\n    id: 89,\n    name: 'Muk',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Muk!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shellder: {\n    id: 90,\n    name: 'Shellder',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Shellder!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cloyster: {\n    id: 91,\n    name: 'Cloyster',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Cloyster!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gastly: {\n    id: 92,\n    name: 'Gastly',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Gastly!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  haunter: {\n    id: 93,\n    name: 'Haunter',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Haunter!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gengar: {\n    id: 94,\n    name: 'Gengar',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Gengar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  onix: {\n    id: 95,\n    name: 'Onix',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Onix!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  drowzee: {\n    id: 96,\n    name: 'Drowzee',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Drowzee!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hypno: {\n    id: 97,\n    name: 'Hypno',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Hypno!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  krabby: {\n    id: 98,\n    name: 'Krabby',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Krabby!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kingler: {\n    id: 99,\n    name: 'Kingler',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Kingler!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  voltorb: {\n    id: 100,\n    name: 'Voltorb',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Voltorb!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  electrode: {\n    id: 101,\n    name: 'Electrode',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Electrode!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  exeggcute: {\n    id: 102,\n    name: 'Exeggcute',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Exeggcute!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  exeggutor: {\n    id: 103,\n    name: 'Exeggutor',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Exeggutor!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cubone: {\n    id: 104,\n    name: 'Cubone',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Cubone!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  marowak: {\n    id: 105,\n    name: 'Marowak',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Marowak!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hitmonlee: {\n    id: 106,\n    name: 'Hitmonlee',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Hitmonlee!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hitmonchan: {\n    id: 107,\n    name: 'Hitmonchan',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Hitmonchan!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lickitung: {\n    id: 108,\n    name: 'Lickitung',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Lickitung!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  koffing: {\n    id: 109,\n    name: 'Koffing',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Koffing!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  weezing: {\n    id: 110,\n    name: 'Weezing',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Weezing!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rhyhorn: {\n    id: 111,\n    name: 'Rhyhorn',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Rhyhorn!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rhydon: {\n    id: 112,\n    name: 'Rhydon',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Rhydon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  chansey: {\n    id: 113,\n    name: 'Chansey',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Chansey!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  tangela: {\n    id: 114,\n    name: 'Tangela',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Tangela!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kangaskhan: {\n    id: 115,\n    name: 'Kangaskhan',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Kangaskhan!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  horsea: {\n    id: 116,\n    name: 'Horsea',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Horsea!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  seadra: {\n    id: 117,\n    name: 'Seadra',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Seadra!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  goldeen: {\n    id: 118,\n    name: 'Goldeen',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Goldeen!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  seaking: {\n    id: 119,\n    name: 'Seaking',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Seaking!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  staryu: {\n    id: 120,\n    name: 'Staryu',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Staryu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  starmie: {\n    id: 121,\n    name: 'Starmie',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Starmie!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mrmime: {\n    id: 122,\n    name: 'Mr. Mime',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Mr. Mime!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  scyther: {\n    id: 123,\n    name: 'Scyther',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Scyther!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  jynx: {\n    id: 124,\n    name: 'Jynx',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Jynx!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  electabuzz: {\n    id: 125,\n    name: 'Electabuzz',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Electabuzz!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  magmar: {\n    id: 126,\n    name: 'Magmar',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Magmar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pinsir: {\n    id: 127,\n    name: 'Pinsir',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Pinsir!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  tauros: {\n    id: 128,\n    name: 'Tauros',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Tauros!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  magikarp: {\n    id: 129,\n    name: 'Magikarp',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Magikarp!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gyarados: {\n    id: 130,\n    name: 'Gyarados',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Gyarados!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lapras: {\n    id: 131,\n    name: 'Lapras',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Lapras!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ditto: {\n    id: 132,\n    name: 'Ditto',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Ditto!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  eevee: {\n    id: 133,\n    name: 'Eevee',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Eevee!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  vaporeon: {\n    id: 134,\n    name: 'Vaporeon',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Vaporeon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  jolteon: {\n    id: 135,\n    name: 'Jolteon',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Jolteon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  flareon: {\n    id: 136,\n    name: 'Flareon',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Flareon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  porygon: {\n    id: 137,\n    name: 'Porygon',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Porygon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  omanyte: {\n    id: 138,\n    name: 'Omanyte',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Omanyte!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  omastar: {\n    id: 139,\n    name: 'Omastar',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Omastar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kabuto: {\n    id: 140,\n    name: 'Kabuto',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Kabuto!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kabutops: {\n    id: 141,\n    name: 'Kabutops',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Kabutops!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  aerodactyl: {\n    id: 142,\n    name: 'Aerodactyl',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Aerodactyl!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  snorlax: {\n    id: 143,\n    name: 'Snorlax',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Snorlax!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  articuno: {\n    id: 144,\n    name: 'Articuno',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Articuno!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  zapdos: {\n    id: 145,\n    name: 'Zapdos',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Zapdos!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  moltres: {\n    id: 146,\n    name: 'Moltres',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Moltres!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dratini: {\n    id: 147,\n    name: 'Dratini',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Dratini!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dragonair: {\n    id: 148,\n    name: 'Dragonair',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Dragonair!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dragonite: {\n    id: 149,\n    name: 'Dragonite',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Dragonite!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mewtwo: {\n    id: 150,\n    name: 'Mewtwo',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Mewtwo!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mew: {\n    id: 151,\n    name: 'Mew',\n    generation: PokemonGeneration.Gen1,\n    cry: 'Mew!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  // Generation 2\n  chikorita: {\n    id: 152,\n    name: 'Chikorita',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Chikorita!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bayleef: {\n    id: 153,\n    name: 'Bayleef',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Bayleef!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  meganium: {\n    id: 154,\n    name: 'Meganium',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Meganium!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  meganium_female: {\n    id: 154,\n    name: 'Meganium (Female)',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Meganium!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cyndaquil: {\n    id: 155,\n    name: 'Cyndaquil',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Cyndaquil!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  quilava: {\n    id: 156,\n    name: 'Quilava',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Quilava!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  typhlosion: {\n    id: 157,\n    name: 'Typhlosion',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Typhlosion!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  totodile: {\n    id: 158,\n    name: 'Totodile',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Totodile!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  croconaw: {\n    id: 159,\n    name: 'Croconaw',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Croconaw!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  feraligatr: {\n    id: 160,\n    name: 'Feraligatr',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Feraligatr!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sentret: {\n    id: 161,\n    name: 'Sentret',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Sentret!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  furret: {\n    id: 162,\n    name: 'Furret',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Furret!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hoothoot: {\n    id: 163,\n    name: 'Hoothoot',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Hoothoot!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  noctowl: {\n    id: 164,\n    name: 'Noctowl',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Noctowl!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ledyba: {\n    id: 165,\n    name: 'Ledyba',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Ledyba!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ledian: {\n    id: 166,\n    name: 'Ledian',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Ledian!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  spinarak: {\n    id: 167,\n    name: 'Spinarak',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Spinarak!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ariados: {\n    id: 168,\n    name: 'Ariados',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Ariados!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  crobat: {\n    id: 169,\n    name: 'Crobat',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Crobat!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  chinchou: {\n    id: 170,\n    name: 'Chinchou',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Chinchou!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lanturn: {\n    id: 171,\n    name: 'Lanturn',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Lanturn!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pichu: {\n    id: 172,\n    name: 'Pichu',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Pichu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pichu_spiky_eared: {\n    id: 172,\n    name: 'Pichu (Spiky-eared)',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Pichu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cleffa: {\n    id: 173,\n    name: 'Cleffa',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Cleffa!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  igglybuff: {\n    id: 174,\n    name: 'Igglybuff',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Igglybuff!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  togepi: {\n    id: 175,\n    name: 'Togepi',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Togepi!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  togetic: {\n    id: 176,\n    name: 'Togetic',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Togetic!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  natu: {\n    id: 177,\n    name: 'Natu',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Natu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  xatu: {\n    id: 178,\n    name: 'Xatu',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Xatu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mareep: {\n    id: 179,\n    name: 'Mareep',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Mareep!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  flaaffy: {\n    id: 180,\n    name: 'Flaaffy',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Flaaffy!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ampharos: {\n    id: 181,\n    name: 'Ampharos',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Ampharos!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bellossom: {\n    id: 182,\n    name: 'Bellossom',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Bellossom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  marill: {\n    id: 183,\n    name: 'Marill',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Marill!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  azumarill: {\n    id: 184,\n    name: 'Azumarill',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Azumarill!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sudowoodo: {\n    id: 185,\n    name: 'Sudowoodo',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Sudowoodo!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  politoed: {\n    id: 186,\n    name: 'Politoed',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Politoed!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hoppip: {\n    id: 187,\n    name: 'Hoppip',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Hoppip!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  skiploom: {\n    id: 188,\n    name: 'Skiploom',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Skiploom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  jumpluff: {\n    id: 189,\n    name: 'Jumpluff',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Jumpluff!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  aipom: {\n    id: 190,\n    name: 'Aipom',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Aipom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sunkern: {\n    id: 191,\n    name: 'Sunkern',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Sunkern!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sunflora: {\n    id: 192,\n    name: 'Sunflora',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Sunflora!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  yanma: {\n    id: 193,\n    name: 'Yanma',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Yanma!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wooper: {\n    id: 194,\n    name: 'Wooper',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Wooper!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  quagsire: {\n    id: 195,\n    name: 'Quagsire',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Quagsire!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  espeon: {\n    id: 196,\n    name: 'Espeon',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Espeon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  umbreon: {\n    id: 197,\n    name: 'Umbreon',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Umbreon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  murkrow: {\n    id: 198,\n    name: 'Murkrow',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Murkrow!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  slowking: {\n    id: 199,\n    name: 'Slowking',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Slowking!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  misdreavus: {\n    id: 200,\n    name: 'Misdreavus',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Misdreavus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_a: {\n    id: 201,\n    name: 'Unown A',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_b: {\n    id: 201,\n    name: 'Unown B',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_c: {\n    id: 201,\n    name: 'Unown C',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_d: {\n    id: 201,\n    name: 'Unown D',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_e: {\n    id: 201,\n    name: 'Unown E',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_f: {\n    id: 201,\n    name: 'Unown F',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_g: {\n    id: 201,\n    name: 'Unown G',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_h: {\n    id: 201,\n    name: 'Unown H',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_i: {\n    id: 201,\n    name: 'Unown I',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_j: {\n    id: 201,\n    name: 'Unown J',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_k: {\n    id: 201,\n    name: 'Unown K',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_l: {\n    id: 201,\n    name: 'Unown L',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_m: {\n    id: 201,\n    name: 'Unown M',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_n: {\n    id: 201,\n    name: 'Unown N',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_o: {\n    id: 201,\n    name: 'Unown O',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_p: {\n    id: 201,\n    name: 'Unown P',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_q: {\n    id: 201,\n    name: 'Unown Q',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_r: {\n    id: 201,\n    name: 'Unown R',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_s: {\n    id: 201,\n    name: 'Unown S',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_t: {\n    id: 201,\n    name: 'Unown T',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_u: {\n    id: 201,\n    name: 'Unown U',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_v: {\n    id: 201,\n    name: 'Unown V',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_w: {\n    id: 201,\n    name: 'Unown W',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_x: {\n    id: 201,\n    name: 'Unown X',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_y: {\n    id: 201,\n    name: 'Unown Y',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_z: {\n    id: 201,\n    name: 'Unown Z',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_exclamation: {\n    id: 201,\n    name: 'Unown !',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  unown_question: {\n    id: 201,\n    name: 'Unown ?',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Unown!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wobbuffet_male: {\n    id: 202,\n    name: 'Wobbuffet (Male)',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Wobbuffet!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wobbuffet_female: {\n    id: 202,\n    name: 'Wobbuffet (Female)',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Wobbuffet!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  girafarig: {\n    id: 203,\n    name: 'Girafarig',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Girafarig!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pineco: {\n    id: 204,\n    name: 'Pineco',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Pineco!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  forretress: {\n    id: 205,\n    name: 'Forretress',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Forretress!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dunsparce: {\n    id: 206,\n    name: 'Dunsparce',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Dunsparce!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gligar: {\n    id: 207,\n    name: 'Gligar',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Gligar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  steelix: {\n    id: 208,\n    name: 'Steelix',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Steelix!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  steelix_female: {\n    id: 208,\n    name: 'Steelix (Female)',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Steelix!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  snubbull: {\n    id: 209,\n    name: 'Snubbull',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Snubbull!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  granbull: {\n    id: 210,\n    name: 'Granbull',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Granbull!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  qwilfish: {\n    id: 211,\n    name: 'Qwilfish',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Qwilfish!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  scizor: {\n    id: 212,\n    name: 'Scizor',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Scizor!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shuckle: {\n    id: 213,\n    name: 'Shuckle',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Shuckle!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  heracross_male: {\n    id: 214,\n    name: 'Heracross (Male)',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Heracross!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  heracross_female: {\n    id: 214,\n    name: 'Heracross (Female)',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Heracross!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sneasel: {\n    id: 215,\n    name: 'Sneasel',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Sneasel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  teddiursa: {\n    id: 216,\n    name: 'Teddiursa',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Teddiursa!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ursaring: {\n    id: 217,\n    name: 'Ursaring',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Ursaring!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  slugma: {\n    id: 218,\n    name: 'Slugma',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Slugma!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  magcargo: {\n    id: 219,\n    name: 'Magcargo',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Magcargo!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  swinub: {\n    id: 220,\n    name: 'Swinub',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Swinub!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  piloswine: {\n    id: 221,\n    name: 'Piloswine',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Piloswine!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  corsola: {\n    id: 222,\n    name: 'Corsola',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Corsola!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  remoraid: {\n    id: 223,\n    name: 'Remoraid',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Remoraid!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  octillery: {\n    id: 224,\n    name: 'Octillery',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Octillery!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  delibird: {\n    id: 225,\n    name: 'Delibird',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Delibird!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mantine: {\n    id: 226,\n    name: 'Mantine',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Mantine!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  skarmory: {\n    id: 227,\n    name: 'Skarmory',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Skarmory!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  houndour: {\n    id: 228,\n    name: 'Houndour',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Houndour!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  houndoom: {\n    id: 229,\n    name: 'Houndoom',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Houndoom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kingdra: {\n    id: 230,\n    name: 'Kingdra',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Kingdra!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  phanpy: {\n    id: 231,\n    name: 'Phanpy',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Phanpy!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  donphan: {\n    id: 232,\n    name: 'Donphan',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Donphan!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  porygon2: {\n    id: 233,\n    name: 'Porygon2',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Porygon2!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  stantler: {\n    id: 234,\n    name: 'Stantler',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Stantler!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  smeargle: {\n    id: 235,\n    name: 'Smeargle',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Smeargle!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  tyrogue: {\n    id: 236,\n    name: 'Tyrogue',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Tyrogue!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hitmontop: {\n    id: 237,\n    name: 'Hitmontop',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Hitmontop!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  smoochum: {\n    id: 238,\n    name: 'Smoochum',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Smoochum!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  elekid: {\n    id: 239,\n    name: 'Elekid',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Elekid!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  magby: {\n    id: 240,\n    name: 'Magby',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Magby!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  miltank: {\n    id: 241,\n    name: 'Miltank',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Miltank!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  blissey: {\n    id: 242,\n    name: 'Blissey',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Blissey!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  raikou: {\n    id: 243,\n    name: 'Raikou',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Raikou!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  entei: {\n    id: 244,\n    name: 'Entei',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Entei!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  suicune: {\n    id: 245,\n    name: 'Suicune',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Suicune!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  larvitar: {\n    id: 246,\n    name: 'Larvitar',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Larvitar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pupitar: {\n    id: 247,\n    name: 'Pupitar',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Pupitar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  tyranitar: {\n    id: 248,\n    name: 'Tyranitar',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Tyranitar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lugia: {\n    id: 249,\n    name: 'Lugia',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Lugia!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  hooh: {\n    id: 250,\n    name: 'Ho-Oh',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Ho-Oh!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  celebi: {\n    id: 251,\n    name: 'Celebi',\n    generation: PokemonGeneration.Gen2,\n    cry: 'Celebi!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  // Generation 3\n  treecko: {\n    id: 252,\n    name: 'Treecko',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Treecko!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  grovyle: {\n    id: 253,\n    name: 'Grovyle',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Grovyle!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sceptile: {\n    id: 254,\n    name: 'Sceptile',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Sceptile!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  torchic: {\n    id: 255,\n    name: 'Torchic',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Torchic!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  combusken: {\n    id: 256,\n    name: 'Combusken',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Combusken!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  blaziken: {\n    id: 257,\n    name: 'Blaziken',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Blaziken!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mudkip: {\n    id: 258,\n    name: 'Mudkip',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Mudkip!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  marshtomp: {\n    id: 259,\n    name: 'Marshtomp',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Marshtomp!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  swampert: {\n    id: 260,\n    name: 'Swampert',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Swampert!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  poochyena: {\n    id: 261,\n    name: 'Poochyena',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Poochyena!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mightyena: {\n    id: 262,\n    name: 'Mightyena',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Mightyena!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  zigzagoon: {\n    id: 263,\n    name: 'Zigzagoon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Zigzagoon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  linoone: {\n    id: 264,\n    name: 'Linoone',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Linoone!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wurmple: {\n    id: 265,\n    name: 'Wurmple',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Wurmple!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  silcoon: {\n    id: 266,\n    name: 'Silcoon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Silcoon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  beautifly: {\n    id: 267,\n    name: 'Beautifly',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Beautifly!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cascoon: {\n    id: 268,\n    name: 'Cascoon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Cascoon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dustox: {\n    id: 269,\n    name: 'Dustox',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Dustox!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lotad: {\n    id: 270,\n    name: 'Lotad',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Lotad!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lombre: {\n    id: 271,\n    name: 'Lombre',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Lombre!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ludicolo: {\n    id: 272,\n    name: 'Ludicolo',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Ludicolo!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  seedot: {\n    id: 273,\n    name: 'Seedot',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Seedot!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nuzleaf: {\n    id: 274,\n    name: 'Nuzleaf',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Nuzleaf!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shiftry: {\n    id: 275,\n    name: 'Shiftry',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Shiftry!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  taillow: {\n    id: 276,\n    name: 'Taillow',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Taillow!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  swellow: {\n    id: 277,\n    name: 'Swellow',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Swellow!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wingull: {\n    id: 278,\n    name: 'Wingull',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Wingull!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pelipper: {\n    id: 279,\n    name: 'Pelipper',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Pelipper!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ralts: {\n    id: 280,\n    name: 'Ralts',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Ralts!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kirlia: {\n    id: 281,\n    name: 'Kirlia',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Kirlia!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gardevoir: {\n    id: 282,\n    name: 'Gardevoir',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Gardevoir!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  surskit: {\n    id: 283,\n    name: 'Surskit',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Surskit!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  masquerain: {\n    id: 284,\n    name: 'Masquerain',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Masquerain!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shroomish: {\n    id: 285,\n    name: 'Shroomish',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Shroomish!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  breloom: {\n    id: 286,\n    name: 'Breloom',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Breloom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  slakoth: {\n    id: 287,\n    name: 'Slakoth',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Slakoth!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  vigoroth: {\n    id: 288,\n    name: 'Vigoroth',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Vigoroth!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  slaking: {\n    id: 289,\n    name: 'Slaking',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Slaking!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nincada: {\n    id: 290,\n    name: 'Nincada',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Nincada!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ninjask: {\n    id: 291,\n    name: 'Ninjask',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Ninjask!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shedinja: {\n    id: 292,\n    name: 'Shedinja',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Shedinja!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  whismur: {\n    id: 293,\n    name: 'Whismur',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Whismur!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  loudred: {\n    id: 294,\n    name: 'Loudred',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Loudred!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  exploud: {\n    id: 295,\n    name: 'Exploud',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Exploud!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  makuhita: {\n    id: 296,\n    name: 'Makuhita',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Makuhita!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hariyama: {\n    id: 297,\n    name: 'Hariyama',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Hariyama!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  azurill: {\n    id: 298,\n    name: 'Azurill',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Azurill!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  nosepass: {\n    id: 299,\n    name: 'Nosepass',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Nosepass!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  skitty: {\n    id: 300,\n    name: 'Skitty',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Skitty!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  delcatty: {\n    id: 301,\n    name: 'Delcatty',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Delcatty!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sableye: {\n    id: 302,\n    name: 'Sableye',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Sableye!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mawile: {\n    id: 303,\n    name: 'Mawile',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Mawile!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  aron: {\n    id: 304,\n    name: 'Aron',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Aron!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lairon: {\n    id: 305,\n    name: 'Lairon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Lairon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  aggron: {\n    id: 306,\n    name: 'Aggron',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Aggron!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  meditite: {\n    id: 307,\n    name: 'Meditite',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Meditite!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  medicham: {\n    id: 308,\n    name: 'Medicham',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Medicham!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  electrike: {\n    id: 309,\n    name: 'Electrike',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Electrike!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  manectric: {\n    id: 310,\n    name: 'Manectric',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Manectric!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  plusle: {\n    id: 311,\n    name: 'Plusle',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Plusle!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  minun: {\n    id: 312,\n    name: 'Minun',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Minun!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  volbeat: {\n    id: 313,\n    name: 'Volbeat',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Volbeat!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  illumise: {\n    id: 314,\n    name: 'Illumise',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Illumise!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  roselia: {\n    id: 315,\n    name: 'Roselia',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Roselia!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gulpin: {\n    id: 316,\n    name: 'Gulpin',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Gulpin!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  swalot: {\n    id: 317,\n    name: 'Swalot',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Swalot!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  carvanha: {\n    id: 318,\n    name: 'Carvanha',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Carvanha!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sharpedo: {\n    id: 319,\n    name: 'Sharpedo',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Sharpedo!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wailmer: {\n    id: 320,\n    name: 'Wailmer',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Wailmer!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wailord: {\n    id: 321,\n    name: 'Wailord',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Wailord!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  numel: {\n    id: 322,\n    name: 'Numel',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Numel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  camerupt: {\n    id: 323,\n    name: 'Camerupt',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Camerupt!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  torkoal: {\n    id: 324,\n    name: 'Torkoal',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Torkoal!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  spoink: {\n    id: 325,\n    name: 'Spoink',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Spoink!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  grumpig: {\n    id: 326,\n    name: 'Grumpig',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Grumpig!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  spinda: {\n    id: 327,\n    name: 'Spinda',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Spinda!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  trapinch: {\n    id: 328,\n    name: 'Trapinch',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Trapinch!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  vibrava: {\n    id: 329,\n    name: 'Vibrava',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Vibrava!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  flygon: {\n    id: 330,\n    name: 'Flygon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Flygon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cacnea: {\n    id: 331,\n    name: 'Cacnea',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Cacnea!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cacturne: {\n    id: 332,\n    name: 'Cacturne',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Cacturne!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  swablu: {\n    id: 333,\n    name: 'Swablu',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Swablu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  altaria: {\n    id: 334,\n    name: 'Altaria',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Altaria!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  zangoose: {\n    id: 335,\n    name: 'Zangoose',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Zangoose!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  seviper: {\n    id: 336,\n    name: 'Seviper',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Seviper!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lunatone: {\n    id: 337,\n    name: 'Lunatone',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Lunatone!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  solrock: {\n    id: 338,\n    name: 'Solrock',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Solrock!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  barboach: {\n    id: 339,\n    name: 'Barboach',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Barboach!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  whiscash: {\n    id: 340,\n    name: 'Whiscash',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Whiscash!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  corphish: {\n    id: 341,\n    name: 'Corphish',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Corphish!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  crawdaunt: {\n    id: 342,\n    name: 'Crawdaunt',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Crawdaunt!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  baltoy: {\n    id: 343,\n    name: 'Baltoy',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Baltoy!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  claydol: {\n    id: 344,\n    name: 'Claydol',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Claydol!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lileep: {\n    id: 345,\n    name: 'Lileep',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Lileep!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cradily: {\n    id: 346,\n    name: 'Cradily',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Cradily!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  anorith: {\n    id: 347,\n    name: 'Anorith',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Anorith!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  armaldo: {\n    id: 348,\n    name: 'Armaldo',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Armaldo!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  feebas: {\n    id: 349,\n    name: 'Feebas',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Feebas!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  milotic: {\n    id: 350,\n    name: 'Milotic',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Milotic!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  castform: {\n    id: 351,\n    name: 'Castform',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Castform!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kecleon: {\n    id: 352,\n    name: 'Kecleon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Kecleon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shuppet: {\n    id: 353,\n    name: 'Shuppet',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Shuppet!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  banette: {\n    id: 354,\n    name: 'Banette',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Banette!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  duskull: {\n    id: 355,\n    name: 'Duskull',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Duskull!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dusclops: {\n    id: 356,\n    name: 'Dusclops',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Dusclops!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  tropius: {\n    id: 357,\n    name: 'Tropius',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Tropius!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  chimecho: {\n    id: 358,\n    name: 'Chimecho',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Chimecho!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  absol: {\n    id: 359,\n    name: 'Absol',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Absol!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wynaut: {\n    id: 360,\n    name: 'Wynaut',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Wynaut!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  snorunt: {\n    id: 361,\n    name: 'Snorunt',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Snorunt!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  glalie: {\n    id: 362,\n    name: 'Glalie',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Glalie!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  spheal: {\n    id: 363,\n    name: 'Spheal',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Spheal!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  sealeo: {\n    id: 364,\n    name: 'Sealeo',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Sealeo!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  walrein: {\n    id: 365,\n    name: 'Walrein',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Walrein!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  clamperl: {\n    id: 366,\n    name: 'Clamperl',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Clamperl!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  huntail: {\n    id: 367,\n    name: 'Huntail',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Huntail!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gorebyss: {\n    id: 368,\n    name: 'Gorebyss',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Gorebyss!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  relicanth: {\n    id: 369,\n    name: 'Relicanth',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Relicanth!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  luvdisc: {\n    id: 370,\n    name: 'Luvdisc',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Luvdisc!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bagon: {\n    id: 371,\n    name: 'Bagon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Bagon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shelgon: {\n    id: 372,\n    name: 'Shelgon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Shelgon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  salamence: {\n    id: 373,\n    name: 'Salamence',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Salamence!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  beldum: {\n    id: 374,\n    name: 'Beldum',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Beldum!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  metang: {\n    id: 375,\n    name: 'Metang',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Metang!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  metagross: {\n    id: 376,\n    name: 'Metagross',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Metagross!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  regirock: {\n    id: 377,\n    name: 'Regirock',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Regirock!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  regice: {\n    id: 378,\n    name: 'Regice',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Regice!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  registeel: {\n    id: 379,\n    name: 'Registeel',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Registeel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  latias: {\n    id: 380,\n    name: 'Latias',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Latias!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  latios: {\n    id: 381,\n    name: 'Latios',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Latios!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kyogre: {\n    id: 382,\n    name: 'Kyogre',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Kyogre!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  groudon: {\n    id: 383,\n    name: 'Groudon',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Groudon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  rayquaza: {\n    id: 384,\n    name: 'Rayquaza',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Rayquaza!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  jirachi: {\n    id: 385,\n    name: 'Jirachi',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Jirachi!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  deoxys: {\n    id: 386,\n    name: 'Deoxys',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Deoxys!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  deoxys_speed: {\n    id: 386,\n    name: 'Deoxys (Speed)',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Deoxys!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  deoxys_attack: {\n    id: 386,\n    name: 'Deoxys (Attack)',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Deoxys!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  deoxys_defense: {\n    id: 386,\n    name: 'Deoxys (Defense)',\n    generation: PokemonGeneration.Gen3,\n    cry: 'Deoxys!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  // Generation 4\n  turtwig: {\n    id: 387,\n    name: 'Turtwig',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Turtwig!',\n    possibleColors: [PokemonColor.default],\n  },\n  grotle: {\n    id: 388,\n    name: 'Grotle',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Grotle!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  torterra: {\n    id: 389,\n    name: 'Torterra',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Torterra!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  chimchar: {\n    id: 390,\n    name: 'Chimchar',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Chimchar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  monferno: {\n    id: 391,\n    name: 'Monferno',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Monferno!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  infernape: {\n    id: 392,\n    name: 'Infernape',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Infernape!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  piplup: {\n    id: 393,\n    name: 'Piplup',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Piplup!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  prinplup: {\n    id: 394,\n    name: 'Prinplup',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Prinplup!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  empoleon: {\n    id: 395,\n    name: 'Empoleon',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Empoleon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  starly: {\n    id: 396,\n    name: 'Starly',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Starly!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  staravia: {\n    id: 397,\n    name: 'Staravia',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Staravia!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  staraptor: {\n    id: 398,\n    name: 'Staraptor',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Staraptor!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bidoof: {\n    id: 399,\n    name: 'Bidoof',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Bidoof!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bibarel: {\n    id: 400,\n    name: 'Bibarel',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Bibarel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  kricketot: {\n    id: 401,\n    name: 'Kricketot',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Kricketot!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  kricketune: {\n    id: 402,\n    name: 'Kricketune',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Kricketune!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  shinx: {\n    id: 403,\n    name: 'Shinx',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Shinx!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  luxio: {\n    id: 404,\n    name: 'Luxio',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Luxio!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  luxray: {\n    id: 405,\n    name: 'Luxray',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Luxray!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  budew: {\n    id: 406,\n    name: 'Budew',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Budew!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  roserade: {\n    id: 407,\n    name: 'Roserade',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Roserade!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  cranidos: {\n    id: 408,\n    name: 'Cranidos',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Cranidos!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rampardos: {\n    id: 409,\n    name: 'Rampardos',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Rampardos!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shieldon: {\n    id: 410,\n    name: 'Shieldon',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Shieldon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bastiodon: {\n    id: 411,\n    name: 'Bastiodon',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Bastiodon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  burmy_plant: {\n    id: 412,\n    name: 'Burmy (Plant)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Burmy!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  burmy_sandy: {\n    id: 412,\n    name: 'Burmy (Sandy)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Burmy!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  burmy_trash: {\n    id: 412,\n    name: 'Burmy (Trash)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Burmy!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wormadam_plant: {\n    id: 413,\n    name: 'Wormadam (Plant)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Wormadam!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wormadam_sandy: {\n    id: 413,\n    name: 'Wormadam (Sandy)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Wormadam!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  wormadam_trash: {\n    id: 413,\n    name: 'Wormadam (Trash)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Wormadam!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mothim: {\n    id: 414,\n    name: 'Mothim',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Mothim!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  combee_male: {\n    id: 415,\n    name: 'Combee (Male)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Combee!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  combee_female: {\n    id: 415,\n    name: 'Combee (Female)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Combee!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  vespiquen: {\n    id: 416,\n    name: 'Vespiquen',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Vespiquen!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  pachirisu: {\n    id: 417,\n    name: 'Pachirisu',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Pachirisu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  buizel: {\n    id: 418,\n    name: 'Buizel',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Buizel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  floatzel: {\n    id: 419,\n    name: 'Floatzel',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Floatzel!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cherubi: {\n    id: 420,\n    name: 'Cherubi',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Cherubi!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  cherrim: {\n    id: 421,\n    name: 'Cherrim',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Cherrim!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shellos_west: {\n    id: 422,\n    name: 'Shellos (West)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Shellos!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shellos_east: {\n    id: 422,\n    name: 'Shellos (East)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Shellos!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gastrodon_west: {\n    id: 423,\n    name: 'Gastrodon (West)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Gastrodon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gastrodon_east: {\n    id: 423,\n    name: 'Gastrodon (East)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Gastrodon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  ambipom: {\n    id: 424,\n    name: 'Ambipom',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Ambipom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  drifloon: {\n    id: 425,\n    name: 'Drifloon',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Drifloon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  drifblim: {\n    id: 426,\n    name: 'Drifblim',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Drifblim!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  buneary: {\n    id: 427,\n    name: 'Buneary',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Buneary!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  lopunny: {\n    id: 428,\n    name: 'Lopunny',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Lopunny!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mismagius: {\n    id: 429,\n    name: 'Mismagius',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Mismagius!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  honchkrow: {\n    id: 430,\n    name: 'Honchkrow',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Honchkrow!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  glameow: {\n    id: 431,\n    name: 'Glameow',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Glameow!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  purugly: {\n    id: 432,\n    name: 'Purugly',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Purugly!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  chingling: {\n    id: 433,\n    name: 'Chingling',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Chingling!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  stunky: {\n    id: 434,\n    name: 'Stunky',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Stunky!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  skuntank: {\n    id: 435,\n    name: 'Skuntank',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Skuntank!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bronzor: {\n    id: 436,\n    name: 'Bronzor',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Bronzor!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bronzong: {\n    id: 437,\n    name: 'Bronzong',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Bronzong!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  bonsly: {\n    id: 438,\n    name: 'Bonsly',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Bonsly!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mimeJr: {\n    id: 439,\n    name: 'Mime Jr.',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Mime Jr.!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  happiny: {\n    id: 440,\n    name: 'Happiny',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Happiny!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  chatot: {\n    id: 441,\n    name: 'Chatot',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Chatot!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  spiritomb: {\n    id: 442,\n    name: 'Spiritomb',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Spiritomb!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gible: {\n    id: 443,\n    name: 'Gible',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Gible!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  gible_female: {\n    id: 443,\n    name: 'Gible (Female)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Gible!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  gabite: {\n    id: 444,\n    name: 'Gabite',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Gabite!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gabite_female: {\n    id: 444,\n    name: 'Gabite (Female)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Gabite!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  garchomp: {\n    id: 445,\n    name: 'Garchomp',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Garchomp!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  garchomp_female: {\n    id: 445,\n    name: 'Garchomp (Female)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Garchomp!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  munchlax: {\n    id: 446,\n    name: 'Munchlax',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Munchlax!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  riolu: {\n    id: 447,\n    name: 'Riolu',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Riolu!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  lucario: {\n    id: 448,\n    name: 'Lucario',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Lucario!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hippopotas_male: {\n    id: 449,\n    name: 'Hippopotas (Male)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Hippopotas!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hippopotas_female: {\n    id: 449,\n    name: 'Hippopotas (Female)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Hippopotas!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hippowdon_male: {\n    id: 450,\n    name: 'Hippowdon (Male)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Hippowdon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  hippowdon_female: {\n    id: 450,\n    name: 'Hippowdon (Female)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Hippowdon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  skorupi: {\n    id: 451,\n    name: 'Skorupi',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Skorupi!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  drapion: {\n    id: 452,\n    name: 'Drapion',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Drapion!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  croagunk: {\n    id: 453,\n    name: 'Croagunk',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Croagunk!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  toxicroak: {\n    id: 454,\n    name: 'Toxicroak',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Toxicroak!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  carnivine: {\n    id: 455,\n    name: 'Carnivine',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Carnivine!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  finneon: {\n    id: 456,\n    name: 'Finneon',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Finneon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lumineon: {\n    id: 457,\n    name: 'Lumineon',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Lumineon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mantyke: {\n    id: 458,\n    name: 'Mantyke',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Mantyke!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  snover: {\n    id: 459,\n    name: 'Snover',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Snover!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  abomasnow: {\n    id: 460,\n    name: 'Abomasnow',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Abomasnow!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  weavile: {\n    id: 461,\n    name: 'Weavile',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Weavile!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  magnezone: {\n    id: 462,\n    name: 'Magnezone',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Magnezone!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  lickilicky: {\n    id: 463,\n    name: 'Lickilicky',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Lickilicky!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rhyperior: {\n    id: 464,\n    name: 'Rhyperior',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Rhyperior!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  tangrowth: {\n    id: 465,\n    name: 'Tangrowth',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Tangrowth!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  electivire: {\n    id: 466,\n    name: 'Electivire',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Electivire!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  magmortar: {\n    id: 467,\n    name: 'Magmortar',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Magmortar!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  togekiss: {\n    id: 468,\n    name: 'Togekiss',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Togekiss!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  yanmega: {\n    id: 469,\n    name: 'Yanmega',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Yanmega!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  leafeon: {\n    id: 470,\n    name: 'Leafeon',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Leafeon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  glaceon: {\n    id: 471,\n    name: 'Glaceon',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Glaceon!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gliscor: {\n    id: 472,\n    name: 'Gliscor',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Gliscor!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mamoswine: {\n    id: 473,\n    name: 'Mamoswine',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Mamoswine!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  porygonZ: {\n    id: 474,\n    name: 'Porygon-Z',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Porygon-Z!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  gallade: {\n    id: 475,\n    name: 'Gallade',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Gallade!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  probopass: {\n    id: 476,\n    name: 'Probopass',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Probopass!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dusknoir: {\n    id: 477,\n    name: 'Dusknoir',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Dusknoir!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  froslass: {\n    id: 478,\n    name: 'Froslass',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Froslass!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rotom: {\n    id: 479,\n    name: 'Rotom',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Rotom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rotom_heat: {\n    id: 479,\n    name: 'Rotom (Heat Form)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Rotom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rotom_wash: {\n    id: 479,\n    name: 'Rotom (Wash Form)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Rotom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  rotom_frost: {\n    id: 479,\n    name: 'Rotom (Frost Form)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Rotom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rotom_fan: {\n    id: 479,\n    name: 'Rotom (Fan Form)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Rotom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  rotom_mow: {\n    id: 479,\n    name: 'Rotom (Mow Form)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Rotom!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  uxie: {\n    id: 480,\n    name: 'Uxie',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Uxie!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  mesprit: {\n    id: 481,\n    name: 'Mesprit',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Mesprit!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  azelf: {\n    id: 482,\n    name: 'Azelf',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Azelf!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  dialga: {\n    id: 483,\n    name: 'Dialga',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Dialga!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  palkia: {\n    id: 484,\n    name: 'Palkia',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Palkia!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  heatran: {\n    id: 485,\n    name: 'Heatran',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Heatran!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  regigigas: {\n    id: 486,\n    name: 'Regigigas',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Regigigas!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  giratina: {\n    id: 487,\n    name: 'Giratina',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Giratina!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  giratina_origin: {\n    id: 487,\n    name: 'Giratina (Origin Form)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Giratina!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  cresselia: {\n    id: 488,\n    name: 'Cresselia',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Cresselia!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  phione: {\n    id: 489,\n    name: 'Phione',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Phione!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  manaphy: {\n    id: 490,\n    name: 'Manaphy',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Manaphy!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  darkrai: {\n    id: 491,\n    name: 'Darkrai',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Darkrai!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shaymin: {\n    id: 492,\n    name: 'Shaymin',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Shaymin!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  shaymin_sky: {\n    id: 492,\n    name: 'Shaymin (Sky Form)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Shaymin!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    extraSprites: [PokemonExtraSprite.leftFacing],\n  },\n  arceus: {\n    id: 493,\n    name: 'Arceus',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_bug: {\n    id: 493,\n    name: 'Arceus (Bug)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n  },\n  arceus_dark: {\n    id: 493,\n    name: 'Arceus (Dark)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_dragon: {\n    id: 493,\n    name: 'Arceus (Dragon)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_electric: {\n    id: 493,\n    name: 'Arceus (Electric)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_fighting: {\n    id: 493,\n    name: 'Arceus (Fighting)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_fire: {\n    id: 493,\n    name: 'Arceus (Fire)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_flying: {\n    id: 493,\n    name: 'Arceus (Flying)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_ghost: {\n    id: 493,\n    name: 'Arceus (Ghost)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_grass: {\n    id: 493,\n    name: 'Arceus (Grass)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_ground: {\n    id: 493,\n    name: 'Arceus (Ground)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_ice: {\n    id: 493,\n    name: 'Arceus (Ice)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_poison: {\n    id: 493,\n    name: 'Arceus (Poison)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_psychic: {\n    id: 493,\n    name: 'Arceus (Psychic)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_rock: {\n    id: 493,\n    name: 'Arceus (Rock)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_steel: {\n    id: 493,\n    name: 'Arceus (Steel)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n  arceus_water: {\n    id: 493,\n    name: 'Arceus (Water)',\n    generation: PokemonGeneration.Gen4,\n    cry: 'Arceus!',\n    possibleColors: [PokemonColor.default, PokemonColor.shiny],\n    originalSpriteSize: 64,\n  },\n};\n\nexport function getAllPokemon(): PokemonType[] {\n  return Object.keys(POKEMON_DATA) as PokemonType[];\n}\n\nexport function getPokemonByGeneration(\n  generation: PokemonGeneration,\n): PokemonType[] {\n  return Object.entries(POKEMON_DATA)\n    .filter(([, config]) => config.generation === generation)\n    .map(([key]) => key as PokemonType);\n}\n\nexport function getDefaultPokemon(): PokemonType {\n  return 'bulbasaur';\n}\n\nexport function getRandomPokemonConfig(): [PokemonType, PokemonConfig] {\n  const keys = Object.keys(POKEMON_DATA);\n  const randomKey = keys[Math.floor(Math.random() * keys.length)];\n  return [randomKey as PokemonType, POKEMON_DATA[randomKey]];\n}\n"
  },
  {
    "path": "src/common/types.ts",
    "content": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { POKEMON_DATA } from './pokemon-data';\n\nexport const enum PokemonColor {\n  default = 'default',\n  shiny = 'shiny',\n  null = 'null',\n}\n\nexport enum PokemonGeneration {\n  Gen1 = 1,\n  Gen2 = 2,\n  Gen3 = 3,\n  Gen4 = 4,\n}\n\nexport type PokemonTypeString = string & keyof typeof POKEMON_DATA;\n\nexport type PokemonType = PokemonTypeString;\n\nexport interface PokemonConfig {\n  id: number;\n  name: string;\n  generation: PokemonGeneration;\n  cry: string;\n  possibleColors: PokemonColor[];\n  originalSpriteSize?: number;\n  extraSprites?: PokemonExtraSprite[];\n}\n\nexport const enum PokemonExtraSprite {\n  leftFacing = 'left_facing',\n}\n\nexport const enum PokemonSpeed {\n  still = 0,\n  verySlow = 1,\n  slow = 2,\n  normal = 3,\n  fast = 4,\n  veryFast = 5,\n}\n\nexport const enum PokemonSize {\n  nano = 'nano',\n  small = 'small',\n  medium = 'medium',\n  large = 'large',\n}\n\nexport const enum ExtPosition {\n  panel = 'panel',\n  explorer = 'explorer',\n}\n\nexport const enum Theme {\n  none = 'none',\n  forest = 'forest',\n  castle = 'castle',\n  beach = 'beach',\n}\n\nexport const enum ColorThemeKind {\n  light = 1,\n  dark = 2,\n  highContrast = 3,\n}\n\nexport class WebviewMessage {\n  text: string;\n  command: string;\n\n  constructor(text: string, command: string) {\n    this.text = text;\n    this.command = command;\n  }\n}\n\nexport const ALL_COLORS = [PokemonColor.default];\nexport const ALL_SCALES = [\n  PokemonSize.nano,\n  PokemonSize.small,\n  PokemonSize.medium,\n  PokemonSize.large,\n];\nexport const ALL_THEMES = [Theme.none, Theme.forest, Theme.castle, Theme.beach];\n"
  },
  {
    "path": "src/extension/extension.ts",
    "content": "import * as vscode from 'vscode';\nimport { ColorThemeKind } from 'vscode';\nimport * as localize from '../common/localize';\nimport { randomName } from '../common/names';\nimport {\n  getDefaultPokemon as getDefaultPokemonType,\n  getPokemonByGeneration,\n  getRandomPokemonConfig,\n  POKEMON_DATA,\n} from '../common/pokemon-data';\nimport {\n  ALL_COLORS,\n  ALL_SCALES,\n  ALL_THEMES,\n  ExtPosition,\n  PokemonColor,\n  PokemonGeneration,\n  PokemonSize,\n  PokemonType,\n  Theme,\n  WebviewMessage,\n} from '../common/types';\nimport { availableColors, normalizeColor } from '../panel/pokemon-collection';\n\nconst EXTRA_POKEMON_KEY = 'vscode-pokemon.extra-pokemon';\nconst EXTRA_POKEMON_KEY_TYPES = EXTRA_POKEMON_KEY + '.types';\nconst EXTRA_POKEMON_KEY_COLORS = EXTRA_POKEMON_KEY + '.colors';\nconst EXTRA_POKEMON_KEY_NAMES = EXTRA_POKEMON_KEY + '.names';\nconst DEFAULT_POKEMON_SCALE = PokemonSize.medium;\nconst DEFAULT_COLOR = PokemonColor.default;\nconst DEFAULT_POKEMON_TYPE = getDefaultPokemonType();\nconst DEFAULT_POSITION = ExtPosition.panel;\nconst DEFAULT_THEME = Theme.none;\n\nclass PokemonQuickPickItem implements vscode.QuickPickItem {\n  constructor(\n    public readonly name_: string,\n    public readonly type: string,\n    public readonly color: string,\n  ) {\n    this.name = name_;\n    this.label = name_;\n    this.description = `${color} ${type}`;\n  }\n\n  name: string;\n  label: string;\n  kind?: vscode.QuickPickItemKind | undefined;\n  description?: string | undefined;\n  detail?: string | undefined;\n  picked?: boolean | undefined;\n  alwaysShow?: boolean | undefined;\n  buttons?: readonly vscode.QuickInputButton[] | undefined;\n}\n\nlet webviewViewProvider: PokemonWebviewViewProvider;\n\nfunction getConfiguredSize(): PokemonSize {\n  var size = vscode.workspace\n    .getConfiguration('vscode-pokemon')\n    .get<PokemonSize>('pokemonSize', DEFAULT_POKEMON_SCALE);\n  if (ALL_SCALES.lastIndexOf(size) === -1) {\n    size = DEFAULT_POKEMON_SCALE;\n  }\n  return size;\n}\n\nfunction getConfiguredTheme(): Theme {\n  var theme = vscode.workspace\n    .getConfiguration('vscode-pokemon')\n    .get<Theme>('theme', DEFAULT_THEME);\n  if (ALL_THEMES.lastIndexOf(theme) === -1) {\n    theme = DEFAULT_THEME;\n  }\n  return theme;\n}\n\nfunction getConfiguredThemeKind(): ColorThemeKind {\n  return vscode.window.activeColorTheme.kind;\n}\n\nfunction getConfigurationPosition() {\n  return vscode.workspace\n    .getConfiguration('vscode-pokemon')\n    .get<ExtPosition>('position', DEFAULT_POSITION);\n}\n\nfunction getThrowWithMouseConfiguration(): boolean {\n  return vscode.workspace\n    .getConfiguration('vscode-pokemon')\n    .get<boolean>('throwBallWithMouse', true);\n}\n\nfunction getConfiguredShinyOdds(): number {\n  return vscode.workspace\n    .getConfiguration('vscode-pokemon')\n    .get<number>('shinyOdds', 8192);\n}\n\nfunction maybeMakeShiny(possibleColors: PokemonColor[]): PokemonColor {\n  if (possibleColors.includes(PokemonColor.shiny)) {\n    const shinyOdds = getConfiguredShinyOdds();\n    if (Math.floor(Math.random() * shinyOdds) === 0) {\n      return PokemonColor.shiny;\n    }\n  }\n  return possibleColors[0];\n}\n\ninterface IDefaultPokemonConfig {\n  type: PokemonType;\n  name?: string;\n  shiny?: boolean;\n}\n\nfunction getConfiguredDefaultPokemon(): PokemonSpecification[] {\n  const defaultConfig = vscode.workspace\n    .getConfiguration('vscode-pokemon')\n    .get<IDefaultPokemonConfig[]>('defaultPokemon', []);\n\n  const size = getConfiguredSize();\n  const result: PokemonSpecification[] = [];\n\n  for (const config of defaultConfig) {\n    // Validate that the pokemon type exists\n    if (POKEMON_DATA[config.type]) {\n      const name = config.name || randomName();\n\n      // If shiny is not specified, default to color to maybeShiny with the pokemon's available colors. If shiny is true, force shiny color. If shiny is false, force default color.\n      let color: PokemonColor;\n      if (config.shiny === undefined) {\n        color = maybeMakeShiny(availableColors(config.type));\n      } else if (config.shiny) {\n        color = PokemonColor.shiny;\n      } else {\n        color = DEFAULT_COLOR;\n      }\n\n      result.push(new PokemonSpecification(color, config.type, size, name));\n    } else {\n      console.warn(\n        `Invalid pokemon type in defaultPokemon config: ${config.type}`,\n      );\n    }\n  }\n\n  return result;\n}\n\nfunction getSessionPokemonCollection(\n  context: vscode.ExtensionContext,\n): PokemonSpecification[] {\n  const savedCollection = PokemonSpecification.collectionFromMemento(\n    context,\n    getConfiguredSize(),\n  );\n\n  if (savedCollection.length > 0) {\n    return savedCollection;\n  }\n\n  return getConfiguredDefaultPokemon();\n}\n\nfunction getDefaultPokemonForFreshSession(\n  context: vscode.ExtensionContext,\n): PokemonSpecification[] {\n  const savedCollection = PokemonSpecification.collectionFromMemento(\n    context,\n    getConfiguredSize(),\n  );\n\n  if (savedCollection.length > 0) {\n    return [];\n  }\n\n  return getConfiguredDefaultPokemon();\n}\n\nexport function shouldSpawnInitialCollection(\n  collection: PokemonSpecification[],\n): boolean {\n  return collection.length > 0;\n}\n\nasync function spawnAndPersistCollection(\n  context: vscode.ExtensionContext,\n  panel: IPokemonPanel,\n  collection: PokemonSpecification[],\n): Promise<void> {\n  collection.forEach((item) => {\n    panel.spawnPokemon(item);\n  });\n\n  await storeCollectionAsMemento(context, collection);\n}\n\nfunction updatePanelThrowWithMouse(): void {\n  const panel = getPokemonPanel();\n  if (panel !== undefined) {\n    panel.setThrowWithMouse(getThrowWithMouseConfiguration());\n  }\n}\n\nasync function updateExtensionPositionContext() {\n  await vscode.commands.executeCommand(\n    'setContext',\n    'vscode-pokemon.position',\n    getConfigurationPosition(),\n  );\n}\n\nexport class PokemonSpecification {\n  color: PokemonColor;\n  type: PokemonType;\n  size: PokemonSize;\n  name: string;\n  generation: string;\n  originalSpriteSize: number;\n\n  constructor(\n    color: PokemonColor,\n    type: PokemonType,\n    size: PokemonSize,\n    name?: string,\n    generation?: string,\n  ) {\n    this.color = color;\n    this.type = type;\n    this.size = size;\n    if (!name) {\n      this.name = randomName();\n    } else {\n      this.name = name;\n    }\n    this.generation = generation || `gen${POKEMON_DATA[type].generation}`;\n    this.originalSpriteSize = POKEMON_DATA[type].originalSpriteSize || 32;\n  }\n\n  static fromConfiguration(): PokemonSpecification {\n    var color = vscode.workspace\n      .getConfiguration('vscode-pokemon')\n      .get<PokemonColor>('pokemonColor', DEFAULT_COLOR);\n    if (ALL_COLORS.lastIndexOf(color) === -1) {\n      color = DEFAULT_COLOR;\n    }\n    var type = vscode.workspace\n      .getConfiguration('vscode-pokemon')\n      .get<PokemonType>('pokemonType', DEFAULT_POKEMON_TYPE);\n\n    // Use POKEMON_DATA to validate the type\n    if (!POKEMON_DATA[type]) {\n      type = DEFAULT_POKEMON_TYPE;\n    }\n\n    return new PokemonSpecification(color, type, getConfiguredSize());\n  }\n\n  static collectionFromMemento(\n    context: vscode.ExtensionContext,\n    size: PokemonSize,\n  ): PokemonSpecification[] {\n    var contextTypes = context.globalState.get<PokemonType[]>(\n      EXTRA_POKEMON_KEY_TYPES,\n      [],\n    );\n    var contextColors = context.globalState.get<PokemonColor[]>(\n      EXTRA_POKEMON_KEY_COLORS,\n      [],\n    );\n    var contextNames = context.globalState.get<string[]>(\n      EXTRA_POKEMON_KEY_NAMES,\n      [],\n    );\n    var result: PokemonSpecification[] = [];\n    for (let index = 0; index < contextTypes.length; index++) {\n      result.push(\n        new PokemonSpecification(\n          contextColors?.[index] ?? DEFAULT_COLOR,\n          contextTypes[index],\n          size,\n          contextNames[index],\n        ),\n      );\n    }\n    return result;\n  }\n}\n\nexport async function storeCollectionAsMemento(\n  context: vscode.ExtensionContext,\n  collection: PokemonSpecification[],\n) {\n  var contextTypes = new Array(collection.length);\n  var contextColors = new Array(collection.length);\n  var contextNames = new Array(collection.length);\n  for (let index = 0; index < collection.length; index++) {\n    contextTypes[index] = collection[index].type;\n    contextColors[index] = collection[index].color;\n    contextNames[index] = collection[index].name;\n  }\n  await context.globalState.update(EXTRA_POKEMON_KEY_TYPES, contextTypes);\n  await context.globalState.update(EXTRA_POKEMON_KEY_COLORS, contextColors);\n  await context.globalState.update(EXTRA_POKEMON_KEY_NAMES, contextNames);\n  context.globalState.setKeysForSync([\n    EXTRA_POKEMON_KEY_TYPES,\n    EXTRA_POKEMON_KEY_COLORS,\n    EXTRA_POKEMON_KEY_NAMES,\n  ]);\n}\n\nlet spawnPokemonStatusBar: vscode.StatusBarItem;\n\ninterface IPokemonInfo {\n  type: PokemonType;\n  name: string;\n  color: PokemonColor;\n}\n\nfunction waitForPokemonList(webview: vscode.Webview): Promise<IPokemonInfo[]> {\n  return new Promise((resolve) => {\n    const disposable = webview.onDidReceiveMessage(\n      (message: WebviewMessage) => {\n        if (message.command !== 'list-pokemon') {\n          return;\n        }\n        disposable.dispose();\n        const pokemonList: IPokemonInfo[] = [];\n        message.text.split('\\n').forEach((pokemon) => {\n          if (!pokemon) {\n            return;\n          }\n          var parts = pokemon.split(',');\n          pokemonList.push({\n            type: parts[0] as PokemonType,\n            name: parts[1],\n            color: parts[2] as PokemonColor,\n          });\n        });\n        resolve(pokemonList);\n      },\n    );\n  });\n}\n\nfunction getPokemonPanel(): IPokemonPanel | undefined {\n  if (\n    getConfigurationPosition() === ExtPosition.explorer &&\n    webviewViewProvider\n  ) {\n    return webviewViewProvider;\n  } else if (PokemonPanel.currentPanel) {\n    return PokemonPanel.currentPanel;\n  } else {\n    return undefined;\n  }\n}\n\nfunction getWebview(): vscode.Webview | undefined {\n  if (\n    getConfigurationPosition() === ExtPosition.explorer &&\n    webviewViewProvider\n  ) {\n    return webviewViewProvider.getWebview();\n  } else if (PokemonPanel.currentPanel) {\n    return PokemonPanel.currentPanel.getWebview();\n  }\n}\n\nexport function activate(context: vscode.ExtensionContext) {\n  // Reset the Pokemon translations cache at startup to load the correct language\n  localize.resetPokemonTranslationsCache();\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand('vscode-pokemon.start', async () => {\n      if (\n        getConfigurationPosition() === ExtPosition.explorer &&\n        webviewViewProvider\n      ) {\n        await vscode.commands.executeCommand('pokemonView.focus');\n      } else {\n        const spec = PokemonSpecification.fromConfiguration();\n        PokemonPanel.createOrShow(\n          context.extensionUri,\n          spec.color,\n          spec.type,\n          spec.size,\n          spec.generation,\n          spec.originalSpriteSize,\n          getConfiguredTheme(),\n          getConfiguredThemeKind(),\n          getThrowWithMouseConfiguration(),\n        );\n\n        if (PokemonPanel.currentPanel) {\n          const collection = getSessionPokemonCollection(context);\n          await spawnAndPersistCollection(\n            context,\n            PokemonPanel.currentPanel,\n            collection,\n          );\n        }\n      }\n    }),\n  );\n\n  spawnPokemonStatusBar = vscode.window.createStatusBarItem(\n    vscode.StatusBarAlignment.Right,\n    100,\n  );\n  spawnPokemonStatusBar.command = 'vscode-pokemon.spawn-pokemon';\n  context.subscriptions.push(spawnPokemonStatusBar);\n\n  context.subscriptions.push(\n    vscode.window.onDidChangeActiveTextEditor(updateStatusBar),\n  );\n  context.subscriptions.push(\n    vscode.window.onDidChangeTextEditorSelection(updateStatusBar),\n  );\n  context.subscriptions.push(\n    vscode.window.onDidChangeActiveTextEditor(updateExtensionPositionContext),\n  );\n  updateStatusBar();\n\n  const spec = PokemonSpecification.fromConfiguration();\n  webviewViewProvider = new PokemonWebviewViewProvider(\n    context,\n    context.extensionUri,\n    spec.color,\n    spec.type,\n    spec.size,\n    spec.generation,\n    spec.originalSpriteSize,\n    getConfiguredTheme(),\n    getConfiguredThemeKind(),\n    getThrowWithMouseConfiguration(),\n  );\n  updateExtensionPositionContext().catch((e) => {\n    console.error(e);\n  });\n\n  context.subscriptions.push(\n    vscode.window.registerWebviewViewProvider(\n      PokemonWebviewViewProvider.viewType,\n      webviewViewProvider,\n    ),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand(\n      'vscode-pokemon.delete-pokemon',\n      async () => {\n        const panel = getPokemonPanel();\n        if (panel === undefined) {\n          await createPokemonPlayground(context);\n          return;\n        }\n        const webview = getWebview();\n        if (!webview) {\n          return;\n        }\n        const listPromise = waitForPokemonList(webview);\n        panel.listPokemon();\n        const pokemonList = await listPromise;\n\n        if (!pokemonList.length) {\n          await vscode.window.showErrorMessage(\n            vscode.l10n.t('There are no pokemon to remove.'),\n          );\n          return;\n        }\n        const pokemon = await vscode.window.showQuickPick<PokemonQuickPickItem>(\n          pokemonList.map((val) => {\n            return new PokemonQuickPickItem(val.name, val.type, val.color);\n          }),\n          {\n            placeHolder: vscode.l10n.t('Select the pokemon to remove.'),\n          },\n        );\n        if (pokemon) {\n          panel.deletePokemon(pokemon.name);\n          const collection = pokemonList\n            .filter((item) => {\n              return item.name !== pokemon.name;\n            })\n            .map<PokemonSpecification>((item) => {\n              return new PokemonSpecification(\n                item.color,\n                item.type,\n                PokemonSize.medium,\n                item.name,\n              );\n            });\n          await storeCollectionAsMemento(context, collection);\n        }\n      },\n    ),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand(\n      'vscode-pokemon.remove-all-pokemon',\n      async () => {\n        const panel = getPokemonPanel();\n        if (panel !== undefined) {\n          panel.resetPokemon();\n          await storeCollectionAsMemento(context, []);\n        } else {\n          await createPokemonPlayground(context);\n          await vscode.window.showInformationMessage(\n            vscode.l10n.t(\n              \"A Pokemon Playground has been created. You can now use the 'Remove All Pokemon' Command to remove all Pokemon.\",\n            ),\n          );\n        }\n      },\n    ),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand('vscode-pokemon.roll-call', async () => {\n      const panel = getPokemonPanel();\n      if (panel !== undefined) {\n        panel.rollCall();\n      } else {\n        await createPokemonPlayground(context);\n      }\n    }),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand(\n      'vscode-pokemon.configure-keybindings',\n      async () => {\n        const items: Array<vscode.QuickPickItem & { commandId: string }> = [\n          {\n            label: vscode.l10n.t('Spawn additional pokemon'),\n            description: 'vscode-pokemon.spawn-pokemon',\n            commandId: 'vscode-pokemon.spawn-pokemon',\n          },\n          {\n            label: vscode.l10n.t('Spawn random pokemon'),\n            description: 'vscode-pokemon.spawn-random-pokemon',\n            commandId: 'vscode-pokemon.spawn-random-pokemon',\n          },\n          {\n            label: vscode.l10n.t('Remove pokemon'),\n            description: 'vscode-pokemon.delete-pokemon',\n            commandId: 'vscode-pokemon.delete-pokemon',\n          },\n          {\n            label: vscode.l10n.t('Remove all pokemon'),\n            description: 'vscode-pokemon.remove-all-pokemon',\n            commandId: 'vscode-pokemon.remove-all-pokemon',\n          },\n        ];\n\n        const picked = await vscode.window.showQuickPick(items, {\n          placeHolder: vscode.l10n.t(\n            'Select a command to configure its keybinding',\n          ),\n          matchOnDescription: true,\n        });\n        if (!picked) {\n          return;\n        }\n        await vscode.commands.executeCommand(\n          'workbench.action.openGlobalKeybindings',\n          picked.commandId,\n        );\n      },\n    ),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand(\n      'vscode-pokemon.change-pokemon-language',\n      async () => {\n        const config = vscode.workspace.getConfiguration('vscode-pokemon');\n        const currentLanguage = config.get<string>('pokemonLanguage', 'auto');\n\n        // Language display names and flags (official Pokemon languages only)\n        /* eslint-disable @typescript-eslint/naming-convention */\n        const languageLabels: {\n          [key: string]: { label: string; description: string };\n        } = {\n          auto: {\n            label: '$(globe) Auto',\n            description: vscode.l10n.t('Use VS Code language'),\n          },\n          'en-US': {\n            label: '🇺🇸 English (US)',\n            description: vscode.l10n.t('English names'),\n          },\n          'fr-FR': {\n            label: '🇫🇷 Français (FR)',\n            description: vscode.l10n.t('French names'),\n          },\n          'de-DE': {\n            label: '🇩🇪 Deutsch (DE)',\n            description: vscode.l10n.t('German names'),\n          },\n          'ja-JP': {\n            label: '🇯🇵 日本語 (JP)',\n            description: vscode.l10n.t('Japanese names'),\n          },\n        } as { [key: string]: { label: string; description: string } };\n        /* eslint-enable @typescript-eslint/naming-convention */\n\n        const languageOptions: Array<vscode.QuickPickItem & { value: string }> =\n          [\n            {\n              label: languageLabels['auto'].label,\n              description: languageLabels['auto'].description,\n              detail:\n                currentLanguage === 'auto'\n                  ? vscode.l10n.t('Current')\n                  : undefined,\n              value: 'auto',\n            },\n            ...localize.SUPPORTED_LOCALES.map((locale) => ({\n              label: languageLabels[locale]?.label || locale,\n              description: languageLabels[locale]?.description || locale,\n              detail:\n                currentLanguage === locale\n                  ? vscode.l10n.t('Current')\n                  : undefined,\n              value: locale,\n            })),\n          ];\n\n        const picked = await vscode.window.showQuickPick(languageOptions, {\n          placeHolder: vscode.l10n.t('Select language for Pokemon names'),\n        });\n\n        if (!picked) {\n          return;\n        }\n\n        // Update configuration persistently\n        await config.update(\n          'pokemonLanguage',\n          picked.value,\n          vscode.ConfigurationTarget.Global,\n        );\n\n        // Reset translation cache to force reload\n        localize.resetPokemonTranslationsCache();\n\n        // Preload translations with the new language\n        // This ensures the cache is immediately available\n        const testPokemon: PokemonType = 'bulbasaur';\n        localize.getLocalizedPokemonName(testPokemon);\n\n        await vscode.window.showInformationMessage(\n          vscode.l10n.t(\n            'Pokemon language changed to {0}. The change will persist after restart.',\n            picked.label,\n          ),\n        );\n      },\n    ),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand(\n      'vscode-pokemon.export-pokemon-list',\n      async () => {\n        const pokemonCollection = PokemonSpecification.collectionFromMemento(\n          context,\n          getConfiguredSize(),\n        );\n        const pokemonJson = JSON.stringify(pokemonCollection, null, 2);\n        const fileName = `pokemonCollection-${Date.now()}.json`;\n        if (!vscode.workspace.workspaceFolders) {\n          await vscode.window.showErrorMessage(\n            vscode.l10n.t(\n              'You must have a folder or workspace open to export pokemonCollection.',\n            ),\n          );\n          return;\n        }\n        const filePath = vscode.Uri.joinPath(\n          vscode.workspace.workspaceFolders[0].uri,\n          fileName,\n        );\n        const newUri = vscode.Uri.file(fileName).with({\n          scheme: 'untitled',\n          path: filePath.fsPath,\n        });\n        await vscode.workspace.openTextDocument(newUri).then(async (doc) => {\n          await vscode.window.showTextDocument(doc).then(async (editor) => {\n            await editor.edit((edit) => {\n              edit.insert(new vscode.Position(0, 0), pokemonJson);\n            });\n          });\n        });\n      },\n    ),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand(\n      'vscode-pokemon.import-pokemon-list',\n      async () => {\n        const options: vscode.OpenDialogOptions = {\n          canSelectMany: false,\n          openLabel: 'Open pokemonCollection.json',\n          filters: {\n            json: ['json'],\n          },\n        };\n        const fileUri = await vscode.window.showOpenDialog(options);\n\n        if (fileUri && fileUri[0]) {\n          console.log('Selected file: ' + fileUri[0].fsPath);\n          try {\n            const fileContents = await vscode.workspace.fs.readFile(fileUri[0]);\n            const pokemonToLoad = JSON.parse(\n              String.fromCharCode.apply(null, Array.from(fileContents)),\n            );\n\n            // load the pokemon into the collection\n            var collection = PokemonSpecification.collectionFromMemento(\n              context,\n              getConfiguredSize(),\n            );\n            // fetch just the pokemon types\n            const panel = getPokemonPanel();\n            for (let i = 0; i < pokemonToLoad.length; i++) {\n              const pokemon = pokemonToLoad[i];\n              const pokemonSpec = new PokemonSpecification(\n                normalizeColor(pokemon.color, pokemon.type),\n                pokemon.type,\n                pokemon.size,\n                pokemon.name,\n              );\n              collection.push(pokemonSpec);\n              if (panel !== undefined) {\n                panel.spawnPokemon(pokemonSpec);\n              }\n            }\n            await storeCollectionAsMemento(context, collection);\n          } catch (e: any) {\n            await vscode.window.showErrorMessage(\n              vscode.l10n.t('Failed to import pokemon: {0}', e?.message),\n            );\n          }\n        }\n      },\n    ),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand(\n      'vscode-pokemon.spawn-pokemon',\n      async () => {\n        const panel = getPokemonPanel();\n        if (\n          getConfigurationPosition() === ExtPosition.explorer &&\n          webviewViewProvider\n        ) {\n          await vscode.commands.executeCommand('pokemonView.focus');\n        }\n        if (panel) {\n          // Dynamic QuickPick: show only generations by default; reveal Pokémon matches when typing\n          const generationItems: Array<\n            vscode.QuickPickItem & {\n              isGeneration: true;\n              gen: PokemonGeneration;\n            }\n          > = Object.values(PokemonGeneration)\n            .filter((gen) => typeof gen === 'number')\n            .map((gen) => ({\n              label: `$(folder) ${vscode.l10n.t('Generation {0}', gen)}`,\n              description: vscode.l10n.t('Browse Gen {0} Pokemon', gen),\n              isGeneration: true as const,\n              gen: gen as PokemonGeneration,\n            }));\n\n          const allPokemonOptions: Array<\n            vscode.QuickPickItem & { value: PokemonType; isGeneration: false }\n          > = Object.entries(POKEMON_DATA).map(([type, config]) => ({\n            label: localize.getLocalizedPokemonName(type as PokemonType),\n            value: type as PokemonType,\n            description: `#${config.id.toString().padStart(4, '0')} - Gen ${config.generation}`,\n            isGeneration: false as const,\n          }));\n\n          const qp = vscode.window.createQuickPick<\n            vscode.QuickPickItem & {\n              isGeneration?: boolean;\n              gen?: PokemonGeneration;\n              value?: PokemonType;\n            }\n          >();\n          qp.placeholder = vscode.l10n.t(\n            'Select a generation or start typing to search for a Pokemon...',\n          );\n          qp.matchOnDescription = true;\n\n          const setGenerationOnlyItems = () => {\n            qp.items = [\n              {\n                label: vscode.l10n.t('Generations'),\n                kind: vscode.QuickPickItemKind.Separator,\n              },\n              ...generationItems,\n            ];\n          };\n\n          const setWithSearchResults = (query: string) => {\n            const q = query.toLowerCase().trim();\n            const results = allPokemonOptions.filter(\n              (opt) =>\n                opt.label.toLowerCase().includes(q) ||\n                (opt.description?.toLowerCase().includes(q) ?? false),\n            );\n            qp.items = [\n              {\n                label: vscode.l10n.t('Generations'),\n                kind: vscode.QuickPickItemKind.Separator,\n              },\n              ...generationItems,\n              {\n                label: vscode.l10n.t('Results'),\n                kind: vscode.QuickPickItemKind.Separator,\n              },\n              ...results,\n            ];\n          };\n\n          setGenerationOnlyItems();\n\n          let selectedPokemonType:\n            | { label: string; value: PokemonType }\n            | undefined;\n\n          const disposables: vscode.Disposable[] = [];\n\n          disposables.push(\n            qp.onDidChangeValue((val) => {\n              if (val && val.trim().length > 0) {\n                setWithSearchResults(val);\n              } else {\n                setGenerationOnlyItems();\n              }\n            }),\n          );\n\n          disposables.push(\n            qp.onDidAccept(async () => {\n              const sel = qp.selectedItems[0] as any;\n              if (!sel) {\n                qp.hide();\n                return;\n              }\n              if (sel.isGeneration) {\n                // Don't hide the first quick pick yet - dispose it manually\n                const pokemonInGeneration = getPokemonByGeneration(\n                  sel.gen as PokemonGeneration,\n                );\n                const pokemonOptions = pokemonInGeneration.map((type) => ({\n                  label: localize.getLocalizedPokemonName(type),\n                  value: type,\n                  description: `#${POKEMON_DATA[type].id\n                    .toString()\n                    .padStart(4, '0')}`,\n                }));\n\n                // Manually dispose the first quick pick to prevent race condition\n                disposables.forEach((d) => d.dispose());\n                qp.dispose();\n\n                const picked = await vscode.window.showQuickPick(\n                  pokemonOptions,\n                  {\n                    placeHolder: vscode.l10n.t('Select a Pokemon'),\n                  },\n                );\n                if (picked) {\n                  selectedPokemonType = picked;\n\n                  // Handle the rest of the flow\n                  const possibleColors = availableColors(\n                    selectedPokemonType.value,\n                  );\n\n                  const name = await vscode.window.showInputBox({\n                    placeHolder: vscode.l10n.t('Leave blank for a random name'),\n                    prompt: vscode.l10n.t('Name your Pokemon'),\n                    value: randomName(),\n                  });\n\n                  if (name === undefined) {\n                    console.log('Cancelled Spawning Pokemon - No Name Entered');\n                    return;\n                  }\n\n                  const spec = new PokemonSpecification(\n                    maybeMakeShiny(possibleColors),\n                    selectedPokemonType.value,\n                    getConfiguredSize(),\n                    name,\n                  );\n\n                  panel.spawnPokemon(spec);\n                  var collection = PokemonSpecification.collectionFromMemento(\n                    context,\n                    getConfiguredSize(),\n                  );\n                  collection.push(spec);\n                  await storeCollectionAsMemento(context, collection);\n                }\n              } else {\n                selectedPokemonType = sel as any;\n                qp.hide();\n              }\n            }),\n          );\n\n          const closed = new Promise<void>((resolve) => {\n            disposables.push(\n              qp.onDidHide(() => {\n                disposables.forEach((d) => d.dispose());\n                qp.dispose();\n                resolve();\n              }),\n            );\n          });\n\n          qp.show();\n          await closed;\n\n          if (!selectedPokemonType) {\n            console.log('Cancelled Spawning Pokemon - No Selection');\n            return;\n          }\n\n          if (!selectedPokemonType) {\n            console.log('Cancelled Spawning Pokemon - No Pokemon Selected');\n            return;\n          }\n\n          // Rest of the existing code\n          const possibleColors = availableColors(selectedPokemonType.value);\n\n          const name = await vscode.window.showInputBox({\n            placeHolder: vscode.l10n.t('Leave blank for a random name'),\n            prompt: vscode.l10n.t('Name your Pokemon'),\n            value: randomName(),\n          });\n\n          if (name === undefined) {\n            console.log('Cancelled Spawning Pokemon - No Name Entered');\n            return;\n          }\n\n          const spec = new PokemonSpecification(\n            maybeMakeShiny(possibleColors),\n            selectedPokemonType.value,\n            getConfiguredSize(),\n            name,\n          );\n\n          panel.spawnPokemon(spec);\n          var collection = PokemonSpecification.collectionFromMemento(\n            context,\n            getConfiguredSize(),\n          );\n          collection.push(spec);\n          await storeCollectionAsMemento(context, collection);\n        } else {\n          await createPokemonPlayground(context);\n          await vscode.window.showInformationMessage(\n            vscode.l10n.t(\n              \"A Pokemon Playground has been created. You can now use the 'Spawn Additional Pokemon' Command to add more Pokemon.\",\n            ),\n          );\n        }\n      },\n    ),\n  );\n\n  context.subscriptions.push(\n    vscode.commands.registerCommand(\n      'vscode-pokemon.spawn-random-pokemon',\n      async () => {\n        const panel = getPokemonPanel();\n        if (\n          getConfigurationPosition() === ExtPosition.explorer &&\n          webviewViewProvider\n        ) {\n          await vscode.commands.executeCommand('pokemonView.focus');\n        }\n        if (panel) {\n          var [randomPokemonType, randomPokemonConfig] =\n            getRandomPokemonConfig();\n          const spec = new PokemonSpecification(\n            maybeMakeShiny(randomPokemonConfig.possibleColors),\n            randomPokemonType,\n            getConfiguredSize(),\n            randomPokemonConfig.name,\n          );\n\n          panel.spawnPokemon(spec);\n          var collection = PokemonSpecification.collectionFromMemento(\n            context,\n            getConfiguredSize(),\n          );\n          collection.push(spec);\n          await storeCollectionAsMemento(context, collection);\n        } else {\n          await createPokemonPlayground(context);\n          await vscode.window.showInformationMessage(\n            vscode.l10n.t(\n              \"A Pokemon Playground has been created. You can now use the 'Remove All Pokemon' Command to remove all Pokemon.\",\n            ),\n          );\n        }\n      },\n    ),\n  );\n\n  // Listening to configuration changes\n  context.subscriptions.push(\n    vscode.workspace.onDidChangeConfiguration(\n      (e: vscode.ConfigurationChangeEvent): void => {\n        if (\n          e.affectsConfiguration('vscode-pokemon.pokemonColor') ||\n          e.affectsConfiguration('vscode-pokemon.pokemonType') ||\n          e.affectsConfiguration('vscode-pokemon.pokemonSize') ||\n          e.affectsConfiguration('vscode-pokemon.theme') ||\n          e.affectsConfiguration('workbench.colorTheme')\n        ) {\n          const spec = PokemonSpecification.fromConfiguration();\n          const panel = getPokemonPanel();\n          if (panel) {\n            panel.updatePokemonColor(spec.color);\n            panel.updatePokemonSize(spec.size);\n            panel.updatePokemonType(spec.type);\n            panel.updateTheme(getConfiguredTheme(), getConfiguredThemeKind());\n            panel.update();\n          }\n        }\n\n        if (e.affectsConfiguration('vscode-pokemon.position')) {\n          void updateExtensionPositionContext();\n        }\n\n        if (e.affectsConfiguration('vscode-pokemon.throwBallWithMouse')) {\n          updatePanelThrowWithMouse();\n        }\n\n        if (e.affectsConfiguration('vscode-pokemon.pokemonLanguage')) {\n          // Reset the Pokemon translations cache when the language changes\n          localize.resetPokemonTranslationsCache();\n          // Update the panel to reflect the new language\n          const panel = getPokemonPanel();\n          if (panel) {\n            panel.update();\n          }\n        }\n      },\n    ),\n  );\n\n  if (vscode.window.registerWebviewPanelSerializer) {\n    // Make sure we register a serializer in activation event\n    vscode.window.registerWebviewPanelSerializer(PokemonPanel.viewType, {\n      async deserializeWebviewPanel(webviewPanel: vscode.WebviewPanel) {\n        // Reset the webview options so we use latest uri for `localResourceRoots`.\n        webviewPanel.webview.options = getWebviewOptions(context.extensionUri);\n        const spec = PokemonSpecification.fromConfiguration();\n        PokemonPanel.revive(\n          webviewPanel,\n          context.extensionUri,\n          spec.color,\n          spec.type,\n          spec.size,\n          spec.generation,\n          spec.originalSpriteSize,\n          getConfiguredTheme(),\n          getConfiguredThemeKind(),\n          getThrowWithMouseConfiguration(),\n        );\n\n        if (PokemonPanel.currentPanel) {\n          const collection = getDefaultPokemonForFreshSession(context);\n          if (shouldSpawnInitialCollection(collection)) {\n            await spawnAndPersistCollection(\n              context,\n              PokemonPanel.currentPanel,\n              collection,\n            );\n          }\n        }\n      },\n    });\n  }\n}\n\nfunction updateStatusBar(): void {\n  spawnPokemonStatusBar.text = `$(squirrel)`;\n  spawnPokemonStatusBar.tooltip = vscode.l10n.t('Spawn Pokemon');\n  spawnPokemonStatusBar.show();\n}\n\nexport function spawnPokemonDeactivate() {\n  spawnPokemonStatusBar.dispose();\n}\n\nfunction getWebviewOptions(\n  extensionUri: vscode.Uri,\n): vscode.WebviewOptions & vscode.WebviewPanelOptions {\n  return {\n    // Enable javascript in the webview\n    enableScripts: true,\n    // And restrict the webview to only loading content from our extension's `media` directory.\n    localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'media')],\n  };\n}\n\ninterface IPokemonPanel {\n  // throwBall(): void;\n  resetPokemon(): void;\n  spawnPokemon(spec: PokemonSpecification): void;\n  deletePokemon(pokemonName: string): void;\n  listPokemon(): void;\n  rollCall(): void;\n  themeKind(): vscode.ColorThemeKind;\n  throwBallWithMouse(): boolean;\n  updatePokemonColor(newColor: PokemonColor): void;\n  updatePokemonType(newType: PokemonType): void;\n  updatePokemonSize(newSize: PokemonSize): void;\n  updateTheme(newTheme: Theme, themeKind: vscode.ColorThemeKind): void;\n  update(): void;\n  setThrowWithMouse(newThrowWithMouse: boolean): void;\n}\n\nclass PokemonWebviewContainer implements IPokemonPanel {\n  protected _extensionUri: vscode.Uri;\n  protected _disposables: vscode.Disposable[] = [];\n  protected _pokemonColor: PokemonColor;\n  protected _pokemonType: PokemonType;\n  protected _pokemonSize: PokemonSize;\n  protected _pokemonGeneration: string;\n  protected _pokemonOriginalSpriteSize: number;\n  protected _theme: Theme;\n  protected _themeKind: vscode.ColorThemeKind;\n  protected _throwBallWithMouse: boolean;\n\n  constructor(\n    extensionUri: vscode.Uri,\n    color: PokemonColor,\n    type: PokemonType,\n    size: PokemonSize,\n    generation: string,\n    originalSpriteSize: number,\n    theme: Theme,\n    themeKind: ColorThemeKind,\n    throwBallWithMouse: boolean,\n  ) {\n    this._extensionUri = extensionUri;\n    this._pokemonColor = color;\n    this._pokemonType = type;\n    this._pokemonSize = size;\n    this._pokemonGeneration = generation;\n    this._pokemonOriginalSpriteSize = originalSpriteSize;\n    this._theme = theme;\n    this._themeKind = themeKind;\n    this._throwBallWithMouse = throwBallWithMouse;\n  }\n\n  public pokemonColor(): PokemonColor {\n    return normalizeColor(this._pokemonColor, this._pokemonType);\n  }\n\n  public pokemonType(): PokemonType {\n    return this._pokemonType;\n  }\n\n  public pokemonSize(): PokemonSize {\n    return this._pokemonSize;\n  }\n\n  public pokemonGeneration(): string {\n    return this._pokemonGeneration;\n  }\n\n  public pokemonOriginalSpriteSize(): number {\n    return this._pokemonOriginalSpriteSize;\n  }\n\n  public theme(): Theme {\n    return this._theme;\n  }\n\n  public themeKind(): vscode.ColorThemeKind {\n    return this._themeKind;\n  }\n\n  public throwBallWithMouse(): boolean {\n    return this._throwBallWithMouse;\n  }\n\n  public updatePokemonColor(newColor: PokemonColor) {\n    this._pokemonColor = newColor;\n  }\n\n  public updatePokemonType(newType: PokemonType) {\n    this._pokemonType = newType;\n  }\n\n  public updatePokemonSize(newSize: PokemonSize) {\n    this._pokemonSize = newSize;\n  }\n\n  public updatePokemonGeneration(newGeneration: string) {\n    this._pokemonGeneration = newGeneration;\n  }\n\n  public updateTheme(newTheme: Theme, themeKind: vscode.ColorThemeKind) {\n    this._theme = newTheme;\n    this._themeKind = themeKind;\n  }\n\n  public setThrowWithMouse(newThrowWithMouse: boolean): void {\n    this._throwBallWithMouse = newThrowWithMouse;\n    void this.getWebview().postMessage({\n      command: 'throw-with-mouse',\n      enabled: newThrowWithMouse,\n    });\n  }\n\n  public throwBall() {\n    void this.getWebview().postMessage({\n      command: 'throw-ball',\n    });\n  }\n\n  public resetPokemon(): void {\n    void this.getWebview().postMessage({\n      command: 'reset-pokemon',\n    });\n  }\n\n  public spawnPokemon(spec: PokemonSpecification) {\n    void this.getWebview().postMessage({\n      command: 'spawn-pokemon',\n      type: spec.type,\n      color: spec.color,\n      name: spec.name,\n      generation: spec.generation,\n      originalSpriteSize: spec.originalSpriteSize,\n    });\n    void this.getWebview().postMessage({\n      command: 'set-size',\n      size: spec.size,\n    });\n  }\n\n  public listPokemon() {\n    void this.getWebview().postMessage({ command: 'list-pokemon' });\n  }\n\n  public rollCall(): void {\n    void this.getWebview().postMessage({ command: 'roll-call' });\n  }\n\n  public deletePokemon(pokemonName: string) {\n    void this.getWebview().postMessage({\n      command: 'delete-pokemon',\n      name: pokemonName,\n    });\n  }\n\n  protected getWebview(): vscode.Webview {\n    throw new Error('Not implemented');\n  }\n\n  protected _update() {\n    const webview = this.getWebview();\n    webview.html = this._getHtmlForWebview(webview);\n  }\n\n  // #TODO: verify if this is needed\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public update() {}\n\n  protected _getHtmlForWebview(webview: vscode.Webview) {\n    // Local path to main script run in the webview\n    const scriptPathOnDisk = vscode.Uri.joinPath(\n      this._extensionUri,\n      'media',\n      'main-bundle.js',\n    );\n\n    // And the uri we use to load this script in the webview\n    const scriptUri = webview.asWebviewUri(scriptPathOnDisk);\n\n    // Local path to css styles\n    const styleResetPath = vscode.Uri.joinPath(\n      this._extensionUri,\n      'media',\n      'reset.css',\n    );\n    const stylesPathMainPath = vscode.Uri.joinPath(\n      this._extensionUri,\n      'media',\n      'pokemon.css',\n    );\n    const silkScreenFontPath = webview.asWebviewUri(\n      vscode.Uri.joinPath(\n        this._extensionUri,\n        'media',\n        'Silkscreen-Regular.ttf',\n      ),\n    );\n\n    // Uri to load styles into webview\n    const stylesResetUri = webview.asWebviewUri(styleResetPath);\n    const stylesMainUri = webview.asWebviewUri(stylesPathMainPath);\n\n    // Get path to resource on disk\n    const basePokemonUri = webview.asWebviewUri(\n      vscode.Uri.joinPath(this._extensionUri, 'media'),\n    );\n\n    // Use a nonce to only allow specific scripts to be run\n    const nonce = getNonce();\n\n    return `<!DOCTYPE html>\n\t\t\t<html lang=\"en\">\n\t\t\t<head>\n\t\t\t\t<meta charset=\"UTF-8\">\n\t\t\t\t<!--\n\t\t\t\t\tUse a content security policy to only allow loading images from https or from our extension directory,\n\t\t\t\t\tand only allow scripts that have a specific nonce.\n\t\t\t\t-->\n\t\t\t\t<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'none'; style-src ${\n          webview.cspSource\n        } 'nonce-${nonce}'; img-src ${\n          webview.cspSource\n        } https:; script-src 'nonce-${nonce}';\n                font-src ${webview.cspSource};\">\n\t\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t\t\t\t<link href=\"${stylesResetUri}\" rel=\"stylesheet\" nonce=\"${nonce}\">\n\t\t\t\t<link href=\"${stylesMainUri}\" rel=\"stylesheet\" nonce=\"${nonce}\">\n                <style nonce=\"${nonce}\">\n                @font-face {\n                    font-family: 'silkscreen';\n                    src: url('${silkScreenFontPath}') format('truetype');\n                }\n                </style>\n\t\t\t\t<title>VS Code Pokemon</title>\n\t\t\t</head>\n\t\t\t<body>\n                <canvas id=\"pokemonCanvas\"></canvas>\n                <div id=\"pokemonContainer\"></div>\n                <div id=\"foreground\"></div>\n                <script nonce=\"${nonce}\" src=\"${scriptUri}\"></script>\n                <script nonce=\"${nonce}\">\n                    pokemonApp.pokemonPanelApp(\n                        \"${basePokemonUri}\",\n                        \"${this.theme()}\",\n                        ${this.themeKind()},\n                        \"${this.pokemonColor()}\",\n                        \"${this.pokemonSize()}\",\n                        \"${this.pokemonType()}\",\n                        \"${this.throwBallWithMouse()}\",\n                        \"${this.pokemonGeneration()}\",\n                        \"${this.pokemonOriginalSpriteSize()}\",\n                    );\n                </script>\n            </body>\n\t\t\t</html>`;\n  }\n}\n\nfunction handleWebviewMessage(message: WebviewMessage) {\n  switch (message.command) {\n    case 'alert':\n      void vscode.window.showErrorMessage(message.text);\n      return;\n    case 'info':\n      void vscode.window.showInformationMessage(message.text);\n      return;\n  }\n}\n\n/**\n * Manages pokemon coding webview panels\n */\nclass PokemonPanel extends PokemonWebviewContainer implements IPokemonPanel {\n  /**\n   * Track the currently panel. Only allow a single panel to exist at a time.\n   */\n  public static currentPanel: PokemonPanel | undefined;\n\n  public static readonly viewType = 'pokemonCoding';\n\n  private readonly _panel: vscode.WebviewPanel;\n\n  public static createOrShow(\n    extensionUri: vscode.Uri,\n    pokemonColor: PokemonColor,\n    pokemonType: PokemonType,\n    pokemonSize: PokemonSize,\n    pokemonGeneration: string,\n    pokemonOriginalSpriteSize: number,\n    theme: Theme,\n    themeKind: ColorThemeKind,\n    throwBallWithMouse: boolean,\n  ) {\n    const column = vscode.window.activeTextEditor\n      ? vscode.window.activeTextEditor.viewColumn\n      : undefined;\n    // If we already have a panel, show it.\n    if (PokemonPanel.currentPanel) {\n      if (\n        pokemonColor === PokemonPanel.currentPanel.pokemonColor() &&\n        pokemonType === PokemonPanel.currentPanel.pokemonType() &&\n        pokemonSize === PokemonPanel.currentPanel.pokemonSize() &&\n        pokemonGeneration === PokemonPanel.currentPanel.pokemonGeneration()\n      ) {\n        PokemonPanel.currentPanel._panel.reveal(column);\n        return;\n      } else {\n        PokemonPanel.currentPanel.updatePokemonColor(pokemonColor);\n        PokemonPanel.currentPanel.updatePokemonType(pokemonType);\n        PokemonPanel.currentPanel.updatePokemonSize(pokemonSize);\n        PokemonPanel.currentPanel.update();\n      }\n    }\n\n    // Otherwise, create a new panel.\n    const panel = vscode.window.createWebviewPanel(\n      PokemonPanel.viewType,\n      vscode.l10n.t('Pokemon Panel'),\n      vscode.ViewColumn.Two,\n      getWebviewOptions(extensionUri),\n    );\n\n    PokemonPanel.currentPanel = new PokemonPanel(\n      panel,\n      extensionUri,\n      pokemonColor,\n      pokemonType,\n      pokemonSize,\n      pokemonGeneration,\n      pokemonOriginalSpriteSize,\n      theme,\n      themeKind,\n      throwBallWithMouse,\n    );\n  }\n\n  public resetPokemon() {\n    void this.getWebview().postMessage({ command: 'reset-pokemon' });\n  }\n\n  public listPokemon() {\n    void this.getWebview().postMessage({ command: 'list-pokemon' });\n  }\n\n  public rollCall(): void {\n    void this.getWebview().postMessage({ command: 'roll-call' });\n  }\n\n  public deletePokemon(pokemonName: string): void {\n    void this.getWebview().postMessage({\n      command: 'delete-pokemon',\n      name: pokemonName,\n    });\n  }\n\n  public static revive(\n    panel: vscode.WebviewPanel,\n    extensionUri: vscode.Uri,\n    pokemonColor: PokemonColor,\n    pokemonType: PokemonType,\n    pokemonSize: PokemonSize,\n    pokemonGeneration: string,\n    pokemonOriginalSpriteSize: number,\n    theme: Theme,\n    themeKind: ColorThemeKind,\n    throwBallWithMouse: boolean,\n  ) {\n    PokemonPanel.currentPanel = new PokemonPanel(\n      panel,\n      extensionUri,\n      pokemonColor,\n      pokemonType,\n      pokemonSize,\n      pokemonGeneration,\n      pokemonOriginalSpriteSize,\n      theme,\n      themeKind,\n      throwBallWithMouse,\n    );\n  }\n\n  private constructor(\n    panel: vscode.WebviewPanel,\n    extensionUri: vscode.Uri,\n    color: PokemonColor,\n    type: PokemonType,\n    size: PokemonSize,\n    generation: string,\n    originalSpriteSize: number,\n    theme: Theme,\n    themeKind: ColorThemeKind,\n    throwBallWithMouse: boolean,\n  ) {\n    super(\n      extensionUri,\n      color,\n      type,\n      size,\n      generation,\n      originalSpriteSize,\n      theme,\n      themeKind,\n      throwBallWithMouse,\n    );\n\n    this._panel = panel;\n\n    // Set the webview's initial html content\n    this._update();\n\n    // Listen for when the panel is disposed\n    // This happens when the user closes the panel or when the panel is closed programmatically\n    this._panel.onDidDispose(() => this.dispose(), null, this._disposables);\n\n    // Update the content based on view changes\n    this._panel.onDidChangeViewState(\n      () => {\n        this.update();\n      },\n      null,\n      this._disposables,\n    );\n\n    // Handle messages from the webview\n    this._panel.webview.onDidReceiveMessage(\n      handleWebviewMessage,\n      null,\n      this._disposables,\n    );\n  }\n\n  public dispose() {\n    PokemonPanel.currentPanel = undefined;\n\n    // Clean up our resources\n    this._panel.dispose();\n\n    while (this._disposables.length) {\n      const x = this._disposables.pop();\n      if (x) {\n        x.dispose();\n      }\n    }\n  }\n\n  public update() {\n    if (this._panel.visible) {\n      this._update();\n    }\n  }\n\n  getWebview(): vscode.Webview {\n    return this._panel.webview;\n  }\n}\n\nclass PokemonWebviewViewProvider extends PokemonWebviewContainer {\n  public static readonly viewType = 'pokemonView';\n\n  private _webviewView?: vscode.WebviewView;\n  private _context: vscode.ExtensionContext;\n\n  constructor(\n    context: vscode.ExtensionContext,\n    extensionUri: vscode.Uri,\n    color: PokemonColor,\n    type: PokemonType,\n    size: PokemonSize,\n    generation: string,\n    originalSpriteSize: number,\n    theme: Theme,\n    themeKind: ColorThemeKind,\n    throwBallWithMouse: boolean,\n  ) {\n    super(\n      extensionUri,\n      color,\n      type,\n      size,\n      generation,\n      originalSpriteSize,\n      theme,\n      themeKind,\n      throwBallWithMouse,\n    );\n    this._context = context;\n  }\n\n  async resolveWebviewView(webviewView: vscode.WebviewView): Promise<void> {\n    this._webviewView = webviewView;\n\n    webviewView.webview.options = getWebviewOptions(this._extensionUri);\n    webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);\n\n    webviewView.webview.onDidReceiveMessage(\n      handleWebviewMessage,\n      null,\n      this._disposables,\n    );\n\n    const collection = getDefaultPokemonForFreshSession(this._context);\n    if (shouldSpawnInitialCollection(collection)) {\n      await spawnAndPersistCollection(this._context, this, collection);\n    }\n  }\n\n  update() {\n    this._update();\n  }\n\n  getWebview(): vscode.Webview {\n    if (this._webviewView === undefined) {\n      throw new Error(\n        vscode.l10n.t(\n          'Panel not active, make sure the pokemon view is visible before running this command.',\n        ),\n      );\n    } else {\n      return this._webviewView.webview;\n    }\n  }\n}\n\nfunction getNonce() {\n  let text = '';\n  const possible =\n    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n  for (let i = 0; i < 32; i++) {\n    text += possible.charAt(Math.floor(Math.random() * possible.length));\n  }\n  return text;\n}\n\nasync function createPokemonPlayground(context: vscode.ExtensionContext) {\n  const spec = PokemonSpecification.fromConfiguration();\n  PokemonPanel.createOrShow(\n    context.extensionUri,\n    spec.color,\n    spec.type,\n    spec.size,\n    spec.generation,\n    spec.originalSpriteSize,\n    getConfiguredTheme(),\n    getConfiguredThemeKind(),\n    getThrowWithMouseConfiguration(),\n  );\n  if (PokemonPanel.currentPanel) {\n    var collection = PokemonSpecification.collectionFromMemento(\n      context,\n      getConfiguredSize(),\n    );\n    collection.forEach((item) => {\n      PokemonPanel.currentPanel?.spawnPokemon(item);\n    });\n    await storeCollectionAsMemento(context, collection);\n  } else {\n    var collection = PokemonSpecification.collectionFromMemento(\n      context,\n      getConfiguredSize(),\n    );\n    collection.push(spec);\n    await storeCollectionAsMemento(context, collection);\n  }\n}\n"
  },
  {
    "path": "src/panel/base-pokemon-type.ts",
    "content": "import { POKEMON_DATA } from '../common/pokemon-data';\nimport {\n  PokemonColor,\n  PokemonExtraSprite,\n  PokemonSize,\n  PokemonSpeed,\n} from '../common/types';\nimport { ISequenceTree } from './sequences';\nimport {\n  States,\n  IState,\n  resolveState,\n  PokemonInstanceState,\n  isStateAboveGround,\n  BallState,\n  ChaseState,\n  HorizontalDirection,\n  FrameResult,\n  IPokemonType,\n} from './states';\n\nexport class InvalidStateError extends Error {\n  fromState: States;\n  pokemonType: string;\n\n  constructor(fromState: States, pokemonType: string) {\n    super(`Invalid state ${fromState} for pokemon type ${pokemonType}`);\n    this.fromState = fromState;\n    this.pokemonType = pokemonType;\n  }\n}\n\nexport abstract class BasePokemonType implements IPokemonType {\n  label: string = 'base';\n  static count: number = 0;\n  sequence: ISequenceTree = {\n    startingState: States.sitIdle,\n    sequenceStates: [],\n  };\n  static possibleColors: PokemonColor[];\n  currentState: IState;\n  currentStateEnum: States;\n  holdState: IState | undefined;\n  holdStateEnum: States | undefined;\n  private el: HTMLImageElement;\n  private collision: HTMLDivElement;\n  private speech: HTMLImageElement;\n  private _left: number;\n  private _bottom: number;\n  pokemonRoot: string;\n  _floor: number;\n  _friend: IPokemonType | undefined;\n  private _name: string;\n  private _baseSpeed: number;\n  private _size: PokemonSize;\n  private _generation: string;\n  private _originalSpriteSize: number;\n\n  constructor(\n    spriteElement: HTMLImageElement,\n    collisionElement: HTMLDivElement,\n    speechElement: HTMLImageElement,\n    size: PokemonSize,\n    left: number,\n    bottom: number,\n    pokemonRoot: string,\n    floor: number,\n    name: string,\n    speed: number,\n    generation: string,\n    originalSpriteSize: number,\n  ) {\n    this.el = spriteElement;\n    this.collision = collisionElement;\n    this.speech = speechElement;\n    this.pokemonRoot = pokemonRoot;\n    this._floor = floor;\n    this._left = left;\n    this._bottom = bottom;\n    this._originalSpriteSize = originalSpriteSize;\n    this.initSprite(size, left, bottom, originalSpriteSize);\n    this.currentStateEnum = this.sequence.startingState;\n    this.currentState = resolveState(this.currentStateEnum, this);\n\n    this._name = name;\n    this._size = size;\n    this._baseSpeed = this.randomizeSpeed(speed);\n    this._generation = generation;\n\n    // Increment the static count of the Pokemon class that the constructor belongs to\n    (this.constructor as typeof BasePokemonType).count += 1;\n  }\n\n  initSprite(\n    pokemonSize: PokemonSize,\n    left: number,\n    bottom: number,\n    originalSpriteSize: number,\n  ) {\n    const spriteSize = this.calculateSpriteWidth(\n      pokemonSize,\n      originalSpriteSize,\n    );\n\n    this.el.style.left = `${left}px`;\n    this.el.style.bottom = `${bottom}px`;\n    this.el.style.width = `${spriteSize}px`;\n    this.el.style.height = `${spriteSize}px`;\n\n    // Remove 'auto' since it gave issues with sizing\n    this.el.style.maxWidth = 'none';\n    this.el.style.maxHeight = 'none';\n\n    this.collision.style.left = `${left}px`;\n    this.collision.style.bottom = `${bottom}px`;\n    this.collision.style.width = `${spriteSize}px`;\n    this.collision.style.height = `${spriteSize}px`;\n\n    this.speech.style.left = `${left}px`;\n    this.speech.style.bottom = `${bottom + spriteSize}px`;\n    this.hideSpeechBubble();\n  }\n\n  get left(): number {\n    return this._left;\n  }\n\n  get bottom(): number {\n    return this._bottom;\n  }\n\n  private repositionAccompanyingElements() {\n    this.collision.style.left = `${this._left}px`;\n    this.collision.style.bottom = `${this._bottom}px`;\n    this.speech.style.left = `${this._left}px`;\n    this.speech.style.bottom = `${\n      this._bottom +\n      this.calculateSpriteWidth(this._size, this._originalSpriteSize)\n    }px`;\n  }\n\n  calculateSpriteWidth(size: PokemonSize, originalSpriteSize: number): number {\n    switch (size) {\n      case PokemonSize.nano:\n        return originalSpriteSize;\n      case PokemonSize.small:\n        return originalSpriteSize * 1.5;\n      case PokemonSize.medium:\n        return originalSpriteSize * 2;\n      case PokemonSize.large:\n        return originalSpriteSize * 2.5;\n      default:\n        return originalSpriteSize;\n    }\n  }\n\n  positionBottom(bottom: number): void {\n    this._bottom = bottom;\n    this.el.style.bottom = `${this._bottom}px`;\n    this.repositionAccompanyingElements();\n  }\n\n  positionLeft(left: number): void {\n    this._left = left;\n    this.el.style.left = `${this._left}px`;\n    this.repositionAccompanyingElements();\n  }\n\n  get width(): number {\n    return this.el.width;\n  }\n\n  get floor(): number {\n    return this._floor;\n  }\n\n  get hello(): string {\n    // return the sound of the name of the animal\n    return ` says hello 👋!`;\n  }\n\n  getState(): PokemonInstanceState {\n    return { currentStateEnum: this.currentStateEnum };\n  }\n\n  get speed(): number {\n    const base = this._baseSpeed ?? 0;\n    switch (this._size) {\n      case PokemonSize.nano:\n        return base * 0.5; // much slower for nano\n      case PokemonSize.small:\n        return base * 0.75; // slower for small\n      case PokemonSize.medium:\n        return base * 1.0; // baseline\n      case PokemonSize.large:\n        return base * 1.25; // slightly faster for large\n      default:\n        return base;\n    }\n  }\n\n  randomizeSpeed(speed: number): number {\n    const min = speed * 0.7;\n    const max = speed * 1.3;\n    const newSpeed = Math.random() * (max - min) + min;\n    return newSpeed;\n  }\n\n  get isMoving(): boolean {\n    return this._baseSpeed !== PokemonSpeed.still;\n  }\n\n  recoverFriend(friend: IPokemonType) {\n    // Recover friends..\n    this._friend = friend;\n  }\n\n  recoverState(state: PokemonInstanceState) {\n    // TODO : Resolve a bug where if it was swiping before, it would fail\n    // because holdState is no longer valid.\n    this.currentStateEnum = state.currentStateEnum ?? States.sitIdle;\n    this.currentState = resolveState(this.currentStateEnum, this);\n\n    if (!isStateAboveGround(this.currentStateEnum)) {\n      // Reset the bottom of the sprite to the floor as the theme\n      // has likely changed.\n      this.positionBottom(this.floor);\n    }\n  }\n\n  get canSwipe() {\n    return !isStateAboveGround(this.currentStateEnum);\n  }\n\n  get canChase() {\n    return !isStateAboveGround(this.currentStateEnum) && this.isMoving;\n  }\n\n  showSpeechBubble(duration: number = 3000, friend: boolean = false) {\n    // Extract the media folder\n    const segments = this.pokemonRoot.split('/');\n    const basePath = segments.slice(0, segments.length - 3).join('/');\n\n    if (friend) {\n      this.speech.src = `${basePath}/heart.png`;\n    } else {\n      this.speech.src = `${basePath}/happy.png`;\n    }\n\n    this.speech.style.display = 'block';\n    setTimeout(() => {\n      this.hideSpeechBubble();\n    }, duration);\n  }\n\n  hideSpeechBubble() {\n    this.speech.style.display = 'none';\n  }\n\n  swipe() {\n    if (this.currentStateEnum === States.swipe) {\n      return;\n    }\n    this.holdState = this.currentState;\n    this.holdStateEnum = this.currentStateEnum;\n    this.currentStateEnum = States.swipe;\n    this.currentState = resolveState(this.currentStateEnum, this);\n    this.showSpeechBubble();\n  }\n\n  chase(ballState: BallState, canvas: HTMLCanvasElement) {\n    this.currentStateEnum = States.chase;\n    this.currentState = new ChaseState(this, ballState, canvas);\n  }\n\n  faceLeft() {\n    this.el.style.transform = 'scaleX(-1)';\n  }\n\n  faceRight() {\n    this.el.style.transform = 'scaleX(1)';\n  }\n\n  setAnimation(face: string, hasLeftFacingSprite: boolean | undefined) {\n    const validFace =\n      !hasLeftFacingSprite && face === 'walk_left' ? 'walk' : face;\n\n    if (this.el.src.endsWith(`_${validFace}_8fps.gif`)) {\n      return;\n    }\n    this.el.src = `${this.pokemonRoot}_${validFace}_8fps.gif`;\n  }\n\n  chooseNextState(fromState: States): States {\n    // Work out next state\n    var possibleNextStates: States[] | undefined = undefined;\n    for (var i = 0; i < this.sequence.sequenceStates.length; i++) {\n      if (this.sequence.sequenceStates[i].state === fromState) {\n        possibleNextStates = this.sequence.sequenceStates[i].possibleNextStates;\n      }\n    }\n    if (!possibleNextStates) {\n      throw new InvalidStateError(fromState, this.label);\n    }\n    // randomly choose the next state\n    const idx = Math.floor(Math.random() * possibleNextStates.length);\n    return possibleNextStates[idx];\n  }\n\n  nextFrame() {\n    const hasLeftFacingSprite = POKEMON_DATA[\n      this.label\n    ]?.extraSprites?.includes(PokemonExtraSprite.leftFacing);\n\n    if (!hasLeftFacingSprite) {\n      if (this.currentState.horizontalDirection === HorizontalDirection.left) {\n        this.faceLeft();\n      } else if (\n        this.currentState.horizontalDirection === HorizontalDirection.right\n      ) {\n        this.faceRight();\n      }\n    } else {\n      this.faceRight();\n    }\n    this.setAnimation(this.currentState.spriteLabel, hasLeftFacingSprite);\n\n    // What's my buddy doing?\n    if (\n      this.hasFriend &&\n      this.currentStateEnum !== States.chaseFriend &&\n      this.isMoving\n    ) {\n      if (\n        this.friend?.isPlaying &&\n        !isStateAboveGround(this.currentStateEnum)\n      ) {\n        this.currentState = resolveState(States.chaseFriend, this);\n        this.currentStateEnum = States.chaseFriend;\n        return;\n      }\n    }\n\n    var frameResult = this.currentState.nextFrame();\n    if (frameResult === FrameResult.stateComplete) {\n      // If recovering from swipe..\n      if (this.holdState && this.holdStateEnum) {\n        this.currentState = this.holdState;\n        this.currentStateEnum = this.holdStateEnum;\n        this.holdState = undefined;\n        this.holdStateEnum = undefined;\n        return;\n      }\n\n      var nextState = this.chooseNextState(this.currentStateEnum);\n      this.currentState = resolveState(nextState, this);\n      this.currentStateEnum = nextState;\n    } else if (frameResult === FrameResult.stateCancel) {\n      if (this.currentStateEnum === States.chase) {\n        var nextState = this.chooseNextState(States.idleWithBall);\n        this.currentState = resolveState(nextState, this);\n        this.currentStateEnum = nextState;\n      } else if (this.currentStateEnum === States.chaseFriend) {\n        var nextState = this.chooseNextState(States.idleWithBall);\n        this.currentState = resolveState(nextState, this);\n        this.currentStateEnum = nextState;\n      }\n    }\n  }\n\n  get hasFriend(): boolean {\n    return this._friend !== undefined;\n  }\n\n  get friend(): IPokemonType | undefined {\n    return this._friend;\n  }\n\n  get name(): string {\n    return this._name;\n  }\n\n  makeFriendsWith(friend: IPokemonType): boolean {\n    this._friend = friend;\n    console.log(this.name, \": I'm now friends ❤️ with \", friend.name);\n    return true;\n  }\n\n  get isPlaying(): boolean {\n    return (\n      this.isMoving &&\n      (this.currentStateEnum === States.runRight ||\n        this.currentStateEnum === States.runLeft)\n    );\n  }\n\n  get emoji(): string {\n    return '🐶';\n  }\n}\n"
  },
  {
    "path": "src/panel/main.ts",
    "content": "// This script will be run within the webview itself\nimport { randomName } from '../common/names';\nimport {\n  PokemonSize,\n  PokemonColor,\n  PokemonType,\n  Theme,\n  ColorThemeKind,\n  WebviewMessage,\n} from '../common/types';\nimport { IPokemonType } from './states';\nimport {\n  createPokemon,\n  PokemonCollection,\n  PokemonElement,\n  IPokemonCollection,\n  availableColors,\n  InvalidPokemonException,\n} from './pokemon-collection';\nimport { PokemonElementState, PokemonPanelState } from './states';\nimport { getRandomPokemonConfig } from '../common/pokemon-data';\n\n/* This is how the VS Code API can be invoked from the panel */\ndeclare global {\n  interface VscodeStateApi {\n    getState(): PokemonPanelState | undefined; // API is actually Any, but we want it to be typed.\n    setState(state: PokemonPanelState): void;\n    postMessage(message: WebviewMessage): void;\n  }\n  function acquireVsCodeApi(): VscodeStateApi;\n}\n\nexport var allPokemon: IPokemonCollection = new PokemonCollection();\nvar pokemonCounter: number;\n\nfunction normalizePokemonCounter(counter: number | undefined): number {\n  if (counter === undefined || Number.isNaN(counter)) {\n    return 0;\n  }\n\n  return Math.max(0, counter);\n}\n\nfunction calculateFloor(size: PokemonSize, theme: Theme): number {\n  switch (theme) {\n    case Theme.forest:\n      switch (size) {\n        case PokemonSize.small:\n          return 30;\n        case PokemonSize.medium:\n          return 40;\n        case PokemonSize.large:\n          return 65;\n        case PokemonSize.nano:\n        default:\n          return 23;\n      }\n    case Theme.castle:\n      switch (size) {\n        case PokemonSize.small:\n          return 60;\n        case PokemonSize.medium:\n          return 80;\n        case PokemonSize.large:\n          return 120;\n        case PokemonSize.nano:\n        default:\n          return 45;\n      }\n    case Theme.beach:\n      switch (size) {\n        case PokemonSize.small:\n          return 60;\n        case PokemonSize.medium:\n          return 80;\n        case PokemonSize.large:\n          return 120;\n        case PokemonSize.nano:\n        default:\n          return 45;\n      }\n  }\n  return 0;\n}\n\nfunction handleMouseOver(e: MouseEvent) {\n  var el = e.currentTarget as HTMLDivElement;\n  allPokemon.pokemonCollection.forEach((element) => {\n    if (element.collision === el) {\n      if (!element.pokemon.canSwipe) {\n        return;\n      }\n      element.pokemon.swipe();\n    }\n  });\n}\n\nfunction startAnimations(\n  collision: HTMLDivElement,\n  pokemon: IPokemonType,\n  stateApi?: VscodeStateApi,\n) {\n  if (!stateApi) {\n    stateApi = acquireVsCodeApi();\n  }\n\n  collision.addEventListener('mouseover', handleMouseOver);\n  setInterval(() => {\n    var updates = allPokemon.seekNewFriends();\n    updates.forEach((message) => {\n      stateApi?.postMessage({\n        text: message,\n        command: 'info',\n      });\n    });\n    pokemon.nextFrame();\n    saveState(stateApi);\n  }, 100);\n}\n\nfunction addPokemonToPanel(\n  pokemonType: PokemonType,\n  basePokemonUri: string,\n  gen: string,\n  originalSpriteSize: number,\n  pokemonColor: PokemonColor,\n  pokemonSize: PokemonSize,\n  left: number,\n  bottom: number,\n  floor: number,\n  name: string,\n  stateApi?: VscodeStateApi,\n  incrementCounter: boolean = true,\n): PokemonElement {\n  var pokemonSpriteElement: HTMLImageElement = document.createElement('img');\n  pokemonSpriteElement.className = 'pokemon';\n  (document.getElementById('pokemonContainer') as HTMLDivElement).appendChild(\n    pokemonSpriteElement,\n  );\n\n  var collisionElement: HTMLDivElement = document.createElement('div');\n  collisionElement.className = 'collision';\n  (document.getElementById('pokemonContainer') as HTMLDivElement).appendChild(\n    collisionElement,\n  );\n\n  var speechBubbleElement: HTMLImageElement = document.createElement('img');\n  speechBubbleElement.className = `bubble bubble-${pokemonSize} b-${originalSpriteSize}`;\n  speechBubbleElement.src = `${basePokemonUri}/heart.png`;\n  (document.getElementById('pokemonContainer') as HTMLDivElement).appendChild(\n    speechBubbleElement,\n  );\n\n  const root = `${basePokemonUri}/${gen}/${pokemonType}/${pokemonColor}`;\n  console.log(\n    'Creating new pokemon : ',\n    pokemonType,\n    root,\n    pokemonColor,\n    pokemonSize,\n    name,\n    originalSpriteSize,\n  );\n  try {\n    if (!availableColors(pokemonType).includes(pokemonColor)) {\n      throw new InvalidPokemonException('Invalid color for pokemon type');\n    }\n    var newPokemon = createPokemon(\n      pokemonType,\n      pokemonSpriteElement,\n      collisionElement,\n      speechBubbleElement,\n      pokemonSize,\n      left,\n      bottom,\n      root,\n      floor,\n      name,\n      gen,\n      originalSpriteSize,\n    );\n    if (incrementCounter) {\n      pokemonCounter++;\n    }\n    startAnimations(collisionElement, newPokemon, stateApi);\n  } catch (e: unknown) {\n    // Remove elements\n    pokemonSpriteElement.remove();\n    collisionElement.remove();\n    speechBubbleElement.remove();\n    throw e;\n  }\n\n  pokemonSpriteElement.style.opacity = '0';\n\n  const pokeballEl = document.createElement('div');\n  pokeballEl.classList.add('pokeball-sprite');\n\n  // Position pokeball at pokemon location + pokemon center offset\n  pokeballEl.style.left = `${left}px`;\n  pokeballEl.style.bottom = `${bottom}px`;\n\n  (document.getElementById('pokemonContainer') as HTMLDivElement).appendChild(\n    pokeballEl,\n  );\n\n  pokeballEl.offsetHeight;\n  pokeballEl.classList.add('pokeball-open');\n\n  // show pokemon earlier while pokeball animation is still running\n  const computed = window.getComputedStyle(pokeballEl);\n  const durationStr = (computed.animationDuration || '0s').split(',')[0].trim();\n  const durationMs = durationStr.endsWith('ms')\n    ? parseFloat(durationStr)\n    : parseFloat(durationStr) * 1000;\n\n  const spawnRatio = 0.7;\n  const spawnDelay = Math.max(0, durationMs * spawnRatio);\n\n  let spawned = false;\n  const showPokemon = () => {\n    if (spawned) {\n      return;\n    }\n    spawned = true;\n    pokemonSpriteElement.classList.add('spawn-pop');\n    pokemonSpriteElement.style.opacity = '1';\n\n    if (pokemonColor === PokemonColor.shiny) {\n      const shinyOverlay = document.createElement('img');\n      shinyOverlay.src = `${basePokemonUri}/shiny-anim.gif?t=${Date.now()}`;\n      shinyOverlay.className = 'shiny-overlay';\n      shinyOverlay.style.left = pokemonSpriteElement.style.left;\n      shinyOverlay.style.bottom = pokemonSpriteElement.style.bottom;\n      shinyOverlay.style.width = pokemonSpriteElement.style.width;\n      shinyOverlay.style.height = pokemonSpriteElement.style.height;\n      (\n        document.getElementById('pokemonContainer') as HTMLDivElement\n      ).appendChild(shinyOverlay);\n      const removeOverlay = () => shinyOverlay.remove();\n      shinyOverlay.addEventListener('animationend', removeOverlay);\n      setTimeout(removeOverlay, 1500);\n    }\n\n    saveState(stateApi);\n  };\n\n  const spawnTimeout = setTimeout(showPokemon, spawnDelay);\n\n  pokeballEl.addEventListener('animationend', (e) => {\n    if (e.animationName !== 'pokeball-open') {\n      return;\n    }\n    pokeballEl.remove();\n    clearTimeout(spawnTimeout);\n    showPokemon();\n  });\n\n  return new PokemonElement(\n    pokemonSpriteElement,\n    collisionElement,\n    speechBubbleElement,\n    newPokemon,\n    pokemonColor,\n    pokemonType,\n    gen,\n    originalSpriteSize,\n  );\n}\n\nfunction removePokemonFromPanel(\n  message: { name: string },\n  stateApi?: VscodeStateApi,\n) {\n  if (!stateApi) {\n    stateApi = acquireVsCodeApi();\n  }\n  // Remove elements\n  var pokemon = allPokemon.locate(message.name);\n\n  if (!pokemon) {\n    stateApi?.postMessage({\n      command: 'error',\n      text: `Could not find pokemon ${message.name}`,\n    });\n    return;\n  }\n\n  var pokemonSpriteElement = pokemon.el;\n  console.log('Removing pokemon ', message.name);\n  console.log('pokemon:', pokemon);\n\n  // Remove from collection immediately so rapid deletes of Pokemon don't interfere with each other\n  allPokemon.removeFromCollection(message.name);\n  pokemon.collision.remove();\n  pokemon.speech.remove();\n  pokemonCounter = normalizePokemonCounter(pokemonCounter - 1);\n  saveState(stateApi);\n\n  stateApi?.postMessage({\n    command: 'info',\n    text: '👋 Removed pokemon ' + message.name,\n  });\n\n  // pokemon fade out\n  pokemonSpriteElement.classList.add('fade-out');\n\n  const pokeballEl = document.createElement('div');\n  pokeballEl.classList.add('pokeball-sprite');\n\n  pokeballEl.style.left = `${pokemon.pokemon.left}px`;\n  pokeballEl.style.bottom = `${pokemon.pokemon.bottom}px`;\n\n  const container = document.getElementById(\n    'pokemonContainer',\n  ) as HTMLDivElement;\n  container.appendChild(pokeballEl);\n\n  pokeballEl.offsetHeight;\n  pokeballEl.classList.add('pokeball-close');\n\n  pokemonSpriteElement.addEventListener(\n    'animationend',\n    (e) => {\n      if (e.animationName !== 'pokemon-fade-out') {\n        return;\n      }\n      pokemonSpriteElement.remove();\n    },\n    { once: true },\n  );\n\n  pokeballEl.addEventListener(\n    'animationend',\n    (e) => {\n      if (e.animationName !== 'pokeball-close') {\n        return;\n      }\n      pokeballEl.remove();\n    },\n    { once: true },\n  );\n}\n\nexport function saveState(stateApi?: VscodeStateApi) {\n  if (!stateApi) {\n    stateApi = acquireVsCodeApi();\n  }\n  var state = new PokemonPanelState();\n  state.pokemonStates = [];\n\n  allPokemon.pokemonCollection.forEach((pokemonItem) => {\n    state.pokemonStates?.push({\n      pokemonName: pokemonItem.pokemon.name,\n      pokemonColor: pokemonItem.color,\n      pokemonType: pokemonItem.type,\n      pokemonState: pokemonItem.pokemon.getState(),\n      pokemonGeneration: pokemonItem.generation,\n      originalSpriteSize: pokemonItem.originalSpriteSize,\n      pokemonFriend: pokemonItem.pokemon.friend?.name ?? undefined,\n      elLeft: pokemonItem.el.style.left,\n      elBottom: pokemonItem.el.style.bottom,\n    });\n  });\n  state.pokemonCounter = normalizePokemonCounter(pokemonCounter);\n  stateApi?.setState(state);\n}\n\nfunction recoverState(\n  basePokemonUri: string,\n  gen: string,\n  pokemonSize: PokemonSize,\n  floor: number,\n  stateApi?: VscodeStateApi,\n) {\n  if (!stateApi) {\n    stateApi = acquireVsCodeApi();\n  }\n  var state = stateApi?.getState();\n  if (!state) {\n    pokemonCounter = 0;\n  } else {\n    pokemonCounter = normalizePokemonCounter(state.pokemonCounter);\n  }\n\n  var recoveryMap: Map<IPokemonType, PokemonElementState> = new Map();\n  console.log(\n    'recoverState: saved pokemon count =',\n    state?.pokemonStates?.length ?? 0,\n  );\n  state?.pokemonStates?.forEach((p) => {\n    console.log('Recovering pokemon ', p.pokemonType, p.pokemonName);\n    try {\n      console.log('Adding pokemon to panel for recovery');\n      var newPokemon = addPokemonToPanel(\n        p.pokemonType ?? 'bulbasaur',\n        basePokemonUri,\n        p.pokemonGeneration ?? 'gen1',\n        p.originalSpriteSize ?? 32,\n        p.pokemonColor ?? PokemonColor.default,\n        pokemonSize,\n        parseInt(p.elLeft ?? '0'),\n        parseInt(p.elBottom ?? '0'),\n        floor,\n        p.pokemonName ?? randomName(),\n        stateApi,\n        false,\n      );\n      allPokemon.push(newPokemon);\n      recoveryMap.set(newPokemon.pokemon, p);\n    } catch (InvalidPokemonException) {\n      console.log(\n        'State had invalid pokemon (' + p.pokemonType + '), discarding.',\n      );\n    }\n  });\n  recoveryMap.forEach((state, pokemon) => {\n    // Recover previous state.\n    if (state.pokemonState !== undefined) {\n      pokemon.recoverState(state.pokemonState);\n    }\n\n    // Resolve friend relationships\n    var friend = undefined;\n    if (state.pokemonFriend) {\n      friend = allPokemon.locate(state.pokemonFriend);\n      if (friend) {\n        pokemon.recoverFriend(friend.pokemon);\n      }\n    }\n  });\n}\n\nfunction randomStartPosition(): number {\n  return Math.floor(Math.random() * (window.innerWidth * 0.7));\n}\n\nlet canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D;\n\nfunction initCanvas() {\n  canvas = document.getElementById('pokemonCanvas') as HTMLCanvasElement;\n  if (!canvas) {\n    console.log('Canvas not ready');\n    return;\n  }\n  ctx = canvas.getContext('2d') as CanvasRenderingContext2D;\n  if (!ctx) {\n    console.log('Canvas context not ready');\n    return;\n  }\n  ctx.canvas.width = window.innerWidth;\n  ctx.canvas.height = window.innerHeight;\n}\n\n// It cannot access the main VS Code APIs directly.\nexport function pokemonPanelApp(\n  basePokemonUri: string,\n  theme: Theme,\n  themeKind: ColorThemeKind,\n  pokemonColor: PokemonColor,\n  pokemonSize: PokemonSize,\n  pokemonType: PokemonType,\n  throwBallWithMouse: boolean,\n  gen: string,\n  originalSpriteSize: number,\n  stateApi?: VscodeStateApi,\n) {\n  var floor = 0;\n  if (!stateApi) {\n    stateApi = acquireVsCodeApi();\n  }\n  // Apply Theme backgrounds\n  const foregroundEl = document.getElementById('foreground');\n  if (theme !== Theme.none) {\n    var _themeKind = '';\n    switch (themeKind) {\n      case ColorThemeKind.dark:\n        _themeKind = 'dark';\n        break;\n      case ColorThemeKind.light:\n        _themeKind = 'light';\n        break;\n      case ColorThemeKind.highContrast:\n      default:\n        _themeKind = 'light';\n        break;\n    }\n\n    document.body.style.backgroundImage = `url('${basePokemonUri}/backgrounds/${theme}/background-${_themeKind}-${pokemonSize}.png')`;\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    foregroundEl!.style.backgroundImage = `url('${basePokemonUri}/backgrounds/${theme}/foreground-${_themeKind}-${pokemonSize}.png')`;\n\n    floor = calculateFloor(pokemonSize, theme); // Themes have pokemonCollection at a specified height from the ground\n  } else {\n    document.body.style.backgroundImage = '';\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    foregroundEl!.style.backgroundImage = '';\n  }\n\n  console.log(\n    'Starting pokemon session',\n    pokemonColor,\n    basePokemonUri,\n    pokemonType,\n    throwBallWithMouse,\n  );\n\n  // New session\n  var state = stateApi?.getState();\n\n  const hasRecoverableState =\n    state !== undefined &&\n    Array.isArray(state.pokemonStates) &&\n    state.pokemonStates.length > 0;\n\n  if (hasRecoverableState) {\n    console.log('Recovering state - ', state);\n    recoverState(basePokemonUri, gen, pokemonSize, floor, stateApi);\n  } else {\n    console.log('No recoverable pokemon state, starting an empty session.');\n    pokemonCounter = normalizePokemonCounter(state?.pokemonCounter);\n    saveState(stateApi);\n  }\n\n  initCanvas();\n\n  // Handle messages sent from the extension to the webview\n  window.addEventListener('message', (event): void => {\n    const message = event.data; // The json data that the extension sent\n    console.log('Received message in panel:', message);\n    switch (message.command) {\n      case 'spawn-pokemon':\n        console.log('adding pokemon to panel from message', message);\n        allPokemon.push(\n          addPokemonToPanel(\n            message.type,\n            basePokemonUri,\n            message.generation,\n            message.originalSpriteSize,\n            message.color,\n            pokemonSize,\n            randomStartPosition(),\n            floor,\n            floor,\n            message.name ?? randomName(),\n            stateApi,\n          ),\n        );\n        saveState(stateApi);\n        break;\n\n      case 'spawn-random-pokemon':\n        var [randomPokemonType, randomPokemonConfig] = getRandomPokemonConfig();\n        console.log('adding random pokemon to panel from message');\n        allPokemon.push(\n          addPokemonToPanel(\n            randomPokemonType,\n            basePokemonUri,\n            randomPokemonConfig.generation.toString(),\n            randomPokemonConfig.originalSpriteSize ?? 32,\n            PokemonColor.default,\n            pokemonSize,\n            randomStartPosition(),\n            floor,\n            floor,\n            randomName(),\n            stateApi,\n          ),\n        );\n        saveState(stateApi);\n        break;\n\n      case 'list-pokemon':\n        var pokemonCollection = allPokemon.pokemonCollection;\n        stateApi?.postMessage({\n          command: 'list-pokemon',\n          text: pokemonCollection\n            .map(\n              (pokemon) =>\n                `${pokemon.type},${pokemon.pokemon.name},${pokemon.color}`,\n            )\n            .join('\\n'),\n        });\n        break;\n\n      case 'roll-call':\n        var pokemonCollection = allPokemon.pokemonCollection;\n        // go through every single\n        // pokemon and then print out their name\n        pokemonCollection.forEach((pokemon) => {\n          stateApi?.postMessage({\n            command: 'info',\n            text: `${pokemon.pokemon.emoji} ${pokemon.pokemon.name} (${pokemon.color} ${pokemon.type}): ${pokemon.pokemon.hello}`,\n          });\n        });\n        break;\n      case 'delete-pokemon':\n        removePokemonFromPanel(message, stateApi);\n        break;\n      case 'reset-pokemon':\n        var pokemonToRemove = [...allPokemon.pokemonCollection];\n        pokemonToRemove.forEach((pokemon) => {\n          removePokemonFromPanel({ name: pokemon.pokemon.name }, stateApi);\n        });\n        // Wait for animations to complete before resetting\n        setTimeout(() => {\n          allPokemon.reset();\n          pokemonCounter = 0;\n          saveState(stateApi);\n        }, 500);\n        break;\n      case 'pause-pokemon':\n        pokemonCounter = 1;\n        saveState(stateApi);\n        break;\n    }\n  });\n}\nwindow.addEventListener('resize', function () {\n  initCanvas();\n});\n"
  },
  {
    "path": "src/panel/pokemon-collection.ts",
    "content": "import {\n  PokemonColor,\n  PokemonSize,\n  PokemonSpeed,\n  PokemonType,\n} from '../common/types';\nimport { Pokemon } from './pokemon';\nimport { IPokemonType } from './states';\n\nexport class PokemonElement {\n  el: HTMLImageElement;\n  collision: HTMLDivElement;\n  speech: HTMLDivElement;\n  pokemon: IPokemonType;\n  color: PokemonColor;\n  type: PokemonType;\n  generation: string;\n  originalSpriteSize: number;\n  remove() {\n    this.el.remove();\n    this.collision.remove();\n    this.speech.remove();\n    this.color = PokemonColor.null;\n  }\n\n  constructor(\n    el: HTMLImageElement,\n    collision: HTMLDivElement,\n    speech: HTMLDivElement,\n    pokemon: IPokemonType,\n    color: PokemonColor,\n    type: PokemonType,\n    generation: string,\n    originalSpriteSize: number,\n  ) {\n    this.el = el;\n    this.collision = collision;\n    this.speech = speech;\n    this.pokemon = pokemon;\n    this.color = color;\n    this.type = type;\n    this.generation = generation;\n    this.originalSpriteSize = originalSpriteSize;\n  }\n}\n\nexport interface IPokemonCollection {\n  pokemonCollection: Array<PokemonElement>;\n  push(pokemon: PokemonElement): void;\n  reset(): void;\n  seekNewFriends(): string[];\n  locate(name: string): PokemonElement | undefined;\n  remove(name: string): void;\n  removeFromCollection(name: string): void;\n}\n\nexport class PokemonCollection implements IPokemonCollection {\n  private _pokemonCollection: Array<PokemonElement>;\n\n  constructor() {\n    this._pokemonCollection = new Array(0);\n  }\n\n  public get pokemonCollection() {\n    return this._pokemonCollection;\n  }\n\n  push(pokemon: PokemonElement) {\n    this._pokemonCollection.push(pokemon);\n  }\n\n  reset() {\n    this._pokemonCollection.forEach((pokemon) => {\n      pokemon.remove();\n    });\n    this._pokemonCollection = [];\n  }\n\n  locate(name: string): PokemonElement | undefined {\n    return this._pokemonCollection.find((collection) => {\n      return collection.pokemon.name === name;\n    });\n  }\n\n  remove(name: string): any {\n    const idx = this._pokemonCollection.findIndex(\n      (pokemon) => pokemon.pokemon.name === name,\n    );\n    if (idx === -1) {\n      return;\n    }\n    this._pokemonCollection[idx].remove();\n    this._pokemonCollection.splice(idx, 1);\n  }\n\n  removeFromCollection(name: string): void {\n    const idx = this._pokemonCollection.findIndex(\n      (pokemon) => pokemon.pokemon.name === name,\n    );\n    if (idx === -1) {\n      return;\n    }\n    this._pokemonCollection.splice(idx, 1);\n  }\n\n  seekNewFriends(): string[] {\n    if (this._pokemonCollection.length <= 1) {\n      return [];\n    } // You can't be friends with yourself.\n    var messages = new Array<string>(0);\n    this._pokemonCollection.forEach((pokemonInCollection) => {\n      if (pokemonInCollection.pokemon.hasFriend) {\n        return;\n      } // I already have a friend!\n      this._pokemonCollection.forEach((potentialFriend) => {\n        if (potentialFriend.pokemon.hasFriend) {\n          return;\n        } // Already has a friend. sorry.\n        if (!potentialFriend.pokemon.canChase) {\n          return;\n        } // Pokemon is busy doing something else.\n        if (\n          potentialFriend.pokemon.left > pokemonInCollection.pokemon.left &&\n          potentialFriend.pokemon.left <\n            pokemonInCollection.pokemon.left + pokemonInCollection.pokemon.width\n        ) {\n          // We found a possible new friend..\n          console.log(\n            pokemonInCollection.pokemon.name,\n            ' wants to be friends with ',\n            potentialFriend.pokemon.name,\n            '.',\n          );\n          if (\n            pokemonInCollection.pokemon.makeFriendsWith(potentialFriend.pokemon)\n          ) {\n            potentialFriend.pokemon.showSpeechBubble(2000, true);\n            pokemonInCollection.pokemon.showSpeechBubble(2000, true);\n          }\n        }\n      });\n    });\n    return messages;\n  }\n}\n\nexport class InvalidPokemonException {\n  message?: string;\n\n  constructor(message?: string) {\n    this.message = message;\n  }\n}\n\nexport function createPokemon(\n  pokemonType: string,\n  el: HTMLImageElement,\n  collision: HTMLDivElement,\n  speech: HTMLImageElement,\n  size: PokemonSize,\n  left: number,\n  bottom: number,\n  pokemonRoot: string,\n  floor: number,\n  name: string,\n  generation: string,\n  originalSpriteSize: number,\n): IPokemonType {\n  if (!name) {\n    throw new InvalidPokemonException('name is undefined');\n  }\n\n  try {\n    return new Pokemon(\n      pokemonType,\n      el,\n      collision,\n      speech,\n      size,\n      left,\n      bottom,\n      pokemonRoot,\n      floor,\n      name,\n      PokemonSpeed.normal,\n      generation,\n      originalSpriteSize,\n    );\n  } catch (error) {\n    throw new InvalidPokemonException(`Invalid Pokemon type: ${pokemonType}`);\n  }\n}\n\nexport function availableColors(pokemonType: PokemonType): PokemonColor[] {\n  const pokemon = Pokemon.getPokemonData(pokemonType);\n  return pokemon ? pokemon.possibleColors : [PokemonColor.default];\n}\n\nexport function normalizeColor(\n  pokemonColor: PokemonColor,\n  pokemonType: PokemonType,\n): PokemonColor {\n  const colors = availableColors(pokemonType);\n  return colors.includes(pokemonColor) ? pokemonColor : colors[0];\n}\n"
  },
  {
    "path": "src/panel/pokemon.ts",
    "content": "import { POKEMON_DATA } from '../common/pokemon-data';\nimport {\n  PokemonColor,\n  PokemonConfig,\n  PokemonGeneration,\n  PokemonSize,\n} from '../common/types';\nimport { BasePokemonType } from './base-pokemon-type';\nimport { States } from './states';\n\nexport class Pokemon extends BasePokemonType {\n  private config: PokemonConfig;\n\n  constructor(\n    pokemonType: string,\n    spriteElement: HTMLImageElement,\n    collisionElement: HTMLDivElement,\n    speechElement: HTMLImageElement,\n    size: PokemonSize,\n    left: number,\n    bottom: number,\n    pokemonRoot: string,\n    floor: number,\n    name: string,\n    speed: number,\n    generation: string,\n    originalSpriteSize: number,\n  ) {\n    super(\n      spriteElement,\n      collisionElement,\n      speechElement,\n      size,\n      left,\n      bottom,\n      pokemonRoot,\n      floor,\n      name,\n      speed,\n      generation,\n      originalSpriteSize,\n    );\n\n    this.config = POKEMON_DATA[pokemonType] || POKEMON_DATA.bulbasaur;\n    this.label = pokemonType;\n  }\n\n  static possibleColors = [PokemonColor.default];\n\n  sequence = {\n    startingState: States.sitIdle,\n    sequenceStates: [\n      {\n        state: States.sitIdle,\n        possibleNextStates: [States.walkLeft, States.walkRight],\n      },\n      {\n        state: States.walkLeft,\n        possibleNextStates: [States.sitIdle, States.walkRight],\n      },\n      {\n        state: States.walkRight,\n        possibleNextStates: [States.sitIdle, States.walkLeft],\n      },\n      {\n        state: States.swipe,\n        possibleNextStates: [States.sitIdle],\n      },\n    ],\n  };\n\n  get generation(): PokemonGeneration {\n    return this.config.generation;\n  }\n\n  get pokedexNumber(): number {\n    return this.config.id;\n  }\n\n  showSpeechBubble(duration: number = 3000, friend: boolean) {\n    super.showSpeechBubble(duration, friend);\n  }\n\n  static getPokemonData(type: string): PokemonConfig | undefined {\n    return POKEMON_DATA[type];\n  }\n}\n\nexport const POKEMON_NAMES: ReadonlyArray<string> = [\n  'Bella',\n  'Charlie',\n  'Molly',\n  'Coco',\n  'Ruby',\n  'Oscar',\n  'Lucy',\n  'Bailey',\n  'Milo',\n  'Daisy',\n  'Archie',\n  'Ollie',\n  'Rosie',\n  'Lola',\n  'Frankie',\n  'Roxy',\n  'Poppy',\n  'Luna',\n  'Jack',\n  'Millie',\n  'Teddy',\n  'Cooper',\n  'Bear',\n  'Rocky',\n  'Alfie',\n  'Hugo',\n  'Bonnie',\n  'Pepper',\n  'Lily',\n  'Tilly',\n  'Leo',\n  'Maggie',\n  'George',\n  'Mia',\n  'Marley',\n  'Harley',\n  'Chloe',\n  'Lulu',\n  'Missy',\n  'Jasper',\n  'Billy',\n  'Nala',\n  'Monty',\n  'Ziggy',\n  'Winston',\n  'Zeus',\n  'Zoe',\n  'Stella',\n  'Sasha',\n  'Rusty',\n  'Gus',\n  'Baxter',\n  'Dexter',\n  'Willow',\n  'Barney',\n  'Bruno',\n  'Penny',\n  'Honey',\n  'Milly',\n  'Murphy',\n  'Simba',\n  'Holly',\n  'Benji',\n  'Henry',\n  'Lilly',\n  'Pippa',\n  'Shadow',\n  'Sam',\n  'Lucky',\n  'Ellie',\n  'Duke',\n  'Jessie',\n  'Cookie',\n  'Harvey',\n  'Bruce',\n  'Jax',\n  'Rex',\n  'Louie',\n  'Jet',\n  'Banjo',\n];\n"
  },
  {
    "path": "src/panel/sequences.ts",
    "content": "import { States } from './states';\n\nexport interface ISequenceNode {\n  state: States;\n  possibleNextStates: States[];\n}\n\nexport interface ISequenceTree {\n  startingState: States;\n  sequenceStates: ISequenceNode[];\n}\n"
  },
  {
    "path": "src/panel/states.ts",
    "content": "import { PokemonColor, PokemonType } from '../common/types';\n\nexport interface IPokemonType {\n  nextFrame(): void;\n\n  // Special methods for actions\n  canSwipe: boolean;\n  canChase: boolean;\n  swipe(): void;\n  chase(ballState: BallState, canvas: HTMLCanvasElement): void;\n  speed: number;\n  isMoving: boolean;\n  hello: string;\n\n  // State API\n  getState(): PokemonInstanceState;\n  recoverState(state: PokemonInstanceState): void;\n  recoverFriend(friend: IPokemonType): void;\n\n  // Positioning\n  bottom: number;\n  left: number;\n  positionBottom(bottom: number): void;\n  positionLeft(left: number): void;\n  width: number;\n  floor: number;\n\n  // Friends API\n  name: string;\n  emoji: string;\n  hasFriend: boolean;\n  friend: IPokemonType | undefined;\n  makeFriendsWith(friend: IPokemonType): boolean;\n  isPlaying: boolean;\n\n  showSpeechBubble(duration: number, friend: boolean): void;\n}\n\nexport class PokemonInstanceState {\n  currentStateEnum: States | undefined;\n}\n\nexport class PokemonElementState {\n  pokemonState: PokemonInstanceState | undefined;\n  pokemonGeneration: string | undefined;\n  originalSpriteSize: number | undefined;\n  pokemonType: PokemonType | undefined;\n  pokemonColor: PokemonColor | undefined;\n  elLeft: string | undefined;\n  elBottom: string | undefined;\n  pokemonName: string | undefined;\n  pokemonFriend: string | undefined;\n}\n\nexport class PokemonPanelState {\n  pokemonStates: Array<PokemonElementState> | undefined;\n  pokemonCounter: number | undefined;\n}\n\nexport enum HorizontalDirection {\n  left,\n  right,\n  natural, // No change to current direction\n}\n\nexport const enum States {\n  sitIdle = 'sit-idle',\n  walkRight = 'walk-right',\n  walkLeft = 'walk-left',\n  runRight = 'run-right',\n  runLeft = 'run-left',\n  lie = 'lie',\n  wallHangLeft = 'wall-hang-left',\n  climbWallLeft = 'climb-wall-left',\n  jumpDownLeft = 'jump-down-left',\n  land = 'land',\n  swipe = 'swipe',\n  idleWithBall = 'idle-with-ball',\n  chase = 'chase',\n  chaseFriend = 'chase-friend',\n  standRight = 'stand-right',\n  standLeft = 'stand-left',\n}\n\nexport enum FrameResult {\n  stateContinue,\n  stateComplete,\n  // Special states\n  stateCancel,\n}\n\nexport class BallState {\n  cx: number;\n  cy: number;\n  vx: number;\n  vy: number;\n  paused: boolean;\n\n  constructor(cx: number, cy: number, vx: number, vy: number) {\n    this.cx = cx;\n    this.cy = cy;\n    this.vx = vx;\n    this.vy = vy;\n    this.paused = false;\n  }\n}\n\nexport function isStateAboveGround(state: States): boolean {\n  return (\n    state === States.climbWallLeft ||\n    state === States.jumpDownLeft ||\n    state === States.land ||\n    state === States.wallHangLeft\n  );\n}\n\nexport function resolveState(state: string, pokemon: IPokemonType): IState {\n  switch (state) {\n    case States.sitIdle:\n      return new SitIdleState(pokemon);\n    case States.walkRight:\n      return new WalkRightState(pokemon);\n    case States.walkLeft:\n      return new WalkLeftState(pokemon);\n    case States.runRight:\n      return new RunRightState(pokemon);\n    case States.runLeft:\n      return new RunLeftState(pokemon);\n    case States.lie:\n      return new LieState(pokemon);\n    case States.wallHangLeft:\n      return new WallHangLeftState(pokemon);\n    case States.climbWallLeft:\n      return new ClimbWallLeftState(pokemon);\n    case States.jumpDownLeft:\n      return new JumpDownLeftState(pokemon);\n    case States.land:\n      return new LandState(pokemon);\n    case States.swipe:\n      return new SwipeState(pokemon);\n    case States.idleWithBall:\n      return new IdleWithBallState(pokemon);\n    case States.chaseFriend:\n      return new ChaseFriendState(pokemon);\n    case States.standRight:\n      return new StandRightState(pokemon);\n    case States.standLeft:\n      return new StandLeftState(pokemon);\n  }\n  return new SitIdleState(pokemon);\n}\n\nexport interface IState {\n  label: string;\n  spriteLabel: string;\n  horizontalDirection: HorizontalDirection;\n  pokemon: IPokemonType;\n  nextFrame(): FrameResult;\n}\n\nclass AbstractStaticState implements IState {\n  label = States.sitIdle;\n  idleCounter: number;\n  spriteLabel = 'idle';\n  holdTime = 50;\n  pokemon: IPokemonType;\n\n  horizontalDirection = HorizontalDirection.left;\n\n  constructor(pokemon: IPokemonType) {\n    this.idleCounter = 0;\n    this.pokemon = pokemon;\n  }\n\n  nextFrame(): FrameResult {\n    this.idleCounter++;\n    if (this.idleCounter > this.holdTime) {\n      return FrameResult.stateComplete;\n    }\n    return FrameResult.stateContinue;\n  }\n}\n\nexport class SitIdleState extends AbstractStaticState {\n  label = States.sitIdle;\n  spriteLabel = 'idle';\n  horizontalDirection = HorizontalDirection.right;\n  holdTime = 50;\n}\n\nexport class LieState extends AbstractStaticState {\n  label = States.lie;\n  spriteLabel = 'lie';\n  horizontalDirection = HorizontalDirection.right;\n  holdTime = 50;\n}\n\nexport class WallHangLeftState extends AbstractStaticState {\n  label = States.wallHangLeft;\n  spriteLabel = 'wallgrab';\n  horizontalDirection = HorizontalDirection.left;\n  holdTime = 50;\n}\n\nexport class LandState extends AbstractStaticState {\n  label = States.land;\n  spriteLabel = 'land';\n  horizontalDirection = HorizontalDirection.left;\n  holdTime = 10;\n}\n\nexport class SwipeState extends AbstractStaticState {\n  label = States.swipe;\n  spriteLabel = 'idle'; // use base idle sprite\n  horizontalDirection = HorizontalDirection.natural;\n  holdTime = 15;\n}\n\nexport class IdleWithBallState extends AbstractStaticState {\n  label = States.idleWithBall;\n  spriteLabel = 'with_ball';\n  horizontalDirection = HorizontalDirection.left;\n  holdTime = 30;\n}\n\nexport class WalkRightState implements IState {\n  label = States.walkRight;\n  pokemon: IPokemonType;\n  spriteLabel = 'walk';\n  horizontalDirection = HorizontalDirection.right;\n  leftBoundary: number;\n  speedMultiplier = 1;\n  idleCounter: number;\n  holdTime = 60;\n\n  constructor(pokemon: IPokemonType) {\n    this.leftBoundary = Math.floor(window.innerWidth * 0.95);\n    this.pokemon = pokemon;\n    this.idleCounter = 0;\n  }\n\n  nextFrame(): FrameResult {\n    this.idleCounter++;\n    this.pokemon.positionLeft(\n      this.pokemon.left + this.pokemon.speed * this.speedMultiplier,\n    );\n\n    // Random chance to stop in the middle\n    if (this.pokemon.isMoving && Math.random() < 0.01) {\n      return FrameResult.stateComplete;\n    }\n\n    if (\n      this.pokemon.isMoving &&\n      this.pokemon.left >= this.leftBoundary - this.pokemon.width\n    ) {\n      return FrameResult.stateComplete;\n    } else if (!this.pokemon.isMoving && this.idleCounter > this.holdTime) {\n      return FrameResult.stateComplete;\n    }\n    return FrameResult.stateContinue;\n  }\n}\n\nexport class WalkLeftState implements IState {\n  label = States.walkLeft;\n  spriteLabel = 'walk_left';\n  horizontalDirection = HorizontalDirection.left;\n  pokemon: IPokemonType;\n  speedMultiplier = 1;\n  idleCounter: number;\n  holdTime = 60;\n\n  constructor(pokemon: IPokemonType) {\n    this.pokemon = pokemon;\n    this.idleCounter = 0;\n  }\n\n  nextFrame(): FrameResult {\n    this.idleCounter++;\n    this.pokemon.positionLeft(\n      this.pokemon.left - this.pokemon.speed * this.speedMultiplier,\n    );\n\n    // Random chance to stop in the middle\n    if (this.pokemon.isMoving && Math.random() < 0.01) {\n      return FrameResult.stateComplete;\n    }\n\n    if (this.pokemon.isMoving && this.pokemon.left <= 0) {\n      return FrameResult.stateComplete;\n    } else if (!this.pokemon.isMoving && this.idleCounter > this.holdTime) {\n      return FrameResult.stateComplete;\n    }\n    return FrameResult.stateContinue;\n  }\n}\n\nexport class RunRightState extends WalkRightState {\n  label = States.runRight;\n  spriteLabel = 'walk_fast';\n  speedMultiplier = 1.6;\n  holdTime = 130;\n}\n\nexport class RunLeftState extends WalkLeftState {\n  label = States.runLeft;\n  spriteLabel = 'walk_fast';\n  speedMultiplier = 1.6;\n  holdTime = 130;\n}\n\nexport class ChaseState implements IState {\n  label = States.chase;\n  spriteLabel = 'run';\n  horizontalDirection = HorizontalDirection.left;\n  ballState: BallState;\n  canvas: HTMLCanvasElement;\n  pokemon: IPokemonType;\n\n  constructor(\n    pokemon: IPokemonType,\n    ballState: BallState,\n    canvas: HTMLCanvasElement,\n  ) {\n    this.pokemon = pokemon;\n    this.ballState = ballState;\n    this.canvas = canvas;\n  }\n\n  nextFrame(): FrameResult {\n    if (this.ballState.paused) {\n      return FrameResult.stateCancel; // Ball is already caught\n    }\n    if (this.pokemon.left > this.ballState.cx) {\n      this.horizontalDirection = HorizontalDirection.left;\n      this.pokemon.positionLeft(this.pokemon.left - this.pokemon.speed);\n    } else {\n      this.horizontalDirection = HorizontalDirection.right;\n      this.pokemon.positionLeft(this.pokemon.left + this.pokemon.speed);\n    }\n\n    if (\n      this.canvas.height - this.ballState.cy <\n        this.pokemon.width + this.pokemon.floor &&\n      this.ballState.cx < this.pokemon.left &&\n      this.pokemon.left < this.ballState.cx + 15\n    ) {\n      // hide ball\n      this.canvas.style.display = 'none';\n      this.ballState.paused = true;\n      return FrameResult.stateComplete;\n    }\n    return FrameResult.stateContinue;\n  }\n}\n\nexport class ChaseFriendState implements IState {\n  label = States.chaseFriend;\n  spriteLabel = 'run';\n  horizontalDirection = HorizontalDirection.left;\n  pokemon: IPokemonType;\n\n  constructor(pokemon: IPokemonType) {\n    this.pokemon = pokemon;\n  }\n\n  nextFrame(): FrameResult {\n    if (!this.pokemon.hasFriend || !this.pokemon.friend?.isPlaying) {\n      return FrameResult.stateCancel; // Friend is no longer playing.\n    }\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    if (this.pokemon.left > this.pokemon.friend!.left) {\n      this.horizontalDirection = HorizontalDirection.left;\n      this.pokemon.positionLeft(this.pokemon.left - this.pokemon.speed);\n    } else {\n      this.horizontalDirection = HorizontalDirection.right;\n      this.pokemon.positionLeft(this.pokemon.left + this.pokemon.speed);\n    }\n\n    return FrameResult.stateContinue;\n  }\n}\n\nexport class ClimbWallLeftState implements IState {\n  label = States.climbWallLeft;\n  spriteLabel = 'wallclimb';\n  horizontalDirection = HorizontalDirection.left;\n  pokemon: IPokemonType;\n\n  constructor(pokemon: IPokemonType) {\n    this.pokemon = pokemon;\n  }\n\n  nextFrame(): FrameResult {\n    this.pokemon.positionBottom(this.pokemon.bottom + 1);\n    if (this.pokemon.bottom >= 100) {\n      return FrameResult.stateComplete;\n    }\n    return FrameResult.stateContinue;\n  }\n}\n\nexport class JumpDownLeftState implements IState {\n  label = States.jumpDownLeft;\n  spriteLabel = 'fall_from_grab';\n  horizontalDirection = HorizontalDirection.right;\n  pokemon: IPokemonType;\n\n  constructor(pokemon: IPokemonType) {\n    this.pokemon = pokemon;\n  }\n\n  nextFrame(): FrameResult {\n    this.pokemon.positionBottom(this.pokemon.bottom - 5);\n    if (this.pokemon.bottom <= this.pokemon.floor) {\n      this.pokemon.positionBottom(this.pokemon.floor);\n      return FrameResult.stateComplete;\n    }\n    return FrameResult.stateContinue;\n  }\n}\n\nexport class StandRightState extends AbstractStaticState {\n  label = States.standRight;\n  spriteLabel = 'stand';\n  horizontalDirection = HorizontalDirection.right;\n  holdTime = 60;\n}\n\nexport class StandLeftState extends AbstractStaticState {\n  label = States.standRight;\n  spriteLabel = 'stand';\n  horizontalDirection = HorizontalDirection.left;\n  holdTime = 60;\n}\n"
  },
  {
    "path": "src/test/gifs.ts",
    "content": "import * as fs from 'fs';\n\nimport { PokemonColor } from '../common/types';\nimport { getAllPokemon, POKEMON_DATA } from '../common/pokemon-data';\n\nconst defaultPokemonConfig = {\n  colors: [PokemonColor.default],\n  states: ['idle', 'walk'],\n};\n\nconst allPokemon = getAllPokemon().reduce(\n  (acc, pokemon) => ({\n    ...acc,\n    [pokemon]: defaultPokemonConfig,\n  }),\n  {} as { [key: string]: { colors: string[]; states: string[] } },\n);\nfunction checkGifFilenames(folder: string) {\n  for (const pokemon in allPokemon) {\n    const allowedColors = allPokemon[pokemon].colors;\n    const allowedStates = allPokemon[pokemon].states;\n    if (!allowedColors) {\n      console.error(`No colors found for pokemon \"${pokemon}\"`);\n      return;\n    }\n\n    // Get the generation number from POKEMON_DATA\n    const generation = POKEMON_DATA[pokemon]?.generation || 1;\n    const genFolder = `gen${generation}`;\n\n    allowedColors.forEach((color) => {\n      allowedStates.forEach((state) => {\n        const filename = `${color}_${state}_8fps.gif`;\n        const filePath = `${folder}/${genFolder}/${pokemon}/${filename}`;\n        if (!fs.existsSync(filePath)) {\n          // \\x1b[31m is the ANSI escape code for red, and \\x1b[0m resets the color back to the terminal's default.\n          console.error(`\\x1b[31mFile \"${filePath}\" does not exist.\\x1b[0m`);\n          return false;\n        } else {\n          console.log(`File \"${filePath}\" exists.`);\n        }\n      });\n    });\n  }\n}\n\nconst mediaFolder = './media';\ncheckGifFilenames(mediaFolder);\n"
  },
  {
    "path": "src/test/package.json",
    "content": "{\n  \"name\": \"vscode-pokemon-test\",\n  \"type\": \"module\"\n}\n"
  },
  {
    "path": "src/test/runTest.js",
    "content": "import * as path from 'path';\nimport { runTests } from 'vscode-test';\nasync function main() {\n  try {\n    // The folder containing the Extension Manifest package.json\n    // Passed to `--extensionDevelopmentPath`\n    const extensionDevelopmentPath = path.resolve(__dirname, '../../');\n    // The path to test runner\n    // Passed to --extensionTestsPath\n    const extensionTestsPath = path.resolve(__dirname, './suite/index');\n    // Download VS Code, unzip it and run the integration test\n    await runTests({ extensionDevelopmentPath, extensionTestsPath });\n  } catch (err) {\n    console.error('Failed to run tests');\n    process.exit(1);\n  }\n}\nmain();\n"
  },
  {
    "path": "src/test/runTest.ts",
    "content": "import * as path from 'path';\n\nimport { runTests } from 'vscode-test';\n\nasync function main() {\n  try {\n    // The folder containing the Extension Manifest package.json\n    // Passed to `--extensionDevelopmentPath`\n    const extensionDevelopmentPath = path.resolve(__dirname, '../../');\n\n    // The path to test runner\n    // Passed to --extensionTestsPath\n    const extensionTestsPath = path.resolve(__dirname, './suite/index');\n\n    // Download VS Code, unzip it and run the integration test\n    await runTests({ extensionDevelopmentPath, extensionTestsPath });\n  } catch (err) {\n    console.error('Failed to run tests');\n    process.exit(1);\n  }\n}\n\nvoid main();\n"
  },
  {
    "path": "src/test/suite/index.js",
    "content": "import * as path from 'path';\nimport * as Mocha from 'mocha';\nimport * as glob from 'glob';\nexport function run() {\n  // Create the mocha test\n  const mocha = new Mocha({\n    ui: 'tdd',\n    color: true,\n    require: ['ts-node/register', 'source-map-support/register'],\n    recursive: true,\n  });\n  const testsRoot = path.resolve(__dirname, '..');\n  return new Promise((c, e) => {\n    glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {\n      if (err) {\n        return e(err);\n      }\n      // Add files to the test suite\n      files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f)));\n      try {\n        // Run the mocha test\n        mocha.run((failures) => {\n          if (failures > 0) {\n            e(new Error(`${failures} tests failed.`));\n          } else {\n            c();\n          }\n        });\n      } catch (err) {\n        console.error(err);\n        e(err);\n      }\n    });\n  });\n}\n"
  },
  {
    "path": "src/test/suite/index.ts",
    "content": "import * as path from 'path';\nimport * as Mocha from 'mocha';\nimport * as glob from 'glob';\nimport { join } from 'path';\n\nfunction setupCoverage() {\n  const NYC = require('nyc');\n  const nyc = new NYC({\n    cwd: join(__dirname, '..', '..', '..'),\n    exclude: ['**/test/**', '.vscode-test/**'],\n    reporter: ['text', 'html', 'lcov'],\n    all: true,\n    instrument: true,\n    hookRequire: true,\n    hookRunInContext: true,\n    hookRunInThisContext: true,\n  });\n\n  nyc.reset();\n  nyc.wrap();\n\n  return nyc;\n}\n\nexport async function run(): Promise<void> {\n  const nyc = process.env.COVERAGE ? setupCoverage() : null;\n\n  // Create the mocha test\n  const mocha = new Mocha({\n    ui: 'tdd',\n    color: true,\n    require: [\n      'ts-node/register',\n      'source-map-support/register',\n      'jsdom-global/register',\n    ],\n  });\n\n  const testsRoot = path.resolve(__dirname, '..');\n\n  return new Promise((c, e) => {\n    glob('**/**.test.js', { cwd: testsRoot }, async (err, files) => {\n      if (err) {\n        return e(err);\n      }\n\n      // Add files to the test suite\n      files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f)));\n\n      try {\n        // Run the mocha test\n        mocha.run((failures) => {\n          if (failures > 0) {\n            e(new Error(`${failures} tests failed.`));\n          } else {\n            c();\n          }\n        });\n      } catch (err) {\n        console.error(err);\n        e(err);\n      } finally {\n        if (nyc) {\n          nyc.writeCoverageFile();\n          await nyc.report();\n        }\n      }\n    });\n  });\n}\n"
  },
  {
    "path": "src/test/suite/panel.test.ts",
    "content": "function mockPanelWindow() {\n  const html =\n    '<!doctype html><html><body><div id=\"pokemonContainer\"></div><div id=\"foreground\"></div></body></html>';\n\n  var jsdom = require('jsdom');\n  var document = new jsdom.JSDOM(html);\n  var window = document.window;\n\n  global.document = window.document;\n  global.window = window;\n  window.console = global.console;\n}\n\nmockPanelWindow();\n"
  },
  {
    "path": "tsconfig.extension.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"module\": \"commonjs\",\n\t\t\"target\": \"esnext\",\n\t\t\"outDir\": \"out\",\n\t\t\"lib\": [\n\t\t\t\"es6\"\n\t\t],\n\t\t\"sourceMap\": true,\n\t\t\"rootDirs\": [\"extension\", \"common\"],\n\t\t\"strict\": true   /* enable all strict type-checking options */\n\t\t/* Additional Checks */\n\t\t// \"noImplicitReturns\": true, /* Report error when not all code paths in function return a value. */\n\t\t// \"noFallthroughCasesInSwitch\": true, /* Report errors for fallthrough cases in switch statement. */\n\t\t// \"noUnusedParameters\": true,  /* Report errors on unused parameters. */\n\t},\n\t\"exclude\": [\n\t\t\"node_modules\",\n\t\t\".vscode-test\",\n\t\t\"src/panel\",\n\t\t\"src/test\"\n\t]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"noImplicitAny\": true,\n        \"strictNullChecks\": true,\n        \"outDir\": \"./.build-out\",\n        \"lib\": [\"es2016\", \"dom\"],\n        \"target\": \"esnext\"\n    },\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "tsconfig.panel.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"module\": \"commonjs\",\n\t\t\"target\": \"esnext\",\n\t\t\"outDir\": \"./build\",\n\t\t\"lib\": [\n\t\t\t\"es6\", \"DOM\"\n\t\t],\n\t\t\"sourceMap\": true,\n\t\t\"rootDirs\": [\"panel\", \"common\"],\n\t\t\"strict\": true   /* enable all strict type-checking options */\n\t\t/* Additional Checks */\n\t\t// \"noImplicitReturns\": true, /* Report error when not all code paths in function return a value. */\n\t\t// \"noFallthroughCasesInSwitch\": true, /* Report errors for fallthrough cases in switch statement. */\n\t\t// \"noUnusedParameters\": true,  /* Report errors on unused parameters. */\n\t},\n\t\"exclude\": [\n\t\t\"node_modules\",\n\t\t\".vscode-test\",\n\t\t\"src/extension\",\n\t\t\"src/test\"\n\t]\n}\n"
  },
  {
    "path": "tsconfig.test.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"module\": \"commonjs\",\n\t\t\"target\": \"esnext\",\n\t\t\"outDir\": \"out\",\n\t\t\"lib\": [\"es6\", \"DOM\"],\n\t\t\"sourceMap\": true,\n\t\t\"rootDirs\": [\"panel\", \"common\", \"test\", \"extension\"],\n\t\t\"strict\": true /* enable all strict type-checking options */\n\t\t/* Additional Checks */\n\t\t// \"noImplicitReturns\": true, /* Report error when not all code paths in function return a value. */\n\t\t// \"noFallthroughCasesInSwitch\": true, /* Report errors for fallthrough cases in switch statement. */\n\t\t// \"noUnusedParameters\": true,  /* Report errors on unused parameters. */\n\t},\n\t\"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "tsconfig.web.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"module\": \"commonjs\",\n\t\t\"target\": \"es2020\",\n\t\t\"outDir\": \"dist\",\n\t\t\"lib\": [\"es6\", \"WebWorker\"],\n\t\t\"sourceMap\": true,\n\t\t\"rootDirs\": [\"panel\", \"common\"],\n\t\t\"strict\": true /* enable all strict type-checking options */\n\t\t/* Additional Checks */\n\t\t// \"noImplicitReturns\": true, /* Report error when not all code paths in function return a value. */\n\t\t// \"noFallthroughCasesInSwitch\": true, /* Report errors for fallthrough cases in switch statement. */\n\t\t// \"noUnusedParameters\": true,  /* Report errors on unused parameters. */\n\t},\n\t\"exclude\": [\n\t\t\"node_modules\",\n\t\t\".vscode-test-web\",\n\t\t\"src/extension\",\n\t\t\"src/test\",\n\t\t\"src/panel\"\n\t]\n}\n"
  },
  {
    "path": "webpack.config.js",
    "content": "//webpack.config.js\nconst path = require('path');\nconst webpack = require('webpack');\nvar removeSourceMapUrlWebpackPlugin = require('@rbarilani/remove-source-map-url-webpack-plugin');\n\n\nconst desktopConfig = {\n\tmode: \"development\",\n\tdevtool: \"inline-source-map\",\n\tentry: {\n\t\tmain: \"./src/panel/main.ts\",\n\t},\n\toutput: {\n\t\tpath: path.resolve(__dirname, './media'),\n\t\tfilename: \"[name]-bundle.js\", // <--- Will be compiled to this single file\n\t\tlibrary: {\n\t\t\tname: 'pokemonApp',\n\t\t\ttype: 'global'\n\t\t}\n\t},\n\tplugins: [\n\t\tnew removeSourceMapUrlWebpackPlugin({\n\t\t\ttest: /main-bundle\\.js$/\n\t\t})\n\t],\n\tresolve: {\n\t\textensions: [\".ts\", \".tsx\", \".js\"],\n\t},\n\tmodule: {\n\t\trules: [{\n\t\t\ttest: /\\.ts$/,\n\t\t\texclude: /node_modules/,\n\t\t\tuse: [\n\t\t\t\t{\n\t\t\t\t\tloader: 'ts-loader',\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tconfigFile: 'tsconfig.panel.json'\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t],\n\t\t}]\n\t},\n};\n\nconst webExtensionConfig = {\n\tmode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')\n\ttarget: 'webworker', // extensions run in a webworker context\n\tentry: {\n\t\textension: './src/extension/extension.ts', // source of the web extension main file\n\t\t// 'test/suite/index': './src/web/test/suite/index.ts', // source of the web extension test runner\n\t},\n\toutput: {\n\t\tfilename: '[name]-web.js',\n\t\tpath: path.join(__dirname, './dist/web'),\n\t\tlibraryTarget: 'commonjs',\n\t},\n\tresolve: {\n\t\tmainFields: ['browser', 'module', 'main'], // look for `browser` entry point in imported node modules\n\t\textensions: ['.ts', '.js'], // support ts-files and js-files\n\t\talias: {\n\t\t\t// provides alternate implementation for node module and source files\n\t\t},\n\t\tfallback: {\n\t\t\t// Webpack 5 no longer polyfills Node.js core modules automatically.\n\t\t\t// see https://webpack.js.org/configuration/resolve/#resolvefallback\n\t\t\t// for the list of Node.js core module polyfills.\n\t\t\t\"assert\": require.resolve('assert'),\n\t\t\t\"path\": require.resolve(\"path-browserify\"),\n\t\t\t\"fs\": false,\n\t\t},\n\t},\n\tmodule: {\n\t\trules: [\n\t\t\t{\n\t\t\t\ttest: /\\.ts$/,\n\t\t\t\texclude: /node_modules/,\n\t\t\t\tuse: [\n\t\t\t\t\t{\n\t\t\t\t\t\tloader: 'ts-loader',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tconfigFile: 'tsconfig.web.json'\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n\tplugins: [\n\t\tnew webpack.ProvidePlugin({\n\t\t\tprocess: 'process/browser', // provide a shim for the global `process` variable\n\t\t}),\n\t],\n\texternals: {\n\t\tvscode: 'commonjs vscode', // ignored because it doesn't exist\n\t},\n\tperformance: {\n\t\thints: false,\n\t},\n\tdevtool: 'nosources-source-map', // create a source map that points to the original source file\n};\n\nmodule.exports = [desktopConfig, webExtensionConfig];"
  }
]