catchemall

{data.pokemon.length} Pokémon · {data.games.length} games

{#if !data.user}

sign in to save your progress.

{/if} {#if saveError}{/if} {#if !data.pokemon.length}

the Pokémon catalog has not been loaded yet.

{/if}

overall progress

{percentage}%

{caughtCount} of {total} entries caught

{#if viewGame}
{#each visiblePokemon as pokemon (pokemon.id)} {@const entry = entryMap.get(pokemon.id)?.get(viewGame.id)} {@const reason = tooltip(entry, viewGame)} {:else} {/each}
Pokémoncaught
#{pokemon.number}{pokemon.name}
{#if entry && reason === null} toggleCaught(entry.id, event.currentTarget.checked)} /> {:else} {!entry ? '—' : entry.availability === 'unknown' ? '?' : '·'} {/if}
no Pokémon found

{filteredPokemon.length ? (pageNumber - 1) * pageSize + 1 : 0}–{Math.min( pageNumber * pageSize, filteredPokemon.length )} of {filteredPokemon.length}

{pageNumber}/{pageCount}
{:else if data.pokemon.length}

no games selected. use “set rules” to choose one.

{/if}
about availability

checkboxes represent confirmed encounters from PokéAPI. “?” means the Pokémon appears in a game catalog but its acquisition method is unconfirmed. “—” means there is no source record. Neither proves it is unobtainable.

set rules

choose the games that count toward your progress.

{#if form?.message}{/if}
{ return async ({ result, update }) => { await update(); if (result.type === 'success') rulesDialog.close(); }; }} >
{#each gamesByGeneration as [generation, games] (generation)}
{#each games as game (game.id)}{/each}
{/each}