diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0d79845 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +.env +.env.* +!.env.example +node_modules +.svelte-kit +build +test-results +playwright-report +*.log diff --git a/.env.example b/.env.example index e69de29..38a5984 100755 --- a/.env.example +++ b/.env.example @@ -0,0 +1,30 @@ +# PostgreSQL connection (server only) +DB_URL=postgresql://postgres:postgres@localhost:5432/personal_dev + +# Use the exact public origin, including scheme and port. Set the same value for both. +ORIGIN=http://localhost:5173 +BETTER_AUTH_URL=http://localhost:5173 +# Generate with: openssl rand -base64 48 +BETTER_AUTH_SECRET= + +# Optional Google login; callback: /api/auth/callback/google +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= + +# Optional osu! login; callback: /api/auth/callback/osu +# These can also serve the existing beatmap finder. +OSU_CLIENT_ID= +OSU_CLIENT_SECRET= +SPOTIFY_CLIENT_ID= +SPOTIFY_CLIENT_SECRET= + +# Public browser key for Animaldex map tiles. +PUBLIC_MAPTILER_API_KEY= + +# Cloudflare R2, shared by Animaldex and admin-uploaded list pictures. +# R2_PUBLIC_URL is the public bucket/custom-domain base URL (without a trailing slash). +R2_ACCOUNT_ID= +R2_ACCESS_KEY_ID= +R2_SECRET_ACCESS_KEY= +R2_BUCKET= +R2_PUBLIC_URL= diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 3f12d99..4182b09 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -1,40 +1,52 @@ -name: build +name: Test and deploy staging on: push: - branches: [main, staging] + branches: [staging] jobs: - build: + staging: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: 1.4.0 + - name: Install and test + run: | + bun install --frozen-lockfile + bun run test:unit -- --run + + # Build once. The same SHA-tagged image stays on the deployment host for + # one-click promotion to production; the production workflow never rebuilds it. - uses: docker/build-push-action@v5 with: context: . push: false load: true tags: git.stanrunge.dev/stan/personal-website:${{ github.sha }} + build-args: | + GIT_SHA=${{ github.sha }} - deploy: - needs: build - runs-on: ubuntu-latest - steps: - - name: setup key + - name: Configure deployment SSH key + env: + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} run: | - mkdir -p ~/.ssh - echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519 + set -euo pipefail + install -d -m 700 ~/.ssh + printf '%s\n' "$DEPLOY_KEY" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -H 172.17.0.1 >> ~/.ssh/known_hosts - - name: pick target + - name: Transfer tested image run: | - if [ "${{ github.ref_name }}" = "main" ]; then - echo "DIR=/opt/personal-website" >> $GITHUB_ENV - else - echo "DIR=/opt/personal-website-staging" >> $GITHUB_ENV - fi + set -euo pipefail + image="git.stanrunge.dev/stan/personal-website:${{ github.sha }}" + docker save "$image" | ssh -o BatchMode=yes deploy@172.17.0.1 'sudo docker load' - - name: deploy + - name: Deploy staging run: | - ssh deploy@172.17.0.1 "echo IMAGE_TAG=${{ github.sha }} | sudo tee $DIR/.env && sudo docker compose -f $DIR/compose.prod.yml up -d" + set -euo pipefail + ssh -o BatchMode=yes deploy@172.17.0.1 \ + "bash -s -- '${{ github.sha }}' '/opt/personal-website-staging' 'https://staging.stanrunge.dev'" \ + < scripts/deploy-remote.sh diff --git a/.gitea/workflows/deploy-production.yml b/.gitea/workflows/deploy-production.yml new file mode 100644 index 0000000..4e3ad0d --- /dev/null +++ b/.gitea/workflows/deploy-production.yml @@ -0,0 +1,41 @@ +name: Deploy production +on: + workflow_dispatch: + +jobs: + promote: + runs-on: ubuntu-latest + steps: + # Always test the staging branch, regardless of which branch the button + # appears on in Gitea's Actions UI. + - uses: actions/checkout@v4 + with: + ref: staging + + - uses: oven-sh/setup-bun@v2 + with: + bun-version: 1.4.0 + - name: Check staging source + run: | + bun install --frozen-lockfile + bun run test:unit -- --run + + - name: Configure deployment SSH key + env: + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} + run: | + set -euo pipefail + install -d -m 700 ~/.ssh + printf '%s\n' "$DEPLOY_KEY" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + ssh-keyscan -H 172.17.0.1 >> ~/.ssh/known_hosts + + - name: Promote the exact staging image + run: | + set -euo pipefail + commit=$(git rev-parse HEAD) + ssh -o BatchMode=yes deploy@172.17.0.1 "bash -s -- '$commit'" \ + < scripts/verify-staging-image.sh + ssh -o BatchMode=yes deploy@172.17.0.1 \ + "bash -s -- '$commit' '/opt/personal-website' 'https://stanrunge.dev'" \ + < scripts/deploy-remote.sh diff --git a/.gitignore b/.gitignore index 4262dd2..db3f8c9 100755 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ vite.config.js.timestamp-* vite.config.ts.timestamp-* .vscode/ + +# Browser test output +/test-results/ +/playwright-report/ diff --git a/.prettierignore b/.prettierignore index ab78a95..3ca4c4b 100755 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,6 @@ package-lock.json pnpm-lock.yaml yarn.lock + +# Generated pinned catalog +data/pokemon-catalog.json diff --git a/Dockerfile b/Dockerfile index 5a012f1..df374d0 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,22 @@ -FROM oven/bun AS builder +FROM oven/bun:1.4.0 AS builder WORKDIR /app COPY package.json bun.lock ./ -RUN bun install +RUN bun install --frozen-lockfile COPY . . RUN bun run build -FROM oven/bun +FROM oven/bun:1.4.0 WORKDIR /app +ARG GIT_SHA=dev +ENV APP_VERSION=$GIT_SHA COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/build ./build +COPY --from=builder /app/scripts ./scripts +COPY --from=builder /app/data ./data +COPY --from=builder /app/src/lib/server/db/schema ./src/lib/server/db/schema +COPY --from=builder /app/src/lib/availability.ts ./src/lib/availability.ts COPY package.json ./ EXPOSE 3000 ENV NODE_ENV=production -CMD ["bun", "build/index.js"] \ No newline at end of file +ENV BODY_SIZE_LIMIT=6M +CMD ["bun", "build/index.js"] diff --git a/bun.lock b/bun.lock index 1b0d0f3..bb6b277 100644 --- a/bun.lock +++ b/bun.lock @@ -12,6 +12,9 @@ "@sveltejs/adapter-node": "^5.5.7", "ai": "^7.0.85", "drizzle-orm": "^1.0.0-rc.4", + "highlight.js": "^11.12.0", + "marked": "^18.0.11", + "marked-highlight": "^2.2.4", "mode-watcher": "^1.1.0", "postgres": "^3.4.9", "zod": "^4.5.4", @@ -23,6 +26,7 @@ "@sveltejs/enhanced-img": "^0.11.0", "@sveltejs/kit": "^2.70.3", "@sveltejs/vite-plugin-svelte": "^7.3.0", + "@tailwindcss/typography": "^0.5.20", "@tailwindcss/vite": "^4.3.3", "@types/eslint": "9.6.1", "@types/pg": "^8.23.1", @@ -467,6 +471,8 @@ "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw=="], + "@tailwindcss/typography": ["@tailwindcss/typography@0.5.20", "", { "dependencies": { "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || >=4.0.0 || insiders" } }, "sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw=="], + "@tailwindcss/vite": ["@tailwindcss/vite@4.3.3", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="], "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], @@ -729,6 +735,8 @@ "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], + "highlight.js": ["highlight.js@11.12.0", "", {}, "sha512-nbfWpyRMcMrPMmDwJB+dhX/eiaPKtc2RB+0QZskqJ3WjRA/FDS0e9hZrx8EC/lbEv8gXy98FcDbNa/dspAaJMg=="], + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], "imagetools-core": ["imagetools-core@9.1.0", "", {}, "sha512-xQjs+2vrxLnAjCq+omuNkd5UQTld9/bP8+YT0LyYTlKfuSQtgUBvqhUwGugzSAh6sCdN+LnROMuLswn5hZ9Fhg=="], @@ -823,6 +831,10 @@ "maplibre-gl": ["maplibre-gl@5.24.0", "", { "dependencies": { "@mapbox/jsonlint-lines-primitives": "^2.0.2", "@mapbox/point-geometry": "^1.1.0", "@mapbox/tiny-sdf": "^2.1.0", "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^2.0.4", "@mapbox/whoots-js": "^3.1.0", "@maplibre/geojson-vt": "^6.1.0", "@maplibre/maplibre-gl-style-spec": "^24.8.1", "@maplibre/mlt": "^1.1.8", "@maplibre/vt-pbf": "^4.3.0", "@types/geojson": "^7946.0.16", "earcut": "^3.0.2", "gl-matrix": "^3.4.4", "kdbush": "^4.0.2", "murmurhash-js": "^1.0.0", "pbf": "^4.0.1", "potpack": "^2.1.0", "quickselect": "^3.0.0", "tinyqueue": "^3.0.0" } }, "sha512-ALyFxgtd5R+65UqZ/++lOqwWcC0SNho9c27fYSyLmG7AfnAul2o46F05aDJGPbFU57wos9dgcIySHs0Xe6ia3A=="], + "marked": ["marked@18.0.14", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-mBHK6FBHuBAlhgRe88w9F0O1AbwwXJUcQibUbC/QcdTbVGAD7aWza+xt3N6oT/jCZx3/OMeS+8rnuiHZcQ9s7A=="], + + "marked-highlight": ["marked-highlight@2.2.4", "", { "peerDependencies": { "marked": ">=4 <19" } }, "sha512-PZxisNMJDduSjc0q6uvjsnqqHCXc9s0eyzxDO9sB1eNGJnd/H1/Fu+z6g/liC1dfJdFW4SftMwMlLvsBhUPrqQ=="], + "minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], @@ -891,7 +903,7 @@ "postcss-scss": ["postcss-scss@4.0.9", "", { "peerDependencies": { "postcss": "^8.4.29" } }, "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A=="], - "postcss-selector-parser": ["postcss-selector-parser@7.1.5", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw=="], + "postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="], "postgres": ["postgres@3.4.9", "", {}, "sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw=="], @@ -1099,6 +1111,8 @@ "svelte-eslint-parser/espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + "svelte-eslint-parser/postcss-selector-parser": ["postcss-selector-parser@7.1.5", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw=="], + "@tailwindcss/node/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], "@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], diff --git a/data/pokemon-catalog.json b/data/pokemon-catalog.json new file mode 100644 index 0000000..b282784 --- /dev/null +++ b/data/pokemon-catalog.json @@ -0,0 +1 @@ +{"source":{"repository":"https://github.com/PokeAPI/pokeapi","revision":"575291cdb197a7e3a320297be276c9de4ef8401a","scope":"All species and game versions in this snapshot; default-form types/stats. Unknown means presence without confirmed encounter data. Missing pairs have no source record, not proven absence."},"pokemon":[{"number":1,"name":"Bulbasaur","generation":1,"type1":"Grass","type2":"Poison","hp":45,"attack":49,"defense":49,"specialAttack":65,"specialDefense":65,"speed":45},{"number":2,"name":"Ivysaur","generation":1,"type1":"Grass","type2":"Poison","hp":60,"attack":62,"defense":63,"specialAttack":80,"specialDefense":80,"speed":60},{"number":3,"name":"Venusaur","generation":1,"type1":"Grass","type2":"Poison","hp":80,"attack":82,"defense":83,"specialAttack":100,"specialDefense":100,"speed":80},{"number":4,"name":"Charmander","generation":1,"type1":"Fire","type2":null,"hp":39,"attack":52,"defense":43,"specialAttack":60,"specialDefense":50,"speed":65},{"number":5,"name":"Charmeleon","generation":1,"type1":"Fire","type2":null,"hp":58,"attack":64,"defense":58,"specialAttack":80,"specialDefense":65,"speed":80},{"number":6,"name":"Charizard","generation":1,"type1":"Fire","type2":"Flying","hp":78,"attack":84,"defense":78,"specialAttack":109,"specialDefense":85,"speed":100},{"number":7,"name":"Squirtle","generation":1,"type1":"Water","type2":null,"hp":44,"attack":48,"defense":65,"specialAttack":50,"specialDefense":64,"speed":43},{"number":8,"name":"Wartortle","generation":1,"type1":"Water","type2":null,"hp":59,"attack":63,"defense":80,"specialAttack":65,"specialDefense":80,"speed":58},{"number":9,"name":"Blastoise","generation":1,"type1":"Water","type2":null,"hp":79,"attack":83,"defense":100,"specialAttack":85,"specialDefense":105,"speed":78},{"number":10,"name":"Caterpie","generation":1,"type1":"Bug","type2":null,"hp":45,"attack":30,"defense":35,"specialAttack":20,"specialDefense":20,"speed":45},{"number":11,"name":"Metapod","generation":1,"type1":"Bug","type2":null,"hp":50,"attack":20,"defense":55,"specialAttack":25,"specialDefense":25,"speed":30},{"number":12,"name":"Butterfree","generation":1,"type1":"Bug","type2":"Flying","hp":60,"attack":45,"defense":50,"specialAttack":90,"specialDefense":80,"speed":70},{"number":13,"name":"Weedle","generation":1,"type1":"Bug","type2":"Poison","hp":40,"attack":35,"defense":30,"specialAttack":20,"specialDefense":20,"speed":50},{"number":14,"name":"Kakuna","generation":1,"type1":"Bug","type2":"Poison","hp":45,"attack":25,"defense":50,"specialAttack":25,"specialDefense":25,"speed":35},{"number":15,"name":"Beedrill","generation":1,"type1":"Bug","type2":"Poison","hp":65,"attack":90,"defense":40,"specialAttack":45,"specialDefense":80,"speed":75},{"number":16,"name":"Pidgey","generation":1,"type1":"Normal","type2":"Flying","hp":40,"attack":45,"defense":40,"specialAttack":35,"specialDefense":35,"speed":56},{"number":17,"name":"Pidgeotto","generation":1,"type1":"Normal","type2":"Flying","hp":63,"attack":60,"defense":55,"specialAttack":50,"specialDefense":50,"speed":71},{"number":18,"name":"Pidgeot","generation":1,"type1":"Normal","type2":"Flying","hp":83,"attack":80,"defense":75,"specialAttack":70,"specialDefense":70,"speed":101},{"number":19,"name":"Rattata","generation":1,"type1":"Normal","type2":null,"hp":30,"attack":56,"defense":35,"specialAttack":25,"specialDefense":35,"speed":72},{"number":20,"name":"Raticate","generation":1,"type1":"Normal","type2":null,"hp":55,"attack":81,"defense":60,"specialAttack":50,"specialDefense":70,"speed":97},{"number":21,"name":"Spearow","generation":1,"type1":"Normal","type2":"Flying","hp":40,"attack":60,"defense":30,"specialAttack":31,"specialDefense":31,"speed":70},{"number":22,"name":"Fearow","generation":1,"type1":"Normal","type2":"Flying","hp":65,"attack":90,"defense":65,"specialAttack":61,"specialDefense":61,"speed":100},{"number":23,"name":"Ekans","generation":1,"type1":"Poison","type2":null,"hp":35,"attack":60,"defense":44,"specialAttack":40,"specialDefense":54,"speed":55},{"number":24,"name":"Arbok","generation":1,"type1":"Poison","type2":null,"hp":60,"attack":95,"defense":69,"specialAttack":65,"specialDefense":79,"speed":80},{"number":25,"name":"Pikachu","generation":1,"type1":"Electric","type2":null,"hp":35,"attack":55,"defense":40,"specialAttack":50,"specialDefense":50,"speed":90},{"number":26,"name":"Raichu","generation":1,"type1":"Electric","type2":null,"hp":60,"attack":90,"defense":55,"specialAttack":90,"specialDefense":80,"speed":110},{"number":27,"name":"Sandshrew","generation":1,"type1":"Ground","type2":null,"hp":50,"attack":75,"defense":85,"specialAttack":20,"specialDefense":30,"speed":40},{"number":28,"name":"Sandslash","generation":1,"type1":"Ground","type2":null,"hp":75,"attack":100,"defense":110,"specialAttack":45,"specialDefense":55,"speed":65},{"number":29,"name":"Nidoran♀","generation":1,"type1":"Poison","type2":null,"hp":55,"attack":47,"defense":52,"specialAttack":40,"specialDefense":40,"speed":41},{"number":30,"name":"Nidorina","generation":1,"type1":"Poison","type2":null,"hp":70,"attack":62,"defense":67,"specialAttack":55,"specialDefense":55,"speed":56},{"number":31,"name":"Nidoqueen","generation":1,"type1":"Poison","type2":"Ground","hp":90,"attack":92,"defense":87,"specialAttack":75,"specialDefense":85,"speed":76},{"number":32,"name":"Nidoran♂","generation":1,"type1":"Poison","type2":null,"hp":46,"attack":57,"defense":40,"specialAttack":40,"specialDefense":40,"speed":50},{"number":33,"name":"Nidorino","generation":1,"type1":"Poison","type2":null,"hp":61,"attack":72,"defense":57,"specialAttack":55,"specialDefense":55,"speed":65},{"number":34,"name":"Nidoking","generation":1,"type1":"Poison","type2":"Ground","hp":81,"attack":102,"defense":77,"specialAttack":85,"specialDefense":75,"speed":85},{"number":35,"name":"Clefairy","generation":1,"type1":"Fairy","type2":null,"hp":70,"attack":45,"defense":48,"specialAttack":60,"specialDefense":65,"speed":35},{"number":36,"name":"Clefable","generation":1,"type1":"Fairy","type2":null,"hp":95,"attack":70,"defense":73,"specialAttack":95,"specialDefense":90,"speed":60},{"number":37,"name":"Vulpix","generation":1,"type1":"Fire","type2":null,"hp":38,"attack":41,"defense":40,"specialAttack":50,"specialDefense":65,"speed":65},{"number":38,"name":"Ninetales","generation":1,"type1":"Fire","type2":null,"hp":73,"attack":76,"defense":75,"specialAttack":81,"specialDefense":100,"speed":100},{"number":39,"name":"Jigglypuff","generation":1,"type1":"Normal","type2":"Fairy","hp":115,"attack":45,"defense":20,"specialAttack":45,"specialDefense":25,"speed":20},{"number":40,"name":"Wigglytuff","generation":1,"type1":"Normal","type2":"Fairy","hp":140,"attack":70,"defense":45,"specialAttack":85,"specialDefense":50,"speed":45},{"number":41,"name":"Zubat","generation":1,"type1":"Poison","type2":"Flying","hp":40,"attack":45,"defense":35,"specialAttack":30,"specialDefense":40,"speed":55},{"number":42,"name":"Golbat","generation":1,"type1":"Poison","type2":"Flying","hp":75,"attack":80,"defense":70,"specialAttack":65,"specialDefense":75,"speed":90},{"number":43,"name":"Oddish","generation":1,"type1":"Grass","type2":"Poison","hp":45,"attack":50,"defense":55,"specialAttack":75,"specialDefense":65,"speed":30},{"number":44,"name":"Gloom","generation":1,"type1":"Grass","type2":"Poison","hp":60,"attack":65,"defense":70,"specialAttack":85,"specialDefense":75,"speed":40},{"number":45,"name":"Vileplume","generation":1,"type1":"Grass","type2":"Poison","hp":75,"attack":80,"defense":85,"specialAttack":110,"specialDefense":90,"speed":50},{"number":46,"name":"Paras","generation":1,"type1":"Bug","type2":"Grass","hp":35,"attack":70,"defense":55,"specialAttack":45,"specialDefense":55,"speed":25},{"number":47,"name":"Parasect","generation":1,"type1":"Bug","type2":"Grass","hp":60,"attack":95,"defense":80,"specialAttack":60,"specialDefense":80,"speed":30},{"number":48,"name":"Venonat","generation":1,"type1":"Bug","type2":"Poison","hp":60,"attack":55,"defense":50,"specialAttack":40,"specialDefense":55,"speed":45},{"number":49,"name":"Venomoth","generation":1,"type1":"Bug","type2":"Poison","hp":70,"attack":65,"defense":60,"specialAttack":90,"specialDefense":75,"speed":90},{"number":50,"name":"Diglett","generation":1,"type1":"Ground","type2":null,"hp":10,"attack":55,"defense":25,"specialAttack":35,"specialDefense":45,"speed":95},{"number":51,"name":"Dugtrio","generation":1,"type1":"Ground","type2":null,"hp":35,"attack":100,"defense":50,"specialAttack":50,"specialDefense":70,"speed":120},{"number":52,"name":"Meowth","generation":1,"type1":"Normal","type2":null,"hp":40,"attack":45,"defense":35,"specialAttack":40,"specialDefense":40,"speed":90},{"number":53,"name":"Persian","generation":1,"type1":"Normal","type2":null,"hp":65,"attack":70,"defense":60,"specialAttack":65,"specialDefense":65,"speed":115},{"number":54,"name":"Psyduck","generation":1,"type1":"Water","type2":null,"hp":50,"attack":52,"defense":48,"specialAttack":65,"specialDefense":50,"speed":55},{"number":55,"name":"Golduck","generation":1,"type1":"Water","type2":null,"hp":80,"attack":82,"defense":78,"specialAttack":95,"specialDefense":80,"speed":85},{"number":56,"name":"Mankey","generation":1,"type1":"Fighting","type2":null,"hp":40,"attack":80,"defense":35,"specialAttack":35,"specialDefense":45,"speed":70},{"number":57,"name":"Primeape","generation":1,"type1":"Fighting","type2":null,"hp":65,"attack":105,"defense":60,"specialAttack":60,"specialDefense":70,"speed":95},{"number":58,"name":"Growlithe","generation":1,"type1":"Fire","type2":null,"hp":55,"attack":70,"defense":45,"specialAttack":70,"specialDefense":50,"speed":60},{"number":59,"name":"Arcanine","generation":1,"type1":"Fire","type2":null,"hp":90,"attack":110,"defense":80,"specialAttack":100,"specialDefense":80,"speed":95},{"number":60,"name":"Poliwag","generation":1,"type1":"Water","type2":null,"hp":40,"attack":50,"defense":40,"specialAttack":40,"specialDefense":40,"speed":90},{"number":61,"name":"Poliwhirl","generation":1,"type1":"Water","type2":null,"hp":65,"attack":65,"defense":65,"specialAttack":50,"specialDefense":50,"speed":90},{"number":62,"name":"Poliwrath","generation":1,"type1":"Water","type2":"Fighting","hp":90,"attack":95,"defense":95,"specialAttack":70,"specialDefense":90,"speed":70},{"number":63,"name":"Abra","generation":1,"type1":"Psychic","type2":null,"hp":25,"attack":20,"defense":15,"specialAttack":105,"specialDefense":55,"speed":90},{"number":64,"name":"Kadabra","generation":1,"type1":"Psychic","type2":null,"hp":40,"attack":35,"defense":30,"specialAttack":120,"specialDefense":70,"speed":105},{"number":65,"name":"Alakazam","generation":1,"type1":"Psychic","type2":null,"hp":55,"attack":50,"defense":45,"specialAttack":135,"specialDefense":95,"speed":120},{"number":66,"name":"Machop","generation":1,"type1":"Fighting","type2":null,"hp":70,"attack":80,"defense":50,"specialAttack":35,"specialDefense":35,"speed":35},{"number":67,"name":"Machoke","generation":1,"type1":"Fighting","type2":null,"hp":80,"attack":100,"defense":70,"specialAttack":50,"specialDefense":60,"speed":45},{"number":68,"name":"Machamp","generation":1,"type1":"Fighting","type2":null,"hp":90,"attack":130,"defense":80,"specialAttack":65,"specialDefense":85,"speed":55},{"number":69,"name":"Bellsprout","generation":1,"type1":"Grass","type2":"Poison","hp":50,"attack":75,"defense":35,"specialAttack":70,"specialDefense":30,"speed":40},{"number":70,"name":"Weepinbell","generation":1,"type1":"Grass","type2":"Poison","hp":65,"attack":90,"defense":50,"specialAttack":85,"specialDefense":45,"speed":55},{"number":71,"name":"Victreebel","generation":1,"type1":"Grass","type2":"Poison","hp":80,"attack":105,"defense":65,"specialAttack":100,"specialDefense":70,"speed":70},{"number":72,"name":"Tentacool","generation":1,"type1":"Water","type2":"Poison","hp":40,"attack":40,"defense":35,"specialAttack":50,"specialDefense":100,"speed":70},{"number":73,"name":"Tentacruel","generation":1,"type1":"Water","type2":"Poison","hp":80,"attack":70,"defense":65,"specialAttack":80,"specialDefense":120,"speed":100},{"number":74,"name":"Geodude","generation":1,"type1":"Rock","type2":"Ground","hp":40,"attack":80,"defense":100,"specialAttack":30,"specialDefense":30,"speed":20},{"number":75,"name":"Graveler","generation":1,"type1":"Rock","type2":"Ground","hp":55,"attack":95,"defense":115,"specialAttack":45,"specialDefense":45,"speed":35},{"number":76,"name":"Golem","generation":1,"type1":"Rock","type2":"Ground","hp":80,"attack":120,"defense":130,"specialAttack":55,"specialDefense":65,"speed":45},{"number":77,"name":"Ponyta","generation":1,"type1":"Fire","type2":null,"hp":50,"attack":85,"defense":55,"specialAttack":65,"specialDefense":65,"speed":90},{"number":78,"name":"Rapidash","generation":1,"type1":"Fire","type2":null,"hp":65,"attack":100,"defense":70,"specialAttack":80,"specialDefense":80,"speed":105},{"number":79,"name":"Slowpoke","generation":1,"type1":"Water","type2":"Psychic","hp":90,"attack":65,"defense":65,"specialAttack":40,"specialDefense":40,"speed":15},{"number":80,"name":"Slowbro","generation":1,"type1":"Water","type2":"Psychic","hp":95,"attack":75,"defense":110,"specialAttack":100,"specialDefense":80,"speed":30},{"number":81,"name":"Magnemite","generation":1,"type1":"Electric","type2":"Steel","hp":25,"attack":35,"defense":70,"specialAttack":95,"specialDefense":55,"speed":45},{"number":82,"name":"Magneton","generation":1,"type1":"Electric","type2":"Steel","hp":50,"attack":60,"defense":95,"specialAttack":120,"specialDefense":70,"speed":70},{"number":83,"name":"Farfetch’d","generation":1,"type1":"Normal","type2":"Flying","hp":52,"attack":90,"defense":55,"specialAttack":58,"specialDefense":62,"speed":60},{"number":84,"name":"Doduo","generation":1,"type1":"Normal","type2":"Flying","hp":35,"attack":85,"defense":45,"specialAttack":35,"specialDefense":35,"speed":75},{"number":85,"name":"Dodrio","generation":1,"type1":"Normal","type2":"Flying","hp":60,"attack":110,"defense":70,"specialAttack":60,"specialDefense":60,"speed":110},{"number":86,"name":"Seel","generation":1,"type1":"Water","type2":null,"hp":65,"attack":45,"defense":55,"specialAttack":45,"specialDefense":70,"speed":45},{"number":87,"name":"Dewgong","generation":1,"type1":"Water","type2":"Ice","hp":90,"attack":70,"defense":80,"specialAttack":70,"specialDefense":95,"speed":70},{"number":88,"name":"Grimer","generation":1,"type1":"Poison","type2":null,"hp":80,"attack":80,"defense":50,"specialAttack":40,"specialDefense":50,"speed":25},{"number":89,"name":"Muk","generation":1,"type1":"Poison","type2":null,"hp":105,"attack":105,"defense":75,"specialAttack":65,"specialDefense":100,"speed":50},{"number":90,"name":"Shellder","generation":1,"type1":"Water","type2":null,"hp":30,"attack":65,"defense":100,"specialAttack":45,"specialDefense":25,"speed":40},{"number":91,"name":"Cloyster","generation":1,"type1":"Water","type2":"Ice","hp":50,"attack":95,"defense":180,"specialAttack":85,"specialDefense":45,"speed":70},{"number":92,"name":"Gastly","generation":1,"type1":"Ghost","type2":"Poison","hp":30,"attack":35,"defense":30,"specialAttack":100,"specialDefense":35,"speed":80},{"number":93,"name":"Haunter","generation":1,"type1":"Ghost","type2":"Poison","hp":45,"attack":50,"defense":45,"specialAttack":115,"specialDefense":55,"speed":95},{"number":94,"name":"Gengar","generation":1,"type1":"Ghost","type2":"Poison","hp":60,"attack":65,"defense":60,"specialAttack":130,"specialDefense":75,"speed":110},{"number":95,"name":"Onix","generation":1,"type1":"Rock","type2":"Ground","hp":35,"attack":45,"defense":160,"specialAttack":30,"specialDefense":45,"speed":70},{"number":96,"name":"Drowzee","generation":1,"type1":"Psychic","type2":null,"hp":60,"attack":48,"defense":45,"specialAttack":43,"specialDefense":90,"speed":42},{"number":97,"name":"Hypno","generation":1,"type1":"Psychic","type2":null,"hp":85,"attack":73,"defense":70,"specialAttack":73,"specialDefense":115,"speed":67},{"number":98,"name":"Krabby","generation":1,"type1":"Water","type2":null,"hp":30,"attack":105,"defense":90,"specialAttack":25,"specialDefense":25,"speed":50},{"number":99,"name":"Kingler","generation":1,"type1":"Water","type2":null,"hp":55,"attack":130,"defense":115,"specialAttack":50,"specialDefense":50,"speed":75},{"number":100,"name":"Voltorb","generation":1,"type1":"Electric","type2":null,"hp":40,"attack":30,"defense":50,"specialAttack":55,"specialDefense":55,"speed":100},{"number":101,"name":"Electrode","generation":1,"type1":"Electric","type2":null,"hp":60,"attack":50,"defense":70,"specialAttack":80,"specialDefense":80,"speed":150},{"number":102,"name":"Exeggcute","generation":1,"type1":"Grass","type2":"Psychic","hp":60,"attack":40,"defense":80,"specialAttack":60,"specialDefense":45,"speed":40},{"number":103,"name":"Exeggutor","generation":1,"type1":"Grass","type2":"Psychic","hp":95,"attack":95,"defense":85,"specialAttack":125,"specialDefense":75,"speed":55},{"number":104,"name":"Cubone","generation":1,"type1":"Ground","type2":null,"hp":50,"attack":50,"defense":95,"specialAttack":40,"specialDefense":50,"speed":35},{"number":105,"name":"Marowak","generation":1,"type1":"Ground","type2":null,"hp":60,"attack":80,"defense":110,"specialAttack":50,"specialDefense":80,"speed":45},{"number":106,"name":"Hitmonlee","generation":1,"type1":"Fighting","type2":null,"hp":50,"attack":120,"defense":53,"specialAttack":35,"specialDefense":110,"speed":87},{"number":107,"name":"Hitmonchan","generation":1,"type1":"Fighting","type2":null,"hp":50,"attack":105,"defense":79,"specialAttack":35,"specialDefense":110,"speed":76},{"number":108,"name":"Lickitung","generation":1,"type1":"Normal","type2":null,"hp":90,"attack":55,"defense":75,"specialAttack":60,"specialDefense":75,"speed":30},{"number":109,"name":"Koffing","generation":1,"type1":"Poison","type2":null,"hp":40,"attack":65,"defense":95,"specialAttack":60,"specialDefense":45,"speed":35},{"number":110,"name":"Weezing","generation":1,"type1":"Poison","type2":null,"hp":65,"attack":90,"defense":120,"specialAttack":85,"specialDefense":70,"speed":60},{"number":111,"name":"Rhyhorn","generation":1,"type1":"Ground","type2":"Rock","hp":80,"attack":85,"defense":95,"specialAttack":30,"specialDefense":30,"speed":25},{"number":112,"name":"Rhydon","generation":1,"type1":"Ground","type2":"Rock","hp":105,"attack":130,"defense":120,"specialAttack":45,"specialDefense":45,"speed":40},{"number":113,"name":"Chansey","generation":1,"type1":"Normal","type2":null,"hp":250,"attack":5,"defense":5,"specialAttack":35,"specialDefense":105,"speed":50},{"number":114,"name":"Tangela","generation":1,"type1":"Grass","type2":null,"hp":65,"attack":55,"defense":115,"specialAttack":100,"specialDefense":40,"speed":60},{"number":115,"name":"Kangaskhan","generation":1,"type1":"Normal","type2":null,"hp":105,"attack":95,"defense":80,"specialAttack":40,"specialDefense":80,"speed":90},{"number":116,"name":"Horsea","generation":1,"type1":"Water","type2":null,"hp":30,"attack":40,"defense":70,"specialAttack":70,"specialDefense":25,"speed":60},{"number":117,"name":"Seadra","generation":1,"type1":"Water","type2":null,"hp":55,"attack":65,"defense":95,"specialAttack":95,"specialDefense":45,"speed":85},{"number":118,"name":"Goldeen","generation":1,"type1":"Water","type2":null,"hp":45,"attack":67,"defense":60,"specialAttack":35,"specialDefense":50,"speed":63},{"number":119,"name":"Seaking","generation":1,"type1":"Water","type2":null,"hp":80,"attack":92,"defense":65,"specialAttack":65,"specialDefense":80,"speed":68},{"number":120,"name":"Staryu","generation":1,"type1":"Water","type2":null,"hp":30,"attack":45,"defense":55,"specialAttack":70,"specialDefense":55,"speed":85},{"number":121,"name":"Starmie","generation":1,"type1":"Water","type2":"Psychic","hp":60,"attack":75,"defense":85,"specialAttack":100,"specialDefense":85,"speed":115},{"number":122,"name":"Mr. Mime","generation":1,"type1":"Psychic","type2":"Fairy","hp":40,"attack":45,"defense":65,"specialAttack":100,"specialDefense":120,"speed":90},{"number":123,"name":"Scyther","generation":1,"type1":"Bug","type2":"Flying","hp":70,"attack":110,"defense":80,"specialAttack":55,"specialDefense":80,"speed":105},{"number":124,"name":"Jynx","generation":1,"type1":"Ice","type2":"Psychic","hp":65,"attack":50,"defense":35,"specialAttack":115,"specialDefense":95,"speed":95},{"number":125,"name":"Electabuzz","generation":1,"type1":"Electric","type2":null,"hp":65,"attack":83,"defense":57,"specialAttack":95,"specialDefense":85,"speed":105},{"number":126,"name":"Magmar","generation":1,"type1":"Fire","type2":null,"hp":65,"attack":95,"defense":57,"specialAttack":100,"specialDefense":85,"speed":93},{"number":127,"name":"Pinsir","generation":1,"type1":"Bug","type2":null,"hp":65,"attack":125,"defense":100,"specialAttack":55,"specialDefense":70,"speed":85},{"number":128,"name":"Tauros","generation":1,"type1":"Normal","type2":null,"hp":75,"attack":100,"defense":95,"specialAttack":40,"specialDefense":70,"speed":110},{"number":129,"name":"Magikarp","generation":1,"type1":"Water","type2":null,"hp":20,"attack":10,"defense":55,"specialAttack":15,"specialDefense":20,"speed":80},{"number":130,"name":"Gyarados","generation":1,"type1":"Water","type2":"Flying","hp":95,"attack":125,"defense":79,"specialAttack":60,"specialDefense":100,"speed":81},{"number":131,"name":"Lapras","generation":1,"type1":"Water","type2":"Ice","hp":130,"attack":85,"defense":80,"specialAttack":85,"specialDefense":95,"speed":60},{"number":132,"name":"Ditto","generation":1,"type1":"Normal","type2":null,"hp":48,"attack":48,"defense":48,"specialAttack":48,"specialDefense":48,"speed":48},{"number":133,"name":"Eevee","generation":1,"type1":"Normal","type2":null,"hp":55,"attack":55,"defense":50,"specialAttack":45,"specialDefense":65,"speed":55},{"number":134,"name":"Vaporeon","generation":1,"type1":"Water","type2":null,"hp":130,"attack":65,"defense":60,"specialAttack":110,"specialDefense":95,"speed":65},{"number":135,"name":"Jolteon","generation":1,"type1":"Electric","type2":null,"hp":65,"attack":65,"defense":60,"specialAttack":110,"specialDefense":95,"speed":130},{"number":136,"name":"Flareon","generation":1,"type1":"Fire","type2":null,"hp":65,"attack":130,"defense":60,"specialAttack":95,"specialDefense":110,"speed":65},{"number":137,"name":"Porygon","generation":1,"type1":"Normal","type2":null,"hp":65,"attack":60,"defense":70,"specialAttack":85,"specialDefense":75,"speed":40},{"number":138,"name":"Omanyte","generation":1,"type1":"Rock","type2":"Water","hp":35,"attack":40,"defense":100,"specialAttack":90,"specialDefense":55,"speed":35},{"number":139,"name":"Omastar","generation":1,"type1":"Rock","type2":"Water","hp":70,"attack":60,"defense":125,"specialAttack":115,"specialDefense":70,"speed":55},{"number":140,"name":"Kabuto","generation":1,"type1":"Rock","type2":"Water","hp":30,"attack":80,"defense":90,"specialAttack":55,"specialDefense":45,"speed":55},{"number":141,"name":"Kabutops","generation":1,"type1":"Rock","type2":"Water","hp":60,"attack":115,"defense":105,"specialAttack":65,"specialDefense":70,"speed":80},{"number":142,"name":"Aerodactyl","generation":1,"type1":"Rock","type2":"Flying","hp":80,"attack":105,"defense":65,"specialAttack":60,"specialDefense":75,"speed":130},{"number":143,"name":"Snorlax","generation":1,"type1":"Normal","type2":null,"hp":160,"attack":110,"defense":65,"specialAttack":65,"specialDefense":110,"speed":30},{"number":144,"name":"Articuno","generation":1,"type1":"Ice","type2":"Flying","hp":90,"attack":85,"defense":100,"specialAttack":95,"specialDefense":125,"speed":85},{"number":145,"name":"Zapdos","generation":1,"type1":"Electric","type2":"Flying","hp":90,"attack":90,"defense":85,"specialAttack":125,"specialDefense":90,"speed":100},{"number":146,"name":"Moltres","generation":1,"type1":"Fire","type2":"Flying","hp":90,"attack":100,"defense":90,"specialAttack":125,"specialDefense":85,"speed":90},{"number":147,"name":"Dratini","generation":1,"type1":"Dragon","type2":null,"hp":41,"attack":64,"defense":45,"specialAttack":50,"specialDefense":50,"speed":50},{"number":148,"name":"Dragonair","generation":1,"type1":"Dragon","type2":null,"hp":61,"attack":84,"defense":65,"specialAttack":70,"specialDefense":70,"speed":70},{"number":149,"name":"Dragonite","generation":1,"type1":"Dragon","type2":"Flying","hp":91,"attack":134,"defense":95,"specialAttack":100,"specialDefense":100,"speed":80},{"number":150,"name":"Mewtwo","generation":1,"type1":"Psychic","type2":null,"hp":106,"attack":110,"defense":90,"specialAttack":154,"specialDefense":90,"speed":130},{"number":151,"name":"Mew","generation":1,"type1":"Psychic","type2":null,"hp":100,"attack":100,"defense":100,"specialAttack":100,"specialDefense":100,"speed":100},{"number":152,"name":"Chikorita","generation":2,"type1":"Grass","type2":null,"hp":45,"attack":49,"defense":65,"specialAttack":49,"specialDefense":65,"speed":45},{"number":153,"name":"Bayleef","generation":2,"type1":"Grass","type2":null,"hp":60,"attack":62,"defense":80,"specialAttack":63,"specialDefense":80,"speed":60},{"number":154,"name":"Meganium","generation":2,"type1":"Grass","type2":null,"hp":80,"attack":82,"defense":100,"specialAttack":83,"specialDefense":100,"speed":80},{"number":155,"name":"Cyndaquil","generation":2,"type1":"Fire","type2":null,"hp":39,"attack":52,"defense":43,"specialAttack":60,"specialDefense":50,"speed":65},{"number":156,"name":"Quilava","generation":2,"type1":"Fire","type2":null,"hp":58,"attack":64,"defense":58,"specialAttack":80,"specialDefense":65,"speed":80},{"number":157,"name":"Typhlosion","generation":2,"type1":"Fire","type2":null,"hp":78,"attack":84,"defense":78,"specialAttack":109,"specialDefense":85,"speed":100},{"number":158,"name":"Totodile","generation":2,"type1":"Water","type2":null,"hp":50,"attack":65,"defense":64,"specialAttack":44,"specialDefense":48,"speed":43},{"number":159,"name":"Croconaw","generation":2,"type1":"Water","type2":null,"hp":65,"attack":80,"defense":80,"specialAttack":59,"specialDefense":63,"speed":58},{"number":160,"name":"Feraligatr","generation":2,"type1":"Water","type2":null,"hp":85,"attack":105,"defense":100,"specialAttack":79,"specialDefense":83,"speed":78},{"number":161,"name":"Sentret","generation":2,"type1":"Normal","type2":null,"hp":35,"attack":46,"defense":34,"specialAttack":35,"specialDefense":45,"speed":20},{"number":162,"name":"Furret","generation":2,"type1":"Normal","type2":null,"hp":85,"attack":76,"defense":64,"specialAttack":45,"specialDefense":55,"speed":90},{"number":163,"name":"Hoothoot","generation":2,"type1":"Normal","type2":"Flying","hp":60,"attack":30,"defense":30,"specialAttack":36,"specialDefense":56,"speed":50},{"number":164,"name":"Noctowl","generation":2,"type1":"Normal","type2":"Flying","hp":100,"attack":50,"defense":50,"specialAttack":86,"specialDefense":96,"speed":70},{"number":165,"name":"Ledyba","generation":2,"type1":"Bug","type2":"Flying","hp":40,"attack":20,"defense":30,"specialAttack":40,"specialDefense":80,"speed":55},{"number":166,"name":"Ledian","generation":2,"type1":"Bug","type2":"Flying","hp":55,"attack":35,"defense":50,"specialAttack":55,"specialDefense":110,"speed":85},{"number":167,"name":"Spinarak","generation":2,"type1":"Bug","type2":"Poison","hp":40,"attack":60,"defense":40,"specialAttack":40,"specialDefense":40,"speed":30},{"number":168,"name":"Ariados","generation":2,"type1":"Bug","type2":"Poison","hp":70,"attack":90,"defense":70,"specialAttack":60,"specialDefense":70,"speed":40},{"number":169,"name":"Crobat","generation":2,"type1":"Poison","type2":"Flying","hp":85,"attack":90,"defense":80,"specialAttack":70,"specialDefense":80,"speed":130},{"number":170,"name":"Chinchou","generation":2,"type1":"Water","type2":"Electric","hp":75,"attack":38,"defense":38,"specialAttack":56,"specialDefense":56,"speed":67},{"number":171,"name":"Lanturn","generation":2,"type1":"Water","type2":"Electric","hp":125,"attack":58,"defense":58,"specialAttack":76,"specialDefense":76,"speed":67},{"number":172,"name":"Pichu","generation":2,"type1":"Electric","type2":null,"hp":20,"attack":40,"defense":15,"specialAttack":35,"specialDefense":35,"speed":60},{"number":173,"name":"Cleffa","generation":2,"type1":"Fairy","type2":null,"hp":50,"attack":25,"defense":28,"specialAttack":45,"specialDefense":55,"speed":15},{"number":174,"name":"Igglybuff","generation":2,"type1":"Normal","type2":"Fairy","hp":90,"attack":30,"defense":15,"specialAttack":40,"specialDefense":20,"speed":15},{"number":175,"name":"Togepi","generation":2,"type1":"Fairy","type2":null,"hp":35,"attack":20,"defense":65,"specialAttack":40,"specialDefense":65,"speed":20},{"number":176,"name":"Togetic","generation":2,"type1":"Fairy","type2":"Flying","hp":55,"attack":40,"defense":85,"specialAttack":80,"specialDefense":105,"speed":40},{"number":177,"name":"Natu","generation":2,"type1":"Psychic","type2":"Flying","hp":40,"attack":50,"defense":45,"specialAttack":70,"specialDefense":45,"speed":70},{"number":178,"name":"Xatu","generation":2,"type1":"Psychic","type2":"Flying","hp":65,"attack":75,"defense":70,"specialAttack":95,"specialDefense":70,"speed":95},{"number":179,"name":"Mareep","generation":2,"type1":"Electric","type2":null,"hp":55,"attack":40,"defense":40,"specialAttack":65,"specialDefense":45,"speed":35},{"number":180,"name":"Flaaffy","generation":2,"type1":"Electric","type2":null,"hp":70,"attack":55,"defense":55,"specialAttack":80,"specialDefense":60,"speed":45},{"number":181,"name":"Ampharos","generation":2,"type1":"Electric","type2":null,"hp":90,"attack":75,"defense":85,"specialAttack":115,"specialDefense":90,"speed":55},{"number":182,"name":"Bellossom","generation":2,"type1":"Grass","type2":null,"hp":75,"attack":80,"defense":95,"specialAttack":90,"specialDefense":100,"speed":50},{"number":183,"name":"Marill","generation":2,"type1":"Water","type2":"Fairy","hp":70,"attack":20,"defense":50,"specialAttack":20,"specialDefense":50,"speed":40},{"number":184,"name":"Azumarill","generation":2,"type1":"Water","type2":"Fairy","hp":100,"attack":50,"defense":80,"specialAttack":60,"specialDefense":80,"speed":50},{"number":185,"name":"Sudowoodo","generation":2,"type1":"Rock","type2":null,"hp":70,"attack":100,"defense":115,"specialAttack":30,"specialDefense":65,"speed":30},{"number":186,"name":"Politoed","generation":2,"type1":"Water","type2":null,"hp":90,"attack":75,"defense":75,"specialAttack":90,"specialDefense":100,"speed":70},{"number":187,"name":"Hoppip","generation":2,"type1":"Grass","type2":"Flying","hp":35,"attack":35,"defense":40,"specialAttack":35,"specialDefense":55,"speed":50},{"number":188,"name":"Skiploom","generation":2,"type1":"Grass","type2":"Flying","hp":55,"attack":45,"defense":50,"specialAttack":45,"specialDefense":65,"speed":80},{"number":189,"name":"Jumpluff","generation":2,"type1":"Grass","type2":"Flying","hp":75,"attack":55,"defense":70,"specialAttack":55,"specialDefense":95,"speed":110},{"number":190,"name":"Aipom","generation":2,"type1":"Normal","type2":null,"hp":55,"attack":70,"defense":55,"specialAttack":40,"specialDefense":55,"speed":85},{"number":191,"name":"Sunkern","generation":2,"type1":"Grass","type2":null,"hp":30,"attack":30,"defense":30,"specialAttack":30,"specialDefense":30,"speed":30},{"number":192,"name":"Sunflora","generation":2,"type1":"Grass","type2":null,"hp":75,"attack":75,"defense":55,"specialAttack":105,"specialDefense":85,"speed":30},{"number":193,"name":"Yanma","generation":2,"type1":"Bug","type2":"Flying","hp":65,"attack":65,"defense":45,"specialAttack":75,"specialDefense":45,"speed":95},{"number":194,"name":"Wooper","generation":2,"type1":"Water","type2":"Ground","hp":55,"attack":45,"defense":45,"specialAttack":25,"specialDefense":25,"speed":15},{"number":195,"name":"Quagsire","generation":2,"type1":"Water","type2":"Ground","hp":95,"attack":85,"defense":85,"specialAttack":65,"specialDefense":65,"speed":35},{"number":196,"name":"Espeon","generation":2,"type1":"Psychic","type2":null,"hp":65,"attack":65,"defense":60,"specialAttack":130,"specialDefense":95,"speed":110},{"number":197,"name":"Umbreon","generation":2,"type1":"Dark","type2":null,"hp":95,"attack":65,"defense":110,"specialAttack":60,"specialDefense":130,"speed":65},{"number":198,"name":"Murkrow","generation":2,"type1":"Dark","type2":"Flying","hp":60,"attack":85,"defense":42,"specialAttack":85,"specialDefense":42,"speed":91},{"number":199,"name":"Slowking","generation":2,"type1":"Water","type2":"Psychic","hp":95,"attack":75,"defense":80,"specialAttack":100,"specialDefense":110,"speed":30},{"number":200,"name":"Misdreavus","generation":2,"type1":"Ghost","type2":null,"hp":60,"attack":60,"defense":60,"specialAttack":85,"specialDefense":85,"speed":85},{"number":201,"name":"Unown","generation":2,"type1":"Psychic","type2":null,"hp":48,"attack":72,"defense":48,"specialAttack":72,"specialDefense":48,"speed":48},{"number":202,"name":"Wobbuffet","generation":2,"type1":"Psychic","type2":null,"hp":190,"attack":33,"defense":58,"specialAttack":33,"specialDefense":58,"speed":33},{"number":203,"name":"Girafarig","generation":2,"type1":"Normal","type2":"Psychic","hp":70,"attack":80,"defense":65,"specialAttack":90,"specialDefense":65,"speed":85},{"number":204,"name":"Pineco","generation":2,"type1":"Bug","type2":null,"hp":50,"attack":65,"defense":90,"specialAttack":35,"specialDefense":35,"speed":15},{"number":205,"name":"Forretress","generation":2,"type1":"Bug","type2":"Steel","hp":75,"attack":90,"defense":140,"specialAttack":60,"specialDefense":60,"speed":40},{"number":206,"name":"Dunsparce","generation":2,"type1":"Normal","type2":null,"hp":100,"attack":70,"defense":70,"specialAttack":65,"specialDefense":65,"speed":45},{"number":207,"name":"Gligar","generation":2,"type1":"Ground","type2":"Flying","hp":65,"attack":75,"defense":105,"specialAttack":35,"specialDefense":65,"speed":85},{"number":208,"name":"Steelix","generation":2,"type1":"Steel","type2":"Ground","hp":75,"attack":85,"defense":200,"specialAttack":55,"specialDefense":65,"speed":30},{"number":209,"name":"Snubbull","generation":2,"type1":"Fairy","type2":null,"hp":60,"attack":80,"defense":50,"specialAttack":40,"specialDefense":40,"speed":30},{"number":210,"name":"Granbull","generation":2,"type1":"Fairy","type2":null,"hp":90,"attack":120,"defense":75,"specialAttack":60,"specialDefense":60,"speed":45},{"number":211,"name":"Qwilfish","generation":2,"type1":"Water","type2":"Poison","hp":65,"attack":95,"defense":85,"specialAttack":55,"specialDefense":55,"speed":85},{"number":212,"name":"Scizor","generation":2,"type1":"Bug","type2":"Steel","hp":70,"attack":130,"defense":100,"specialAttack":55,"specialDefense":80,"speed":65},{"number":213,"name":"Shuckle","generation":2,"type1":"Bug","type2":"Rock","hp":20,"attack":10,"defense":230,"specialAttack":10,"specialDefense":230,"speed":5},{"number":214,"name":"Heracross","generation":2,"type1":"Bug","type2":"Fighting","hp":80,"attack":125,"defense":75,"specialAttack":40,"specialDefense":95,"speed":85},{"number":215,"name":"Sneasel","generation":2,"type1":"Dark","type2":"Ice","hp":55,"attack":95,"defense":55,"specialAttack":35,"specialDefense":75,"speed":115},{"number":216,"name":"Teddiursa","generation":2,"type1":"Normal","type2":null,"hp":60,"attack":80,"defense":50,"specialAttack":50,"specialDefense":50,"speed":40},{"number":217,"name":"Ursaring","generation":2,"type1":"Normal","type2":null,"hp":90,"attack":130,"defense":75,"specialAttack":75,"specialDefense":75,"speed":55},{"number":218,"name":"Slugma","generation":2,"type1":"Fire","type2":null,"hp":40,"attack":40,"defense":40,"specialAttack":70,"specialDefense":40,"speed":20},{"number":219,"name":"Magcargo","generation":2,"type1":"Fire","type2":"Rock","hp":60,"attack":50,"defense":120,"specialAttack":90,"specialDefense":80,"speed":30},{"number":220,"name":"Swinub","generation":2,"type1":"Ice","type2":"Ground","hp":50,"attack":50,"defense":40,"specialAttack":30,"specialDefense":30,"speed":50},{"number":221,"name":"Piloswine","generation":2,"type1":"Ice","type2":"Ground","hp":100,"attack":100,"defense":80,"specialAttack":60,"specialDefense":60,"speed":50},{"number":222,"name":"Corsola","generation":2,"type1":"Water","type2":"Rock","hp":65,"attack":55,"defense":95,"specialAttack":65,"specialDefense":95,"speed":35},{"number":223,"name":"Remoraid","generation":2,"type1":"Water","type2":null,"hp":35,"attack":65,"defense":35,"specialAttack":65,"specialDefense":35,"speed":65},{"number":224,"name":"Octillery","generation":2,"type1":"Water","type2":null,"hp":75,"attack":105,"defense":75,"specialAttack":105,"specialDefense":75,"speed":45},{"number":225,"name":"Delibird","generation":2,"type1":"Ice","type2":"Flying","hp":45,"attack":55,"defense":45,"specialAttack":65,"specialDefense":45,"speed":75},{"number":226,"name":"Mantine","generation":2,"type1":"Water","type2":"Flying","hp":85,"attack":40,"defense":70,"specialAttack":80,"specialDefense":140,"speed":70},{"number":227,"name":"Skarmory","generation":2,"type1":"Steel","type2":"Flying","hp":65,"attack":80,"defense":140,"specialAttack":40,"specialDefense":70,"speed":70},{"number":228,"name":"Houndour","generation":2,"type1":"Dark","type2":"Fire","hp":45,"attack":60,"defense":30,"specialAttack":80,"specialDefense":50,"speed":65},{"number":229,"name":"Houndoom","generation":2,"type1":"Dark","type2":"Fire","hp":75,"attack":90,"defense":50,"specialAttack":110,"specialDefense":80,"speed":95},{"number":230,"name":"Kingdra","generation":2,"type1":"Water","type2":"Dragon","hp":75,"attack":95,"defense":95,"specialAttack":95,"specialDefense":95,"speed":85},{"number":231,"name":"Phanpy","generation":2,"type1":"Ground","type2":null,"hp":90,"attack":60,"defense":60,"specialAttack":40,"specialDefense":40,"speed":40},{"number":232,"name":"Donphan","generation":2,"type1":"Ground","type2":null,"hp":90,"attack":120,"defense":120,"specialAttack":60,"specialDefense":60,"speed":50},{"number":233,"name":"Porygon2","generation":2,"type1":"Normal","type2":null,"hp":85,"attack":80,"defense":90,"specialAttack":105,"specialDefense":95,"speed":60},{"number":234,"name":"Stantler","generation":2,"type1":"Normal","type2":null,"hp":73,"attack":95,"defense":62,"specialAttack":85,"specialDefense":65,"speed":85},{"number":235,"name":"Smeargle","generation":2,"type1":"Normal","type2":null,"hp":55,"attack":20,"defense":35,"specialAttack":20,"specialDefense":45,"speed":75},{"number":236,"name":"Tyrogue","generation":2,"type1":"Fighting","type2":null,"hp":35,"attack":35,"defense":35,"specialAttack":35,"specialDefense":35,"speed":35},{"number":237,"name":"Hitmontop","generation":2,"type1":"Fighting","type2":null,"hp":50,"attack":95,"defense":95,"specialAttack":35,"specialDefense":110,"speed":70},{"number":238,"name":"Smoochum","generation":2,"type1":"Ice","type2":"Psychic","hp":45,"attack":30,"defense":15,"specialAttack":85,"specialDefense":65,"speed":65},{"number":239,"name":"Elekid","generation":2,"type1":"Electric","type2":null,"hp":45,"attack":63,"defense":37,"specialAttack":65,"specialDefense":55,"speed":95},{"number":240,"name":"Magby","generation":2,"type1":"Fire","type2":null,"hp":45,"attack":75,"defense":37,"specialAttack":70,"specialDefense":55,"speed":83},{"number":241,"name":"Miltank","generation":2,"type1":"Normal","type2":null,"hp":95,"attack":80,"defense":105,"specialAttack":40,"specialDefense":70,"speed":100},{"number":242,"name":"Blissey","generation":2,"type1":"Normal","type2":null,"hp":255,"attack":10,"defense":10,"specialAttack":75,"specialDefense":135,"speed":55},{"number":243,"name":"Raikou","generation":2,"type1":"Electric","type2":null,"hp":90,"attack":85,"defense":75,"specialAttack":115,"specialDefense":100,"speed":115},{"number":244,"name":"Entei","generation":2,"type1":"Fire","type2":null,"hp":115,"attack":115,"defense":85,"specialAttack":90,"specialDefense":75,"speed":100},{"number":245,"name":"Suicune","generation":2,"type1":"Water","type2":null,"hp":100,"attack":75,"defense":115,"specialAttack":90,"specialDefense":115,"speed":85},{"number":246,"name":"Larvitar","generation":2,"type1":"Rock","type2":"Ground","hp":50,"attack":64,"defense":50,"specialAttack":45,"specialDefense":50,"speed":41},{"number":247,"name":"Pupitar","generation":2,"type1":"Rock","type2":"Ground","hp":70,"attack":84,"defense":70,"specialAttack":65,"specialDefense":70,"speed":51},{"number":248,"name":"Tyranitar","generation":2,"type1":"Rock","type2":"Dark","hp":100,"attack":134,"defense":110,"specialAttack":95,"specialDefense":100,"speed":61},{"number":249,"name":"Lugia","generation":2,"type1":"Psychic","type2":"Flying","hp":106,"attack":90,"defense":130,"specialAttack":90,"specialDefense":154,"speed":110},{"number":250,"name":"Ho-Oh","generation":2,"type1":"Fire","type2":"Flying","hp":106,"attack":130,"defense":90,"specialAttack":110,"specialDefense":154,"speed":90},{"number":251,"name":"Celebi","generation":2,"type1":"Psychic","type2":"Grass","hp":100,"attack":100,"defense":100,"specialAttack":100,"specialDefense":100,"speed":100},{"number":252,"name":"Treecko","generation":3,"type1":"Grass","type2":null,"hp":40,"attack":45,"defense":35,"specialAttack":65,"specialDefense":55,"speed":70},{"number":253,"name":"Grovyle","generation":3,"type1":"Grass","type2":null,"hp":50,"attack":65,"defense":45,"specialAttack":85,"specialDefense":65,"speed":95},{"number":254,"name":"Sceptile","generation":3,"type1":"Grass","type2":null,"hp":70,"attack":85,"defense":65,"specialAttack":105,"specialDefense":85,"speed":120},{"number":255,"name":"Torchic","generation":3,"type1":"Fire","type2":null,"hp":45,"attack":60,"defense":40,"specialAttack":70,"specialDefense":50,"speed":45},{"number":256,"name":"Combusken","generation":3,"type1":"Fire","type2":"Fighting","hp":60,"attack":85,"defense":60,"specialAttack":85,"specialDefense":60,"speed":55},{"number":257,"name":"Blaziken","generation":3,"type1":"Fire","type2":"Fighting","hp":80,"attack":120,"defense":70,"specialAttack":110,"specialDefense":70,"speed":80},{"number":258,"name":"Mudkip","generation":3,"type1":"Water","type2":null,"hp":50,"attack":70,"defense":50,"specialAttack":50,"specialDefense":50,"speed":40},{"number":259,"name":"Marshtomp","generation":3,"type1":"Water","type2":"Ground","hp":70,"attack":85,"defense":70,"specialAttack":60,"specialDefense":70,"speed":50},{"number":260,"name":"Swampert","generation":3,"type1":"Water","type2":"Ground","hp":100,"attack":110,"defense":90,"specialAttack":85,"specialDefense":90,"speed":60},{"number":261,"name":"Poochyena","generation":3,"type1":"Dark","type2":null,"hp":35,"attack":55,"defense":35,"specialAttack":30,"specialDefense":30,"speed":35},{"number":262,"name":"Mightyena","generation":3,"type1":"Dark","type2":null,"hp":70,"attack":90,"defense":70,"specialAttack":60,"specialDefense":60,"speed":70},{"number":263,"name":"Zigzagoon","generation":3,"type1":"Normal","type2":null,"hp":38,"attack":30,"defense":41,"specialAttack":30,"specialDefense":41,"speed":60},{"number":264,"name":"Linoone","generation":3,"type1":"Normal","type2":null,"hp":78,"attack":70,"defense":61,"specialAttack":50,"specialDefense":61,"speed":100},{"number":265,"name":"Wurmple","generation":3,"type1":"Bug","type2":null,"hp":45,"attack":45,"defense":35,"specialAttack":20,"specialDefense":30,"speed":20},{"number":266,"name":"Silcoon","generation":3,"type1":"Bug","type2":null,"hp":50,"attack":35,"defense":55,"specialAttack":25,"specialDefense":25,"speed":15},{"number":267,"name":"Beautifly","generation":3,"type1":"Bug","type2":"Flying","hp":60,"attack":70,"defense":50,"specialAttack":100,"specialDefense":50,"speed":65},{"number":268,"name":"Cascoon","generation":3,"type1":"Bug","type2":null,"hp":50,"attack":35,"defense":55,"specialAttack":25,"specialDefense":25,"speed":15},{"number":269,"name":"Dustox","generation":3,"type1":"Bug","type2":"Poison","hp":60,"attack":50,"defense":70,"specialAttack":50,"specialDefense":90,"speed":65},{"number":270,"name":"Lotad","generation":3,"type1":"Water","type2":"Grass","hp":40,"attack":30,"defense":30,"specialAttack":40,"specialDefense":50,"speed":30},{"number":271,"name":"Lombre","generation":3,"type1":"Water","type2":"Grass","hp":60,"attack":50,"defense":50,"specialAttack":60,"specialDefense":70,"speed":50},{"number":272,"name":"Ludicolo","generation":3,"type1":"Water","type2":"Grass","hp":80,"attack":70,"defense":70,"specialAttack":90,"specialDefense":100,"speed":70},{"number":273,"name":"Seedot","generation":3,"type1":"Grass","type2":null,"hp":40,"attack":40,"defense":50,"specialAttack":30,"specialDefense":30,"speed":30},{"number":274,"name":"Nuzleaf","generation":3,"type1":"Grass","type2":"Dark","hp":70,"attack":70,"defense":40,"specialAttack":60,"specialDefense":40,"speed":60},{"number":275,"name":"Shiftry","generation":3,"type1":"Grass","type2":"Dark","hp":90,"attack":100,"defense":60,"specialAttack":90,"specialDefense":60,"speed":80},{"number":276,"name":"Taillow","generation":3,"type1":"Normal","type2":"Flying","hp":40,"attack":55,"defense":30,"specialAttack":30,"specialDefense":30,"speed":85},{"number":277,"name":"Swellow","generation":3,"type1":"Normal","type2":"Flying","hp":60,"attack":85,"defense":60,"specialAttack":75,"specialDefense":50,"speed":125},{"number":278,"name":"Wingull","generation":3,"type1":"Water","type2":"Flying","hp":40,"attack":30,"defense":30,"specialAttack":55,"specialDefense":30,"speed":85},{"number":279,"name":"Pelipper","generation":3,"type1":"Water","type2":"Flying","hp":60,"attack":50,"defense":100,"specialAttack":95,"specialDefense":70,"speed":65},{"number":280,"name":"Ralts","generation":3,"type1":"Psychic","type2":"Fairy","hp":28,"attack":25,"defense":25,"specialAttack":45,"specialDefense":35,"speed":40},{"number":281,"name":"Kirlia","generation":3,"type1":"Psychic","type2":"Fairy","hp":38,"attack":35,"defense":35,"specialAttack":65,"specialDefense":55,"speed":50},{"number":282,"name":"Gardevoir","generation":3,"type1":"Psychic","type2":"Fairy","hp":68,"attack":65,"defense":65,"specialAttack":125,"specialDefense":115,"speed":80},{"number":283,"name":"Surskit","generation":3,"type1":"Bug","type2":"Water","hp":40,"attack":30,"defense":32,"specialAttack":50,"specialDefense":52,"speed":65},{"number":284,"name":"Masquerain","generation":3,"type1":"Bug","type2":"Flying","hp":70,"attack":60,"defense":62,"specialAttack":100,"specialDefense":82,"speed":80},{"number":285,"name":"Shroomish","generation":3,"type1":"Grass","type2":null,"hp":60,"attack":40,"defense":60,"specialAttack":40,"specialDefense":60,"speed":35},{"number":286,"name":"Breloom","generation":3,"type1":"Grass","type2":"Fighting","hp":60,"attack":130,"defense":80,"specialAttack":60,"specialDefense":60,"speed":70},{"number":287,"name":"Slakoth","generation":3,"type1":"Normal","type2":null,"hp":60,"attack":60,"defense":60,"specialAttack":35,"specialDefense":35,"speed":30},{"number":288,"name":"Vigoroth","generation":3,"type1":"Normal","type2":null,"hp":80,"attack":80,"defense":80,"specialAttack":55,"specialDefense":55,"speed":90},{"number":289,"name":"Slaking","generation":3,"type1":"Normal","type2":null,"hp":150,"attack":160,"defense":100,"specialAttack":95,"specialDefense":65,"speed":100},{"number":290,"name":"Nincada","generation":3,"type1":"Bug","type2":"Ground","hp":31,"attack":45,"defense":90,"specialAttack":30,"specialDefense":30,"speed":40},{"number":291,"name":"Ninjask","generation":3,"type1":"Bug","type2":"Flying","hp":61,"attack":90,"defense":45,"specialAttack":50,"specialDefense":50,"speed":160},{"number":292,"name":"Shedinja","generation":3,"type1":"Bug","type2":"Ghost","hp":1,"attack":90,"defense":45,"specialAttack":30,"specialDefense":30,"speed":40},{"number":293,"name":"Whismur","generation":3,"type1":"Normal","type2":null,"hp":64,"attack":51,"defense":23,"specialAttack":51,"specialDefense":23,"speed":28},{"number":294,"name":"Loudred","generation":3,"type1":"Normal","type2":null,"hp":84,"attack":71,"defense":43,"specialAttack":71,"specialDefense":43,"speed":48},{"number":295,"name":"Exploud","generation":3,"type1":"Normal","type2":null,"hp":104,"attack":91,"defense":63,"specialAttack":91,"specialDefense":73,"speed":68},{"number":296,"name":"Makuhita","generation":3,"type1":"Fighting","type2":null,"hp":72,"attack":60,"defense":30,"specialAttack":20,"specialDefense":30,"speed":25},{"number":297,"name":"Hariyama","generation":3,"type1":"Fighting","type2":null,"hp":144,"attack":120,"defense":60,"specialAttack":40,"specialDefense":60,"speed":50},{"number":298,"name":"Azurill","generation":3,"type1":"Normal","type2":"Fairy","hp":50,"attack":20,"defense":40,"specialAttack":20,"specialDefense":40,"speed":20},{"number":299,"name":"Nosepass","generation":3,"type1":"Rock","type2":null,"hp":30,"attack":45,"defense":135,"specialAttack":45,"specialDefense":90,"speed":30},{"number":300,"name":"Skitty","generation":3,"type1":"Normal","type2":null,"hp":50,"attack":45,"defense":45,"specialAttack":35,"specialDefense":35,"speed":50},{"number":301,"name":"Delcatty","generation":3,"type1":"Normal","type2":null,"hp":70,"attack":65,"defense":65,"specialAttack":55,"specialDefense":55,"speed":90},{"number":302,"name":"Sableye","generation":3,"type1":"Dark","type2":"Ghost","hp":50,"attack":75,"defense":75,"specialAttack":65,"specialDefense":65,"speed":50},{"number":303,"name":"Mawile","generation":3,"type1":"Steel","type2":"Fairy","hp":50,"attack":85,"defense":85,"specialAttack":55,"specialDefense":55,"speed":50},{"number":304,"name":"Aron","generation":3,"type1":"Steel","type2":"Rock","hp":50,"attack":70,"defense":100,"specialAttack":40,"specialDefense":40,"speed":30},{"number":305,"name":"Lairon","generation":3,"type1":"Steel","type2":"Rock","hp":60,"attack":90,"defense":140,"specialAttack":50,"specialDefense":50,"speed":40},{"number":306,"name":"Aggron","generation":3,"type1":"Steel","type2":"Rock","hp":70,"attack":110,"defense":180,"specialAttack":60,"specialDefense":60,"speed":50},{"number":307,"name":"Meditite","generation":3,"type1":"Fighting","type2":"Psychic","hp":30,"attack":40,"defense":55,"specialAttack":40,"specialDefense":55,"speed":60},{"number":308,"name":"Medicham","generation":3,"type1":"Fighting","type2":"Psychic","hp":60,"attack":60,"defense":75,"specialAttack":60,"specialDefense":75,"speed":80},{"number":309,"name":"Electrike","generation":3,"type1":"Electric","type2":null,"hp":40,"attack":45,"defense":40,"specialAttack":65,"specialDefense":40,"speed":65},{"number":310,"name":"Manectric","generation":3,"type1":"Electric","type2":null,"hp":70,"attack":75,"defense":60,"specialAttack":105,"specialDefense":60,"speed":105},{"number":311,"name":"Plusle","generation":3,"type1":"Electric","type2":null,"hp":60,"attack":50,"defense":40,"specialAttack":85,"specialDefense":75,"speed":95},{"number":312,"name":"Minun","generation":3,"type1":"Electric","type2":null,"hp":60,"attack":40,"defense":50,"specialAttack":75,"specialDefense":85,"speed":95},{"number":313,"name":"Volbeat","generation":3,"type1":"Bug","type2":null,"hp":65,"attack":73,"defense":75,"specialAttack":47,"specialDefense":85,"speed":85},{"number":314,"name":"Illumise","generation":3,"type1":"Bug","type2":null,"hp":65,"attack":47,"defense":75,"specialAttack":73,"specialDefense":85,"speed":85},{"number":315,"name":"Roselia","generation":3,"type1":"Grass","type2":"Poison","hp":50,"attack":60,"defense":45,"specialAttack":100,"specialDefense":80,"speed":65},{"number":316,"name":"Gulpin","generation":3,"type1":"Poison","type2":null,"hp":70,"attack":43,"defense":53,"specialAttack":43,"specialDefense":53,"speed":40},{"number":317,"name":"Swalot","generation":3,"type1":"Poison","type2":null,"hp":100,"attack":73,"defense":83,"specialAttack":73,"specialDefense":83,"speed":55},{"number":318,"name":"Carvanha","generation":3,"type1":"Water","type2":"Dark","hp":45,"attack":90,"defense":20,"specialAttack":65,"specialDefense":20,"speed":65},{"number":319,"name":"Sharpedo","generation":3,"type1":"Water","type2":"Dark","hp":70,"attack":120,"defense":40,"specialAttack":95,"specialDefense":40,"speed":95},{"number":320,"name":"Wailmer","generation":3,"type1":"Water","type2":null,"hp":130,"attack":70,"defense":35,"specialAttack":70,"specialDefense":35,"speed":60},{"number":321,"name":"Wailord","generation":3,"type1":"Water","type2":null,"hp":170,"attack":90,"defense":45,"specialAttack":90,"specialDefense":45,"speed":60},{"number":322,"name":"Numel","generation":3,"type1":"Fire","type2":"Ground","hp":60,"attack":60,"defense":40,"specialAttack":65,"specialDefense":45,"speed":35},{"number":323,"name":"Camerupt","generation":3,"type1":"Fire","type2":"Ground","hp":70,"attack":100,"defense":70,"specialAttack":105,"specialDefense":75,"speed":40},{"number":324,"name":"Torkoal","generation":3,"type1":"Fire","type2":null,"hp":70,"attack":85,"defense":140,"specialAttack":85,"specialDefense":70,"speed":20},{"number":325,"name":"Spoink","generation":3,"type1":"Psychic","type2":null,"hp":60,"attack":25,"defense":35,"specialAttack":70,"specialDefense":80,"speed":60},{"number":326,"name":"Grumpig","generation":3,"type1":"Psychic","type2":null,"hp":80,"attack":45,"defense":65,"specialAttack":90,"specialDefense":110,"speed":80},{"number":327,"name":"Spinda","generation":3,"type1":"Normal","type2":null,"hp":60,"attack":60,"defense":60,"specialAttack":60,"specialDefense":60,"speed":60},{"number":328,"name":"Trapinch","generation":3,"type1":"Ground","type2":null,"hp":45,"attack":100,"defense":45,"specialAttack":45,"specialDefense":45,"speed":10},{"number":329,"name":"Vibrava","generation":3,"type1":"Ground","type2":"Dragon","hp":50,"attack":70,"defense":50,"specialAttack":50,"specialDefense":50,"speed":70},{"number":330,"name":"Flygon","generation":3,"type1":"Ground","type2":"Dragon","hp":80,"attack":100,"defense":80,"specialAttack":80,"specialDefense":80,"speed":100},{"number":331,"name":"Cacnea","generation":3,"type1":"Grass","type2":null,"hp":50,"attack":85,"defense":40,"specialAttack":85,"specialDefense":40,"speed":35},{"number":332,"name":"Cacturne","generation":3,"type1":"Grass","type2":"Dark","hp":70,"attack":115,"defense":60,"specialAttack":115,"specialDefense":60,"speed":55},{"number":333,"name":"Swablu","generation":3,"type1":"Normal","type2":"Flying","hp":45,"attack":40,"defense":60,"specialAttack":40,"specialDefense":75,"speed":50},{"number":334,"name":"Altaria","generation":3,"type1":"Dragon","type2":"Flying","hp":75,"attack":70,"defense":90,"specialAttack":70,"specialDefense":105,"speed":80},{"number":335,"name":"Zangoose","generation":3,"type1":"Normal","type2":null,"hp":73,"attack":115,"defense":60,"specialAttack":60,"specialDefense":60,"speed":90},{"number":336,"name":"Seviper","generation":3,"type1":"Poison","type2":null,"hp":73,"attack":100,"defense":60,"specialAttack":100,"specialDefense":60,"speed":65},{"number":337,"name":"Lunatone","generation":3,"type1":"Rock","type2":"Psychic","hp":90,"attack":55,"defense":65,"specialAttack":95,"specialDefense":85,"speed":70},{"number":338,"name":"Solrock","generation":3,"type1":"Rock","type2":"Psychic","hp":90,"attack":95,"defense":85,"specialAttack":55,"specialDefense":65,"speed":70},{"number":339,"name":"Barboach","generation":3,"type1":"Water","type2":"Ground","hp":50,"attack":48,"defense":43,"specialAttack":46,"specialDefense":41,"speed":60},{"number":340,"name":"Whiscash","generation":3,"type1":"Water","type2":"Ground","hp":110,"attack":78,"defense":73,"specialAttack":76,"specialDefense":71,"speed":60},{"number":341,"name":"Corphish","generation":3,"type1":"Water","type2":null,"hp":43,"attack":80,"defense":65,"specialAttack":50,"specialDefense":35,"speed":35},{"number":342,"name":"Crawdaunt","generation":3,"type1":"Water","type2":"Dark","hp":63,"attack":120,"defense":85,"specialAttack":90,"specialDefense":55,"speed":55},{"number":343,"name":"Baltoy","generation":3,"type1":"Ground","type2":"Psychic","hp":40,"attack":40,"defense":55,"specialAttack":40,"specialDefense":70,"speed":55},{"number":344,"name":"Claydol","generation":3,"type1":"Ground","type2":"Psychic","hp":60,"attack":70,"defense":105,"specialAttack":70,"specialDefense":120,"speed":75},{"number":345,"name":"Lileep","generation":3,"type1":"Rock","type2":"Grass","hp":66,"attack":41,"defense":77,"specialAttack":61,"specialDefense":87,"speed":23},{"number":346,"name":"Cradily","generation":3,"type1":"Rock","type2":"Grass","hp":86,"attack":81,"defense":97,"specialAttack":81,"specialDefense":107,"speed":43},{"number":347,"name":"Anorith","generation":3,"type1":"Rock","type2":"Bug","hp":45,"attack":95,"defense":50,"specialAttack":40,"specialDefense":50,"speed":75},{"number":348,"name":"Armaldo","generation":3,"type1":"Rock","type2":"Bug","hp":75,"attack":125,"defense":100,"specialAttack":70,"specialDefense":80,"speed":45},{"number":349,"name":"Feebas","generation":3,"type1":"Water","type2":null,"hp":20,"attack":15,"defense":20,"specialAttack":10,"specialDefense":55,"speed":80},{"number":350,"name":"Milotic","generation":3,"type1":"Water","type2":null,"hp":95,"attack":60,"defense":79,"specialAttack":100,"specialDefense":125,"speed":81},{"number":351,"name":"Castform","generation":3,"type1":"Normal","type2":null,"hp":70,"attack":70,"defense":70,"specialAttack":70,"specialDefense":70,"speed":70},{"number":352,"name":"Kecleon","generation":3,"type1":"Normal","type2":null,"hp":60,"attack":90,"defense":70,"specialAttack":60,"specialDefense":120,"speed":40},{"number":353,"name":"Shuppet","generation":3,"type1":"Ghost","type2":null,"hp":44,"attack":75,"defense":35,"specialAttack":63,"specialDefense":33,"speed":45},{"number":354,"name":"Banette","generation":3,"type1":"Ghost","type2":null,"hp":64,"attack":115,"defense":65,"specialAttack":83,"specialDefense":63,"speed":65},{"number":355,"name":"Duskull","generation":3,"type1":"Ghost","type2":null,"hp":20,"attack":40,"defense":90,"specialAttack":30,"specialDefense":90,"speed":25},{"number":356,"name":"Dusclops","generation":3,"type1":"Ghost","type2":null,"hp":40,"attack":70,"defense":130,"specialAttack":60,"specialDefense":130,"speed":25},{"number":357,"name":"Tropius","generation":3,"type1":"Grass","type2":"Flying","hp":99,"attack":68,"defense":83,"specialAttack":72,"specialDefense":87,"speed":51},{"number":358,"name":"Chimecho","generation":3,"type1":"Psychic","type2":null,"hp":75,"attack":50,"defense":80,"specialAttack":95,"specialDefense":90,"speed":65},{"number":359,"name":"Absol","generation":3,"type1":"Dark","type2":null,"hp":65,"attack":130,"defense":60,"specialAttack":75,"specialDefense":60,"speed":75},{"number":360,"name":"Wynaut","generation":3,"type1":"Psychic","type2":null,"hp":95,"attack":23,"defense":48,"specialAttack":23,"specialDefense":48,"speed":23},{"number":361,"name":"Snorunt","generation":3,"type1":"Ice","type2":null,"hp":50,"attack":50,"defense":50,"specialAttack":50,"specialDefense":50,"speed":50},{"number":362,"name":"Glalie","generation":3,"type1":"Ice","type2":null,"hp":80,"attack":80,"defense":80,"specialAttack":80,"specialDefense":80,"speed":80},{"number":363,"name":"Spheal","generation":3,"type1":"Ice","type2":"Water","hp":70,"attack":40,"defense":50,"specialAttack":55,"specialDefense":50,"speed":25},{"number":364,"name":"Sealeo","generation":3,"type1":"Ice","type2":"Water","hp":90,"attack":60,"defense":70,"specialAttack":75,"specialDefense":70,"speed":45},{"number":365,"name":"Walrein","generation":3,"type1":"Ice","type2":"Water","hp":110,"attack":80,"defense":90,"specialAttack":95,"specialDefense":90,"speed":65},{"number":366,"name":"Clamperl","generation":3,"type1":"Water","type2":null,"hp":35,"attack":64,"defense":85,"specialAttack":74,"specialDefense":55,"speed":32},{"number":367,"name":"Huntail","generation":3,"type1":"Water","type2":null,"hp":55,"attack":104,"defense":105,"specialAttack":94,"specialDefense":75,"speed":52},{"number":368,"name":"Gorebyss","generation":3,"type1":"Water","type2":null,"hp":55,"attack":84,"defense":105,"specialAttack":114,"specialDefense":75,"speed":52},{"number":369,"name":"Relicanth","generation":3,"type1":"Water","type2":"Rock","hp":100,"attack":90,"defense":130,"specialAttack":45,"specialDefense":65,"speed":55},{"number":370,"name":"Luvdisc","generation":3,"type1":"Water","type2":null,"hp":43,"attack":30,"defense":55,"specialAttack":40,"specialDefense":65,"speed":97},{"number":371,"name":"Bagon","generation":3,"type1":"Dragon","type2":null,"hp":45,"attack":75,"defense":60,"specialAttack":40,"specialDefense":30,"speed":50},{"number":372,"name":"Shelgon","generation":3,"type1":"Dragon","type2":null,"hp":65,"attack":95,"defense":100,"specialAttack":60,"specialDefense":50,"speed":50},{"number":373,"name":"Salamence","generation":3,"type1":"Dragon","type2":"Flying","hp":95,"attack":135,"defense":80,"specialAttack":110,"specialDefense":80,"speed":100},{"number":374,"name":"Beldum","generation":3,"type1":"Steel","type2":"Psychic","hp":40,"attack":55,"defense":80,"specialAttack":35,"specialDefense":60,"speed":30},{"number":375,"name":"Metang","generation":3,"type1":"Steel","type2":"Psychic","hp":60,"attack":75,"defense":100,"specialAttack":55,"specialDefense":80,"speed":50},{"number":376,"name":"Metagross","generation":3,"type1":"Steel","type2":"Psychic","hp":80,"attack":135,"defense":130,"specialAttack":95,"specialDefense":90,"speed":70},{"number":377,"name":"Regirock","generation":3,"type1":"Rock","type2":null,"hp":80,"attack":100,"defense":200,"specialAttack":50,"specialDefense":100,"speed":50},{"number":378,"name":"Regice","generation":3,"type1":"Ice","type2":null,"hp":80,"attack":50,"defense":100,"specialAttack":100,"specialDefense":200,"speed":50},{"number":379,"name":"Registeel","generation":3,"type1":"Steel","type2":null,"hp":80,"attack":75,"defense":150,"specialAttack":75,"specialDefense":150,"speed":50},{"number":380,"name":"Latias","generation":3,"type1":"Dragon","type2":"Psychic","hp":80,"attack":80,"defense":90,"specialAttack":110,"specialDefense":130,"speed":110},{"number":381,"name":"Latios","generation":3,"type1":"Dragon","type2":"Psychic","hp":80,"attack":90,"defense":80,"specialAttack":130,"specialDefense":110,"speed":110},{"number":382,"name":"Kyogre","generation":3,"type1":"Water","type2":null,"hp":100,"attack":100,"defense":90,"specialAttack":150,"specialDefense":140,"speed":90},{"number":383,"name":"Groudon","generation":3,"type1":"Ground","type2":null,"hp":100,"attack":150,"defense":140,"specialAttack":100,"specialDefense":90,"speed":90},{"number":384,"name":"Rayquaza","generation":3,"type1":"Dragon","type2":"Flying","hp":105,"attack":150,"defense":90,"specialAttack":150,"specialDefense":90,"speed":95},{"number":385,"name":"Jirachi","generation":3,"type1":"Steel","type2":"Psychic","hp":100,"attack":100,"defense":100,"specialAttack":100,"specialDefense":100,"speed":100},{"number":386,"name":"Deoxys","generation":3,"type1":"Psychic","type2":null,"hp":50,"attack":150,"defense":50,"specialAttack":150,"specialDefense":50,"speed":150},{"number":387,"name":"Turtwig","generation":4,"type1":"Grass","type2":null,"hp":55,"attack":68,"defense":64,"specialAttack":45,"specialDefense":55,"speed":31},{"number":388,"name":"Grotle","generation":4,"type1":"Grass","type2":null,"hp":75,"attack":89,"defense":85,"specialAttack":55,"specialDefense":65,"speed":36},{"number":389,"name":"Torterra","generation":4,"type1":"Grass","type2":"Ground","hp":95,"attack":109,"defense":105,"specialAttack":75,"specialDefense":85,"speed":56},{"number":390,"name":"Chimchar","generation":4,"type1":"Fire","type2":null,"hp":44,"attack":58,"defense":44,"specialAttack":58,"specialDefense":44,"speed":61},{"number":391,"name":"Monferno","generation":4,"type1":"Fire","type2":"Fighting","hp":64,"attack":78,"defense":52,"specialAttack":78,"specialDefense":52,"speed":81},{"number":392,"name":"Infernape","generation":4,"type1":"Fire","type2":"Fighting","hp":76,"attack":104,"defense":71,"specialAttack":104,"specialDefense":71,"speed":108},{"number":393,"name":"Piplup","generation":4,"type1":"Water","type2":null,"hp":53,"attack":51,"defense":53,"specialAttack":61,"specialDefense":56,"speed":40},{"number":394,"name":"Prinplup","generation":4,"type1":"Water","type2":null,"hp":64,"attack":66,"defense":68,"specialAttack":81,"specialDefense":76,"speed":50},{"number":395,"name":"Empoleon","generation":4,"type1":"Water","type2":"Steel","hp":84,"attack":86,"defense":88,"specialAttack":111,"specialDefense":101,"speed":60},{"number":396,"name":"Starly","generation":4,"type1":"Normal","type2":"Flying","hp":40,"attack":55,"defense":30,"specialAttack":30,"specialDefense":30,"speed":60},{"number":397,"name":"Staravia","generation":4,"type1":"Normal","type2":"Flying","hp":55,"attack":75,"defense":50,"specialAttack":40,"specialDefense":40,"speed":80},{"number":398,"name":"Staraptor","generation":4,"type1":"Normal","type2":"Flying","hp":85,"attack":120,"defense":70,"specialAttack":50,"specialDefense":60,"speed":100},{"number":399,"name":"Bidoof","generation":4,"type1":"Normal","type2":null,"hp":59,"attack":45,"defense":40,"specialAttack":35,"specialDefense":40,"speed":31},{"number":400,"name":"Bibarel","generation":4,"type1":"Normal","type2":"Water","hp":79,"attack":85,"defense":60,"specialAttack":55,"specialDefense":60,"speed":71},{"number":401,"name":"Kricketot","generation":4,"type1":"Bug","type2":null,"hp":37,"attack":25,"defense":41,"specialAttack":25,"specialDefense":41,"speed":25},{"number":402,"name":"Kricketune","generation":4,"type1":"Bug","type2":null,"hp":77,"attack":85,"defense":51,"specialAttack":55,"specialDefense":51,"speed":65},{"number":403,"name":"Shinx","generation":4,"type1":"Electric","type2":null,"hp":45,"attack":65,"defense":34,"specialAttack":40,"specialDefense":34,"speed":45},{"number":404,"name":"Luxio","generation":4,"type1":"Electric","type2":null,"hp":60,"attack":85,"defense":49,"specialAttack":60,"specialDefense":49,"speed":60},{"number":405,"name":"Luxray","generation":4,"type1":"Electric","type2":null,"hp":80,"attack":120,"defense":79,"specialAttack":95,"specialDefense":79,"speed":70},{"number":406,"name":"Budew","generation":4,"type1":"Grass","type2":"Poison","hp":40,"attack":30,"defense":35,"specialAttack":50,"specialDefense":70,"speed":55},{"number":407,"name":"Roserade","generation":4,"type1":"Grass","type2":"Poison","hp":60,"attack":70,"defense":65,"specialAttack":125,"specialDefense":105,"speed":90},{"number":408,"name":"Cranidos","generation":4,"type1":"Rock","type2":null,"hp":67,"attack":125,"defense":40,"specialAttack":30,"specialDefense":30,"speed":58},{"number":409,"name":"Rampardos","generation":4,"type1":"Rock","type2":null,"hp":97,"attack":165,"defense":60,"specialAttack":65,"specialDefense":50,"speed":58},{"number":410,"name":"Shieldon","generation":4,"type1":"Rock","type2":"Steel","hp":30,"attack":42,"defense":118,"specialAttack":42,"specialDefense":88,"speed":30},{"number":411,"name":"Bastiodon","generation":4,"type1":"Rock","type2":"Steel","hp":60,"attack":52,"defense":168,"specialAttack":47,"specialDefense":138,"speed":30},{"number":412,"name":"Burmy","generation":4,"type1":"Bug","type2":null,"hp":40,"attack":29,"defense":45,"specialAttack":29,"specialDefense":45,"speed":36},{"number":413,"name":"Wormadam","generation":4,"type1":"Bug","type2":"Grass","hp":60,"attack":59,"defense":85,"specialAttack":79,"specialDefense":105,"speed":36},{"number":414,"name":"Mothim","generation":4,"type1":"Bug","type2":"Flying","hp":70,"attack":94,"defense":50,"specialAttack":94,"specialDefense":50,"speed":66},{"number":415,"name":"Combee","generation":4,"type1":"Bug","type2":"Flying","hp":30,"attack":30,"defense":42,"specialAttack":30,"specialDefense":42,"speed":70},{"number":416,"name":"Vespiquen","generation":4,"type1":"Bug","type2":"Flying","hp":70,"attack":80,"defense":102,"specialAttack":80,"specialDefense":102,"speed":40},{"number":417,"name":"Pachirisu","generation":4,"type1":"Electric","type2":null,"hp":60,"attack":45,"defense":70,"specialAttack":45,"specialDefense":90,"speed":95},{"number":418,"name":"Buizel","generation":4,"type1":"Water","type2":null,"hp":55,"attack":65,"defense":35,"specialAttack":60,"specialDefense":30,"speed":85},{"number":419,"name":"Floatzel","generation":4,"type1":"Water","type2":null,"hp":85,"attack":105,"defense":55,"specialAttack":85,"specialDefense":50,"speed":115},{"number":420,"name":"Cherubi","generation":4,"type1":"Grass","type2":null,"hp":45,"attack":35,"defense":45,"specialAttack":62,"specialDefense":53,"speed":35},{"number":421,"name":"Cherrim","generation":4,"type1":"Grass","type2":null,"hp":70,"attack":60,"defense":70,"specialAttack":87,"specialDefense":78,"speed":85},{"number":422,"name":"Shellos","generation":4,"type1":"Water","type2":null,"hp":76,"attack":48,"defense":48,"specialAttack":57,"specialDefense":62,"speed":34},{"number":423,"name":"Gastrodon","generation":4,"type1":"Water","type2":"Ground","hp":111,"attack":83,"defense":68,"specialAttack":92,"specialDefense":82,"speed":39},{"number":424,"name":"Ambipom","generation":4,"type1":"Normal","type2":null,"hp":75,"attack":100,"defense":66,"specialAttack":60,"specialDefense":66,"speed":115},{"number":425,"name":"Drifloon","generation":4,"type1":"Ghost","type2":"Flying","hp":90,"attack":50,"defense":34,"specialAttack":60,"specialDefense":44,"speed":70},{"number":426,"name":"Drifblim","generation":4,"type1":"Ghost","type2":"Flying","hp":150,"attack":80,"defense":44,"specialAttack":90,"specialDefense":54,"speed":80},{"number":427,"name":"Buneary","generation":4,"type1":"Normal","type2":null,"hp":55,"attack":66,"defense":44,"specialAttack":44,"specialDefense":56,"speed":85},{"number":428,"name":"Lopunny","generation":4,"type1":"Normal","type2":null,"hp":65,"attack":76,"defense":84,"specialAttack":54,"specialDefense":96,"speed":105},{"number":429,"name":"Mismagius","generation":4,"type1":"Ghost","type2":null,"hp":60,"attack":60,"defense":60,"specialAttack":105,"specialDefense":105,"speed":105},{"number":430,"name":"Honchkrow","generation":4,"type1":"Dark","type2":"Flying","hp":100,"attack":125,"defense":52,"specialAttack":105,"specialDefense":52,"speed":71},{"number":431,"name":"Glameow","generation":4,"type1":"Normal","type2":null,"hp":49,"attack":55,"defense":42,"specialAttack":42,"specialDefense":37,"speed":85},{"number":432,"name":"Purugly","generation":4,"type1":"Normal","type2":null,"hp":71,"attack":82,"defense":64,"specialAttack":64,"specialDefense":59,"speed":112},{"number":433,"name":"Chingling","generation":4,"type1":"Psychic","type2":null,"hp":45,"attack":30,"defense":50,"specialAttack":65,"specialDefense":50,"speed":45},{"number":434,"name":"Stunky","generation":4,"type1":"Poison","type2":"Dark","hp":63,"attack":63,"defense":47,"specialAttack":41,"specialDefense":41,"speed":74},{"number":435,"name":"Skuntank","generation":4,"type1":"Poison","type2":"Dark","hp":103,"attack":93,"defense":67,"specialAttack":71,"specialDefense":61,"speed":84},{"number":436,"name":"Bronzor","generation":4,"type1":"Steel","type2":"Psychic","hp":57,"attack":24,"defense":86,"specialAttack":24,"specialDefense":86,"speed":23},{"number":437,"name":"Bronzong","generation":4,"type1":"Steel","type2":"Psychic","hp":67,"attack":89,"defense":116,"specialAttack":79,"specialDefense":116,"speed":33},{"number":438,"name":"Bonsly","generation":4,"type1":"Rock","type2":null,"hp":50,"attack":80,"defense":95,"specialAttack":10,"specialDefense":45,"speed":10},{"number":439,"name":"Mime Jr.","generation":4,"type1":"Psychic","type2":"Fairy","hp":20,"attack":25,"defense":45,"specialAttack":70,"specialDefense":90,"speed":60},{"number":440,"name":"Happiny","generation":4,"type1":"Normal","type2":null,"hp":100,"attack":5,"defense":5,"specialAttack":15,"specialDefense":65,"speed":30},{"number":441,"name":"Chatot","generation":4,"type1":"Normal","type2":"Flying","hp":76,"attack":65,"defense":45,"specialAttack":92,"specialDefense":42,"speed":91},{"number":442,"name":"Spiritomb","generation":4,"type1":"Ghost","type2":"Dark","hp":50,"attack":92,"defense":108,"specialAttack":92,"specialDefense":108,"speed":35},{"number":443,"name":"Gible","generation":4,"type1":"Dragon","type2":"Ground","hp":58,"attack":70,"defense":45,"specialAttack":40,"specialDefense":45,"speed":42},{"number":444,"name":"Gabite","generation":4,"type1":"Dragon","type2":"Ground","hp":68,"attack":90,"defense":65,"specialAttack":50,"specialDefense":55,"speed":82},{"number":445,"name":"Garchomp","generation":4,"type1":"Dragon","type2":"Ground","hp":108,"attack":130,"defense":95,"specialAttack":80,"specialDefense":85,"speed":102},{"number":446,"name":"Munchlax","generation":4,"type1":"Normal","type2":null,"hp":135,"attack":85,"defense":40,"specialAttack":40,"specialDefense":85,"speed":5},{"number":447,"name":"Riolu","generation":4,"type1":"Fighting","type2":null,"hp":40,"attack":70,"defense":40,"specialAttack":35,"specialDefense":40,"speed":60},{"number":448,"name":"Lucario","generation":4,"type1":"Fighting","type2":"Steel","hp":70,"attack":110,"defense":70,"specialAttack":115,"specialDefense":70,"speed":90},{"number":449,"name":"Hippopotas","generation":4,"type1":"Ground","type2":null,"hp":68,"attack":72,"defense":78,"specialAttack":38,"specialDefense":42,"speed":32},{"number":450,"name":"Hippowdon","generation":4,"type1":"Ground","type2":null,"hp":108,"attack":112,"defense":118,"specialAttack":68,"specialDefense":72,"speed":47},{"number":451,"name":"Skorupi","generation":4,"type1":"Poison","type2":"Bug","hp":40,"attack":50,"defense":90,"specialAttack":30,"specialDefense":55,"speed":65},{"number":452,"name":"Drapion","generation":4,"type1":"Poison","type2":"Dark","hp":70,"attack":90,"defense":110,"specialAttack":60,"specialDefense":75,"speed":95},{"number":453,"name":"Croagunk","generation":4,"type1":"Poison","type2":"Fighting","hp":48,"attack":61,"defense":40,"specialAttack":61,"specialDefense":40,"speed":50},{"number":454,"name":"Toxicroak","generation":4,"type1":"Poison","type2":"Fighting","hp":83,"attack":106,"defense":65,"specialAttack":86,"specialDefense":65,"speed":85},{"number":455,"name":"Carnivine","generation":4,"type1":"Grass","type2":null,"hp":74,"attack":100,"defense":72,"specialAttack":90,"specialDefense":72,"speed":46},{"number":456,"name":"Finneon","generation":4,"type1":"Water","type2":null,"hp":49,"attack":49,"defense":56,"specialAttack":49,"specialDefense":61,"speed":66},{"number":457,"name":"Lumineon","generation":4,"type1":"Water","type2":null,"hp":69,"attack":69,"defense":76,"specialAttack":69,"specialDefense":86,"speed":91},{"number":458,"name":"Mantyke","generation":4,"type1":"Water","type2":"Flying","hp":45,"attack":20,"defense":50,"specialAttack":60,"specialDefense":120,"speed":50},{"number":459,"name":"Snover","generation":4,"type1":"Grass","type2":"Ice","hp":60,"attack":62,"defense":50,"specialAttack":62,"specialDefense":60,"speed":40},{"number":460,"name":"Abomasnow","generation":4,"type1":"Grass","type2":"Ice","hp":90,"attack":92,"defense":75,"specialAttack":92,"specialDefense":85,"speed":60},{"number":461,"name":"Weavile","generation":4,"type1":"Dark","type2":"Ice","hp":70,"attack":120,"defense":65,"specialAttack":45,"specialDefense":85,"speed":125},{"number":462,"name":"Magnezone","generation":4,"type1":"Electric","type2":"Steel","hp":70,"attack":70,"defense":115,"specialAttack":130,"specialDefense":90,"speed":60},{"number":463,"name":"Lickilicky","generation":4,"type1":"Normal","type2":null,"hp":110,"attack":85,"defense":95,"specialAttack":80,"specialDefense":95,"speed":50},{"number":464,"name":"Rhyperior","generation":4,"type1":"Ground","type2":"Rock","hp":115,"attack":140,"defense":130,"specialAttack":55,"specialDefense":55,"speed":40},{"number":465,"name":"Tangrowth","generation":4,"type1":"Grass","type2":null,"hp":100,"attack":100,"defense":125,"specialAttack":110,"specialDefense":50,"speed":50},{"number":466,"name":"Electivire","generation":4,"type1":"Electric","type2":null,"hp":75,"attack":123,"defense":67,"specialAttack":95,"specialDefense":85,"speed":95},{"number":467,"name":"Magmortar","generation":4,"type1":"Fire","type2":null,"hp":75,"attack":95,"defense":67,"specialAttack":125,"specialDefense":95,"speed":83},{"number":468,"name":"Togekiss","generation":4,"type1":"Fairy","type2":"Flying","hp":85,"attack":50,"defense":95,"specialAttack":120,"specialDefense":115,"speed":80},{"number":469,"name":"Yanmega","generation":4,"type1":"Bug","type2":"Flying","hp":86,"attack":76,"defense":86,"specialAttack":116,"specialDefense":56,"speed":95},{"number":470,"name":"Leafeon","generation":4,"type1":"Grass","type2":null,"hp":65,"attack":110,"defense":130,"specialAttack":60,"specialDefense":65,"speed":95},{"number":471,"name":"Glaceon","generation":4,"type1":"Ice","type2":null,"hp":65,"attack":60,"defense":110,"specialAttack":130,"specialDefense":95,"speed":65},{"number":472,"name":"Gliscor","generation":4,"type1":"Ground","type2":"Flying","hp":75,"attack":95,"defense":125,"specialAttack":45,"specialDefense":75,"speed":95},{"number":473,"name":"Mamoswine","generation":4,"type1":"Ice","type2":"Ground","hp":110,"attack":130,"defense":80,"specialAttack":70,"specialDefense":60,"speed":80},{"number":474,"name":"Porygon-Z","generation":4,"type1":"Normal","type2":null,"hp":85,"attack":80,"defense":70,"specialAttack":135,"specialDefense":75,"speed":90},{"number":475,"name":"Gallade","generation":4,"type1":"Psychic","type2":"Fighting","hp":68,"attack":125,"defense":65,"specialAttack":65,"specialDefense":115,"speed":80},{"number":476,"name":"Probopass","generation":4,"type1":"Rock","type2":"Steel","hp":60,"attack":55,"defense":145,"specialAttack":75,"specialDefense":150,"speed":40},{"number":477,"name":"Dusknoir","generation":4,"type1":"Ghost","type2":null,"hp":45,"attack":100,"defense":135,"specialAttack":65,"specialDefense":135,"speed":45},{"number":478,"name":"Froslass","generation":4,"type1":"Ice","type2":"Ghost","hp":70,"attack":80,"defense":70,"specialAttack":80,"specialDefense":70,"speed":110},{"number":479,"name":"Rotom","generation":4,"type1":"Electric","type2":"Ghost","hp":50,"attack":50,"defense":77,"specialAttack":95,"specialDefense":77,"speed":91},{"number":480,"name":"Uxie","generation":4,"type1":"Psychic","type2":null,"hp":75,"attack":75,"defense":130,"specialAttack":75,"specialDefense":130,"speed":95},{"number":481,"name":"Mesprit","generation":4,"type1":"Psychic","type2":null,"hp":80,"attack":105,"defense":105,"specialAttack":105,"specialDefense":105,"speed":80},{"number":482,"name":"Azelf","generation":4,"type1":"Psychic","type2":null,"hp":75,"attack":125,"defense":70,"specialAttack":125,"specialDefense":70,"speed":115},{"number":483,"name":"Dialga","generation":4,"type1":"Steel","type2":"Dragon","hp":100,"attack":120,"defense":120,"specialAttack":150,"specialDefense":100,"speed":90},{"number":484,"name":"Palkia","generation":4,"type1":"Water","type2":"Dragon","hp":90,"attack":120,"defense":100,"specialAttack":150,"specialDefense":120,"speed":100},{"number":485,"name":"Heatran","generation":4,"type1":"Fire","type2":"Steel","hp":91,"attack":90,"defense":106,"specialAttack":130,"specialDefense":106,"speed":77},{"number":486,"name":"Regigigas","generation":4,"type1":"Normal","type2":null,"hp":110,"attack":160,"defense":110,"specialAttack":80,"specialDefense":110,"speed":100},{"number":487,"name":"Giratina","generation":4,"type1":"Ghost","type2":"Dragon","hp":150,"attack":100,"defense":120,"specialAttack":100,"specialDefense":120,"speed":90},{"number":488,"name":"Cresselia","generation":4,"type1":"Psychic","type2":null,"hp":120,"attack":70,"defense":110,"specialAttack":75,"specialDefense":120,"speed":85},{"number":489,"name":"Phione","generation":4,"type1":"Water","type2":null,"hp":80,"attack":80,"defense":80,"specialAttack":80,"specialDefense":80,"speed":80},{"number":490,"name":"Manaphy","generation":4,"type1":"Water","type2":null,"hp":100,"attack":100,"defense":100,"specialAttack":100,"specialDefense":100,"speed":100},{"number":491,"name":"Darkrai","generation":4,"type1":"Dark","type2":null,"hp":70,"attack":90,"defense":90,"specialAttack":135,"specialDefense":90,"speed":125},{"number":492,"name":"Shaymin","generation":4,"type1":"Grass","type2":null,"hp":100,"attack":100,"defense":100,"specialAttack":100,"specialDefense":100,"speed":100},{"number":493,"name":"Arceus","generation":4,"type1":"Normal","type2":null,"hp":120,"attack":120,"defense":120,"specialAttack":120,"specialDefense":120,"speed":120},{"number":494,"name":"Victini","generation":5,"type1":"Psychic","type2":"Fire","hp":100,"attack":100,"defense":100,"specialAttack":100,"specialDefense":100,"speed":100},{"number":495,"name":"Snivy","generation":5,"type1":"Grass","type2":null,"hp":45,"attack":45,"defense":55,"specialAttack":45,"specialDefense":55,"speed":63},{"number":496,"name":"Servine","generation":5,"type1":"Grass","type2":null,"hp":60,"attack":60,"defense":75,"specialAttack":60,"specialDefense":75,"speed":83},{"number":497,"name":"Serperior","generation":5,"type1":"Grass","type2":null,"hp":75,"attack":75,"defense":95,"specialAttack":75,"specialDefense":95,"speed":113},{"number":498,"name":"Tepig","generation":5,"type1":"Fire","type2":null,"hp":65,"attack":63,"defense":45,"specialAttack":45,"specialDefense":45,"speed":45},{"number":499,"name":"Pignite","generation":5,"type1":"Fire","type2":"Fighting","hp":90,"attack":93,"defense":55,"specialAttack":70,"specialDefense":55,"speed":55},{"number":500,"name":"Emboar","generation":5,"type1":"Fire","type2":"Fighting","hp":110,"attack":123,"defense":65,"specialAttack":100,"specialDefense":65,"speed":65},{"number":501,"name":"Oshawott","generation":5,"type1":"Water","type2":null,"hp":55,"attack":55,"defense":45,"specialAttack":63,"specialDefense":45,"speed":45},{"number":502,"name":"Dewott","generation":5,"type1":"Water","type2":null,"hp":75,"attack":75,"defense":60,"specialAttack":83,"specialDefense":60,"speed":60},{"number":503,"name":"Samurott","generation":5,"type1":"Water","type2":null,"hp":95,"attack":100,"defense":85,"specialAttack":108,"specialDefense":70,"speed":70},{"number":504,"name":"Patrat","generation":5,"type1":"Normal","type2":null,"hp":45,"attack":55,"defense":39,"specialAttack":35,"specialDefense":39,"speed":42},{"number":505,"name":"Watchog","generation":5,"type1":"Normal","type2":null,"hp":60,"attack":85,"defense":69,"specialAttack":60,"specialDefense":69,"speed":77},{"number":506,"name":"Lillipup","generation":5,"type1":"Normal","type2":null,"hp":45,"attack":60,"defense":45,"specialAttack":25,"specialDefense":45,"speed":55},{"number":507,"name":"Herdier","generation":5,"type1":"Normal","type2":null,"hp":65,"attack":80,"defense":65,"specialAttack":35,"specialDefense":65,"speed":60},{"number":508,"name":"Stoutland","generation":5,"type1":"Normal","type2":null,"hp":85,"attack":110,"defense":90,"specialAttack":45,"specialDefense":90,"speed":80},{"number":509,"name":"Purrloin","generation":5,"type1":"Dark","type2":null,"hp":41,"attack":50,"defense":37,"specialAttack":50,"specialDefense":37,"speed":66},{"number":510,"name":"Liepard","generation":5,"type1":"Dark","type2":null,"hp":64,"attack":88,"defense":50,"specialAttack":88,"specialDefense":50,"speed":106},{"number":511,"name":"Pansage","generation":5,"type1":"Grass","type2":null,"hp":50,"attack":53,"defense":48,"specialAttack":53,"specialDefense":48,"speed":64},{"number":512,"name":"Simisage","generation":5,"type1":"Grass","type2":null,"hp":75,"attack":98,"defense":63,"specialAttack":98,"specialDefense":63,"speed":101},{"number":513,"name":"Pansear","generation":5,"type1":"Fire","type2":null,"hp":50,"attack":53,"defense":48,"specialAttack":53,"specialDefense":48,"speed":64},{"number":514,"name":"Simisear","generation":5,"type1":"Fire","type2":null,"hp":75,"attack":98,"defense":63,"specialAttack":98,"specialDefense":63,"speed":101},{"number":515,"name":"Panpour","generation":5,"type1":"Water","type2":null,"hp":50,"attack":53,"defense":48,"specialAttack":53,"specialDefense":48,"speed":64},{"number":516,"name":"Simipour","generation":5,"type1":"Water","type2":null,"hp":75,"attack":98,"defense":63,"specialAttack":98,"specialDefense":63,"speed":101},{"number":517,"name":"Munna","generation":5,"type1":"Psychic","type2":null,"hp":76,"attack":25,"defense":45,"specialAttack":67,"specialDefense":55,"speed":24},{"number":518,"name":"Musharna","generation":5,"type1":"Psychic","type2":null,"hp":116,"attack":55,"defense":85,"specialAttack":107,"specialDefense":95,"speed":29},{"number":519,"name":"Pidove","generation":5,"type1":"Normal","type2":"Flying","hp":50,"attack":55,"defense":50,"specialAttack":36,"specialDefense":30,"speed":43},{"number":520,"name":"Tranquill","generation":5,"type1":"Normal","type2":"Flying","hp":62,"attack":77,"defense":62,"specialAttack":50,"specialDefense":42,"speed":65},{"number":521,"name":"Unfezant","generation":5,"type1":"Normal","type2":"Flying","hp":80,"attack":115,"defense":80,"specialAttack":65,"specialDefense":55,"speed":93},{"number":522,"name":"Blitzle","generation":5,"type1":"Electric","type2":null,"hp":45,"attack":60,"defense":32,"specialAttack":50,"specialDefense":32,"speed":76},{"number":523,"name":"Zebstrika","generation":5,"type1":"Electric","type2":null,"hp":75,"attack":100,"defense":63,"specialAttack":80,"specialDefense":63,"speed":116},{"number":524,"name":"Roggenrola","generation":5,"type1":"Rock","type2":null,"hp":55,"attack":75,"defense":85,"specialAttack":25,"specialDefense":25,"speed":15},{"number":525,"name":"Boldore","generation":5,"type1":"Rock","type2":null,"hp":70,"attack":105,"defense":105,"specialAttack":50,"specialDefense":40,"speed":20},{"number":526,"name":"Gigalith","generation":5,"type1":"Rock","type2":null,"hp":85,"attack":135,"defense":130,"specialAttack":60,"specialDefense":80,"speed":25},{"number":527,"name":"Woobat","generation":5,"type1":"Psychic","type2":"Flying","hp":65,"attack":45,"defense":43,"specialAttack":55,"specialDefense":43,"speed":72},{"number":528,"name":"Swoobat","generation":5,"type1":"Psychic","type2":"Flying","hp":67,"attack":57,"defense":55,"specialAttack":77,"specialDefense":55,"speed":114},{"number":529,"name":"Drilbur","generation":5,"type1":"Ground","type2":null,"hp":60,"attack":85,"defense":40,"specialAttack":30,"specialDefense":45,"speed":68},{"number":530,"name":"Excadrill","generation":5,"type1":"Ground","type2":"Steel","hp":110,"attack":135,"defense":60,"specialAttack":50,"specialDefense":65,"speed":88},{"number":531,"name":"Audino","generation":5,"type1":"Normal","type2":null,"hp":103,"attack":60,"defense":86,"specialAttack":60,"specialDefense":86,"speed":50},{"number":532,"name":"Timburr","generation":5,"type1":"Fighting","type2":null,"hp":75,"attack":80,"defense":55,"specialAttack":25,"specialDefense":35,"speed":35},{"number":533,"name":"Gurdurr","generation":5,"type1":"Fighting","type2":null,"hp":85,"attack":105,"defense":85,"specialAttack":40,"specialDefense":50,"speed":40},{"number":534,"name":"Conkeldurr","generation":5,"type1":"Fighting","type2":null,"hp":105,"attack":140,"defense":95,"specialAttack":55,"specialDefense":65,"speed":45},{"number":535,"name":"Tympole","generation":5,"type1":"Water","type2":null,"hp":50,"attack":50,"defense":40,"specialAttack":50,"specialDefense":40,"speed":64},{"number":536,"name":"Palpitoad","generation":5,"type1":"Water","type2":"Ground","hp":75,"attack":65,"defense":55,"specialAttack":65,"specialDefense":55,"speed":69},{"number":537,"name":"Seismitoad","generation":5,"type1":"Water","type2":"Ground","hp":105,"attack":95,"defense":75,"specialAttack":85,"specialDefense":75,"speed":74},{"number":538,"name":"Throh","generation":5,"type1":"Fighting","type2":null,"hp":120,"attack":100,"defense":85,"specialAttack":30,"specialDefense":85,"speed":45},{"number":539,"name":"Sawk","generation":5,"type1":"Fighting","type2":null,"hp":75,"attack":125,"defense":75,"specialAttack":30,"specialDefense":75,"speed":85},{"number":540,"name":"Sewaddle","generation":5,"type1":"Bug","type2":"Grass","hp":45,"attack":53,"defense":70,"specialAttack":40,"specialDefense":60,"speed":42},{"number":541,"name":"Swadloon","generation":5,"type1":"Bug","type2":"Grass","hp":55,"attack":63,"defense":90,"specialAttack":50,"specialDefense":80,"speed":42},{"number":542,"name":"Leavanny","generation":5,"type1":"Bug","type2":"Grass","hp":75,"attack":103,"defense":80,"specialAttack":70,"specialDefense":80,"speed":92},{"number":543,"name":"Venipede","generation":5,"type1":"Bug","type2":"Poison","hp":30,"attack":45,"defense":59,"specialAttack":30,"specialDefense":39,"speed":57},{"number":544,"name":"Whirlipede","generation":5,"type1":"Bug","type2":"Poison","hp":40,"attack":55,"defense":99,"specialAttack":40,"specialDefense":79,"speed":47},{"number":545,"name":"Scolipede","generation":5,"type1":"Bug","type2":"Poison","hp":60,"attack":100,"defense":89,"specialAttack":55,"specialDefense":69,"speed":112},{"number":546,"name":"Cottonee","generation":5,"type1":"Grass","type2":"Fairy","hp":40,"attack":27,"defense":60,"specialAttack":37,"specialDefense":50,"speed":66},{"number":547,"name":"Whimsicott","generation":5,"type1":"Grass","type2":"Fairy","hp":60,"attack":67,"defense":85,"specialAttack":77,"specialDefense":75,"speed":116},{"number":548,"name":"Petilil","generation":5,"type1":"Grass","type2":null,"hp":45,"attack":35,"defense":50,"specialAttack":70,"specialDefense":50,"speed":30},{"number":549,"name":"Lilligant","generation":5,"type1":"Grass","type2":null,"hp":70,"attack":60,"defense":75,"specialAttack":110,"specialDefense":75,"speed":90},{"number":550,"name":"Basculin","generation":5,"type1":"Water","type2":null,"hp":70,"attack":92,"defense":65,"specialAttack":80,"specialDefense":55,"speed":98},{"number":551,"name":"Sandile","generation":5,"type1":"Ground","type2":"Dark","hp":50,"attack":72,"defense":35,"specialAttack":35,"specialDefense":35,"speed":65},{"number":552,"name":"Krokorok","generation":5,"type1":"Ground","type2":"Dark","hp":60,"attack":82,"defense":45,"specialAttack":45,"specialDefense":45,"speed":74},{"number":553,"name":"Krookodile","generation":5,"type1":"Ground","type2":"Dark","hp":95,"attack":117,"defense":80,"specialAttack":65,"specialDefense":70,"speed":92},{"number":554,"name":"Darumaka","generation":5,"type1":"Fire","type2":null,"hp":70,"attack":90,"defense":45,"specialAttack":15,"specialDefense":45,"speed":50},{"number":555,"name":"Darmanitan","generation":5,"type1":"Fire","type2":null,"hp":105,"attack":140,"defense":55,"specialAttack":30,"specialDefense":55,"speed":95},{"number":556,"name":"Maractus","generation":5,"type1":"Grass","type2":null,"hp":75,"attack":86,"defense":67,"specialAttack":106,"specialDefense":67,"speed":60},{"number":557,"name":"Dwebble","generation":5,"type1":"Bug","type2":"Rock","hp":50,"attack":65,"defense":85,"specialAttack":35,"specialDefense":35,"speed":55},{"number":558,"name":"Crustle","generation":5,"type1":"Bug","type2":"Rock","hp":70,"attack":105,"defense":125,"specialAttack":65,"specialDefense":75,"speed":45},{"number":559,"name":"Scraggy","generation":5,"type1":"Dark","type2":"Fighting","hp":50,"attack":75,"defense":70,"specialAttack":35,"specialDefense":70,"speed":48},{"number":560,"name":"Scrafty","generation":5,"type1":"Dark","type2":"Fighting","hp":65,"attack":90,"defense":115,"specialAttack":45,"specialDefense":115,"speed":58},{"number":561,"name":"Sigilyph","generation":5,"type1":"Psychic","type2":"Flying","hp":72,"attack":58,"defense":80,"specialAttack":103,"specialDefense":80,"speed":97},{"number":562,"name":"Yamask","generation":5,"type1":"Ghost","type2":null,"hp":38,"attack":30,"defense":85,"specialAttack":55,"specialDefense":65,"speed":30},{"number":563,"name":"Cofagrigus","generation":5,"type1":"Ghost","type2":null,"hp":58,"attack":50,"defense":145,"specialAttack":95,"specialDefense":105,"speed":30},{"number":564,"name":"Tirtouga","generation":5,"type1":"Water","type2":"Rock","hp":54,"attack":78,"defense":103,"specialAttack":53,"specialDefense":45,"speed":22},{"number":565,"name":"Carracosta","generation":5,"type1":"Water","type2":"Rock","hp":74,"attack":108,"defense":133,"specialAttack":83,"specialDefense":65,"speed":32},{"number":566,"name":"Archen","generation":5,"type1":"Rock","type2":"Flying","hp":55,"attack":112,"defense":45,"specialAttack":74,"specialDefense":45,"speed":70},{"number":567,"name":"Archeops","generation":5,"type1":"Rock","type2":"Flying","hp":75,"attack":140,"defense":65,"specialAttack":112,"specialDefense":65,"speed":110},{"number":568,"name":"Trubbish","generation":5,"type1":"Poison","type2":null,"hp":50,"attack":50,"defense":62,"specialAttack":40,"specialDefense":62,"speed":65},{"number":569,"name":"Garbodor","generation":5,"type1":"Poison","type2":null,"hp":80,"attack":95,"defense":82,"specialAttack":60,"specialDefense":82,"speed":75},{"number":570,"name":"Zorua","generation":5,"type1":"Dark","type2":null,"hp":40,"attack":65,"defense":40,"specialAttack":80,"specialDefense":40,"speed":65},{"number":571,"name":"Zoroark","generation":5,"type1":"Dark","type2":null,"hp":60,"attack":105,"defense":60,"specialAttack":120,"specialDefense":60,"speed":105},{"number":572,"name":"Minccino","generation":5,"type1":"Normal","type2":null,"hp":55,"attack":50,"defense":40,"specialAttack":40,"specialDefense":40,"speed":75},{"number":573,"name":"Cinccino","generation":5,"type1":"Normal","type2":null,"hp":75,"attack":95,"defense":60,"specialAttack":65,"specialDefense":60,"speed":115},{"number":574,"name":"Gothita","generation":5,"type1":"Psychic","type2":null,"hp":45,"attack":30,"defense":50,"specialAttack":55,"specialDefense":65,"speed":45},{"number":575,"name":"Gothorita","generation":5,"type1":"Psychic","type2":null,"hp":60,"attack":45,"defense":70,"specialAttack":75,"specialDefense":85,"speed":55},{"number":576,"name":"Gothitelle","generation":5,"type1":"Psychic","type2":null,"hp":70,"attack":55,"defense":95,"specialAttack":95,"specialDefense":110,"speed":65},{"number":577,"name":"Solosis","generation":5,"type1":"Psychic","type2":null,"hp":45,"attack":30,"defense":40,"specialAttack":105,"specialDefense":50,"speed":20},{"number":578,"name":"Duosion","generation":5,"type1":"Psychic","type2":null,"hp":65,"attack":40,"defense":50,"specialAttack":125,"specialDefense":60,"speed":30},{"number":579,"name":"Reuniclus","generation":5,"type1":"Psychic","type2":null,"hp":110,"attack":65,"defense":75,"specialAttack":125,"specialDefense":85,"speed":30},{"number":580,"name":"Ducklett","generation":5,"type1":"Water","type2":"Flying","hp":62,"attack":44,"defense":50,"specialAttack":44,"specialDefense":50,"speed":55},{"number":581,"name":"Swanna","generation":5,"type1":"Water","type2":"Flying","hp":75,"attack":87,"defense":63,"specialAttack":87,"specialDefense":63,"speed":98},{"number":582,"name":"Vanillite","generation":5,"type1":"Ice","type2":null,"hp":36,"attack":50,"defense":50,"specialAttack":65,"specialDefense":60,"speed":44},{"number":583,"name":"Vanillish","generation":5,"type1":"Ice","type2":null,"hp":51,"attack":65,"defense":65,"specialAttack":80,"specialDefense":75,"speed":59},{"number":584,"name":"Vanilluxe","generation":5,"type1":"Ice","type2":null,"hp":71,"attack":95,"defense":85,"specialAttack":110,"specialDefense":95,"speed":79},{"number":585,"name":"Deerling","generation":5,"type1":"Normal","type2":"Grass","hp":60,"attack":60,"defense":50,"specialAttack":40,"specialDefense":50,"speed":75},{"number":586,"name":"Sawsbuck","generation":5,"type1":"Normal","type2":"Grass","hp":80,"attack":100,"defense":70,"specialAttack":60,"specialDefense":70,"speed":95},{"number":587,"name":"Emolga","generation":5,"type1":"Electric","type2":"Flying","hp":55,"attack":75,"defense":60,"specialAttack":75,"specialDefense":60,"speed":103},{"number":588,"name":"Karrablast","generation":5,"type1":"Bug","type2":null,"hp":50,"attack":75,"defense":45,"specialAttack":40,"specialDefense":45,"speed":60},{"number":589,"name":"Escavalier","generation":5,"type1":"Bug","type2":"Steel","hp":70,"attack":135,"defense":105,"specialAttack":60,"specialDefense":105,"speed":20},{"number":590,"name":"Foongus","generation":5,"type1":"Grass","type2":"Poison","hp":69,"attack":55,"defense":45,"specialAttack":55,"specialDefense":55,"speed":15},{"number":591,"name":"Amoonguss","generation":5,"type1":"Grass","type2":"Poison","hp":114,"attack":85,"defense":70,"specialAttack":85,"specialDefense":80,"speed":30},{"number":592,"name":"Frillish","generation":5,"type1":"Water","type2":"Ghost","hp":55,"attack":40,"defense":50,"specialAttack":65,"specialDefense":85,"speed":40},{"number":593,"name":"Jellicent","generation":5,"type1":"Water","type2":"Ghost","hp":100,"attack":60,"defense":70,"specialAttack":85,"specialDefense":105,"speed":60},{"number":594,"name":"Alomomola","generation":5,"type1":"Water","type2":null,"hp":165,"attack":75,"defense":80,"specialAttack":40,"specialDefense":45,"speed":65},{"number":595,"name":"Joltik","generation":5,"type1":"Bug","type2":"Electric","hp":50,"attack":47,"defense":50,"specialAttack":57,"specialDefense":50,"speed":65},{"number":596,"name":"Galvantula","generation":5,"type1":"Bug","type2":"Electric","hp":70,"attack":77,"defense":60,"specialAttack":97,"specialDefense":60,"speed":108},{"number":597,"name":"Ferroseed","generation":5,"type1":"Grass","type2":"Steel","hp":44,"attack":50,"defense":91,"specialAttack":24,"specialDefense":86,"speed":10},{"number":598,"name":"Ferrothorn","generation":5,"type1":"Grass","type2":"Steel","hp":74,"attack":94,"defense":131,"specialAttack":54,"specialDefense":116,"speed":20},{"number":599,"name":"Klink","generation":5,"type1":"Steel","type2":null,"hp":40,"attack":55,"defense":70,"specialAttack":45,"specialDefense":60,"speed":30},{"number":600,"name":"Klang","generation":5,"type1":"Steel","type2":null,"hp":60,"attack":80,"defense":95,"specialAttack":70,"specialDefense":85,"speed":50},{"number":601,"name":"Klinklang","generation":5,"type1":"Steel","type2":null,"hp":60,"attack":100,"defense":115,"specialAttack":70,"specialDefense":85,"speed":90},{"number":602,"name":"Tynamo","generation":5,"type1":"Electric","type2":null,"hp":35,"attack":55,"defense":40,"specialAttack":45,"specialDefense":40,"speed":60},{"number":603,"name":"Eelektrik","generation":5,"type1":"Electric","type2":null,"hp":65,"attack":85,"defense":70,"specialAttack":75,"specialDefense":70,"speed":40},{"number":604,"name":"Eelektross","generation":5,"type1":"Electric","type2":null,"hp":85,"attack":115,"defense":80,"specialAttack":105,"specialDefense":80,"speed":50},{"number":605,"name":"Elgyem","generation":5,"type1":"Psychic","type2":null,"hp":55,"attack":55,"defense":55,"specialAttack":85,"specialDefense":55,"speed":30},{"number":606,"name":"Beheeyem","generation":5,"type1":"Psychic","type2":null,"hp":75,"attack":75,"defense":75,"specialAttack":125,"specialDefense":95,"speed":40},{"number":607,"name":"Litwick","generation":5,"type1":"Ghost","type2":"Fire","hp":50,"attack":30,"defense":55,"specialAttack":65,"specialDefense":55,"speed":20},{"number":608,"name":"Lampent","generation":5,"type1":"Ghost","type2":"Fire","hp":60,"attack":40,"defense":60,"specialAttack":95,"specialDefense":60,"speed":55},{"number":609,"name":"Chandelure","generation":5,"type1":"Ghost","type2":"Fire","hp":60,"attack":55,"defense":90,"specialAttack":145,"specialDefense":90,"speed":80},{"number":610,"name":"Axew","generation":5,"type1":"Dragon","type2":null,"hp":46,"attack":87,"defense":60,"specialAttack":30,"specialDefense":40,"speed":57},{"number":611,"name":"Fraxure","generation":5,"type1":"Dragon","type2":null,"hp":66,"attack":117,"defense":70,"specialAttack":40,"specialDefense":50,"speed":67},{"number":612,"name":"Haxorus","generation":5,"type1":"Dragon","type2":null,"hp":76,"attack":147,"defense":90,"specialAttack":60,"specialDefense":70,"speed":97},{"number":613,"name":"Cubchoo","generation":5,"type1":"Ice","type2":null,"hp":55,"attack":70,"defense":40,"specialAttack":60,"specialDefense":40,"speed":40},{"number":614,"name":"Beartic","generation":5,"type1":"Ice","type2":null,"hp":95,"attack":130,"defense":80,"specialAttack":70,"specialDefense":80,"speed":50},{"number":615,"name":"Cryogonal","generation":5,"type1":"Ice","type2":null,"hp":80,"attack":50,"defense":50,"specialAttack":95,"specialDefense":135,"speed":105},{"number":616,"name":"Shelmet","generation":5,"type1":"Bug","type2":null,"hp":50,"attack":40,"defense":85,"specialAttack":40,"specialDefense":65,"speed":25},{"number":617,"name":"Accelgor","generation":5,"type1":"Bug","type2":null,"hp":80,"attack":70,"defense":40,"specialAttack":100,"specialDefense":60,"speed":145},{"number":618,"name":"Stunfisk","generation":5,"type1":"Ground","type2":"Electric","hp":109,"attack":66,"defense":84,"specialAttack":81,"specialDefense":99,"speed":32},{"number":619,"name":"Mienfoo","generation":5,"type1":"Fighting","type2":null,"hp":45,"attack":85,"defense":50,"specialAttack":55,"specialDefense":50,"speed":65},{"number":620,"name":"Mienshao","generation":5,"type1":"Fighting","type2":null,"hp":65,"attack":125,"defense":60,"specialAttack":95,"specialDefense":60,"speed":105},{"number":621,"name":"Druddigon","generation":5,"type1":"Dragon","type2":null,"hp":77,"attack":120,"defense":90,"specialAttack":60,"specialDefense":90,"speed":48},{"number":622,"name":"Golett","generation":5,"type1":"Ground","type2":"Ghost","hp":59,"attack":74,"defense":50,"specialAttack":35,"specialDefense":50,"speed":35},{"number":623,"name":"Golurk","generation":5,"type1":"Ground","type2":"Ghost","hp":89,"attack":124,"defense":80,"specialAttack":55,"specialDefense":80,"speed":55},{"number":624,"name":"Pawniard","generation":5,"type1":"Dark","type2":"Steel","hp":45,"attack":85,"defense":70,"specialAttack":40,"specialDefense":40,"speed":60},{"number":625,"name":"Bisharp","generation":5,"type1":"Dark","type2":"Steel","hp":65,"attack":125,"defense":100,"specialAttack":60,"specialDefense":70,"speed":70},{"number":626,"name":"Bouffalant","generation":5,"type1":"Normal","type2":null,"hp":95,"attack":110,"defense":95,"specialAttack":40,"specialDefense":95,"speed":55},{"number":627,"name":"Rufflet","generation":5,"type1":"Normal","type2":"Flying","hp":70,"attack":83,"defense":50,"specialAttack":37,"specialDefense":50,"speed":60},{"number":628,"name":"Braviary","generation":5,"type1":"Normal","type2":"Flying","hp":100,"attack":123,"defense":75,"specialAttack":57,"specialDefense":75,"speed":80},{"number":629,"name":"Vullaby","generation":5,"type1":"Dark","type2":"Flying","hp":70,"attack":55,"defense":75,"specialAttack":45,"specialDefense":65,"speed":60},{"number":630,"name":"Mandibuzz","generation":5,"type1":"Dark","type2":"Flying","hp":110,"attack":65,"defense":105,"specialAttack":55,"specialDefense":95,"speed":80},{"number":631,"name":"Heatmor","generation":5,"type1":"Fire","type2":null,"hp":85,"attack":97,"defense":66,"specialAttack":105,"specialDefense":66,"speed":65},{"number":632,"name":"Durant","generation":5,"type1":"Bug","type2":"Steel","hp":58,"attack":109,"defense":112,"specialAttack":48,"specialDefense":48,"speed":109},{"number":633,"name":"Deino","generation":5,"type1":"Dark","type2":"Dragon","hp":52,"attack":65,"defense":50,"specialAttack":45,"specialDefense":50,"speed":38},{"number":634,"name":"Zweilous","generation":5,"type1":"Dark","type2":"Dragon","hp":72,"attack":85,"defense":70,"specialAttack":65,"specialDefense":70,"speed":58},{"number":635,"name":"Hydreigon","generation":5,"type1":"Dark","type2":"Dragon","hp":92,"attack":105,"defense":90,"specialAttack":125,"specialDefense":90,"speed":98},{"number":636,"name":"Larvesta","generation":5,"type1":"Bug","type2":"Fire","hp":55,"attack":85,"defense":55,"specialAttack":50,"specialDefense":55,"speed":60},{"number":637,"name":"Volcarona","generation":5,"type1":"Bug","type2":"Fire","hp":85,"attack":60,"defense":65,"specialAttack":135,"specialDefense":105,"speed":100},{"number":638,"name":"Cobalion","generation":5,"type1":"Steel","type2":"Fighting","hp":91,"attack":90,"defense":129,"specialAttack":90,"specialDefense":72,"speed":108},{"number":639,"name":"Terrakion","generation":5,"type1":"Rock","type2":"Fighting","hp":91,"attack":129,"defense":90,"specialAttack":72,"specialDefense":90,"speed":108},{"number":640,"name":"Virizion","generation":5,"type1":"Grass","type2":"Fighting","hp":91,"attack":90,"defense":72,"specialAttack":90,"specialDefense":129,"speed":108},{"number":641,"name":"Tornadus","generation":5,"type1":"Flying","type2":null,"hp":79,"attack":115,"defense":70,"specialAttack":125,"specialDefense":80,"speed":111},{"number":642,"name":"Thundurus","generation":5,"type1":"Electric","type2":"Flying","hp":79,"attack":115,"defense":70,"specialAttack":125,"specialDefense":80,"speed":111},{"number":643,"name":"Reshiram","generation":5,"type1":"Dragon","type2":"Fire","hp":100,"attack":120,"defense":100,"specialAttack":150,"specialDefense":120,"speed":90},{"number":644,"name":"Zekrom","generation":5,"type1":"Dragon","type2":"Electric","hp":100,"attack":150,"defense":120,"specialAttack":120,"specialDefense":100,"speed":90},{"number":645,"name":"Landorus","generation":5,"type1":"Ground","type2":"Flying","hp":89,"attack":125,"defense":90,"specialAttack":115,"specialDefense":80,"speed":101},{"number":646,"name":"Kyurem","generation":5,"type1":"Dragon","type2":"Ice","hp":125,"attack":130,"defense":90,"specialAttack":130,"specialDefense":90,"speed":95},{"number":647,"name":"Keldeo","generation":5,"type1":"Water","type2":"Fighting","hp":91,"attack":72,"defense":90,"specialAttack":129,"specialDefense":90,"speed":108},{"number":648,"name":"Meloetta","generation":5,"type1":"Normal","type2":"Psychic","hp":100,"attack":77,"defense":77,"specialAttack":128,"specialDefense":128,"speed":90},{"number":649,"name":"Genesect","generation":5,"type1":"Bug","type2":"Steel","hp":71,"attack":120,"defense":95,"specialAttack":120,"specialDefense":95,"speed":99},{"number":650,"name":"Chespin","generation":6,"type1":"Grass","type2":null,"hp":56,"attack":61,"defense":65,"specialAttack":48,"specialDefense":45,"speed":38},{"number":651,"name":"Quilladin","generation":6,"type1":"Grass","type2":null,"hp":61,"attack":78,"defense":95,"specialAttack":56,"specialDefense":58,"speed":57},{"number":652,"name":"Chesnaught","generation":6,"type1":"Grass","type2":"Fighting","hp":88,"attack":107,"defense":122,"specialAttack":74,"specialDefense":75,"speed":64},{"number":653,"name":"Fennekin","generation":6,"type1":"Fire","type2":null,"hp":40,"attack":45,"defense":40,"specialAttack":62,"specialDefense":60,"speed":60},{"number":654,"name":"Braixen","generation":6,"type1":"Fire","type2":null,"hp":59,"attack":59,"defense":58,"specialAttack":90,"specialDefense":70,"speed":73},{"number":655,"name":"Delphox","generation":6,"type1":"Fire","type2":"Psychic","hp":75,"attack":69,"defense":72,"specialAttack":114,"specialDefense":100,"speed":104},{"number":656,"name":"Froakie","generation":6,"type1":"Water","type2":null,"hp":41,"attack":56,"defense":40,"specialAttack":62,"specialDefense":44,"speed":71},{"number":657,"name":"Frogadier","generation":6,"type1":"Water","type2":null,"hp":54,"attack":63,"defense":52,"specialAttack":83,"specialDefense":56,"speed":97},{"number":658,"name":"Greninja","generation":6,"type1":"Water","type2":"Dark","hp":72,"attack":95,"defense":67,"specialAttack":103,"specialDefense":71,"speed":122},{"number":659,"name":"Bunnelby","generation":6,"type1":"Normal","type2":null,"hp":38,"attack":36,"defense":38,"specialAttack":32,"specialDefense":36,"speed":57},{"number":660,"name":"Diggersby","generation":6,"type1":"Normal","type2":"Ground","hp":85,"attack":56,"defense":77,"specialAttack":50,"specialDefense":77,"speed":78},{"number":661,"name":"Fletchling","generation":6,"type1":"Normal","type2":"Flying","hp":45,"attack":50,"defense":43,"specialAttack":40,"specialDefense":38,"speed":62},{"number":662,"name":"Fletchinder","generation":6,"type1":"Fire","type2":"Flying","hp":62,"attack":73,"defense":55,"specialAttack":56,"specialDefense":52,"speed":84},{"number":663,"name":"Talonflame","generation":6,"type1":"Fire","type2":"Flying","hp":78,"attack":81,"defense":71,"specialAttack":74,"specialDefense":69,"speed":126},{"number":664,"name":"Scatterbug","generation":6,"type1":"Bug","type2":null,"hp":38,"attack":35,"defense":40,"specialAttack":27,"specialDefense":25,"speed":35},{"number":665,"name":"Spewpa","generation":6,"type1":"Bug","type2":null,"hp":45,"attack":22,"defense":60,"specialAttack":27,"specialDefense":30,"speed":29},{"number":666,"name":"Vivillon","generation":6,"type1":"Bug","type2":"Flying","hp":80,"attack":52,"defense":50,"specialAttack":90,"specialDefense":50,"speed":89},{"number":667,"name":"Litleo","generation":6,"type1":"Fire","type2":"Normal","hp":62,"attack":50,"defense":58,"specialAttack":73,"specialDefense":54,"speed":72},{"number":668,"name":"Pyroar","generation":6,"type1":"Fire","type2":"Normal","hp":86,"attack":68,"defense":72,"specialAttack":109,"specialDefense":66,"speed":106},{"number":669,"name":"Flabébé","generation":6,"type1":"Fairy","type2":null,"hp":44,"attack":38,"defense":39,"specialAttack":61,"specialDefense":79,"speed":42},{"number":670,"name":"Floette","generation":6,"type1":"Fairy","type2":null,"hp":54,"attack":45,"defense":47,"specialAttack":75,"specialDefense":98,"speed":52},{"number":671,"name":"Florges","generation":6,"type1":"Fairy","type2":null,"hp":78,"attack":65,"defense":68,"specialAttack":112,"specialDefense":154,"speed":75},{"number":672,"name":"Skiddo","generation":6,"type1":"Grass","type2":null,"hp":66,"attack":65,"defense":48,"specialAttack":62,"specialDefense":57,"speed":52},{"number":673,"name":"Gogoat","generation":6,"type1":"Grass","type2":null,"hp":123,"attack":100,"defense":62,"specialAttack":97,"specialDefense":81,"speed":68},{"number":674,"name":"Pancham","generation":6,"type1":"Fighting","type2":null,"hp":67,"attack":82,"defense":62,"specialAttack":46,"specialDefense":48,"speed":43},{"number":675,"name":"Pangoro","generation":6,"type1":"Fighting","type2":"Dark","hp":95,"attack":124,"defense":78,"specialAttack":69,"specialDefense":71,"speed":58},{"number":676,"name":"Furfrou","generation":6,"type1":"Normal","type2":null,"hp":75,"attack":80,"defense":60,"specialAttack":65,"specialDefense":90,"speed":102},{"number":677,"name":"Espurr","generation":6,"type1":"Psychic","type2":null,"hp":62,"attack":48,"defense":54,"specialAttack":63,"specialDefense":60,"speed":68},{"number":678,"name":"Meowstic","generation":6,"type1":"Psychic","type2":null,"hp":74,"attack":48,"defense":76,"specialAttack":83,"specialDefense":81,"speed":104},{"number":679,"name":"Honedge","generation":6,"type1":"Steel","type2":"Ghost","hp":45,"attack":80,"defense":100,"specialAttack":35,"specialDefense":37,"speed":28},{"number":680,"name":"Doublade","generation":6,"type1":"Steel","type2":"Ghost","hp":59,"attack":110,"defense":150,"specialAttack":45,"specialDefense":49,"speed":35},{"number":681,"name":"Aegislash","generation":6,"type1":"Steel","type2":"Ghost","hp":60,"attack":50,"defense":140,"specialAttack":50,"specialDefense":140,"speed":60},{"number":682,"name":"Spritzee","generation":6,"type1":"Fairy","type2":null,"hp":78,"attack":52,"defense":60,"specialAttack":63,"specialDefense":65,"speed":23},{"number":683,"name":"Aromatisse","generation":6,"type1":"Fairy","type2":null,"hp":101,"attack":72,"defense":72,"specialAttack":99,"specialDefense":89,"speed":29},{"number":684,"name":"Swirlix","generation":6,"type1":"Fairy","type2":null,"hp":62,"attack":48,"defense":66,"specialAttack":59,"specialDefense":57,"speed":49},{"number":685,"name":"Slurpuff","generation":6,"type1":"Fairy","type2":null,"hp":82,"attack":80,"defense":86,"specialAttack":85,"specialDefense":75,"speed":72},{"number":686,"name":"Inkay","generation":6,"type1":"Dark","type2":"Psychic","hp":53,"attack":54,"defense":53,"specialAttack":37,"specialDefense":46,"speed":45},{"number":687,"name":"Malamar","generation":6,"type1":"Dark","type2":"Psychic","hp":86,"attack":92,"defense":88,"specialAttack":68,"specialDefense":75,"speed":73},{"number":688,"name":"Binacle","generation":6,"type1":"Rock","type2":"Water","hp":42,"attack":52,"defense":67,"specialAttack":39,"specialDefense":56,"speed":50},{"number":689,"name":"Barbaracle","generation":6,"type1":"Rock","type2":"Water","hp":72,"attack":105,"defense":115,"specialAttack":54,"specialDefense":86,"speed":68},{"number":690,"name":"Skrelp","generation":6,"type1":"Poison","type2":"Water","hp":50,"attack":60,"defense":60,"specialAttack":60,"specialDefense":60,"speed":30},{"number":691,"name":"Dragalge","generation":6,"type1":"Poison","type2":"Dragon","hp":65,"attack":75,"defense":90,"specialAttack":97,"specialDefense":123,"speed":44},{"number":692,"name":"Clauncher","generation":6,"type1":"Water","type2":null,"hp":50,"attack":53,"defense":62,"specialAttack":58,"specialDefense":63,"speed":44},{"number":693,"name":"Clawitzer","generation":6,"type1":"Water","type2":null,"hp":71,"attack":73,"defense":88,"specialAttack":120,"specialDefense":89,"speed":59},{"number":694,"name":"Helioptile","generation":6,"type1":"Electric","type2":"Normal","hp":44,"attack":38,"defense":33,"specialAttack":61,"specialDefense":43,"speed":70},{"number":695,"name":"Heliolisk","generation":6,"type1":"Electric","type2":"Normal","hp":62,"attack":55,"defense":52,"specialAttack":109,"specialDefense":94,"speed":109},{"number":696,"name":"Tyrunt","generation":6,"type1":"Rock","type2":"Dragon","hp":58,"attack":89,"defense":77,"specialAttack":45,"specialDefense":45,"speed":48},{"number":697,"name":"Tyrantrum","generation":6,"type1":"Rock","type2":"Dragon","hp":82,"attack":121,"defense":119,"specialAttack":69,"specialDefense":59,"speed":71},{"number":698,"name":"Amaura","generation":6,"type1":"Rock","type2":"Ice","hp":77,"attack":59,"defense":50,"specialAttack":67,"specialDefense":63,"speed":46},{"number":699,"name":"Aurorus","generation":6,"type1":"Rock","type2":"Ice","hp":123,"attack":77,"defense":72,"specialAttack":99,"specialDefense":92,"speed":58},{"number":700,"name":"Sylveon","generation":6,"type1":"Fairy","type2":null,"hp":95,"attack":65,"defense":65,"specialAttack":110,"specialDefense":130,"speed":60},{"number":701,"name":"Hawlucha","generation":6,"type1":"Fighting","type2":"Flying","hp":78,"attack":92,"defense":75,"specialAttack":74,"specialDefense":63,"speed":118},{"number":702,"name":"Dedenne","generation":6,"type1":"Electric","type2":"Fairy","hp":67,"attack":58,"defense":57,"specialAttack":81,"specialDefense":67,"speed":101},{"number":703,"name":"Carbink","generation":6,"type1":"Rock","type2":"Fairy","hp":50,"attack":50,"defense":150,"specialAttack":50,"specialDefense":150,"speed":50},{"number":704,"name":"Goomy","generation":6,"type1":"Dragon","type2":null,"hp":45,"attack":50,"defense":35,"specialAttack":55,"specialDefense":75,"speed":40},{"number":705,"name":"Sliggoo","generation":6,"type1":"Dragon","type2":null,"hp":68,"attack":75,"defense":53,"specialAttack":83,"specialDefense":113,"speed":60},{"number":706,"name":"Goodra","generation":6,"type1":"Dragon","type2":null,"hp":90,"attack":100,"defense":70,"specialAttack":110,"specialDefense":150,"speed":80},{"number":707,"name":"Klefki","generation":6,"type1":"Steel","type2":"Fairy","hp":57,"attack":80,"defense":91,"specialAttack":80,"specialDefense":87,"speed":75},{"number":708,"name":"Phantump","generation":6,"type1":"Ghost","type2":"Grass","hp":43,"attack":70,"defense":48,"specialAttack":50,"specialDefense":60,"speed":38},{"number":709,"name":"Trevenant","generation":6,"type1":"Ghost","type2":"Grass","hp":85,"attack":110,"defense":76,"specialAttack":65,"specialDefense":82,"speed":56},{"number":710,"name":"Pumpkaboo","generation":6,"type1":"Ghost","type2":"Grass","hp":49,"attack":66,"defense":70,"specialAttack":44,"specialDefense":55,"speed":51},{"number":711,"name":"Gourgeist","generation":6,"type1":"Ghost","type2":"Grass","hp":65,"attack":90,"defense":122,"specialAttack":58,"specialDefense":75,"speed":84},{"number":712,"name":"Bergmite","generation":6,"type1":"Ice","type2":null,"hp":55,"attack":69,"defense":85,"specialAttack":32,"specialDefense":35,"speed":28},{"number":713,"name":"Avalugg","generation":6,"type1":"Ice","type2":null,"hp":95,"attack":117,"defense":184,"specialAttack":44,"specialDefense":46,"speed":28},{"number":714,"name":"Noibat","generation":6,"type1":"Flying","type2":"Dragon","hp":40,"attack":30,"defense":35,"specialAttack":45,"specialDefense":40,"speed":55},{"number":715,"name":"Noivern","generation":6,"type1":"Flying","type2":"Dragon","hp":85,"attack":70,"defense":80,"specialAttack":97,"specialDefense":80,"speed":123},{"number":716,"name":"Xerneas","generation":6,"type1":"Fairy","type2":null,"hp":126,"attack":131,"defense":95,"specialAttack":131,"specialDefense":98,"speed":99},{"number":717,"name":"Yveltal","generation":6,"type1":"Dark","type2":"Flying","hp":126,"attack":131,"defense":95,"specialAttack":131,"specialDefense":98,"speed":99},{"number":718,"name":"Zygarde","generation":6,"type1":"Dragon","type2":"Ground","hp":108,"attack":100,"defense":121,"specialAttack":81,"specialDefense":95,"speed":95},{"number":719,"name":"Diancie","generation":6,"type1":"Rock","type2":"Fairy","hp":50,"attack":100,"defense":150,"specialAttack":100,"specialDefense":150,"speed":50},{"number":720,"name":"Hoopa","generation":6,"type1":"Psychic","type2":"Ghost","hp":80,"attack":110,"defense":60,"specialAttack":150,"specialDefense":130,"speed":70},{"number":721,"name":"Volcanion","generation":6,"type1":"Fire","type2":"Water","hp":80,"attack":110,"defense":120,"specialAttack":130,"specialDefense":90,"speed":70},{"number":722,"name":"Rowlet","generation":7,"type1":"Grass","type2":"Flying","hp":68,"attack":55,"defense":55,"specialAttack":50,"specialDefense":50,"speed":42},{"number":723,"name":"Dartrix","generation":7,"type1":"Grass","type2":"Flying","hp":78,"attack":75,"defense":75,"specialAttack":70,"specialDefense":70,"speed":52},{"number":724,"name":"Decidueye","generation":7,"type1":"Grass","type2":"Ghost","hp":78,"attack":107,"defense":75,"specialAttack":100,"specialDefense":100,"speed":70},{"number":725,"name":"Litten","generation":7,"type1":"Fire","type2":null,"hp":45,"attack":65,"defense":40,"specialAttack":60,"specialDefense":40,"speed":70},{"number":726,"name":"Torracat","generation":7,"type1":"Fire","type2":null,"hp":65,"attack":85,"defense":50,"specialAttack":80,"specialDefense":50,"speed":90},{"number":727,"name":"Incineroar","generation":7,"type1":"Fire","type2":"Dark","hp":95,"attack":115,"defense":90,"specialAttack":80,"specialDefense":90,"speed":60},{"number":728,"name":"Popplio","generation":7,"type1":"Water","type2":null,"hp":50,"attack":54,"defense":54,"specialAttack":66,"specialDefense":56,"speed":40},{"number":729,"name":"Brionne","generation":7,"type1":"Water","type2":null,"hp":60,"attack":69,"defense":69,"specialAttack":91,"specialDefense":81,"speed":50},{"number":730,"name":"Primarina","generation":7,"type1":"Water","type2":"Fairy","hp":80,"attack":74,"defense":74,"specialAttack":126,"specialDefense":116,"speed":60},{"number":731,"name":"Pikipek","generation":7,"type1":"Normal","type2":"Flying","hp":35,"attack":75,"defense":30,"specialAttack":30,"specialDefense":30,"speed":65},{"number":732,"name":"Trumbeak","generation":7,"type1":"Normal","type2":"Flying","hp":55,"attack":85,"defense":50,"specialAttack":40,"specialDefense":50,"speed":75},{"number":733,"name":"Toucannon","generation":7,"type1":"Normal","type2":"Flying","hp":80,"attack":120,"defense":75,"specialAttack":75,"specialDefense":75,"speed":60},{"number":734,"name":"Yungoos","generation":7,"type1":"Normal","type2":null,"hp":48,"attack":70,"defense":30,"specialAttack":30,"specialDefense":30,"speed":45},{"number":735,"name":"Gumshoos","generation":7,"type1":"Normal","type2":null,"hp":88,"attack":110,"defense":60,"specialAttack":55,"specialDefense":60,"speed":45},{"number":736,"name":"Grubbin","generation":7,"type1":"Bug","type2":null,"hp":47,"attack":62,"defense":45,"specialAttack":55,"specialDefense":45,"speed":46},{"number":737,"name":"Charjabug","generation":7,"type1":"Bug","type2":"Electric","hp":57,"attack":82,"defense":95,"specialAttack":55,"specialDefense":75,"speed":36},{"number":738,"name":"Vikavolt","generation":7,"type1":"Bug","type2":"Electric","hp":77,"attack":70,"defense":90,"specialAttack":145,"specialDefense":75,"speed":43},{"number":739,"name":"Crabrawler","generation":7,"type1":"Fighting","type2":null,"hp":47,"attack":82,"defense":57,"specialAttack":42,"specialDefense":47,"speed":63},{"number":740,"name":"Crabominable","generation":7,"type1":"Fighting","type2":"Ice","hp":97,"attack":132,"defense":77,"specialAttack":62,"specialDefense":67,"speed":43},{"number":741,"name":"Oricorio","generation":7,"type1":"Fire","type2":"Flying","hp":75,"attack":70,"defense":70,"specialAttack":98,"specialDefense":70,"speed":93},{"number":742,"name":"Cutiefly","generation":7,"type1":"Bug","type2":"Fairy","hp":40,"attack":45,"defense":40,"specialAttack":55,"specialDefense":40,"speed":84},{"number":743,"name":"Ribombee","generation":7,"type1":"Bug","type2":"Fairy","hp":60,"attack":55,"defense":60,"specialAttack":95,"specialDefense":70,"speed":124},{"number":744,"name":"Rockruff","generation":7,"type1":"Rock","type2":null,"hp":45,"attack":65,"defense":40,"specialAttack":30,"specialDefense":40,"speed":60},{"number":745,"name":"Lycanroc","generation":7,"type1":"Rock","type2":null,"hp":75,"attack":115,"defense":65,"specialAttack":55,"specialDefense":65,"speed":112},{"number":746,"name":"Wishiwashi","generation":7,"type1":"Water","type2":null,"hp":45,"attack":20,"defense":20,"specialAttack":25,"specialDefense":25,"speed":40},{"number":747,"name":"Mareanie","generation":7,"type1":"Poison","type2":"Water","hp":50,"attack":53,"defense":62,"specialAttack":43,"specialDefense":52,"speed":45},{"number":748,"name":"Toxapex","generation":7,"type1":"Poison","type2":"Water","hp":50,"attack":63,"defense":152,"specialAttack":53,"specialDefense":142,"speed":35},{"number":749,"name":"Mudbray","generation":7,"type1":"Ground","type2":null,"hp":70,"attack":100,"defense":70,"specialAttack":45,"specialDefense":55,"speed":45},{"number":750,"name":"Mudsdale","generation":7,"type1":"Ground","type2":null,"hp":100,"attack":125,"defense":100,"specialAttack":55,"specialDefense":85,"speed":35},{"number":751,"name":"Dewpider","generation":7,"type1":"Water","type2":"Bug","hp":38,"attack":40,"defense":52,"specialAttack":40,"specialDefense":72,"speed":27},{"number":752,"name":"Araquanid","generation":7,"type1":"Water","type2":"Bug","hp":68,"attack":70,"defense":92,"specialAttack":50,"specialDefense":132,"speed":42},{"number":753,"name":"Fomantis","generation":7,"type1":"Grass","type2":null,"hp":40,"attack":55,"defense":35,"specialAttack":50,"specialDefense":35,"speed":35},{"number":754,"name":"Lurantis","generation":7,"type1":"Grass","type2":null,"hp":70,"attack":105,"defense":90,"specialAttack":80,"specialDefense":90,"speed":45},{"number":755,"name":"Morelull","generation":7,"type1":"Grass","type2":"Fairy","hp":40,"attack":35,"defense":55,"specialAttack":65,"specialDefense":75,"speed":15},{"number":756,"name":"Shiinotic","generation":7,"type1":"Grass","type2":"Fairy","hp":60,"attack":45,"defense":80,"specialAttack":90,"specialDefense":100,"speed":30},{"number":757,"name":"Salandit","generation":7,"type1":"Poison","type2":"Fire","hp":48,"attack":44,"defense":40,"specialAttack":71,"specialDefense":40,"speed":77},{"number":758,"name":"Salazzle","generation":7,"type1":"Poison","type2":"Fire","hp":68,"attack":64,"defense":60,"specialAttack":111,"specialDefense":60,"speed":117},{"number":759,"name":"Stufful","generation":7,"type1":"Normal","type2":"Fighting","hp":70,"attack":75,"defense":50,"specialAttack":45,"specialDefense":50,"speed":50},{"number":760,"name":"Bewear","generation":7,"type1":"Normal","type2":"Fighting","hp":120,"attack":125,"defense":80,"specialAttack":55,"specialDefense":60,"speed":60},{"number":761,"name":"Bounsweet","generation":7,"type1":"Grass","type2":null,"hp":42,"attack":30,"defense":38,"specialAttack":30,"specialDefense":38,"speed":32},{"number":762,"name":"Steenee","generation":7,"type1":"Grass","type2":null,"hp":52,"attack":40,"defense":48,"specialAttack":40,"specialDefense":48,"speed":62},{"number":763,"name":"Tsareena","generation":7,"type1":"Grass","type2":null,"hp":72,"attack":120,"defense":98,"specialAttack":50,"specialDefense":98,"speed":72},{"number":764,"name":"Comfey","generation":7,"type1":"Fairy","type2":null,"hp":51,"attack":52,"defense":90,"specialAttack":82,"specialDefense":110,"speed":100},{"number":765,"name":"Oranguru","generation":7,"type1":"Normal","type2":"Psychic","hp":90,"attack":60,"defense":80,"specialAttack":90,"specialDefense":110,"speed":60},{"number":766,"name":"Passimian","generation":7,"type1":"Fighting","type2":null,"hp":100,"attack":120,"defense":90,"specialAttack":40,"specialDefense":60,"speed":80},{"number":767,"name":"Wimpod","generation":7,"type1":"Bug","type2":"Water","hp":25,"attack":35,"defense":40,"specialAttack":20,"specialDefense":30,"speed":80},{"number":768,"name":"Golisopod","generation":7,"type1":"Bug","type2":"Water","hp":75,"attack":125,"defense":140,"specialAttack":60,"specialDefense":90,"speed":40},{"number":769,"name":"Sandygast","generation":7,"type1":"Ghost","type2":"Ground","hp":55,"attack":55,"defense":80,"specialAttack":70,"specialDefense":45,"speed":15},{"number":770,"name":"Palossand","generation":7,"type1":"Ghost","type2":"Ground","hp":85,"attack":75,"defense":110,"specialAttack":100,"specialDefense":75,"speed":35},{"number":771,"name":"Pyukumuku","generation":7,"type1":"Water","type2":null,"hp":55,"attack":60,"defense":130,"specialAttack":30,"specialDefense":130,"speed":5},{"number":772,"name":"Type: Null","generation":7,"type1":"Normal","type2":null,"hp":95,"attack":95,"defense":95,"specialAttack":95,"specialDefense":95,"speed":59},{"number":773,"name":"Silvally","generation":7,"type1":"Normal","type2":null,"hp":95,"attack":95,"defense":95,"specialAttack":95,"specialDefense":95,"speed":95},{"number":774,"name":"Minior","generation":7,"type1":"Rock","type2":"Flying","hp":60,"attack":60,"defense":100,"specialAttack":60,"specialDefense":100,"speed":60},{"number":775,"name":"Komala","generation":7,"type1":"Normal","type2":null,"hp":65,"attack":115,"defense":65,"specialAttack":75,"specialDefense":95,"speed":65},{"number":776,"name":"Turtonator","generation":7,"type1":"Fire","type2":"Dragon","hp":60,"attack":78,"defense":135,"specialAttack":91,"specialDefense":85,"speed":36},{"number":777,"name":"Togedemaru","generation":7,"type1":"Electric","type2":"Steel","hp":65,"attack":98,"defense":63,"specialAttack":40,"specialDefense":73,"speed":96},{"number":778,"name":"Mimikyu","generation":7,"type1":"Ghost","type2":"Fairy","hp":55,"attack":90,"defense":80,"specialAttack":50,"specialDefense":105,"speed":96},{"number":779,"name":"Bruxish","generation":7,"type1":"Water","type2":"Psychic","hp":68,"attack":105,"defense":70,"specialAttack":70,"specialDefense":70,"speed":92},{"number":780,"name":"Drampa","generation":7,"type1":"Normal","type2":"Dragon","hp":78,"attack":60,"defense":85,"specialAttack":135,"specialDefense":91,"speed":36},{"number":781,"name":"Dhelmise","generation":7,"type1":"Ghost","type2":"Grass","hp":70,"attack":131,"defense":100,"specialAttack":86,"specialDefense":90,"speed":40},{"number":782,"name":"Jangmo-o","generation":7,"type1":"Dragon","type2":null,"hp":45,"attack":55,"defense":65,"specialAttack":45,"specialDefense":45,"speed":45},{"number":783,"name":"Hakamo-o","generation":7,"type1":"Dragon","type2":"Fighting","hp":55,"attack":75,"defense":90,"specialAttack":65,"specialDefense":70,"speed":65},{"number":784,"name":"Kommo-o","generation":7,"type1":"Dragon","type2":"Fighting","hp":75,"attack":110,"defense":125,"specialAttack":100,"specialDefense":105,"speed":85},{"number":785,"name":"Tapu Koko","generation":7,"type1":"Electric","type2":"Fairy","hp":70,"attack":115,"defense":85,"specialAttack":95,"specialDefense":75,"speed":130},{"number":786,"name":"Tapu Lele","generation":7,"type1":"Psychic","type2":"Fairy","hp":70,"attack":85,"defense":75,"specialAttack":130,"specialDefense":115,"speed":95},{"number":787,"name":"Tapu Bulu","generation":7,"type1":"Grass","type2":"Fairy","hp":70,"attack":130,"defense":115,"specialAttack":85,"specialDefense":95,"speed":75},{"number":788,"name":"Tapu Fini","generation":7,"type1":"Water","type2":"Fairy","hp":70,"attack":75,"defense":115,"specialAttack":95,"specialDefense":130,"speed":85},{"number":789,"name":"Cosmog","generation":7,"type1":"Psychic","type2":null,"hp":43,"attack":29,"defense":31,"specialAttack":29,"specialDefense":31,"speed":37},{"number":790,"name":"Cosmoem","generation":7,"type1":"Psychic","type2":null,"hp":43,"attack":29,"defense":131,"specialAttack":29,"specialDefense":131,"speed":37},{"number":791,"name":"Solgaleo","generation":7,"type1":"Psychic","type2":"Steel","hp":137,"attack":137,"defense":107,"specialAttack":113,"specialDefense":89,"speed":97},{"number":792,"name":"Lunala","generation":7,"type1":"Psychic","type2":"Ghost","hp":137,"attack":113,"defense":89,"specialAttack":137,"specialDefense":107,"speed":97},{"number":793,"name":"Nihilego","generation":7,"type1":"Rock","type2":"Poison","hp":109,"attack":53,"defense":47,"specialAttack":127,"specialDefense":131,"speed":103},{"number":794,"name":"Buzzwole","generation":7,"type1":"Bug","type2":"Fighting","hp":107,"attack":139,"defense":139,"specialAttack":53,"specialDefense":53,"speed":79},{"number":795,"name":"Pheromosa","generation":7,"type1":"Bug","type2":"Fighting","hp":71,"attack":137,"defense":37,"specialAttack":137,"specialDefense":37,"speed":151},{"number":796,"name":"Xurkitree","generation":7,"type1":"Electric","type2":null,"hp":83,"attack":89,"defense":71,"specialAttack":173,"specialDefense":71,"speed":83},{"number":797,"name":"Celesteela","generation":7,"type1":"Steel","type2":"Flying","hp":97,"attack":101,"defense":103,"specialAttack":107,"specialDefense":101,"speed":61},{"number":798,"name":"Kartana","generation":7,"type1":"Grass","type2":"Steel","hp":59,"attack":181,"defense":131,"specialAttack":59,"specialDefense":31,"speed":109},{"number":799,"name":"Guzzlord","generation":7,"type1":"Dark","type2":"Dragon","hp":223,"attack":101,"defense":53,"specialAttack":97,"specialDefense":53,"speed":43},{"number":800,"name":"Necrozma","generation":7,"type1":"Psychic","type2":null,"hp":97,"attack":107,"defense":101,"specialAttack":127,"specialDefense":89,"speed":79},{"number":801,"name":"Magearna","generation":7,"type1":"Steel","type2":"Fairy","hp":80,"attack":95,"defense":115,"specialAttack":130,"specialDefense":115,"speed":65},{"number":802,"name":"Marshadow","generation":7,"type1":"Fighting","type2":"Ghost","hp":90,"attack":125,"defense":80,"specialAttack":90,"specialDefense":90,"speed":125},{"number":803,"name":"Poipole","generation":7,"type1":"Poison","type2":null,"hp":67,"attack":73,"defense":67,"specialAttack":73,"specialDefense":67,"speed":73},{"number":804,"name":"Naganadel","generation":7,"type1":"Poison","type2":"Dragon","hp":73,"attack":73,"defense":73,"specialAttack":127,"specialDefense":73,"speed":121},{"number":805,"name":"Stakataka","generation":7,"type1":"Rock","type2":"Steel","hp":61,"attack":131,"defense":211,"specialAttack":53,"specialDefense":101,"speed":13},{"number":806,"name":"Blacephalon","generation":7,"type1":"Fire","type2":"Ghost","hp":53,"attack":127,"defense":53,"specialAttack":151,"specialDefense":79,"speed":107},{"number":807,"name":"Zeraora","generation":7,"type1":"Electric","type2":null,"hp":88,"attack":112,"defense":75,"specialAttack":102,"specialDefense":80,"speed":143},{"number":808,"name":"Meltan","generation":7,"type1":"Steel","type2":null,"hp":46,"attack":65,"defense":65,"specialAttack":55,"specialDefense":35,"speed":34},{"number":809,"name":"Melmetal","generation":7,"type1":"Steel","type2":null,"hp":135,"attack":143,"defense":143,"specialAttack":80,"specialDefense":65,"speed":34},{"number":810,"name":"Grookey","generation":8,"type1":"Grass","type2":null,"hp":50,"attack":65,"defense":50,"specialAttack":40,"specialDefense":40,"speed":65},{"number":811,"name":"Thwackey","generation":8,"type1":"Grass","type2":null,"hp":70,"attack":85,"defense":70,"specialAttack":55,"specialDefense":60,"speed":80},{"number":812,"name":"Rillaboom","generation":8,"type1":"Grass","type2":null,"hp":100,"attack":125,"defense":90,"specialAttack":60,"specialDefense":70,"speed":85},{"number":813,"name":"Scorbunny","generation":8,"type1":"Fire","type2":null,"hp":50,"attack":71,"defense":40,"specialAttack":40,"specialDefense":40,"speed":69},{"number":814,"name":"Raboot","generation":8,"type1":"Fire","type2":null,"hp":65,"attack":86,"defense":60,"specialAttack":55,"specialDefense":60,"speed":94},{"number":815,"name":"Cinderace","generation":8,"type1":"Fire","type2":null,"hp":80,"attack":116,"defense":75,"specialAttack":65,"specialDefense":75,"speed":119},{"number":816,"name":"Sobble","generation":8,"type1":"Water","type2":null,"hp":50,"attack":40,"defense":40,"specialAttack":70,"specialDefense":40,"speed":70},{"number":817,"name":"Drizzile","generation":8,"type1":"Water","type2":null,"hp":65,"attack":60,"defense":55,"specialAttack":95,"specialDefense":55,"speed":90},{"number":818,"name":"Inteleon","generation":8,"type1":"Water","type2":null,"hp":70,"attack":85,"defense":65,"specialAttack":125,"specialDefense":65,"speed":120},{"number":819,"name":"Skwovet","generation":8,"type1":"Normal","type2":null,"hp":70,"attack":55,"defense":55,"specialAttack":35,"specialDefense":35,"speed":25},{"number":820,"name":"Greedent","generation":8,"type1":"Normal","type2":null,"hp":120,"attack":95,"defense":95,"specialAttack":55,"specialDefense":75,"speed":20},{"number":821,"name":"Rookidee","generation":8,"type1":"Flying","type2":null,"hp":38,"attack":47,"defense":35,"specialAttack":33,"specialDefense":35,"speed":57},{"number":822,"name":"Corvisquire","generation":8,"type1":"Flying","type2":null,"hp":68,"attack":67,"defense":55,"specialAttack":43,"specialDefense":55,"speed":77},{"number":823,"name":"Corviknight","generation":8,"type1":"Flying","type2":"Steel","hp":98,"attack":87,"defense":105,"specialAttack":53,"specialDefense":85,"speed":67},{"number":824,"name":"Blipbug","generation":8,"type1":"Bug","type2":null,"hp":25,"attack":20,"defense":20,"specialAttack":25,"specialDefense":45,"speed":45},{"number":825,"name":"Dottler","generation":8,"type1":"Bug","type2":"Psychic","hp":50,"attack":35,"defense":80,"specialAttack":50,"specialDefense":90,"speed":30},{"number":826,"name":"Orbeetle","generation":8,"type1":"Bug","type2":"Psychic","hp":60,"attack":45,"defense":110,"specialAttack":80,"specialDefense":120,"speed":90},{"number":827,"name":"Nickit","generation":8,"type1":"Dark","type2":null,"hp":40,"attack":28,"defense":28,"specialAttack":47,"specialDefense":52,"speed":50},{"number":828,"name":"Thievul","generation":8,"type1":"Dark","type2":null,"hp":70,"attack":58,"defense":58,"specialAttack":87,"specialDefense":92,"speed":90},{"number":829,"name":"Gossifleur","generation":8,"type1":"Grass","type2":null,"hp":40,"attack":40,"defense":60,"specialAttack":40,"specialDefense":60,"speed":10},{"number":830,"name":"Eldegoss","generation":8,"type1":"Grass","type2":null,"hp":60,"attack":50,"defense":90,"specialAttack":80,"specialDefense":120,"speed":60},{"number":831,"name":"Wooloo","generation":8,"type1":"Normal","type2":null,"hp":42,"attack":40,"defense":55,"specialAttack":40,"specialDefense":45,"speed":48},{"number":832,"name":"Dubwool","generation":8,"type1":"Normal","type2":null,"hp":72,"attack":80,"defense":100,"specialAttack":60,"specialDefense":90,"speed":88},{"number":833,"name":"Chewtle","generation":8,"type1":"Water","type2":null,"hp":50,"attack":64,"defense":50,"specialAttack":38,"specialDefense":38,"speed":44},{"number":834,"name":"Drednaw","generation":8,"type1":"Water","type2":"Rock","hp":90,"attack":115,"defense":90,"specialAttack":48,"specialDefense":68,"speed":74},{"number":835,"name":"Yamper","generation":8,"type1":"Electric","type2":null,"hp":59,"attack":45,"defense":50,"specialAttack":40,"specialDefense":50,"speed":26},{"number":836,"name":"Boltund","generation":8,"type1":"Electric","type2":null,"hp":69,"attack":90,"defense":60,"specialAttack":90,"specialDefense":60,"speed":121},{"number":837,"name":"Rolycoly","generation":8,"type1":"Rock","type2":null,"hp":30,"attack":40,"defense":50,"specialAttack":40,"specialDefense":50,"speed":30},{"number":838,"name":"Carkol","generation":8,"type1":"Rock","type2":"Fire","hp":80,"attack":60,"defense":90,"specialAttack":60,"specialDefense":70,"speed":50},{"number":839,"name":"Coalossal","generation":8,"type1":"Rock","type2":"Fire","hp":110,"attack":80,"defense":120,"specialAttack":80,"specialDefense":90,"speed":30},{"number":840,"name":"Applin","generation":8,"type1":"Grass","type2":"Dragon","hp":40,"attack":40,"defense":80,"specialAttack":40,"specialDefense":40,"speed":20},{"number":841,"name":"Flapple","generation":8,"type1":"Grass","type2":"Dragon","hp":70,"attack":110,"defense":80,"specialAttack":95,"specialDefense":60,"speed":70},{"number":842,"name":"Appletun","generation":8,"type1":"Grass","type2":"Dragon","hp":110,"attack":85,"defense":80,"specialAttack":100,"specialDefense":80,"speed":30},{"number":843,"name":"Silicobra","generation":8,"type1":"Ground","type2":null,"hp":52,"attack":57,"defense":75,"specialAttack":35,"specialDefense":50,"speed":46},{"number":844,"name":"Sandaconda","generation":8,"type1":"Ground","type2":null,"hp":72,"attack":107,"defense":125,"specialAttack":65,"specialDefense":70,"speed":71},{"number":845,"name":"Cramorant","generation":8,"type1":"Flying","type2":"Water","hp":70,"attack":85,"defense":55,"specialAttack":85,"specialDefense":95,"speed":85},{"number":846,"name":"Arrokuda","generation":8,"type1":"Water","type2":null,"hp":41,"attack":63,"defense":40,"specialAttack":40,"specialDefense":30,"speed":66},{"number":847,"name":"Barraskewda","generation":8,"type1":"Water","type2":null,"hp":61,"attack":123,"defense":60,"specialAttack":60,"specialDefense":50,"speed":136},{"number":848,"name":"Toxel","generation":8,"type1":"Electric","type2":"Poison","hp":40,"attack":38,"defense":35,"specialAttack":54,"specialDefense":35,"speed":40},{"number":849,"name":"Toxtricity","generation":8,"type1":"Electric","type2":"Poison","hp":75,"attack":98,"defense":70,"specialAttack":114,"specialDefense":70,"speed":75},{"number":850,"name":"Sizzlipede","generation":8,"type1":"Fire","type2":"Bug","hp":50,"attack":65,"defense":45,"specialAttack":50,"specialDefense":50,"speed":45},{"number":851,"name":"Centiskorch","generation":8,"type1":"Fire","type2":"Bug","hp":100,"attack":115,"defense":65,"specialAttack":90,"specialDefense":90,"speed":65},{"number":852,"name":"Clobbopus","generation":8,"type1":"Fighting","type2":null,"hp":50,"attack":68,"defense":60,"specialAttack":50,"specialDefense":50,"speed":32},{"number":853,"name":"Grapploct","generation":8,"type1":"Fighting","type2":null,"hp":80,"attack":118,"defense":90,"specialAttack":70,"specialDefense":80,"speed":42},{"number":854,"name":"Sinistea","generation":8,"type1":"Ghost","type2":null,"hp":40,"attack":45,"defense":45,"specialAttack":74,"specialDefense":54,"speed":50},{"number":855,"name":"Polteageist","generation":8,"type1":"Ghost","type2":null,"hp":60,"attack":65,"defense":65,"specialAttack":134,"specialDefense":114,"speed":70},{"number":856,"name":"Hatenna","generation":8,"type1":"Psychic","type2":null,"hp":42,"attack":30,"defense":45,"specialAttack":56,"specialDefense":53,"speed":39},{"number":857,"name":"Hattrem","generation":8,"type1":"Psychic","type2":null,"hp":57,"attack":40,"defense":65,"specialAttack":86,"specialDefense":73,"speed":49},{"number":858,"name":"Hatterene","generation":8,"type1":"Psychic","type2":"Fairy","hp":57,"attack":90,"defense":95,"specialAttack":136,"specialDefense":103,"speed":29},{"number":859,"name":"Impidimp","generation":8,"type1":"Dark","type2":"Fairy","hp":45,"attack":45,"defense":30,"specialAttack":55,"specialDefense":40,"speed":50},{"number":860,"name":"Morgrem","generation":8,"type1":"Dark","type2":"Fairy","hp":65,"attack":60,"defense":45,"specialAttack":75,"specialDefense":55,"speed":70},{"number":861,"name":"Grimmsnarl","generation":8,"type1":"Dark","type2":"Fairy","hp":95,"attack":120,"defense":65,"specialAttack":95,"specialDefense":75,"speed":60},{"number":862,"name":"Obstagoon","generation":8,"type1":"Dark","type2":"Normal","hp":93,"attack":90,"defense":101,"specialAttack":60,"specialDefense":81,"speed":95},{"number":863,"name":"Perrserker","generation":8,"type1":"Steel","type2":null,"hp":70,"attack":110,"defense":100,"specialAttack":50,"specialDefense":60,"speed":50},{"number":864,"name":"Cursola","generation":8,"type1":"Ghost","type2":null,"hp":60,"attack":95,"defense":50,"specialAttack":145,"specialDefense":130,"speed":30},{"number":865,"name":"Sirfetch’d","generation":8,"type1":"Fighting","type2":null,"hp":62,"attack":135,"defense":95,"specialAttack":68,"specialDefense":82,"speed":65},{"number":866,"name":"Mr. Rime","generation":8,"type1":"Ice","type2":"Psychic","hp":80,"attack":85,"defense":75,"specialAttack":110,"specialDefense":100,"speed":70},{"number":867,"name":"Runerigus","generation":8,"type1":"Ground","type2":"Ghost","hp":58,"attack":95,"defense":145,"specialAttack":50,"specialDefense":105,"speed":30},{"number":868,"name":"Milcery","generation":8,"type1":"Fairy","type2":null,"hp":45,"attack":40,"defense":40,"specialAttack":50,"specialDefense":61,"speed":34},{"number":869,"name":"Alcremie","generation":8,"type1":"Fairy","type2":null,"hp":65,"attack":60,"defense":75,"specialAttack":110,"specialDefense":121,"speed":64},{"number":870,"name":"Falinks","generation":8,"type1":"Fighting","type2":null,"hp":65,"attack":100,"defense":100,"specialAttack":70,"specialDefense":60,"speed":75},{"number":871,"name":"Pincurchin","generation":8,"type1":"Electric","type2":null,"hp":48,"attack":101,"defense":95,"specialAttack":91,"specialDefense":85,"speed":15},{"number":872,"name":"Snom","generation":8,"type1":"Ice","type2":"Bug","hp":30,"attack":25,"defense":35,"specialAttack":45,"specialDefense":30,"speed":20},{"number":873,"name":"Frosmoth","generation":8,"type1":"Ice","type2":"Bug","hp":70,"attack":65,"defense":60,"specialAttack":125,"specialDefense":90,"speed":65},{"number":874,"name":"Stonjourner","generation":8,"type1":"Rock","type2":null,"hp":100,"attack":125,"defense":135,"specialAttack":20,"specialDefense":20,"speed":70},{"number":875,"name":"Eiscue","generation":8,"type1":"Ice","type2":null,"hp":75,"attack":80,"defense":110,"specialAttack":65,"specialDefense":90,"speed":50},{"number":876,"name":"Indeedee","generation":8,"type1":"Psychic","type2":"Normal","hp":60,"attack":65,"defense":55,"specialAttack":105,"specialDefense":95,"speed":95},{"number":877,"name":"Morpeko","generation":8,"type1":"Electric","type2":"Dark","hp":58,"attack":95,"defense":58,"specialAttack":70,"specialDefense":58,"speed":97},{"number":878,"name":"Cufant","generation":8,"type1":"Steel","type2":null,"hp":72,"attack":80,"defense":49,"specialAttack":40,"specialDefense":49,"speed":40},{"number":879,"name":"Copperajah","generation":8,"type1":"Steel","type2":null,"hp":122,"attack":130,"defense":69,"specialAttack":80,"specialDefense":69,"speed":30},{"number":880,"name":"Dracozolt","generation":8,"type1":"Electric","type2":"Dragon","hp":90,"attack":100,"defense":90,"specialAttack":80,"specialDefense":70,"speed":75},{"number":881,"name":"Arctozolt","generation":8,"type1":"Electric","type2":"Ice","hp":90,"attack":100,"defense":90,"specialAttack":90,"specialDefense":80,"speed":55},{"number":882,"name":"Dracovish","generation":8,"type1":"Water","type2":"Dragon","hp":90,"attack":90,"defense":100,"specialAttack":70,"specialDefense":80,"speed":75},{"number":883,"name":"Arctovish","generation":8,"type1":"Water","type2":"Ice","hp":90,"attack":90,"defense":100,"specialAttack":80,"specialDefense":90,"speed":55},{"number":884,"name":"Duraludon","generation":8,"type1":"Steel","type2":"Dragon","hp":70,"attack":95,"defense":115,"specialAttack":120,"specialDefense":50,"speed":85},{"number":885,"name":"Dreepy","generation":8,"type1":"Dragon","type2":"Ghost","hp":28,"attack":60,"defense":30,"specialAttack":40,"specialDefense":30,"speed":82},{"number":886,"name":"Drakloak","generation":8,"type1":"Dragon","type2":"Ghost","hp":68,"attack":80,"defense":50,"specialAttack":60,"specialDefense":50,"speed":102},{"number":887,"name":"Dragapult","generation":8,"type1":"Dragon","type2":"Ghost","hp":88,"attack":120,"defense":75,"specialAttack":100,"specialDefense":75,"speed":142},{"number":888,"name":"Zacian","generation":8,"type1":"Fairy","type2":null,"hp":92,"attack":120,"defense":115,"specialAttack":80,"specialDefense":115,"speed":138},{"number":889,"name":"Zamazenta","generation":8,"type1":"Fighting","type2":null,"hp":92,"attack":120,"defense":115,"specialAttack":80,"specialDefense":115,"speed":138},{"number":890,"name":"Eternatus","generation":8,"type1":"Poison","type2":"Dragon","hp":140,"attack":85,"defense":95,"specialAttack":145,"specialDefense":95,"speed":130},{"number":891,"name":"Kubfu","generation":8,"type1":"Fighting","type2":null,"hp":60,"attack":90,"defense":60,"specialAttack":53,"specialDefense":50,"speed":72},{"number":892,"name":"Urshifu","generation":8,"type1":"Fighting","type2":"Dark","hp":100,"attack":130,"defense":100,"specialAttack":63,"specialDefense":60,"speed":97},{"number":893,"name":"Zarude","generation":8,"type1":"Dark","type2":"Grass","hp":105,"attack":120,"defense":105,"specialAttack":70,"specialDefense":95,"speed":105},{"number":894,"name":"Regieleki","generation":8,"type1":"Electric","type2":null,"hp":80,"attack":100,"defense":50,"specialAttack":100,"specialDefense":50,"speed":200},{"number":895,"name":"Regidrago","generation":8,"type1":"Dragon","type2":null,"hp":200,"attack":100,"defense":50,"specialAttack":100,"specialDefense":50,"speed":80},{"number":896,"name":"Glastrier","generation":8,"type1":"Ice","type2":null,"hp":100,"attack":145,"defense":130,"specialAttack":65,"specialDefense":110,"speed":30},{"number":897,"name":"Spectrier","generation":8,"type1":"Ghost","type2":null,"hp":100,"attack":65,"defense":60,"specialAttack":145,"specialDefense":80,"speed":130},{"number":898,"name":"Calyrex","generation":8,"type1":"Psychic","type2":"Grass","hp":100,"attack":80,"defense":80,"specialAttack":80,"specialDefense":80,"speed":80},{"number":899,"name":"Wyrdeer","generation":8,"type1":"Normal","type2":"Psychic","hp":103,"attack":105,"defense":72,"specialAttack":105,"specialDefense":75,"speed":65},{"number":900,"name":"Kleavor","generation":8,"type1":"Bug","type2":"Rock","hp":70,"attack":135,"defense":95,"specialAttack":45,"specialDefense":70,"speed":85},{"number":901,"name":"Ursaluna","generation":8,"type1":"Ground","type2":"Normal","hp":130,"attack":140,"defense":105,"specialAttack":45,"specialDefense":80,"speed":50},{"number":902,"name":"Basculegion","generation":8,"type1":"Water","type2":"Ghost","hp":120,"attack":112,"defense":65,"specialAttack":80,"specialDefense":75,"speed":78},{"number":903,"name":"Sneasler","generation":8,"type1":"Fighting","type2":"Poison","hp":80,"attack":130,"defense":60,"specialAttack":40,"specialDefense":80,"speed":120},{"number":904,"name":"Overqwil","generation":8,"type1":"Dark","type2":"Poison","hp":85,"attack":115,"defense":95,"specialAttack":65,"specialDefense":65,"speed":85},{"number":905,"name":"Enamorus","generation":8,"type1":"Fairy","type2":"Flying","hp":74,"attack":115,"defense":70,"specialAttack":135,"specialDefense":80,"speed":106},{"number":906,"name":"Sprigatito","generation":9,"type1":"Grass","type2":null,"hp":40,"attack":61,"defense":54,"specialAttack":45,"specialDefense":45,"speed":65},{"number":907,"name":"Floragato","generation":9,"type1":"Grass","type2":null,"hp":61,"attack":80,"defense":63,"specialAttack":60,"specialDefense":63,"speed":83},{"number":908,"name":"Meowscarada","generation":9,"type1":"Grass","type2":"Dark","hp":76,"attack":110,"defense":70,"specialAttack":81,"specialDefense":70,"speed":123},{"number":909,"name":"Fuecoco","generation":9,"type1":"Fire","type2":null,"hp":67,"attack":45,"defense":59,"specialAttack":63,"specialDefense":40,"speed":36},{"number":910,"name":"Crocalor","generation":9,"type1":"Fire","type2":null,"hp":81,"attack":55,"defense":78,"specialAttack":90,"specialDefense":58,"speed":49},{"number":911,"name":"Skeledirge","generation":9,"type1":"Fire","type2":"Ghost","hp":104,"attack":75,"defense":100,"specialAttack":110,"specialDefense":75,"speed":66},{"number":912,"name":"Quaxly","generation":9,"type1":"Water","type2":null,"hp":55,"attack":65,"defense":45,"specialAttack":50,"specialDefense":45,"speed":50},{"number":913,"name":"Quaxwell","generation":9,"type1":"Water","type2":null,"hp":70,"attack":85,"defense":65,"specialAttack":65,"specialDefense":60,"speed":65},{"number":914,"name":"Quaquaval","generation":9,"type1":"Water","type2":"Fighting","hp":85,"attack":120,"defense":80,"specialAttack":85,"specialDefense":75,"speed":85},{"number":915,"name":"Lechonk","generation":9,"type1":"Normal","type2":null,"hp":54,"attack":45,"defense":40,"specialAttack":35,"specialDefense":45,"speed":35},{"number":916,"name":"Oinkologne","generation":9,"type1":"Normal","type2":null,"hp":110,"attack":100,"defense":75,"specialAttack":59,"specialDefense":80,"speed":65},{"number":917,"name":"Tarountula","generation":9,"type1":"Bug","type2":null,"hp":35,"attack":41,"defense":45,"specialAttack":29,"specialDefense":40,"speed":20},{"number":918,"name":"Spidops","generation":9,"type1":"Bug","type2":null,"hp":60,"attack":79,"defense":92,"specialAttack":52,"specialDefense":86,"speed":35},{"number":919,"name":"Nymble","generation":9,"type1":"Bug","type2":null,"hp":33,"attack":46,"defense":40,"specialAttack":21,"specialDefense":25,"speed":45},{"number":920,"name":"Lokix","generation":9,"type1":"Bug","type2":"Dark","hp":71,"attack":102,"defense":78,"specialAttack":52,"specialDefense":55,"speed":92},{"number":921,"name":"Pawmi","generation":9,"type1":"Electric","type2":null,"hp":45,"attack":50,"defense":20,"specialAttack":40,"specialDefense":25,"speed":60},{"number":922,"name":"Pawmo","generation":9,"type1":"Electric","type2":"Fighting","hp":60,"attack":75,"defense":40,"specialAttack":50,"specialDefense":40,"speed":85},{"number":923,"name":"Pawmot","generation":9,"type1":"Electric","type2":"Fighting","hp":70,"attack":115,"defense":70,"specialAttack":70,"specialDefense":60,"speed":105},{"number":924,"name":"Tandemaus","generation":9,"type1":"Normal","type2":null,"hp":50,"attack":50,"defense":45,"specialAttack":40,"specialDefense":45,"speed":75},{"number":925,"name":"Maushold","generation":9,"type1":"Normal","type2":null,"hp":74,"attack":75,"defense":70,"specialAttack":65,"specialDefense":75,"speed":111},{"number":926,"name":"Fidough","generation":9,"type1":"Fairy","type2":null,"hp":37,"attack":55,"defense":70,"specialAttack":30,"specialDefense":55,"speed":65},{"number":927,"name":"Dachsbun","generation":9,"type1":"Fairy","type2":null,"hp":57,"attack":80,"defense":115,"specialAttack":50,"specialDefense":80,"speed":95},{"number":928,"name":"Smoliv","generation":9,"type1":"Grass","type2":"Normal","hp":41,"attack":35,"defense":45,"specialAttack":58,"specialDefense":51,"speed":30},{"number":929,"name":"Dolliv","generation":9,"type1":"Grass","type2":"Normal","hp":52,"attack":53,"defense":60,"specialAttack":78,"specialDefense":78,"speed":33},{"number":930,"name":"Arboliva","generation":9,"type1":"Grass","type2":"Normal","hp":78,"attack":69,"defense":90,"specialAttack":125,"specialDefense":109,"speed":39},{"number":931,"name":"Squawkabilly","generation":9,"type1":"Normal","type2":"Flying","hp":82,"attack":96,"defense":51,"specialAttack":45,"specialDefense":51,"speed":92},{"number":932,"name":"Nacli","generation":9,"type1":"Rock","type2":null,"hp":55,"attack":55,"defense":75,"specialAttack":35,"specialDefense":35,"speed":25},{"number":933,"name":"Naclstack","generation":9,"type1":"Rock","type2":null,"hp":60,"attack":60,"defense":100,"specialAttack":35,"specialDefense":65,"speed":35},{"number":934,"name":"Garganacl","generation":9,"type1":"Rock","type2":null,"hp":100,"attack":100,"defense":130,"specialAttack":45,"specialDefense":90,"speed":35},{"number":935,"name":"Charcadet","generation":9,"type1":"Fire","type2":null,"hp":40,"attack":50,"defense":40,"specialAttack":50,"specialDefense":40,"speed":35},{"number":936,"name":"Armarouge","generation":9,"type1":"Fire","type2":"Psychic","hp":85,"attack":60,"defense":100,"specialAttack":125,"specialDefense":80,"speed":75},{"number":937,"name":"Ceruledge","generation":9,"type1":"Fire","type2":"Ghost","hp":75,"attack":125,"defense":80,"specialAttack":60,"specialDefense":100,"speed":85},{"number":938,"name":"Tadbulb","generation":9,"type1":"Electric","type2":null,"hp":61,"attack":31,"defense":41,"specialAttack":59,"specialDefense":35,"speed":45},{"number":939,"name":"Bellibolt","generation":9,"type1":"Electric","type2":null,"hp":109,"attack":64,"defense":91,"specialAttack":103,"specialDefense":83,"speed":45},{"number":940,"name":"Wattrel","generation":9,"type1":"Electric","type2":"Flying","hp":40,"attack":40,"defense":35,"specialAttack":55,"specialDefense":40,"speed":70},{"number":941,"name":"Kilowattrel","generation":9,"type1":"Electric","type2":"Flying","hp":70,"attack":70,"defense":60,"specialAttack":105,"specialDefense":60,"speed":125},{"number":942,"name":"Maschiff","generation":9,"type1":"Dark","type2":null,"hp":60,"attack":78,"defense":60,"specialAttack":40,"specialDefense":51,"speed":51},{"number":943,"name":"Mabosstiff","generation":9,"type1":"Dark","type2":null,"hp":80,"attack":120,"defense":90,"specialAttack":60,"specialDefense":70,"speed":85},{"number":944,"name":"Shroodle","generation":9,"type1":"Poison","type2":"Normal","hp":40,"attack":65,"defense":35,"specialAttack":40,"specialDefense":35,"speed":75},{"number":945,"name":"Grafaiai","generation":9,"type1":"Poison","type2":"Normal","hp":63,"attack":95,"defense":65,"specialAttack":80,"specialDefense":72,"speed":110},{"number":946,"name":"Bramblin","generation":9,"type1":"Grass","type2":"Ghost","hp":40,"attack":65,"defense":30,"specialAttack":45,"specialDefense":35,"speed":60},{"number":947,"name":"Brambleghast","generation":9,"type1":"Grass","type2":"Ghost","hp":55,"attack":115,"defense":70,"specialAttack":80,"specialDefense":70,"speed":90},{"number":948,"name":"Toedscool","generation":9,"type1":"Ground","type2":"Grass","hp":40,"attack":40,"defense":35,"specialAttack":50,"specialDefense":100,"speed":70},{"number":949,"name":"Toedscruel","generation":9,"type1":"Ground","type2":"Grass","hp":80,"attack":70,"defense":65,"specialAttack":80,"specialDefense":120,"speed":100},{"number":950,"name":"Klawf","generation":9,"type1":"Rock","type2":null,"hp":70,"attack":100,"defense":115,"specialAttack":35,"specialDefense":55,"speed":75},{"number":951,"name":"Capsakid","generation":9,"type1":"Grass","type2":null,"hp":50,"attack":62,"defense":40,"specialAttack":62,"specialDefense":40,"speed":50},{"number":952,"name":"Scovillain","generation":9,"type1":"Grass","type2":"Fire","hp":65,"attack":108,"defense":65,"specialAttack":108,"specialDefense":65,"speed":75},{"number":953,"name":"Rellor","generation":9,"type1":"Bug","type2":null,"hp":41,"attack":50,"defense":60,"specialAttack":31,"specialDefense":58,"speed":30},{"number":954,"name":"Rabsca","generation":9,"type1":"Bug","type2":"Psychic","hp":75,"attack":50,"defense":85,"specialAttack":115,"specialDefense":100,"speed":45},{"number":955,"name":"Flittle","generation":9,"type1":"Psychic","type2":null,"hp":30,"attack":35,"defense":30,"specialAttack":55,"specialDefense":30,"speed":75},{"number":956,"name":"Espathra","generation":9,"type1":"Psychic","type2":null,"hp":95,"attack":60,"defense":60,"specialAttack":101,"specialDefense":60,"speed":105},{"number":957,"name":"Tinkatink","generation":9,"type1":"Fairy","type2":"Steel","hp":50,"attack":45,"defense":45,"specialAttack":35,"specialDefense":64,"speed":58},{"number":958,"name":"Tinkatuff","generation":9,"type1":"Fairy","type2":"Steel","hp":65,"attack":55,"defense":55,"specialAttack":45,"specialDefense":82,"speed":78},{"number":959,"name":"Tinkaton","generation":9,"type1":"Fairy","type2":"Steel","hp":85,"attack":75,"defense":77,"specialAttack":70,"specialDefense":105,"speed":94},{"number":960,"name":"Wiglett","generation":9,"type1":"Water","type2":null,"hp":10,"attack":55,"defense":25,"specialAttack":35,"specialDefense":25,"speed":95},{"number":961,"name":"Wugtrio","generation":9,"type1":"Water","type2":null,"hp":35,"attack":100,"defense":50,"specialAttack":50,"specialDefense":70,"speed":120},{"number":962,"name":"Bombirdier","generation":9,"type1":"Flying","type2":"Dark","hp":70,"attack":103,"defense":85,"specialAttack":60,"specialDefense":85,"speed":82},{"number":963,"name":"Finizen","generation":9,"type1":"Water","type2":null,"hp":70,"attack":45,"defense":40,"specialAttack":45,"specialDefense":40,"speed":75},{"number":964,"name":"Palafin","generation":9,"type1":"Water","type2":null,"hp":100,"attack":70,"defense":72,"specialAttack":53,"specialDefense":62,"speed":100},{"number":965,"name":"Varoom","generation":9,"type1":"Steel","type2":"Poison","hp":45,"attack":70,"defense":63,"specialAttack":30,"specialDefense":45,"speed":47},{"number":966,"name":"Revavroom","generation":9,"type1":"Steel","type2":"Poison","hp":80,"attack":119,"defense":90,"specialAttack":54,"specialDefense":67,"speed":90},{"number":967,"name":"Cyclizar","generation":9,"type1":"Dragon","type2":"Normal","hp":70,"attack":95,"defense":65,"specialAttack":85,"specialDefense":65,"speed":121},{"number":968,"name":"Orthworm","generation":9,"type1":"Steel","type2":null,"hp":70,"attack":85,"defense":145,"specialAttack":60,"specialDefense":55,"speed":65},{"number":969,"name":"Glimmet","generation":9,"type1":"Rock","type2":"Poison","hp":48,"attack":35,"defense":42,"specialAttack":105,"specialDefense":60,"speed":60},{"number":970,"name":"Glimmora","generation":9,"type1":"Rock","type2":"Poison","hp":83,"attack":55,"defense":90,"specialAttack":130,"specialDefense":81,"speed":86},{"number":971,"name":"Greavard","generation":9,"type1":"Ghost","type2":null,"hp":50,"attack":61,"defense":60,"specialAttack":30,"specialDefense":55,"speed":34},{"number":972,"name":"Houndstone","generation":9,"type1":"Ghost","type2":null,"hp":72,"attack":101,"defense":100,"specialAttack":50,"specialDefense":97,"speed":68},{"number":973,"name":"Flamigo","generation":9,"type1":"Flying","type2":"Fighting","hp":82,"attack":115,"defense":74,"specialAttack":75,"specialDefense":64,"speed":90},{"number":974,"name":"Cetoddle","generation":9,"type1":"Ice","type2":null,"hp":108,"attack":68,"defense":45,"specialAttack":30,"specialDefense":40,"speed":43},{"number":975,"name":"Cetitan","generation":9,"type1":"Ice","type2":null,"hp":170,"attack":113,"defense":65,"specialAttack":45,"specialDefense":55,"speed":73},{"number":976,"name":"Veluza","generation":9,"type1":"Water","type2":"Psychic","hp":90,"attack":102,"defense":73,"specialAttack":78,"specialDefense":65,"speed":70},{"number":977,"name":"Dondozo","generation":9,"type1":"Water","type2":null,"hp":150,"attack":100,"defense":115,"specialAttack":65,"specialDefense":65,"speed":35},{"number":978,"name":"Tatsugiri","generation":9,"type1":"Dragon","type2":"Water","hp":68,"attack":50,"defense":60,"specialAttack":120,"specialDefense":95,"speed":82},{"number":979,"name":"Annihilape","generation":9,"type1":"Fighting","type2":"Ghost","hp":110,"attack":115,"defense":80,"specialAttack":50,"specialDefense":90,"speed":90},{"number":980,"name":"Clodsire","generation":9,"type1":"Poison","type2":"Ground","hp":130,"attack":75,"defense":60,"specialAttack":45,"specialDefense":100,"speed":20},{"number":981,"name":"Farigiraf","generation":9,"type1":"Normal","type2":"Psychic","hp":120,"attack":90,"defense":70,"specialAttack":110,"specialDefense":70,"speed":60},{"number":982,"name":"Dudunsparce","generation":9,"type1":"Normal","type2":null,"hp":125,"attack":100,"defense":80,"specialAttack":85,"specialDefense":75,"speed":55},{"number":983,"name":"Kingambit","generation":9,"type1":"Dark","type2":"Steel","hp":100,"attack":135,"defense":120,"specialAttack":60,"specialDefense":85,"speed":50},{"number":984,"name":"Great Tusk","generation":9,"type1":"Ground","type2":"Fighting","hp":115,"attack":131,"defense":131,"specialAttack":53,"specialDefense":53,"speed":87},{"number":985,"name":"Scream Tail","generation":9,"type1":"Fairy","type2":"Psychic","hp":115,"attack":65,"defense":99,"specialAttack":65,"specialDefense":115,"speed":111},{"number":986,"name":"Brute Bonnet","generation":9,"type1":"Grass","type2":"Dark","hp":111,"attack":127,"defense":99,"specialAttack":79,"specialDefense":99,"speed":55},{"number":987,"name":"Flutter Mane","generation":9,"type1":"Ghost","type2":"Fairy","hp":55,"attack":55,"defense":55,"specialAttack":135,"specialDefense":135,"speed":135},{"number":988,"name":"Slither Wing","generation":9,"type1":"Bug","type2":"Fighting","hp":85,"attack":135,"defense":79,"specialAttack":85,"specialDefense":105,"speed":81},{"number":989,"name":"Sandy Shocks","generation":9,"type1":"Electric","type2":"Ground","hp":85,"attack":81,"defense":97,"specialAttack":121,"specialDefense":85,"speed":101},{"number":990,"name":"Iron Treads","generation":9,"type1":"Ground","type2":"Steel","hp":90,"attack":112,"defense":120,"specialAttack":72,"specialDefense":70,"speed":106},{"number":991,"name":"Iron Bundle","generation":9,"type1":"Ice","type2":"Water","hp":56,"attack":80,"defense":114,"specialAttack":124,"specialDefense":60,"speed":136},{"number":992,"name":"Iron Hands","generation":9,"type1":"Fighting","type2":"Electric","hp":154,"attack":140,"defense":108,"specialAttack":50,"specialDefense":68,"speed":50},{"number":993,"name":"Iron Jugulis","generation":9,"type1":"Dark","type2":"Flying","hp":94,"attack":80,"defense":86,"specialAttack":122,"specialDefense":80,"speed":108},{"number":994,"name":"Iron Moth","generation":9,"type1":"Fire","type2":"Poison","hp":80,"attack":70,"defense":60,"specialAttack":140,"specialDefense":110,"speed":110},{"number":995,"name":"Iron Thorns","generation":9,"type1":"Rock","type2":"Electric","hp":100,"attack":134,"defense":110,"specialAttack":70,"specialDefense":84,"speed":72},{"number":996,"name":"Frigibax","generation":9,"type1":"Dragon","type2":"Ice","hp":65,"attack":75,"defense":45,"specialAttack":35,"specialDefense":45,"speed":55},{"number":997,"name":"Arctibax","generation":9,"type1":"Dragon","type2":"Ice","hp":90,"attack":95,"defense":66,"specialAttack":45,"specialDefense":65,"speed":62},{"number":998,"name":"Baxcalibur","generation":9,"type1":"Dragon","type2":"Ice","hp":115,"attack":145,"defense":92,"specialAttack":75,"specialDefense":86,"speed":87},{"number":999,"name":"Gimmighoul","generation":9,"type1":"Ghost","type2":null,"hp":45,"attack":30,"defense":70,"specialAttack":75,"specialDefense":70,"speed":10},{"number":1000,"name":"Gholdengo","generation":9,"type1":"Steel","type2":"Ghost","hp":87,"attack":60,"defense":95,"specialAttack":133,"specialDefense":91,"speed":84},{"number":1001,"name":"Wo-Chien","generation":9,"type1":"Dark","type2":"Grass","hp":85,"attack":85,"defense":100,"specialAttack":95,"specialDefense":135,"speed":70},{"number":1002,"name":"Chien-Pao","generation":9,"type1":"Dark","type2":"Ice","hp":80,"attack":120,"defense":80,"specialAttack":90,"specialDefense":65,"speed":135},{"number":1003,"name":"Ting-Lu","generation":9,"type1":"Dark","type2":"Ground","hp":155,"attack":110,"defense":125,"specialAttack":55,"specialDefense":80,"speed":45},{"number":1004,"name":"Chi-Yu","generation":9,"type1":"Dark","type2":"Fire","hp":55,"attack":80,"defense":80,"specialAttack":135,"specialDefense":120,"speed":100},{"number":1005,"name":"Roaring Moon","generation":9,"type1":"Dragon","type2":"Dark","hp":105,"attack":139,"defense":71,"specialAttack":55,"specialDefense":101,"speed":119},{"number":1006,"name":"Iron Valiant","generation":9,"type1":"Fairy","type2":"Fighting","hp":74,"attack":130,"defense":90,"specialAttack":120,"specialDefense":60,"speed":116},{"number":1007,"name":"Koraidon","generation":9,"type1":"Fighting","type2":"Dragon","hp":100,"attack":135,"defense":115,"specialAttack":85,"specialDefense":100,"speed":135},{"number":1008,"name":"Miraidon","generation":9,"type1":"Electric","type2":"Dragon","hp":100,"attack":85,"defense":100,"specialAttack":135,"specialDefense":115,"speed":135},{"number":1009,"name":"Walking Wake","generation":9,"type1":"Water","type2":"Dragon","hp":99,"attack":83,"defense":91,"specialAttack":125,"specialDefense":83,"speed":109},{"number":1010,"name":"Iron Leaves","generation":9,"type1":"Grass","type2":"Psychic","hp":90,"attack":130,"defense":88,"specialAttack":70,"specialDefense":108,"speed":104},{"number":1011,"name":"Dipplin","generation":9,"type1":"Grass","type2":"Dragon","hp":80,"attack":80,"defense":110,"specialAttack":95,"specialDefense":80,"speed":40},{"number":1012,"name":"Poltchageist","generation":9,"type1":"Grass","type2":"Ghost","hp":40,"attack":45,"defense":45,"specialAttack":74,"specialDefense":54,"speed":50},{"number":1013,"name":"Sinistcha","generation":9,"type1":"Grass","type2":"Ghost","hp":71,"attack":60,"defense":106,"specialAttack":121,"specialDefense":80,"speed":70},{"number":1014,"name":"Okidogi","generation":9,"type1":"Poison","type2":"Fighting","hp":88,"attack":128,"defense":115,"specialAttack":58,"specialDefense":86,"speed":80},{"number":1015,"name":"Munkidori","generation":9,"type1":"Poison","type2":"Psychic","hp":88,"attack":75,"defense":66,"specialAttack":130,"specialDefense":90,"speed":106},{"number":1016,"name":"Fezandipiti","generation":9,"type1":"Poison","type2":"Fairy","hp":88,"attack":91,"defense":82,"specialAttack":70,"specialDefense":125,"speed":99},{"number":1017,"name":"Ogerpon","generation":9,"type1":"Grass","type2":null,"hp":80,"attack":120,"defense":84,"specialAttack":60,"specialDefense":96,"speed":110},{"number":1018,"name":"Archaludon","generation":9,"type1":"Steel","type2":"Dragon","hp":90,"attack":105,"defense":130,"specialAttack":125,"specialDefense":65,"speed":85},{"number":1019,"name":"Hydrapple","generation":9,"type1":"Grass","type2":"Dragon","hp":106,"attack":80,"defense":110,"specialAttack":120,"specialDefense":80,"speed":44},{"number":1020,"name":"Gouging Fire","generation":9,"type1":"Fire","type2":"Dragon","hp":105,"attack":115,"defense":121,"specialAttack":65,"specialDefense":93,"speed":91},{"number":1021,"name":"Raging Bolt","generation":9,"type1":"Electric","type2":"Dragon","hp":125,"attack":73,"defense":91,"specialAttack":137,"specialDefense":89,"speed":75},{"number":1022,"name":"Iron Boulder","generation":9,"type1":"Rock","type2":"Psychic","hp":90,"attack":120,"defense":80,"specialAttack":68,"specialDefense":108,"speed":124},{"number":1023,"name":"Iron Crown","generation":9,"type1":"Steel","type2":"Psychic","hp":90,"attack":72,"defense":100,"specialAttack":122,"specialDefense":108,"speed":98},{"number":1024,"name":"Terapagos","generation":9,"type1":"Normal","type2":null,"hp":90,"attack":65,"defense":85,"specialAttack":65,"specialDefense":85,"speed":60},{"number":1025,"name":"Pecharunt","generation":9,"type1":"Poison","type2":"Ghost","hp":88,"attack":88,"defense":160,"specialAttack":88,"specialDefense":88,"speed":88}],"games":[{"sourceId":1,"name":"Red","generation":1},{"sourceId":2,"name":"Blue","generation":1},{"sourceId":3,"name":"Yellow","generation":1},{"sourceId":4,"name":"Gold","generation":2},{"sourceId":5,"name":"Silver","generation":2},{"sourceId":6,"name":"Crystal","generation":2},{"sourceId":7,"name":"Ruby","generation":3},{"sourceId":8,"name":"Sapphire","generation":3},{"sourceId":9,"name":"Emerald","generation":3},{"sourceId":10,"name":"FireRed","generation":3},{"sourceId":11,"name":"LeafGreen","generation":3},{"sourceId":12,"name":"Diamond","generation":4},{"sourceId":13,"name":"Pearl","generation":4},{"sourceId":14,"name":"Platinum","generation":4},{"sourceId":15,"name":"HeartGold","generation":4},{"sourceId":16,"name":"SoulSilver","generation":4},{"sourceId":17,"name":"Black","generation":5},{"sourceId":18,"name":"White","generation":5},{"sourceId":19,"name":"Colosseum","generation":3},{"sourceId":20,"name":"XD","generation":3},{"sourceId":21,"name":"Black 2","generation":5},{"sourceId":22,"name":"White 2","generation":5},{"sourceId":23,"name":"X","generation":6},{"sourceId":24,"name":"Y","generation":6},{"sourceId":25,"name":"Omega Ruby","generation":6},{"sourceId":26,"name":"Alpha Sapphire","generation":6},{"sourceId":27,"name":"Sun","generation":7},{"sourceId":28,"name":"Moon","generation":7},{"sourceId":29,"name":"Ultra Sun","generation":7},{"sourceId":30,"name":"Ultra Moon","generation":7},{"sourceId":31,"name":"Let’s Go, Pikachu!","generation":7},{"sourceId":32,"name":"Let’s Go, Eevee!","generation":7},{"sourceId":33,"name":"Sword","generation":8},{"sourceId":34,"name":"Shield","generation":8},{"sourceId":35,"name":"Sword: The Isle of Armor","generation":8},{"sourceId":36,"name":"Sword: The Crown Tundra","generation":8},{"sourceId":37,"name":"Brilliant Diamond","generation":8},{"sourceId":38,"name":"Shining Pearl","generation":8},{"sourceId":39,"name":"Legends: Arceus","generation":8},{"sourceId":40,"name":"Scarlet","generation":9},{"sourceId":41,"name":"Violet","generation":9},{"sourceId":42,"name":"Scarlet: The Teal Mask","generation":9},{"sourceId":43,"name":"Scarlet: The Indigo Disk","generation":9},{"sourceId":44,"name":"Red (Japan)","generation":1},{"sourceId":45,"name":"Green (Japan)","generation":1},{"sourceId":46,"name":"Blue (Japan)","generation":1},{"sourceId":47,"name":"Legends: Z-A","generation":9},{"sourceId":48,"name":"Mega Dimension","generation":9},{"sourceId":49,"name":"Champions","generation":9},{"sourceId":50,"name":"Shield: The Isle of Armor","generation":8},{"sourceId":51,"name":"Shield: The Crown Tundra","generation":8},{"sourceId":52,"name":"Violet: The Teal Mask","generation":9},{"sourceId":53,"name":"Violet: The Indigo Disk","generation":9}],"entries":[[1,1,"catchable"],[1,2,"catchable"],[1,3,"catchable"],[1,4,"unknown"],[1,5,"unknown"],[1,6,"unknown"],[1,7,"unknown"],[1,8,"unknown"],[1,9,"unknown"],[1,10,"catchable"],[1,11,"catchable"],[1,12,"unknown"],[1,13,"unknown"],[1,14,"unknown"],[1,15,"catchable"],[1,16,"catchable"],[1,17,"unknown"],[1,18,"unknown"],[1,21,"unknown"],[1,22,"unknown"],[1,23,"catchable"],[1,24,"catchable"],[1,25,"unknown"],[1,26,"unknown"],[1,27,"unknown"],[1,28,"unknown"],[1,29,"catchable"],[1,30,"catchable"],[1,31,"catchable"],[1,32,"catchable"],[1,33,"unknown"],[1,34,"unknown"],[1,35,"catchable"],[1,36,"unknown"],[1,37,"unknown"],[1,38,"unknown"],[1,39,"unknown"],[1,40,"unknown"],[1,41,"unknown"],[1,42,"unknown"],[1,43,"unknown"],[1,44,"catchable"],[1,45,"catchable"],[1,46,"unknown"],[1,47,"unknown"],[1,48,"unknown"],[1,50,"catchable"],[1,53,"unknown"],[2,1,"unknown"],[2,2,"unknown"],[2,3,"unknown"],[2,4,"unknown"],[2,5,"unknown"],[2,6,"unknown"],[2,7,"unknown"],[2,8,"unknown"],[2,9,"unknown"],[2,10,"unknown"],[2,11,"unknown"],[2,12,"unknown"],[2,13,"unknown"],[2,14,"unknown"],[2,15,"unknown"],[2,16,"unknown"],[2,17,"unknown"],[2,18,"unknown"],[2,21,"unknown"],[2,22,"unknown"],[2,23,"catchable"],[2,24,"catchable"],[2,25,"unknown"],[2,26,"unknown"],[2,27,"unknown"],[2,28,"unknown"],[2,29,"unknown"],[2,30,"unknown"],[2,31,"unknown"],[2,32,"unknown"],[2,33,"unknown"],[2,34,"unknown"],[2,35,"unknown"],[2,36,"catchable"],[2,37,"unknown"],[2,38,"unknown"],[2,39,"unknown"],[2,40,"unknown"],[2,41,"unknown"],[2,42,"unknown"],[2,43,"unknown"],[2,44,"unknown"],[2,45,"unknown"],[2,46,"unknown"],[2,47,"unknown"],[2,48,"unknown"],[2,50,"unknown"],[2,51,"catchable"],[2,53,"unknown"],[3,1,"unknown"],[3,2,"unknown"],[3,3,"unknown"],[3,4,"unknown"],[3,5,"unknown"],[3,6,"unknown"],[3,7,"unknown"],[3,8,"unknown"],[3,9,"unknown"],[3,10,"unknown"],[3,11,"unknown"],[3,12,"unknown"],[3,13,"unknown"],[3,14,"unknown"],[3,15,"unknown"],[3,16,"unknown"],[3,17,"unknown"],[3,18,"unknown"],[3,21,"unknown"],[3,22,"unknown"],[3,23,"unknown"],[3,24,"unknown"],[3,25,"unknown"],[3,26,"unknown"],[3,27,"unknown"],[3,28,"unknown"],[3,29,"unknown"],[3,30,"unknown"],[3,31,"unknown"],[3,32,"unknown"],[3,33,"unknown"],[3,34,"unknown"],[3,35,"catchable"],[3,36,"unknown"],[3,37,"unknown"],[3,38,"unknown"],[3,39,"unknown"],[3,40,"unknown"],[3,41,"unknown"],[3,42,"unknown"],[3,43,"unknown"],[3,44,"unknown"],[3,45,"unknown"],[3,46,"unknown"],[3,47,"unknown"],[3,48,"unknown"],[3,49,"unknown"],[3,50,"catchable"],[3,53,"unknown"],[4,1,"catchable"],[4,2,"catchable"],[4,3,"catchable"],[4,4,"unknown"],[4,5,"unknown"],[4,6,"unknown"],[4,7,"unknown"],[4,8,"unknown"],[4,9,"unknown"],[4,10,"catchable"],[4,11,"catchable"],[4,12,"unknown"],[4,13,"unknown"],[4,14,"unknown"],[4,15,"catchable"],[4,16,"catchable"],[4,17,"unknown"],[4,18,"unknown"],[4,21,"unknown"],[4,22,"unknown"],[4,23,"catchable"],[4,24,"catchable"],[4,25,"unknown"],[4,26,"unknown"],[4,27,"unknown"],[4,28,"unknown"],[4,29,"catchable"],[4,30,"catchable"],[4,31,"catchable"],[4,32,"catchable"],[4,33,"catchable"],[4,34,"catchable"],[4,35,"unknown"],[4,36,"unknown"],[4,37,"unknown"],[4,38,"unknown"],[4,39,"unknown"],[4,40,"unknown"],[4,41,"unknown"],[4,42,"unknown"],[4,43,"unknown"],[4,44,"catchable"],[4,45,"catchable"],[4,46,"unknown"],[4,47,"unknown"],[4,48,"unknown"],[4,53,"unknown"],[5,1,"unknown"],[5,2,"unknown"],[5,3,"unknown"],[5,4,"unknown"],[5,5,"unknown"],[5,6,"unknown"],[5,7,"unknown"],[5,8,"unknown"],[5,9,"unknown"],[5,10,"unknown"],[5,11,"unknown"],[5,12,"unknown"],[5,13,"unknown"],[5,14,"unknown"],[5,15,"unknown"],[5,16,"unknown"],[5,17,"unknown"],[5,18,"unknown"],[5,21,"unknown"],[5,22,"unknown"],[5,23,"catchable"],[5,24,"catchable"],[5,25,"unknown"],[5,26,"unknown"],[5,27,"unknown"],[5,28,"unknown"],[5,29,"unknown"],[5,30,"unknown"],[5,31,"unknown"],[5,32,"unknown"],[5,33,"catchable"],[5,34,"catchable"],[5,35,"unknown"],[5,36,"catchable"],[5,37,"unknown"],[5,38,"unknown"],[5,39,"unknown"],[5,40,"unknown"],[5,41,"unknown"],[5,42,"unknown"],[5,43,"unknown"],[5,44,"unknown"],[5,45,"unknown"],[5,46,"unknown"],[5,47,"unknown"],[5,48,"unknown"],[5,51,"catchable"],[5,53,"unknown"],[6,1,"unknown"],[6,2,"unknown"],[6,3,"unknown"],[6,4,"unknown"],[6,5,"unknown"],[6,6,"unknown"],[6,7,"unknown"],[6,8,"unknown"],[6,9,"unknown"],[6,10,"unknown"],[6,11,"unknown"],[6,12,"unknown"],[6,13,"unknown"],[6,14,"unknown"],[6,15,"unknown"],[6,16,"unknown"],[6,17,"unknown"],[6,18,"unknown"],[6,21,"unknown"],[6,22,"unknown"],[6,23,"unknown"],[6,24,"unknown"],[6,25,"unknown"],[6,26,"unknown"],[6,27,"unknown"],[6,28,"unknown"],[6,29,"unknown"],[6,30,"unknown"],[6,31,"catchable"],[6,32,"catchable"],[6,33,"catchable"],[6,34,"catchable"],[6,35,"catchable"],[6,36,"unknown"],[6,37,"unknown"],[6,38,"unknown"],[6,39,"unknown"],[6,40,"unknown"],[6,41,"unknown"],[6,42,"unknown"],[6,43,"unknown"],[6,44,"unknown"],[6,45,"unknown"],[6,46,"unknown"],[6,47,"unknown"],[6,48,"unknown"],[6,49,"unknown"],[6,50,"catchable"],[6,53,"unknown"],[7,1,"catchable"],[7,2,"catchable"],[7,3,"catchable"],[7,4,"unknown"],[7,5,"unknown"],[7,6,"unknown"],[7,7,"unknown"],[7,8,"unknown"],[7,9,"unknown"],[7,10,"catchable"],[7,11,"catchable"],[7,12,"unknown"],[7,13,"unknown"],[7,14,"unknown"],[7,15,"catchable"],[7,16,"catchable"],[7,17,"unknown"],[7,18,"unknown"],[7,21,"unknown"],[7,22,"unknown"],[7,23,"catchable"],[7,24,"catchable"],[7,25,"unknown"],[7,26,"unknown"],[7,27,"unknown"],[7,28,"unknown"],[7,29,"catchable"],[7,30,"catchable"],[7,31,"catchable"],[7,32,"catchable"],[7,33,"unknown"],[7,34,"unknown"],[7,35,"catchable"],[7,36,"unknown"],[7,37,"unknown"],[7,38,"unknown"],[7,39,"unknown"],[7,40,"unknown"],[7,41,"unknown"],[7,42,"unknown"],[7,43,"unknown"],[7,44,"catchable"],[7,45,"catchable"],[7,46,"unknown"],[7,47,"unknown"],[7,48,"unknown"],[7,50,"catchable"],[7,53,"unknown"],[8,1,"unknown"],[8,2,"unknown"],[8,3,"unknown"],[8,4,"unknown"],[8,5,"unknown"],[8,6,"unknown"],[8,7,"unknown"],[8,8,"unknown"],[8,9,"unknown"],[8,10,"unknown"],[8,11,"unknown"],[8,12,"unknown"],[8,13,"unknown"],[8,14,"unknown"],[8,15,"unknown"],[8,16,"unknown"],[8,17,"unknown"],[8,18,"unknown"],[8,21,"unknown"],[8,22,"unknown"],[8,23,"catchable"],[8,24,"catchable"],[8,25,"unknown"],[8,26,"unknown"],[8,27,"unknown"],[8,28,"unknown"],[8,29,"unknown"],[8,30,"unknown"],[8,31,"unknown"],[8,32,"unknown"],[8,33,"unknown"],[8,34,"unknown"],[8,35,"unknown"],[8,36,"catchable"],[8,37,"unknown"],[8,38,"unknown"],[8,39,"unknown"],[8,40,"unknown"],[8,41,"unknown"],[8,42,"unknown"],[8,43,"unknown"],[8,44,"unknown"],[8,45,"unknown"],[8,46,"unknown"],[8,47,"unknown"],[8,48,"unknown"],[8,50,"unknown"],[8,51,"catchable"],[8,53,"unknown"],[9,1,"unknown"],[9,2,"unknown"],[9,3,"unknown"],[9,4,"unknown"],[9,5,"unknown"],[9,6,"unknown"],[9,7,"unknown"],[9,8,"unknown"],[9,9,"unknown"],[9,10,"unknown"],[9,11,"unknown"],[9,12,"unknown"],[9,13,"unknown"],[9,14,"unknown"],[9,15,"unknown"],[9,16,"unknown"],[9,17,"unknown"],[9,18,"unknown"],[9,21,"unknown"],[9,22,"unknown"],[9,23,"unknown"],[9,24,"unknown"],[9,25,"unknown"],[9,26,"unknown"],[9,27,"unknown"],[9,28,"unknown"],[9,29,"unknown"],[9,30,"unknown"],[9,31,"unknown"],[9,32,"unknown"],[9,33,"unknown"],[9,34,"unknown"],[9,35,"catchable"],[9,36,"unknown"],[9,37,"unknown"],[9,38,"unknown"],[9,39,"unknown"],[9,40,"unknown"],[9,41,"unknown"],[9,42,"unknown"],[9,43,"unknown"],[9,44,"unknown"],[9,45,"unknown"],[9,46,"unknown"],[9,47,"unknown"],[9,48,"unknown"],[9,49,"unknown"],[9,50,"catchable"],[9,53,"unknown"],[10,1,"catchable"],[10,2,"catchable"],[10,3,"catchable"],[10,4,"catchable"],[10,5,"unknown"],[10,6,"catchable"],[10,7,"unknown"],[10,8,"unknown"],[10,9,"unknown"],[10,10,"catchable"],[10,11,"catchable"],[10,12,"catchable"],[10,13,"catchable"],[10,14,"catchable"],[10,15,"catchable"],[10,16,"catchable"],[10,17,"unknown"],[10,18,"unknown"],[10,21,"unknown"],[10,22,"unknown"],[10,23,"catchable"],[10,24,"catchable"],[10,25,"unknown"],[10,26,"unknown"],[10,27,"catchable"],[10,28,"catchable"],[10,29,"catchable"],[10,30,"catchable"],[10,31,"catchable"],[10,32,"catchable"],[10,33,"catchable"],[10,34,"catchable"],[10,35,"unknown"],[10,36,"unknown"],[10,37,"unknown"],[10,38,"unknown"],[10,39,"unknown"],[10,44,"catchable"],[10,45,"catchable"],[10,46,"unknown"],[11,1,"catchable"],[11,2,"catchable"],[11,3,"catchable"],[11,4,"catchable"],[11,5,"unknown"],[11,6,"catchable"],[11,7,"unknown"],[11,8,"unknown"],[11,9,"unknown"],[11,10,"catchable"],[11,11,"catchable"],[11,12,"catchable"],[11,13,"catchable"],[11,14,"catchable"],[11,15,"catchable"],[11,16,"catchable"],[11,17,"unknown"],[11,18,"catchable"],[11,21,"unknown"],[11,22,"unknown"],[11,23,"unknown"],[11,24,"catchable"],[11,25,"unknown"],[11,26,"unknown"],[11,27,"catchable"],[11,28,"catchable"],[11,29,"catchable"],[11,30,"catchable"],[11,31,"catchable"],[11,32,"catchable"],[11,33,"catchable"],[11,34,"catchable"],[11,35,"unknown"],[11,36,"unknown"],[11,37,"unknown"],[11,38,"unknown"],[11,39,"unknown"],[11,44,"catchable"],[11,45,"catchable"],[11,46,"unknown"],[12,1,"unknown"],[12,2,"unknown"],[12,3,"unknown"],[12,4,"catchable"],[12,5,"unknown"],[12,6,"catchable"],[12,7,"unknown"],[12,8,"unknown"],[12,9,"unknown"],[12,10,"unknown"],[12,11,"unknown"],[12,12,"unknown"],[12,13,"unknown"],[12,14,"unknown"],[12,15,"catchable"],[12,16,"catchable"],[12,17,"unknown"],[12,18,"catchable"],[12,20,"catchable"],[12,21,"unknown"],[12,22,"catchable"],[12,23,"catchable"],[12,24,"catchable"],[12,25,"unknown"],[12,26,"unknown"],[12,27,"catchable"],[12,28,"catchable"],[12,29,"catchable"],[12,30,"catchable"],[12,31,"catchable"],[12,32,"unknown"],[12,33,"catchable"],[12,34,"catchable"],[12,35,"unknown"],[12,36,"catchable"],[12,37,"unknown"],[12,38,"unknown"],[12,39,"unknown"],[12,44,"unknown"],[12,45,"unknown"],[12,46,"unknown"],[12,51,"catchable"],[13,1,"catchable"],[13,2,"catchable"],[13,3,"unknown"],[13,4,"unknown"],[13,5,"catchable"],[13,6,"catchable"],[13,7,"unknown"],[13,8,"unknown"],[13,9,"unknown"],[13,10,"catchable"],[13,11,"catchable"],[13,12,"catchable"],[13,13,"catchable"],[13,14,"catchable"],[13,15,"catchable"],[13,16,"catchable"],[13,17,"unknown"],[13,18,"unknown"],[13,21,"unknown"],[13,22,"unknown"],[13,23,"catchable"],[13,24,"catchable"],[13,25,"unknown"],[13,26,"unknown"],[13,27,"unknown"],[13,28,"unknown"],[13,29,"unknown"],[13,30,"unknown"],[13,31,"catchable"],[13,32,"catchable"],[13,44,"catchable"],[13,45,"catchable"],[13,46,"unknown"],[13,47,"unknown"],[14,1,"catchable"],[14,2,"catchable"],[14,3,"unknown"],[14,4,"unknown"],[14,5,"catchable"],[14,6,"catchable"],[14,7,"unknown"],[14,8,"unknown"],[14,9,"unknown"],[14,10,"catchable"],[14,11,"catchable"],[14,12,"catchable"],[14,13,"catchable"],[14,14,"catchable"],[14,15,"catchable"],[14,16,"catchable"],[14,17,"catchable"],[14,18,"unknown"],[14,21,"unknown"],[14,22,"unknown"],[14,23,"catchable"],[14,24,"catchable"],[14,25,"unknown"],[14,26,"unknown"],[14,27,"unknown"],[14,28,"unknown"],[14,29,"unknown"],[14,30,"unknown"],[14,31,"catchable"],[14,32,"catchable"],[14,44,"catchable"],[14,45,"catchable"],[14,46,"unknown"],[14,47,"unknown"],[15,1,"unknown"],[15,2,"unknown"],[15,3,"unknown"],[15,4,"unknown"],[15,5,"catchable"],[15,6,"catchable"],[15,7,"unknown"],[15,8,"unknown"],[15,9,"unknown"],[15,10,"unknown"],[15,11,"unknown"],[15,12,"unknown"],[15,13,"unknown"],[15,14,"unknown"],[15,15,"catchable"],[15,16,"catchable"],[15,17,"catchable"],[15,18,"unknown"],[15,20,"catchable"],[15,21,"catchable"],[15,22,"unknown"],[15,23,"unknown"],[15,24,"unknown"],[15,25,"unknown"],[15,26,"unknown"],[15,27,"unknown"],[15,28,"unknown"],[15,29,"catchable"],[15,30,"catchable"],[15,31,"unknown"],[15,32,"catchable"],[15,44,"unknown"],[15,45,"unknown"],[15,46,"unknown"],[15,47,"unknown"],[15,49,"unknown"],[16,1,"catchable"],[16,2,"catchable"],[16,3,"catchable"],[16,4,"catchable"],[16,5,"catchable"],[16,6,"catchable"],[16,7,"unknown"],[16,8,"unknown"],[16,9,"unknown"],[16,10,"catchable"],[16,11,"catchable"],[16,12,"catchable"],[16,13,"catchable"],[16,14,"catchable"],[16,15,"catchable"],[16,16,"catchable"],[16,17,"unknown"],[16,18,"unknown"],[16,21,"unknown"],[16,22,"unknown"],[16,23,"catchable"],[16,24,"catchable"],[16,25,"unknown"],[16,26,"unknown"],[16,27,"unknown"],[16,28,"unknown"],[16,29,"unknown"],[16,30,"unknown"],[16,31,"catchable"],[16,32,"catchable"],[16,44,"catchable"],[16,45,"catchable"],[16,46,"unknown"],[16,47,"unknown"],[17,1,"catchable"],[17,2,"catchable"],[17,3,"catchable"],[17,4,"catchable"],[17,5,"catchable"],[17,6,"catchable"],[17,7,"unknown"],[17,8,"unknown"],[17,9,"unknown"],[17,10,"catchable"],[17,11,"catchable"],[17,12,"unknown"],[17,13,"unknown"],[17,14,"unknown"],[17,15,"catchable"],[17,16,"catchable"],[17,17,"unknown"],[17,18,"unknown"],[17,20,"catchable"],[17,21,"unknown"],[17,22,"unknown"],[17,23,"unknown"],[17,24,"unknown"],[17,25,"unknown"],[17,26,"unknown"],[17,27,"unknown"],[17,28,"unknown"],[17,29,"unknown"],[17,30,"unknown"],[17,31,"catchable"],[17,32,"catchable"],[17,44,"catchable"],[17,45,"catchable"],[17,46,"unknown"],[17,47,"unknown"],[18,1,"unknown"],[18,2,"unknown"],[18,3,"unknown"],[18,4,"unknown"],[18,5,"unknown"],[18,6,"unknown"],[18,7,"unknown"],[18,8,"unknown"],[18,9,"unknown"],[18,10,"unknown"],[18,11,"unknown"],[18,12,"unknown"],[18,13,"unknown"],[18,14,"unknown"],[18,15,"unknown"],[18,16,"unknown"],[18,17,"unknown"],[18,18,"unknown"],[18,21,"unknown"],[18,22,"unknown"],[18,23,"unknown"],[18,24,"unknown"],[18,25,"unknown"],[18,26,"unknown"],[18,27,"unknown"],[18,28,"unknown"],[18,29,"catchable"],[18,30,"catchable"],[18,31,"catchable"],[18,32,"catchable"],[18,44,"unknown"],[18,45,"unknown"],[18,46,"unknown"],[18,47,"unknown"],[18,49,"unknown"],[19,1,"catchable"],[19,2,"catchable"],[19,3,"catchable"],[19,4,"catchable"],[19,5,"catchable"],[19,6,"catchable"],[19,7,"unknown"],[19,8,"unknown"],[19,9,"unknown"],[19,10,"catchable"],[19,11,"catchable"],[19,12,"catchable"],[19,13,"catchable"],[19,14,"catchable"],[19,15,"catchable"],[19,16,"catchable"],[19,17,"unknown"],[19,18,"unknown"],[19,21,"catchable"],[19,22,"catchable"],[19,23,"unknown"],[19,24,"unknown"],[19,25,"unknown"],[19,26,"unknown"],[19,27,"catchable"],[19,28,"catchable"],[19,29,"catchable"],[19,30,"catchable"],[19,31,"catchable"],[19,32,"catchable"],[19,44,"catchable"],[19,45,"catchable"],[19,46,"unknown"],[20,1,"catchable"],[20,2,"catchable"],[20,3,"catchable"],[20,4,"catchable"],[20,5,"catchable"],[20,6,"catchable"],[20,7,"unknown"],[20,8,"unknown"],[20,9,"unknown"],[20,10,"catchable"],[20,11,"catchable"],[20,12,"catchable"],[20,13,"catchable"],[20,14,"catchable"],[20,15,"catchable"],[20,16,"catchable"],[20,17,"catchable"],[20,18,"catchable"],[20,20,"catchable"],[20,21,"catchable"],[20,22,"catchable"],[20,23,"unknown"],[20,24,"unknown"],[20,25,"unknown"],[20,26,"unknown"],[20,27,"catchable"],[20,28,"catchable"],[20,29,"catchable"],[20,30,"catchable"],[20,31,"catchable"],[20,32,"catchable"],[20,44,"catchable"],[20,45,"catchable"],[20,46,"unknown"],[21,1,"catchable"],[21,2,"catchable"],[21,3,"catchable"],[21,4,"catchable"],[21,5,"catchable"],[21,6,"catchable"],[21,7,"unknown"],[21,8,"unknown"],[21,9,"unknown"],[21,10,"catchable"],[21,11,"catchable"],[21,12,"catchable"],[21,13,"catchable"],[21,14,"catchable"],[21,15,"catchable"],[21,16,"catchable"],[21,17,"unknown"],[21,18,"unknown"],[21,20,"catchable"],[21,21,"unknown"],[21,22,"unknown"],[21,23,"catchable"],[21,24,"catchable"],[21,25,"unknown"],[21,26,"unknown"],[21,27,"catchable"],[21,28,"catchable"],[21,29,"catchable"],[21,30,"catchable"],[21,31,"catchable"],[21,32,"catchable"],[21,44,"catchable"],[21,45,"catchable"],[21,46,"unknown"],[22,1,"catchable"],[22,2,"catchable"],[22,3,"catchable"],[22,4,"catchable"],[22,5,"catchable"],[22,6,"catchable"],[22,7,"unknown"],[22,8,"unknown"],[22,9,"unknown"],[22,10,"catchable"],[22,11,"catchable"],[22,12,"catchable"],[22,13,"catchable"],[22,14,"catchable"],[22,15,"catchable"],[22,16,"catchable"],[22,17,"catchable"],[22,18,"catchable"],[22,21,"unknown"],[22,22,"unknown"],[22,23,"catchable"],[22,24,"catchable"],[22,25,"unknown"],[22,26,"unknown"],[22,27,"catchable"],[22,28,"catchable"],[22,29,"catchable"],[22,30,"catchable"],[22,31,"catchable"],[22,32,"catchable"],[22,44,"catchable"],[22,45,"catchable"],[22,46,"unknown"],[23,1,"catchable"],[23,2,"unknown"],[23,3,"unknown"],[23,4,"catchable"],[23,5,"catchable"],[23,6,"catchable"],[23,7,"unknown"],[23,8,"unknown"],[23,9,"unknown"],[23,10,"catchable"],[23,11,"unknown"],[23,12,"catchable"],[23,13,"catchable"],[23,14,"catchable"],[23,15,"catchable"],[23,16,"catchable"],[23,17,"unknown"],[23,18,"unknown"],[23,21,"unknown"],[23,22,"unknown"],[23,23,"catchable"],[23,24,"catchable"],[23,25,"unknown"],[23,26,"unknown"],[23,27,"unknown"],[23,28,"unknown"],[23,29,"catchable"],[23,30,"catchable"],[23,31,"unknown"],[23,32,"catchable"],[23,40,"unknown"],[23,41,"unknown"],[23,42,"unknown"],[23,43,"unknown"],[23,44,"catchable"],[23,45,"unknown"],[23,46,"unknown"],[23,47,"unknown"],[23,48,"unknown"],[23,52,"unknown"],[24,1,"catchable"],[24,2,"unknown"],[24,3,"unknown"],[24,4,"unknown"],[24,5,"catchable"],[24,6,"catchable"],[24,7,"unknown"],[24,8,"unknown"],[24,9,"unknown"],[24,10,"catchable"],[24,11,"unknown"],[24,12,"catchable"],[24,13,"catchable"],[24,14,"catchable"],[24,15,"catchable"],[24,16,"catchable"],[24,17,"unknown"],[24,18,"unknown"],[24,20,"catchable"],[24,21,"unknown"],[24,22,"unknown"],[24,23,"catchable"],[24,24,"catchable"],[24,25,"unknown"],[24,26,"unknown"],[24,27,"unknown"],[24,28,"unknown"],[24,29,"catchable"],[24,30,"catchable"],[24,31,"unknown"],[24,32,"unknown"],[24,40,"unknown"],[24,41,"unknown"],[24,42,"unknown"],[24,43,"unknown"],[24,44,"catchable"],[24,45,"unknown"],[24,46,"unknown"],[24,47,"unknown"],[24,48,"unknown"],[24,49,"unknown"],[24,52,"unknown"],[25,1,"catchable"],[25,2,"catchable"],[25,3,"catchable"],[25,4,"catchable"],[25,5,"catchable"],[25,6,"catchable"],[25,7,"catchable"],[25,8,"catchable"],[25,9,"catchable"],[25,10,"catchable"],[25,11,"catchable"],[25,12,"catchable"],[25,13,"catchable"],[25,14,"catchable"],[25,15,"catchable"],[25,16,"catchable"],[25,17,"unknown"],[25,18,"unknown"],[25,21,"unknown"],[25,22,"unknown"],[25,23,"catchable"],[25,24,"catchable"],[25,25,"catchable"],[25,26,"catchable"],[25,27,"catchable"],[25,28,"catchable"],[25,29,"catchable"],[25,30,"catchable"],[25,31,"catchable"],[25,32,"catchable"],[25,33,"catchable"],[25,34,"catchable"],[25,35,"catchable"],[25,36,"unknown"],[25,37,"unknown"],[25,38,"unknown"],[25,39,"unknown"],[25,40,"unknown"],[25,41,"unknown"],[25,42,"unknown"],[25,43,"unknown"],[25,44,"catchable"],[25,45,"catchable"],[25,46,"catchable"],[25,47,"unknown"],[25,48,"unknown"],[25,49,"unknown"],[25,50,"catchable"],[25,52,"unknown"],[26,1,"catchable"],[26,2,"catchable"],[26,3,"unknown"],[26,4,"unknown"],[26,5,"unknown"],[26,6,"unknown"],[26,7,"unknown"],[26,8,"unknown"],[26,9,"unknown"],[26,10,"unknown"],[26,11,"unknown"],[26,12,"unknown"],[26,13,"unknown"],[26,14,"unknown"],[26,15,"unknown"],[26,16,"unknown"],[26,17,"unknown"],[26,18,"unknown"],[26,21,"unknown"],[26,22,"unknown"],[26,23,"unknown"],[26,24,"unknown"],[26,25,"unknown"],[26,26,"unknown"],[26,27,"unknown"],[26,28,"unknown"],[26,29,"unknown"],[26,30,"unknown"],[26,31,"catchable"],[26,32,"catchable"],[26,33,"catchable"],[26,34,"catchable"],[26,35,"catchable"],[26,36,"catchable"],[26,37,"unknown"],[26,38,"unknown"],[26,39,"unknown"],[26,40,"unknown"],[26,41,"unknown"],[26,42,"unknown"],[26,43,"unknown"],[26,44,"catchable"],[26,45,"catchable"],[26,46,"unknown"],[26,47,"unknown"],[26,48,"unknown"],[26,49,"unknown"],[26,50,"catchable"],[26,51,"catchable"],[26,52,"unknown"],[27,1,"unknown"],[27,2,"catchable"],[27,3,"catchable"],[27,4,"catchable"],[27,5,"catchable"],[27,6,"catchable"],[27,7,"catchable"],[27,8,"catchable"],[27,9,"catchable"],[27,10,"unknown"],[27,11,"catchable"],[27,12,"catchable"],[27,13,"catchable"],[27,14,"catchable"],[27,15,"catchable"],[27,16,"catchable"],[27,17,"unknown"],[27,18,"unknown"],[27,20,"catchable"],[27,21,"catchable"],[27,22,"catchable"],[27,23,"catchable"],[27,24,"catchable"],[27,25,"catchable"],[27,26,"catchable"],[27,27,"unknown"],[27,28,"catchable"],[27,29,"unknown"],[27,30,"catchable"],[27,31,"catchable"],[27,32,"unknown"],[27,33,"unknown"],[27,34,"unknown"],[27,35,"catchable"],[27,36,"unknown"],[27,37,"unknown"],[27,38,"unknown"],[27,39,"unknown"],[27,40,"unknown"],[27,41,"unknown"],[27,42,"unknown"],[27,43,"unknown"],[27,44,"unknown"],[27,45,"catchable"],[27,46,"unknown"],[27,47,"unknown"],[27,48,"unknown"],[27,50,"catchable"],[27,52,"unknown"],[27,53,"unknown"],[28,1,"unknown"],[28,2,"catchable"],[28,3,"catchable"],[28,4,"catchable"],[28,5,"unknown"],[28,6,"catchable"],[28,7,"unknown"],[28,8,"unknown"],[28,9,"unknown"],[28,10,"unknown"],[28,11,"catchable"],[28,12,"catchable"],[28,13,"catchable"],[28,14,"catchable"],[28,15,"catchable"],[28,16,"catchable"],[28,17,"catchable"],[28,18,"catchable"],[28,21,"catchable"],[28,22,"catchable"],[28,23,"catchable"],[28,24,"catchable"],[28,25,"unknown"],[28,26,"unknown"],[28,27,"unknown"],[28,28,"unknown"],[28,29,"unknown"],[28,30,"unknown"],[28,31,"unknown"],[28,32,"unknown"],[28,33,"unknown"],[28,34,"unknown"],[28,35,"catchable"],[28,36,"catchable"],[28,37,"unknown"],[28,38,"unknown"],[28,39,"unknown"],[28,40,"unknown"],[28,41,"unknown"],[28,42,"unknown"],[28,43,"unknown"],[28,44,"unknown"],[28,45,"catchable"],[28,46,"unknown"],[28,47,"unknown"],[28,48,"unknown"],[28,50,"catchable"],[28,51,"catchable"],[28,52,"unknown"],[28,53,"unknown"],[29,1,"catchable"],[29,2,"catchable"],[29,3,"catchable"],[29,4,"catchable"],[29,5,"catchable"],[29,6,"catchable"],[29,7,"unknown"],[29,8,"unknown"],[29,9,"unknown"],[29,10,"catchable"],[29,11,"catchable"],[29,12,"catchable"],[29,13,"catchable"],[29,14,"catchable"],[29,15,"catchable"],[29,16,"catchable"],[29,17,"unknown"],[29,18,"unknown"],[29,21,"catchable"],[29,22,"catchable"],[29,23,"catchable"],[29,24,"catchable"],[29,25,"unknown"],[29,26,"unknown"],[29,27,"unknown"],[29,28,"unknown"],[29,29,"unknown"],[29,30,"unknown"],[29,31,"catchable"],[29,32,"catchable"],[29,33,"unknown"],[29,34,"unknown"],[29,35,"unknown"],[29,36,"catchable"],[29,37,"unknown"],[29,38,"unknown"],[29,39,"unknown"],[29,44,"catchable"],[29,45,"catchable"],[29,46,"unknown"],[29,51,"catchable"],[30,1,"catchable"],[30,2,"catchable"],[30,3,"catchable"],[30,4,"catchable"],[30,5,"catchable"],[30,6,"catchable"],[30,7,"unknown"],[30,8,"unknown"],[30,9,"unknown"],[30,10,"catchable"],[30,11,"catchable"],[30,12,"catchable"],[30,13,"catchable"],[30,14,"catchable"],[30,15,"catchable"],[30,16,"catchable"],[30,17,"unknown"],[30,18,"unknown"],[30,21,"unknown"],[30,22,"unknown"],[30,23,"catchable"],[30,24,"catchable"],[30,25,"unknown"],[30,26,"unknown"],[30,27,"unknown"],[30,28,"unknown"],[30,29,"unknown"],[30,30,"unknown"],[30,31,"catchable"],[30,32,"catchable"],[30,33,"unknown"],[30,34,"unknown"],[30,35,"unknown"],[30,36,"catchable"],[30,37,"unknown"],[30,38,"unknown"],[30,39,"unknown"],[30,44,"catchable"],[30,45,"catchable"],[30,46,"unknown"],[30,51,"catchable"],[31,1,"unknown"],[31,2,"unknown"],[31,3,"unknown"],[31,4,"unknown"],[31,5,"unknown"],[31,6,"unknown"],[31,7,"unknown"],[31,8,"unknown"],[31,9,"unknown"],[31,10,"unknown"],[31,11,"unknown"],[31,12,"unknown"],[31,13,"unknown"],[31,14,"unknown"],[31,15,"unknown"],[31,16,"unknown"],[31,17,"unknown"],[31,18,"unknown"],[31,21,"unknown"],[31,22,"unknown"],[31,23,"unknown"],[31,24,"unknown"],[31,25,"unknown"],[31,26,"unknown"],[31,27,"unknown"],[31,28,"unknown"],[31,29,"unknown"],[31,30,"unknown"],[31,31,"catchable"],[31,32,"catchable"],[31,33,"unknown"],[31,34,"unknown"],[31,35,"unknown"],[31,36,"catchable"],[31,37,"unknown"],[31,38,"unknown"],[31,39,"unknown"],[31,44,"unknown"],[31,45,"unknown"],[31,46,"unknown"],[31,51,"catchable"],[32,1,"catchable"],[32,2,"catchable"],[32,3,"catchable"],[32,4,"catchable"],[32,5,"catchable"],[32,6,"catchable"],[32,7,"unknown"],[32,8,"unknown"],[32,9,"unknown"],[32,10,"catchable"],[32,11,"catchable"],[32,12,"catchable"],[32,13,"catchable"],[32,14,"catchable"],[32,15,"catchable"],[32,16,"catchable"],[32,17,"unknown"],[32,18,"unknown"],[32,21,"catchable"],[32,22,"catchable"],[32,23,"catchable"],[32,24,"catchable"],[32,25,"unknown"],[32,26,"unknown"],[32,27,"unknown"],[32,28,"unknown"],[32,29,"unknown"],[32,30,"unknown"],[32,31,"catchable"],[32,32,"catchable"],[32,33,"unknown"],[32,34,"unknown"],[32,35,"unknown"],[32,36,"catchable"],[32,37,"unknown"],[32,38,"unknown"],[32,39,"unknown"],[32,44,"catchable"],[32,45,"catchable"],[32,46,"unknown"],[32,51,"catchable"],[33,1,"catchable"],[33,2,"catchable"],[33,3,"catchable"],[33,4,"catchable"],[33,5,"catchable"],[33,6,"catchable"],[33,7,"unknown"],[33,8,"unknown"],[33,9,"unknown"],[33,10,"catchable"],[33,11,"catchable"],[33,12,"catchable"],[33,13,"catchable"],[33,14,"catchable"],[33,15,"catchable"],[33,16,"catchable"],[33,17,"unknown"],[33,18,"unknown"],[33,21,"unknown"],[33,22,"unknown"],[33,23,"catchable"],[33,24,"catchable"],[33,25,"unknown"],[33,26,"unknown"],[33,27,"unknown"],[33,28,"unknown"],[33,29,"unknown"],[33,30,"unknown"],[33,31,"catchable"],[33,32,"catchable"],[33,33,"unknown"],[33,34,"unknown"],[33,35,"unknown"],[33,36,"catchable"],[33,37,"unknown"],[33,38,"unknown"],[33,39,"unknown"],[33,44,"catchable"],[33,45,"catchable"],[33,46,"unknown"],[33,51,"catchable"],[34,1,"unknown"],[34,2,"unknown"],[34,3,"unknown"],[34,4,"unknown"],[34,5,"unknown"],[34,6,"unknown"],[34,7,"unknown"],[34,8,"unknown"],[34,9,"unknown"],[34,10,"unknown"],[34,11,"unknown"],[34,12,"unknown"],[34,13,"unknown"],[34,14,"unknown"],[34,15,"unknown"],[34,16,"unknown"],[34,17,"unknown"],[34,18,"unknown"],[34,21,"unknown"],[34,22,"unknown"],[34,23,"unknown"],[34,24,"unknown"],[34,25,"unknown"],[34,26,"unknown"],[34,27,"unknown"],[34,28,"unknown"],[34,29,"unknown"],[34,30,"unknown"],[34,31,"catchable"],[34,32,"catchable"],[34,33,"unknown"],[34,34,"unknown"],[34,35,"unknown"],[34,36,"catchable"],[34,37,"unknown"],[34,38,"unknown"],[34,39,"unknown"],[34,44,"unknown"],[34,45,"unknown"],[34,46,"unknown"],[34,51,"catchable"],[35,1,"catchable"],[35,2,"catchable"],[35,3,"catchable"],[35,4,"catchable"],[35,5,"catchable"],[35,6,"catchable"],[35,7,"unknown"],[35,8,"unknown"],[35,9,"unknown"],[35,10,"catchable"],[35,11,"catchable"],[35,12,"catchable"],[35,13,"catchable"],[35,14,"catchable"],[35,15,"catchable"],[35,16,"catchable"],[35,17,"catchable"],[35,18,"catchable"],[35,21,"catchable"],[35,22,"catchable"],[35,23,"catchable"],[35,24,"catchable"],[35,25,"unknown"],[35,26,"unknown"],[35,27,"catchable"],[35,28,"catchable"],[35,29,"catchable"],[35,30,"catchable"],[35,31,"catchable"],[35,32,"catchable"],[35,33,"catchable"],[35,34,"catchable"],[35,35,"catchable"],[35,36,"catchable"],[35,37,"unknown"],[35,38,"unknown"],[35,39,"unknown"],[35,40,"unknown"],[35,41,"unknown"],[35,42,"unknown"],[35,43,"unknown"],[35,44,"catchable"],[35,45,"catchable"],[35,46,"unknown"],[35,47,"unknown"],[35,48,"unknown"],[35,50,"catchable"],[35,51,"catchable"],[35,52,"unknown"],[36,1,"unknown"],[36,2,"unknown"],[36,3,"unknown"],[36,4,"unknown"],[36,5,"unknown"],[36,6,"unknown"],[36,7,"unknown"],[36,8,"unknown"],[36,9,"unknown"],[36,10,"unknown"],[36,11,"unknown"],[36,12,"unknown"],[36,13,"unknown"],[36,14,"unknown"],[36,15,"unknown"],[36,16,"unknown"],[36,17,"catchable"],[36,18,"catchable"],[36,21,"catchable"],[36,22,"catchable"],[36,23,"unknown"],[36,24,"unknown"],[36,25,"unknown"],[36,26,"unknown"],[36,27,"unknown"],[36,28,"unknown"],[36,29,"unknown"],[36,30,"unknown"],[36,31,"catchable"],[36,32,"catchable"],[36,33,"catchable"],[36,34,"catchable"],[36,35,"catchable"],[36,36,"catchable"],[36,37,"unknown"],[36,38,"unknown"],[36,39,"unknown"],[36,40,"unknown"],[36,41,"unknown"],[36,42,"unknown"],[36,43,"unknown"],[36,44,"unknown"],[36,45,"unknown"],[36,46,"catchable"],[36,47,"unknown"],[36,48,"unknown"],[36,49,"unknown"],[36,50,"catchable"],[36,51,"catchable"],[36,52,"unknown"],[37,1,"unknown"],[37,2,"catchable"],[37,3,"catchable"],[37,4,"unknown"],[37,5,"catchable"],[37,6,"unknown"],[37,7,"catchable"],[37,8,"catchable"],[37,9,"catchable"],[37,10,"unknown"],[37,11,"catchable"],[37,12,"catchable"],[37,13,"catchable"],[37,14,"catchable"],[37,15,"unknown"],[37,16,"catchable"],[37,17,"catchable"],[37,18,"catchable"],[37,20,"catchable"],[37,21,"catchable"],[37,22,"catchable"],[37,23,"unknown"],[37,24,"unknown"],[37,25,"catchable"],[37,26,"catchable"],[37,27,"catchable"],[37,28,"unknown"],[37,29,"catchable"],[37,30,"unknown"],[37,31,"unknown"],[37,32,"catchable"],[37,33,"catchable"],[37,34,"catchable"],[37,35,"catchable"],[37,36,"unknown"],[37,37,"unknown"],[37,38,"unknown"],[37,39,"unknown"],[37,40,"unknown"],[37,41,"unknown"],[37,42,"unknown"],[37,43,"unknown"],[37,44,"unknown"],[37,45,"catchable"],[37,46,"unknown"],[37,47,"unknown"],[37,48,"unknown"],[37,50,"catchable"],[37,52,"unknown"],[37,53,"unknown"],[38,1,"unknown"],[38,2,"unknown"],[38,3,"unknown"],[38,4,"unknown"],[38,5,"unknown"],[38,6,"unknown"],[38,7,"unknown"],[38,8,"unknown"],[38,9,"unknown"],[38,10,"unknown"],[38,11,"unknown"],[38,12,"unknown"],[38,13,"unknown"],[38,14,"unknown"],[38,15,"unknown"],[38,16,"unknown"],[38,17,"catchable"],[38,18,"catchable"],[38,21,"catchable"],[38,22,"catchable"],[38,23,"catchable"],[38,24,"catchable"],[38,25,"unknown"],[38,26,"unknown"],[38,27,"unknown"],[38,28,"unknown"],[38,29,"unknown"],[38,30,"unknown"],[38,31,"unknown"],[38,32,"catchable"],[38,33,"catchable"],[38,34,"catchable"],[38,35,"catchable"],[38,36,"catchable"],[38,37,"unknown"],[38,38,"unknown"],[38,39,"unknown"],[38,40,"unknown"],[38,41,"unknown"],[38,42,"unknown"],[38,43,"unknown"],[38,44,"unknown"],[38,45,"unknown"],[38,46,"unknown"],[38,47,"unknown"],[38,48,"unknown"],[38,49,"unknown"],[38,52,"unknown"],[38,53,"unknown"],[39,1,"catchable"],[39,2,"catchable"],[39,3,"catchable"],[39,4,"catchable"],[39,5,"catchable"],[39,6,"catchable"],[39,7,"catchable"],[39,8,"catchable"],[39,9,"catchable"],[39,10,"catchable"],[39,11,"catchable"],[39,12,"catchable"],[39,13,"catchable"],[39,14,"catchable"],[39,15,"catchable"],[39,16,"catchable"],[39,17,"catchable"],[39,18,"catchable"],[39,21,"catchable"],[39,22,"catchable"],[39,23,"catchable"],[39,24,"catchable"],[39,25,"unknown"],[39,26,"unknown"],[39,27,"catchable"],[39,28,"catchable"],[39,29,"catchable"],[39,30,"catchable"],[39,31,"catchable"],[39,32,"catchable"],[39,33,"unknown"],[39,34,"unknown"],[39,35,"catchable"],[39,36,"catchable"],[39,37,"unknown"],[39,38,"unknown"],[39,39,"unknown"],[39,40,"unknown"],[39,41,"unknown"],[39,42,"unknown"],[39,43,"unknown"],[39,44,"catchable"],[39,45,"catchable"],[39,46,"unknown"],[39,47,"unknown"],[39,48,"unknown"],[39,50,"catchable"],[39,51,"catchable"],[40,1,"catchable"],[40,2,"catchable"],[40,3,"catchable"],[40,4,"unknown"],[40,5,"unknown"],[40,6,"unknown"],[40,7,"unknown"],[40,8,"unknown"],[40,9,"unknown"],[40,10,"unknown"],[40,11,"unknown"],[40,12,"unknown"],[40,13,"unknown"],[40,14,"unknown"],[40,15,"unknown"],[40,16,"unknown"],[40,17,"catchable"],[40,18,"catchable"],[40,21,"catchable"],[40,22,"catchable"],[40,23,"unknown"],[40,24,"unknown"],[40,25,"unknown"],[40,26,"unknown"],[40,27,"unknown"],[40,28,"unknown"],[40,29,"unknown"],[40,30,"unknown"],[40,31,"unknown"],[40,32,"unknown"],[40,33,"unknown"],[40,34,"unknown"],[40,35,"catchable"],[40,36,"catchable"],[40,37,"unknown"],[40,38,"unknown"],[40,39,"unknown"],[40,40,"unknown"],[40,41,"unknown"],[40,42,"unknown"],[40,43,"unknown"],[40,44,"catchable"],[40,45,"catchable"],[40,46,"unknown"],[40,47,"unknown"],[40,48,"unknown"],[40,49,"unknown"],[40,50,"catchable"],[40,51,"catchable"],[41,1,"catchable"],[41,2,"catchable"],[41,3,"catchable"],[41,4,"catchable"],[41,5,"catchable"],[41,6,"catchable"],[41,7,"catchable"],[41,8,"catchable"],[41,9,"catchable"],[41,10,"catchable"],[41,11,"catchable"],[41,12,"catchable"],[41,13,"catchable"],[41,14,"catchable"],[41,15,"catchable"],[41,16,"catchable"],[41,17,"unknown"],[41,18,"unknown"],[41,20,"catchable"],[41,21,"catchable"],[41,22,"catchable"],[41,23,"catchable"],[41,24,"catchable"],[41,25,"catchable"],[41,26,"catchable"],[41,27,"catchable"],[41,28,"catchable"],[41,29,"catchable"],[41,30,"catchable"],[41,31,"catchable"],[41,32,"catchable"],[41,33,"unknown"],[41,34,"unknown"],[41,35,"unknown"],[41,36,"catchable"],[41,37,"unknown"],[41,38,"unknown"],[41,39,"unknown"],[41,44,"catchable"],[41,45,"catchable"],[41,46,"unknown"],[41,47,"unknown"],[41,48,"unknown"],[41,51,"catchable"],[42,1,"catchable"],[42,2,"catchable"],[42,3,"catchable"],[42,4,"catchable"],[42,5,"catchable"],[42,6,"catchable"],[42,7,"catchable"],[42,8,"catchable"],[42,9,"catchable"],[42,10,"catchable"],[42,11,"catchable"],[42,12,"catchable"],[42,13,"catchable"],[42,14,"catchable"],[42,15,"catchable"],[42,16,"catchable"],[42,17,"catchable"],[42,18,"catchable"],[42,21,"catchable"],[42,22,"catchable"],[42,23,"unknown"],[42,24,"unknown"],[42,25,"catchable"],[42,26,"catchable"],[42,27,"catchable"],[42,28,"catchable"],[42,29,"catchable"],[42,30,"catchable"],[42,31,"catchable"],[42,32,"catchable"],[42,33,"unknown"],[42,34,"unknown"],[42,35,"unknown"],[42,36,"catchable"],[42,37,"unknown"],[42,38,"unknown"],[42,39,"unknown"],[42,44,"catchable"],[42,45,"catchable"],[42,46,"unknown"],[42,47,"unknown"],[42,48,"unknown"],[42,51,"catchable"],[43,1,"catchable"],[43,2,"unknown"],[43,3,"catchable"],[43,4,"catchable"],[43,5,"catchable"],[43,6,"catchable"],[43,7,"catchable"],[43,8,"catchable"],[43,9,"catchable"],[43,10,"catchable"],[43,11,"unknown"],[43,12,"catchable"],[43,13,"catchable"],[43,14,"catchable"],[43,15,"catchable"],[43,16,"catchable"],[43,17,"unknown"],[43,18,"unknown"],[43,21,"unknown"],[43,22,"unknown"],[43,23,"catchable"],[43,24,"catchable"],[43,25,"catchable"],[43,26,"catchable"],[43,27,"unknown"],[43,28,"unknown"],[43,29,"unknown"],[43,30,"unknown"],[43,31,"catchable"],[43,32,"unknown"],[43,33,"catchable"],[43,34,"catchable"],[43,35,"unknown"],[43,36,"unknown"],[43,37,"unknown"],[43,38,"unknown"],[43,39,"unknown"],[43,40,"unknown"],[43,41,"unknown"],[43,42,"unknown"],[43,43,"unknown"],[43,44,"catchable"],[43,45,"unknown"],[43,46,"unknown"],[43,47,"unknown"],[43,48,"unknown"],[43,53,"unknown"],[44,1,"catchable"],[44,2,"unknown"],[44,3,"catchable"],[44,4,"catchable"],[44,5,"catchable"],[44,6,"catchable"],[44,7,"catchable"],[44,8,"catchable"],[44,9,"catchable"],[44,10,"catchable"],[44,11,"unknown"],[44,12,"catchable"],[44,13,"catchable"],[44,14,"catchable"],[44,15,"catchable"],[44,16,"catchable"],[44,17,"unknown"],[44,18,"unknown"],[44,21,"unknown"],[44,22,"unknown"],[44,23,"catchable"],[44,24,"catchable"],[44,25,"unknown"],[44,26,"unknown"],[44,27,"unknown"],[44,28,"unknown"],[44,29,"unknown"],[44,30,"unknown"],[44,31,"catchable"],[44,32,"unknown"],[44,33,"catchable"],[44,34,"catchable"],[44,35,"unknown"],[44,36,"catchable"],[44,37,"unknown"],[44,38,"unknown"],[44,39,"unknown"],[44,40,"unknown"],[44,41,"unknown"],[44,42,"unknown"],[44,43,"unknown"],[44,44,"catchable"],[44,45,"unknown"],[44,46,"unknown"],[44,47,"unknown"],[44,48,"unknown"],[44,51,"catchable"],[44,53,"unknown"],[45,1,"unknown"],[45,2,"unknown"],[45,3,"unknown"],[45,4,"unknown"],[45,5,"unknown"],[45,6,"unknown"],[45,7,"unknown"],[45,8,"unknown"],[45,9,"unknown"],[45,10,"unknown"],[45,11,"unknown"],[45,12,"unknown"],[45,13,"unknown"],[45,14,"unknown"],[45,15,"unknown"],[45,16,"unknown"],[45,17,"unknown"],[45,18,"unknown"],[45,21,"unknown"],[45,22,"unknown"],[45,23,"unknown"],[45,24,"unknown"],[45,25,"unknown"],[45,26,"unknown"],[45,27,"unknown"],[45,28,"unknown"],[45,29,"unknown"],[45,30,"unknown"],[45,31,"catchable"],[45,32,"unknown"],[45,33,"catchable"],[45,34,"catchable"],[45,35,"unknown"],[45,36,"catchable"],[45,37,"unknown"],[45,38,"unknown"],[45,39,"unknown"],[45,40,"unknown"],[45,41,"unknown"],[45,42,"unknown"],[45,43,"unknown"],[45,44,"unknown"],[45,45,"unknown"],[45,46,"unknown"],[45,47,"unknown"],[45,48,"unknown"],[45,49,"unknown"],[45,51,"catchable"],[45,53,"unknown"],[46,1,"catchable"],[46,2,"catchable"],[46,3,"catchable"],[46,4,"catchable"],[46,5,"catchable"],[46,6,"catchable"],[46,7,"unknown"],[46,8,"unknown"],[46,9,"unknown"],[46,10,"catchable"],[46,11,"catchable"],[46,12,"catchable"],[46,13,"catchable"],[46,14,"catchable"],[46,15,"catchable"],[46,16,"catchable"],[46,17,"unknown"],[46,18,"unknown"],[46,20,"catchable"],[46,21,"unknown"],[46,22,"unknown"],[46,23,"catchable"],[46,24,"catchable"],[46,25,"unknown"],[46,26,"unknown"],[46,27,"catchable"],[46,28,"catchable"],[46,29,"catchable"],[46,30,"catchable"],[46,31,"catchable"],[46,32,"catchable"],[46,39,"unknown"],[46,44,"catchable"],[46,45,"catchable"],[46,46,"unknown"],[47,1,"catchable"],[47,2,"catchable"],[47,3,"catchable"],[47,4,"unknown"],[47,5,"unknown"],[47,6,"catchable"],[47,7,"unknown"],[47,8,"unknown"],[47,9,"unknown"],[47,10,"catchable"],[47,11,"catchable"],[47,12,"unknown"],[47,13,"unknown"],[47,14,"unknown"],[47,15,"catchable"],[47,16,"catchable"],[47,17,"unknown"],[47,18,"unknown"],[47,21,"unknown"],[47,22,"unknown"],[47,23,"unknown"],[47,24,"unknown"],[47,25,"unknown"],[47,26,"unknown"],[47,27,"unknown"],[47,28,"unknown"],[47,29,"catchable"],[47,30,"catchable"],[47,31,"unknown"],[47,32,"unknown"],[47,39,"unknown"],[47,44,"catchable"],[47,45,"catchable"],[47,46,"unknown"],[48,1,"catchable"],[48,2,"catchable"],[48,3,"catchable"],[48,4,"catchable"],[48,5,"catchable"],[48,6,"catchable"],[48,7,"unknown"],[48,8,"unknown"],[48,9,"unknown"],[48,10,"catchable"],[48,11,"catchable"],[48,12,"catchable"],[48,13,"catchable"],[48,14,"catchable"],[48,15,"catchable"],[48,16,"catchable"],[48,17,"unknown"],[48,18,"unknown"],[48,21,"catchable"],[48,22,"catchable"],[48,23,"unknown"],[48,24,"unknown"],[48,25,"unknown"],[48,26,"unknown"],[48,27,"unknown"],[48,28,"unknown"],[48,29,"unknown"],[48,30,"unknown"],[48,31,"catchable"],[48,32,"catchable"],[48,40,"unknown"],[48,41,"unknown"],[48,42,"unknown"],[48,43,"unknown"],[48,44,"catchable"],[48,45,"catchable"],[48,46,"unknown"],[48,47,"unknown"],[48,48,"unknown"],[48,53,"unknown"],[49,1,"catchable"],[49,2,"catchable"],[49,3,"catchable"],[49,4,"catchable"],[49,5,"catchable"],[49,6,"catchable"],[49,7,"unknown"],[49,8,"unknown"],[49,9,"unknown"],[49,10,"catchable"],[49,11,"catchable"],[49,12,"catchable"],[49,13,"catchable"],[49,14,"catchable"],[49,15,"catchable"],[49,16,"catchable"],[49,17,"catchable"],[49,18,"catchable"],[49,20,"catchable"],[49,21,"unknown"],[49,22,"unknown"],[49,23,"catchable"],[49,24,"catchable"],[49,25,"catchable"],[49,26,"catchable"],[49,27,"unknown"],[49,28,"unknown"],[49,29,"unknown"],[49,30,"unknown"],[49,31,"catchable"],[49,32,"catchable"],[49,40,"unknown"],[49,41,"unknown"],[49,42,"unknown"],[49,43,"unknown"],[49,44,"catchable"],[49,45,"catchable"],[49,46,"unknown"],[49,47,"unknown"],[49,48,"unknown"],[49,53,"unknown"],[50,1,"catchable"],[50,2,"catchable"],[50,3,"catchable"],[50,4,"catchable"],[50,5,"catchable"],[50,6,"catchable"],[50,7,"unknown"],[50,8,"unknown"],[50,9,"unknown"],[50,10,"catchable"],[50,11,"catchable"],[50,12,"catchable"],[50,13,"catchable"],[50,14,"catchable"],[50,15,"catchable"],[50,16,"catchable"],[50,17,"unknown"],[50,18,"unknown"],[50,21,"unknown"],[50,22,"unknown"],[50,23,"unknown"],[50,24,"unknown"],[50,25,"unknown"],[50,26,"unknown"],[50,27,"catchable"],[50,28,"catchable"],[50,29,"catchable"],[50,30,"catchable"],[50,31,"catchable"],[50,32,"catchable"],[50,33,"catchable"],[50,34,"catchable"],[50,35,"catchable"],[50,36,"unknown"],[50,37,"unknown"],[50,38,"unknown"],[50,39,"unknown"],[50,40,"unknown"],[50,41,"unknown"],[50,42,"unknown"],[50,43,"unknown"],[50,44,"catchable"],[50,45,"catchable"],[50,46,"unknown"],[50,47,"unknown"],[50,48,"unknown"],[50,50,"catchable"],[50,53,"unknown"],[51,1,"catchable"],[51,2,"catchable"],[51,3,"catchable"],[51,4,"catchable"],[51,5,"catchable"],[51,6,"catchable"],[51,7,"unknown"],[51,8,"unknown"],[51,9,"unknown"],[51,10,"catchable"],[51,11,"catchable"],[51,12,"catchable"],[51,13,"catchable"],[51,14,"catchable"],[51,15,"catchable"],[51,16,"catchable"],[51,17,"unknown"],[51,18,"unknown"],[51,20,"catchable"],[51,21,"unknown"],[51,22,"unknown"],[51,23,"catchable"],[51,24,"catchable"],[51,25,"unknown"],[51,26,"unknown"],[51,27,"catchable"],[51,28,"catchable"],[51,29,"catchable"],[51,30,"catchable"],[51,31,"catchable"],[51,32,"catchable"],[51,33,"catchable"],[51,34,"catchable"],[51,35,"unknown"],[51,36,"catchable"],[51,37,"unknown"],[51,38,"unknown"],[51,39,"unknown"],[51,40,"unknown"],[51,41,"unknown"],[51,42,"unknown"],[51,43,"unknown"],[51,44,"catchable"],[51,45,"catchable"],[51,46,"unknown"],[51,47,"unknown"],[51,48,"unknown"],[51,51,"catchable"],[51,53,"unknown"],[52,1,"unknown"],[52,2,"catchable"],[52,3,"unknown"],[52,4,"unknown"],[52,5,"catchable"],[52,6,"catchable"],[52,7,"unknown"],[52,8,"unknown"],[52,9,"catchable"],[52,10,"catchable"],[52,11,"catchable"],[52,12,"catchable"],[52,13,"catchable"],[52,14,"catchable"],[52,15,"unknown"],[52,16,"catchable"],[52,17,"unknown"],[52,18,"unknown"],[52,20,"catchable"],[52,21,"unknown"],[52,22,"unknown"],[52,23,"unknown"],[52,24,"unknown"],[52,25,"unknown"],[52,26,"unknown"],[52,27,"catchable"],[52,28,"catchable"],[52,29,"catchable"],[52,30,"catchable"],[52,31,"unknown"],[52,32,"catchable"],[52,33,"catchable"],[52,34,"catchable"],[52,35,"catchable"],[52,36,"catchable"],[52,37,"unknown"],[52,38,"unknown"],[52,39,"unknown"],[52,40,"unknown"],[52,41,"unknown"],[52,42,"unknown"],[52,43,"unknown"],[52,44,"unknown"],[52,45,"catchable"],[52,46,"unknown"],[52,47,"unknown"],[52,48,"unknown"],[52,50,"catchable"],[52,51,"catchable"],[53,1,"unknown"],[53,2,"unknown"],[53,3,"unknown"],[53,4,"unknown"],[53,5,"catchable"],[53,6,"catchable"],[53,7,"unknown"],[53,8,"unknown"],[53,9,"unknown"],[53,10,"catchable"],[53,11,"catchable"],[53,12,"unknown"],[53,13,"unknown"],[53,14,"unknown"],[53,15,"unknown"],[53,16,"catchable"],[53,17,"unknown"],[53,18,"unknown"],[53,21,"unknown"],[53,22,"unknown"],[53,23,"unknown"],[53,24,"unknown"],[53,25,"catchable"],[53,26,"catchable"],[53,27,"unknown"],[53,28,"unknown"],[53,29,"catchable"],[53,30,"catchable"],[53,31,"catchable"],[53,32,"unknown"],[53,33,"unknown"],[53,34,"unknown"],[53,35,"unknown"],[53,36,"catchable"],[53,37,"unknown"],[53,38,"unknown"],[53,39,"unknown"],[53,40,"unknown"],[53,41,"unknown"],[53,42,"unknown"],[53,43,"unknown"],[53,44,"unknown"],[53,45,"unknown"],[53,46,"unknown"],[53,47,"unknown"],[53,48,"unknown"],[53,49,"unknown"],[53,51,"catchable"],[54,1,"catchable"],[54,2,"catchable"],[54,3,"catchable"],[54,4,"catchable"],[54,5,"catchable"],[54,6,"catchable"],[54,7,"catchable"],[54,8,"catchable"],[54,9,"catchable"],[54,10,"catchable"],[54,11,"unknown"],[54,12,"catchable"],[54,13,"catchable"],[54,14,"catchable"],[54,15,"catchable"],[54,16,"catchable"],[54,17,"unknown"],[54,18,"unknown"],[54,21,"catchable"],[54,22,"catchable"],[54,23,"catchable"],[54,24,"catchable"],[54,25,"catchable"],[54,26,"catchable"],[54,27,"catchable"],[54,28,"catchable"],[54,29,"catchable"],[54,30,"catchable"],[54,31,"catchable"],[54,32,"catchable"],[54,33,"unknown"],[54,34,"unknown"],[54,35,"catchable"],[54,36,"unknown"],[54,37,"unknown"],[54,38,"unknown"],[54,39,"unknown"],[54,40,"unknown"],[54,41,"unknown"],[54,42,"unknown"],[54,43,"unknown"],[54,44,"catchable"],[54,45,"catchable"],[54,46,"unknown"],[54,47,"unknown"],[54,48,"unknown"],[54,50,"catchable"],[55,1,"catchable"],[55,2,"catchable"],[55,3,"catchable"],[55,4,"catchable"],[55,5,"catchable"],[55,6,"catchable"],[55,7,"catchable"],[55,8,"catchable"],[55,9,"catchable"],[55,10,"catchable"],[55,11,"unknown"],[55,12,"catchable"],[55,13,"catchable"],[55,14,"catchable"],[55,15,"catchable"],[55,16,"catchable"],[55,17,"catchable"],[55,18,"catchable"],[55,20,"catchable"],[55,21,"catchable"],[55,22,"catchable"],[55,23,"unknown"],[55,24,"unknown"],[55,25,"unknown"],[55,26,"unknown"],[55,27,"catchable"],[55,28,"catchable"],[55,29,"catchable"],[55,30,"catchable"],[55,31,"catchable"],[55,32,"catchable"],[55,33,"unknown"],[55,34,"unknown"],[55,35,"catchable"],[55,36,"catchable"],[55,37,"unknown"],[55,38,"unknown"],[55,39,"unknown"],[55,40,"unknown"],[55,41,"unknown"],[55,42,"unknown"],[55,43,"unknown"],[55,44,"catchable"],[55,45,"catchable"],[55,46,"unknown"],[55,47,"unknown"],[55,48,"unknown"],[55,50,"catchable"],[55,51,"catchable"],[56,1,"catchable"],[56,2,"unknown"],[56,3,"catchable"],[56,4,"catchable"],[56,5,"unknown"],[56,6,"unknown"],[56,7,"unknown"],[56,8,"unknown"],[56,9,"unknown"],[56,10,"catchable"],[56,11,"catchable"],[56,12,"catchable"],[56,13,"catchable"],[56,14,"catchable"],[56,15,"catchable"],[56,16,"unknown"],[56,17,"unknown"],[56,18,"unknown"],[56,21,"unknown"],[56,22,"unknown"],[56,23,"catchable"],[56,24,"catchable"],[56,25,"unknown"],[56,26,"unknown"],[56,27,"catchable"],[56,28,"catchable"],[56,29,"catchable"],[56,30,"catchable"],[56,31,"catchable"],[56,32,"unknown"],[56,40,"unknown"],[56,41,"unknown"],[56,42,"unknown"],[56,43,"unknown"],[56,44,"catchable"],[56,45,"unknown"],[56,46,"unknown"],[56,47,"unknown"],[56,48,"unknown"],[56,52,"unknown"],[57,1,"unknown"],[57,2,"unknown"],[57,3,"catchable"],[57,4,"catchable"],[57,5,"unknown"],[57,6,"unknown"],[57,7,"unknown"],[57,8,"unknown"],[57,9,"unknown"],[57,10,"catchable"],[57,11,"catchable"],[57,12,"catchable"],[57,13,"catchable"],[57,14,"catchable"],[57,15,"catchable"],[57,16,"unknown"],[57,17,"unknown"],[57,18,"unknown"],[57,20,"catchable"],[57,21,"unknown"],[57,22,"unknown"],[57,23,"unknown"],[57,24,"unknown"],[57,25,"unknown"],[57,26,"unknown"],[57,27,"catchable"],[57,28,"catchable"],[57,29,"catchable"],[57,30,"catchable"],[57,31,"unknown"],[57,32,"unknown"],[57,40,"unknown"],[57,41,"unknown"],[57,42,"unknown"],[57,43,"unknown"],[57,44,"unknown"],[57,45,"unknown"],[57,46,"unknown"],[57,47,"unknown"],[57,48,"unknown"],[57,52,"unknown"],[58,1,"catchable"],[58,2,"unknown"],[58,3,"catchable"],[58,4,"catchable"],[58,5,"unknown"],[58,6,"catchable"],[58,7,"unknown"],[58,8,"unknown"],[58,9,"unknown"],[58,10,"catchable"],[58,11,"unknown"],[58,12,"catchable"],[58,13,"catchable"],[58,14,"catchable"],[58,15,"catchable"],[58,16,"unknown"],[58,17,"unknown"],[58,18,"unknown"],[58,20,"catchable"],[58,21,"catchable"],[58,22,"catchable"],[58,23,"catchable"],[58,24,"catchable"],[58,25,"unknown"],[58,26,"unknown"],[58,27,"catchable"],[58,28,"catchable"],[58,29,"catchable"],[58,30,"catchable"],[58,31,"catchable"],[58,32,"unknown"],[58,33,"catchable"],[58,34,"catchable"],[58,35,"unknown"],[58,36,"unknown"],[58,37,"unknown"],[58,38,"unknown"],[58,39,"unknown"],[58,40,"unknown"],[58,41,"unknown"],[58,42,"unknown"],[58,43,"unknown"],[58,44,"catchable"],[58,45,"unknown"],[58,46,"unknown"],[58,47,"unknown"],[58,48,"unknown"],[58,52,"unknown"],[59,1,"unknown"],[59,2,"unknown"],[59,3,"unknown"],[59,4,"unknown"],[59,5,"unknown"],[59,6,"unknown"],[59,7,"unknown"],[59,8,"unknown"],[59,9,"unknown"],[59,10,"unknown"],[59,11,"unknown"],[59,12,"unknown"],[59,13,"unknown"],[59,14,"unknown"],[59,15,"unknown"],[59,16,"unknown"],[59,17,"unknown"],[59,18,"unknown"],[59,21,"unknown"],[59,22,"unknown"],[59,23,"unknown"],[59,24,"unknown"],[59,25,"unknown"],[59,26,"unknown"],[59,27,"unknown"],[59,28,"unknown"],[59,29,"unknown"],[59,30,"unknown"],[59,31,"catchable"],[59,32,"catchable"],[59,33,"catchable"],[59,34,"catchable"],[59,35,"unknown"],[59,36,"unknown"],[59,37,"unknown"],[59,38,"unknown"],[59,39,"unknown"],[59,40,"unknown"],[59,41,"unknown"],[59,42,"unknown"],[59,43,"unknown"],[59,44,"unknown"],[59,45,"unknown"],[59,46,"unknown"],[59,47,"unknown"],[59,48,"unknown"],[59,49,"unknown"],[59,50,"catchable"],[59,51,"catchable"],[59,52,"unknown"],[60,1,"catchable"],[60,2,"catchable"],[60,3,"catchable"],[60,4,"catchable"],[60,5,"catchable"],[60,6,"catchable"],[60,7,"unknown"],[60,8,"unknown"],[60,9,"unknown"],[60,10,"catchable"],[60,11,"catchable"],[60,12,"catchable"],[60,13,"catchable"],[60,14,"catchable"],[60,15,"catchable"],[60,16,"catchable"],[60,17,"catchable"],[60,18,"catchable"],[60,21,"catchable"],[60,22,"catchable"],[60,23,"catchable"],[60,24,"catchable"],[60,25,"unknown"],[60,26,"unknown"],[60,27,"catchable"],[60,28,"catchable"],[60,29,"catchable"],[60,30,"catchable"],[60,31,"catchable"],[60,32,"catchable"],[60,33,"unknown"],[60,34,"unknown"],[60,35,"catchable"],[60,36,"unknown"],[60,37,"unknown"],[60,38,"unknown"],[60,39,"unknown"],[60,40,"unknown"],[60,41,"unknown"],[60,42,"unknown"],[60,43,"unknown"],[60,44,"catchable"],[60,45,"catchable"],[60,46,"unknown"],[60,47,"unknown"],[60,48,"unknown"],[60,50,"catchable"],[60,52,"unknown"],[61,1,"catchable"],[61,2,"catchable"],[61,3,"catchable"],[61,4,"catchable"],[61,5,"catchable"],[61,6,"catchable"],[61,7,"unknown"],[61,8,"unknown"],[61,9,"unknown"],[61,10,"catchable"],[61,11,"catchable"],[61,12,"catchable"],[61,13,"catchable"],[61,14,"catchable"],[61,15,"catchable"],[61,16,"catchable"],[61,17,"catchable"],[61,18,"catchable"],[61,21,"catchable"],[61,22,"catchable"],[61,23,"catchable"],[61,24,"catchable"],[61,25,"unknown"],[61,26,"unknown"],[61,27,"catchable"],[61,28,"catchable"],[61,29,"catchable"],[61,30,"catchable"],[61,31,"catchable"],[61,32,"catchable"],[61,33,"unknown"],[61,34,"unknown"],[61,35,"catchable"],[61,36,"unknown"],[61,37,"unknown"],[61,38,"unknown"],[61,39,"unknown"],[61,40,"unknown"],[61,41,"unknown"],[61,42,"unknown"],[61,43,"unknown"],[61,44,"catchable"],[61,45,"catchable"],[61,46,"unknown"],[61,47,"unknown"],[61,48,"unknown"],[61,50,"catchable"],[61,52,"unknown"],[62,1,"unknown"],[62,2,"unknown"],[62,3,"unknown"],[62,4,"unknown"],[62,5,"unknown"],[62,6,"unknown"],[62,7,"unknown"],[62,8,"unknown"],[62,9,"unknown"],[62,10,"unknown"],[62,11,"unknown"],[62,12,"unknown"],[62,13,"unknown"],[62,14,"unknown"],[62,15,"unknown"],[62,16,"unknown"],[62,17,"catchable"],[62,18,"catchable"],[62,20,"catchable"],[62,21,"catchable"],[62,22,"catchable"],[62,23,"catchable"],[62,24,"catchable"],[62,25,"unknown"],[62,26,"unknown"],[62,27,"catchable"],[62,28,"catchable"],[62,29,"catchable"],[62,30,"catchable"],[62,31,"catchable"],[62,32,"catchable"],[62,33,"unknown"],[62,34,"unknown"],[62,35,"catchable"],[62,36,"catchable"],[62,37,"unknown"],[62,38,"unknown"],[62,39,"unknown"],[62,40,"unknown"],[62,41,"unknown"],[62,42,"unknown"],[62,43,"unknown"],[62,44,"unknown"],[62,45,"unknown"],[62,46,"unknown"],[62,47,"unknown"],[62,48,"unknown"],[62,50,"catchable"],[62,51,"catchable"],[62,52,"unknown"],[63,1,"catchable"],[63,2,"catchable"],[63,3,"catchable"],[63,4,"catchable"],[63,5,"catchable"],[63,6,"catchable"],[63,7,"catchable"],[63,8,"catchable"],[63,9,"catchable"],[63,10,"catchable"],[63,11,"catchable"],[63,12,"catchable"],[63,13,"catchable"],[63,14,"catchable"],[63,15,"catchable"],[63,16,"catchable"],[63,17,"unknown"],[63,18,"unknown"],[63,21,"unknown"],[63,22,"unknown"],[63,23,"catchable"],[63,24,"catchable"],[63,25,"unknown"],[63,26,"unknown"],[63,27,"catchable"],[63,28,"catchable"],[63,29,"catchable"],[63,30,"catchable"],[63,31,"catchable"],[63,32,"catchable"],[63,33,"unknown"],[63,34,"unknown"],[63,35,"catchable"],[63,36,"unknown"],[63,37,"unknown"],[63,38,"unknown"],[63,39,"unknown"],[63,44,"catchable"],[63,45,"catchable"],[63,46,"catchable"],[63,47,"unknown"],[63,50,"catchable"],[64,1,"catchable"],[64,2,"catchable"],[64,3,"catchable"],[64,4,"catchable"],[64,5,"catchable"],[64,6,"catchable"],[64,7,"unknown"],[64,8,"unknown"],[64,9,"unknown"],[64,10,"catchable"],[64,11,"catchable"],[64,12,"catchable"],[64,13,"catchable"],[64,14,"catchable"],[64,15,"catchable"],[64,16,"catchable"],[64,17,"unknown"],[64,18,"unknown"],[64,21,"unknown"],[64,22,"unknown"],[64,23,"unknown"],[64,24,"unknown"],[64,25,"unknown"],[64,26,"unknown"],[64,27,"catchable"],[64,28,"catchable"],[64,29,"unknown"],[64,30,"unknown"],[64,31,"catchable"],[64,32,"catchable"],[64,33,"unknown"],[64,34,"unknown"],[64,35,"catchable"],[64,36,"catchable"],[64,37,"unknown"],[64,38,"unknown"],[64,39,"unknown"],[64,44,"catchable"],[64,45,"catchable"],[64,46,"unknown"],[64,47,"unknown"],[64,50,"catchable"],[64,51,"catchable"],[65,1,"unknown"],[65,2,"unknown"],[65,3,"unknown"],[65,4,"unknown"],[65,5,"unknown"],[65,6,"unknown"],[65,7,"unknown"],[65,8,"unknown"],[65,9,"unknown"],[65,10,"unknown"],[65,11,"unknown"],[65,12,"unknown"],[65,13,"unknown"],[65,14,"unknown"],[65,15,"unknown"],[65,16,"unknown"],[65,17,"unknown"],[65,18,"unknown"],[65,21,"catchable"],[65,22,"catchable"],[65,23,"unknown"],[65,24,"unknown"],[65,25,"unknown"],[65,26,"unknown"],[65,27,"unknown"],[65,28,"unknown"],[65,29,"unknown"],[65,30,"unknown"],[65,31,"unknown"],[65,32,"unknown"],[65,33,"unknown"],[65,34,"unknown"],[65,35,"catchable"],[65,36,"unknown"],[65,37,"unknown"],[65,38,"unknown"],[65,39,"unknown"],[65,44,"unknown"],[65,45,"unknown"],[65,46,"unknown"],[65,47,"unknown"],[65,49,"unknown"],[65,50,"catchable"],[66,1,"catchable"],[66,2,"catchable"],[66,3,"catchable"],[66,4,"catchable"],[66,5,"catchable"],[66,6,"catchable"],[66,7,"catchable"],[66,8,"catchable"],[66,9,"catchable"],[66,10,"catchable"],[66,11,"catchable"],[66,12,"catchable"],[66,13,"catchable"],[66,14,"catchable"],[66,15,"catchable"],[66,16,"catchable"],[66,17,"unknown"],[66,18,"unknown"],[66,21,"unknown"],[66,22,"unknown"],[66,23,"catchable"],[66,24,"catchable"],[66,25,"catchable"],[66,26,"catchable"],[66,27,"catchable"],[66,28,"catchable"],[66,29,"catchable"],[66,30,"catchable"],[66,31,"catchable"],[66,32,"catchable"],[66,33,"catchable"],[66,34,"catchable"],[66,35,"unknown"],[66,36,"unknown"],[66,37,"unknown"],[66,38,"unknown"],[66,39,"unknown"],[66,44,"catchable"],[66,45,"catchable"],[66,46,"unknown"],[66,47,"unknown"],[67,1,"catchable"],[67,2,"catchable"],[67,3,"catchable"],[67,4,"catchable"],[67,5,"catchable"],[67,6,"catchable"],[67,7,"unknown"],[67,8,"unknown"],[67,9,"unknown"],[67,10,"catchable"],[67,11,"catchable"],[67,12,"catchable"],[67,13,"catchable"],[67,14,"catchable"],[67,15,"catchable"],[67,16,"catchable"],[67,17,"unknown"],[67,18,"unknown"],[67,21,"unknown"],[67,22,"unknown"],[67,23,"catchable"],[67,24,"catchable"],[67,25,"unknown"],[67,26,"unknown"],[67,27,"catchable"],[67,28,"catchable"],[67,29,"catchable"],[67,30,"catchable"],[67,31,"catchable"],[67,32,"catchable"],[67,33,"catchable"],[67,34,"catchable"],[67,35,"unknown"],[67,36,"catchable"],[67,37,"unknown"],[67,38,"unknown"],[67,39,"unknown"],[67,44,"catchable"],[67,45,"catchable"],[67,46,"unknown"],[67,47,"unknown"],[67,51,"catchable"],[68,1,"unknown"],[68,2,"unknown"],[68,3,"unknown"],[68,4,"unknown"],[68,5,"unknown"],[68,6,"unknown"],[68,7,"unknown"],[68,8,"unknown"],[68,9,"unknown"],[68,10,"unknown"],[68,11,"unknown"],[68,12,"unknown"],[68,13,"unknown"],[68,14,"unknown"],[68,15,"unknown"],[68,16,"unknown"],[68,17,"unknown"],[68,18,"unknown"],[68,21,"unknown"],[68,22,"unknown"],[68,23,"unknown"],[68,24,"unknown"],[68,25,"unknown"],[68,26,"unknown"],[68,27,"unknown"],[68,28,"unknown"],[68,29,"unknown"],[68,30,"unknown"],[68,31,"unknown"],[68,32,"unknown"],[68,33,"catchable"],[68,34,"catchable"],[68,35,"unknown"],[68,36,"catchable"],[68,37,"unknown"],[68,38,"unknown"],[68,39,"unknown"],[68,44,"unknown"],[68,45,"unknown"],[68,46,"unknown"],[68,47,"unknown"],[68,49,"unknown"],[68,51,"catchable"],[69,1,"unknown"],[69,2,"catchable"],[69,3,"catchable"],[69,4,"catchable"],[69,5,"catchable"],[69,6,"catchable"],[69,7,"unknown"],[69,8,"unknown"],[69,9,"unknown"],[69,10,"unknown"],[69,11,"catchable"],[69,12,"catchable"],[69,13,"catchable"],[69,14,"catchable"],[69,15,"catchable"],[69,16,"catchable"],[69,17,"unknown"],[69,18,"unknown"],[69,21,"unknown"],[69,22,"unknown"],[69,23,"catchable"],[69,24,"catchable"],[69,25,"unknown"],[69,26,"unknown"],[69,27,"catchable"],[69,28,"catchable"],[69,29,"unknown"],[69,30,"unknown"],[69,31,"unknown"],[69,32,"catchable"],[69,40,"unknown"],[69,41,"unknown"],[69,42,"unknown"],[69,43,"unknown"],[69,44,"unknown"],[69,45,"catchable"],[69,46,"unknown"],[69,47,"unknown"],[69,48,"unknown"],[69,52,"unknown"],[70,1,"unknown"],[70,2,"catchable"],[70,3,"catchable"],[70,4,"catchable"],[70,5,"catchable"],[70,6,"catchable"],[70,7,"unknown"],[70,8,"unknown"],[70,9,"unknown"],[70,10,"unknown"],[70,11,"catchable"],[70,12,"catchable"],[70,13,"catchable"],[70,14,"catchable"],[70,15,"catchable"],[70,16,"catchable"],[70,17,"unknown"],[70,18,"unknown"],[70,20,"catchable"],[70,21,"unknown"],[70,22,"unknown"],[70,23,"catchable"],[70,24,"catchable"],[70,25,"unknown"],[70,26,"unknown"],[70,27,"unknown"],[70,28,"unknown"],[70,29,"unknown"],[70,30,"unknown"],[70,31,"unknown"],[70,32,"catchable"],[70,40,"unknown"],[70,41,"unknown"],[70,42,"unknown"],[70,43,"unknown"],[70,44,"unknown"],[70,45,"catchable"],[70,46,"unknown"],[70,47,"unknown"],[70,48,"unknown"],[70,52,"unknown"],[71,1,"unknown"],[71,2,"unknown"],[71,3,"unknown"],[71,4,"unknown"],[71,5,"unknown"],[71,6,"unknown"],[71,7,"unknown"],[71,8,"unknown"],[71,9,"unknown"],[71,10,"unknown"],[71,11,"unknown"],[71,12,"unknown"],[71,13,"unknown"],[71,14,"unknown"],[71,15,"unknown"],[71,16,"unknown"],[71,17,"unknown"],[71,18,"unknown"],[71,21,"unknown"],[71,22,"unknown"],[71,23,"unknown"],[71,24,"unknown"],[71,25,"unknown"],[71,26,"unknown"],[71,27,"unknown"],[71,28,"unknown"],[71,29,"unknown"],[71,30,"unknown"],[71,31,"unknown"],[71,32,"catchable"],[71,40,"unknown"],[71,41,"unknown"],[71,42,"unknown"],[71,43,"unknown"],[71,44,"unknown"],[71,45,"unknown"],[71,46,"unknown"],[71,47,"unknown"],[71,48,"unknown"],[71,49,"unknown"],[71,52,"unknown"],[72,1,"catchable"],[72,2,"catchable"],[72,3,"catchable"],[72,4,"catchable"],[72,5,"catchable"],[72,6,"catchable"],[72,7,"catchable"],[72,8,"catchable"],[72,9,"catchable"],[72,10,"catchable"],[72,11,"catchable"],[72,12,"catchable"],[72,13,"catchable"],[72,14,"catchable"],[72,15,"catchable"],[72,16,"catchable"],[72,17,"unknown"],[72,18,"unknown"],[72,21,"unknown"],[72,22,"unknown"],[72,23,"catchable"],[72,24,"catchable"],[72,25,"unknown"],[72,26,"unknown"],[72,27,"catchable"],[72,28,"catchable"],[72,29,"catchable"],[72,30,"catchable"],[72,31,"catchable"],[72,32,"catchable"],[72,33,"unknown"],[72,34,"unknown"],[72,35,"catchable"],[72,36,"unknown"],[72,37,"unknown"],[72,38,"unknown"],[72,39,"unknown"],[72,40,"unknown"],[72,41,"unknown"],[72,42,"unknown"],[72,43,"unknown"],[72,44,"catchable"],[72,45,"catchable"],[72,46,"unknown"],[72,47,"unknown"],[72,48,"unknown"],[72,50,"catchable"],[72,53,"unknown"],[73,1,"unknown"],[73,2,"unknown"],[73,3,"catchable"],[73,4,"catchable"],[73,5,"catchable"],[73,6,"catchable"],[73,7,"catchable"],[73,8,"catchable"],[73,9,"catchable"],[73,10,"catchable"],[73,11,"catchable"],[73,12,"catchable"],[73,13,"catchable"],[73,14,"catchable"],[73,15,"catchable"],[73,16,"catchable"],[73,17,"unknown"],[73,18,"unknown"],[73,21,"unknown"],[73,22,"unknown"],[73,23,"unknown"],[73,24,"unknown"],[73,25,"unknown"],[73,26,"unknown"],[73,27,"catchable"],[73,28,"catchable"],[73,29,"catchable"],[73,30,"catchable"],[73,31,"catchable"],[73,32,"catchable"],[73,33,"unknown"],[73,34,"unknown"],[73,35,"catchable"],[73,36,"catchable"],[73,37,"unknown"],[73,38,"unknown"],[73,39,"unknown"],[73,40,"unknown"],[73,41,"unknown"],[73,42,"unknown"],[73,43,"unknown"],[73,44,"unknown"],[73,45,"unknown"],[73,46,"unknown"],[73,47,"unknown"],[73,48,"unknown"],[73,50,"catchable"],[73,51,"catchable"],[73,53,"unknown"],[74,1,"catchable"],[74,2,"catchable"],[74,3,"catchable"],[74,4,"catchable"],[74,5,"catchable"],[74,6,"catchable"],[74,7,"catchable"],[74,8,"catchable"],[74,9,"catchable"],[74,10,"catchable"],[74,11,"catchable"],[74,12,"catchable"],[74,13,"catchable"],[74,14,"catchable"],[74,15,"catchable"],[74,16,"catchable"],[74,17,"unknown"],[74,18,"unknown"],[74,21,"unknown"],[74,22,"unknown"],[74,23,"catchable"],[74,24,"catchable"],[74,25,"catchable"],[74,26,"catchable"],[74,27,"catchable"],[74,28,"catchable"],[74,29,"unknown"],[74,30,"unknown"],[74,31,"catchable"],[74,32,"catchable"],[74,37,"unknown"],[74,38,"unknown"],[74,39,"unknown"],[74,40,"unknown"],[74,41,"unknown"],[74,42,"unknown"],[74,43,"unknown"],[74,44,"catchable"],[74,45,"catchable"],[74,46,"unknown"],[74,47,"unknown"],[74,48,"unknown"],[74,52,"unknown"],[74,53,"unknown"],[75,1,"catchable"],[75,2,"catchable"],[75,3,"catchable"],[75,4,"catchable"],[75,5,"catchable"],[75,6,"catchable"],[75,7,"catchable"],[75,8,"catchable"],[75,9,"catchable"],[75,10,"catchable"],[75,11,"catchable"],[75,12,"catchable"],[75,13,"catchable"],[75,14,"catchable"],[75,15,"catchable"],[75,16,"catchable"],[75,17,"catchable"],[75,18,"catchable"],[75,21,"unknown"],[75,22,"unknown"],[75,23,"catchable"],[75,24,"catchable"],[75,25,"catchable"],[75,26,"catchable"],[75,27,"catchable"],[75,28,"catchable"],[75,29,"catchable"],[75,30,"catchable"],[75,31,"catchable"],[75,32,"catchable"],[75,37,"unknown"],[75,38,"unknown"],[75,39,"unknown"],[75,40,"unknown"],[75,41,"unknown"],[75,42,"unknown"],[75,43,"unknown"],[75,44,"catchable"],[75,45,"catchable"],[75,46,"unknown"],[75,47,"unknown"],[75,48,"unknown"],[75,52,"unknown"],[75,53,"unknown"],[76,1,"unknown"],[76,2,"unknown"],[76,3,"unknown"],[76,4,"unknown"],[76,5,"unknown"],[76,6,"unknown"],[76,7,"unknown"],[76,8,"unknown"],[76,9,"unknown"],[76,10,"unknown"],[76,11,"unknown"],[76,12,"unknown"],[76,13,"unknown"],[76,14,"unknown"],[76,15,"catchable"],[76,16,"catchable"],[76,17,"unknown"],[76,18,"unknown"],[76,21,"unknown"],[76,22,"unknown"],[76,23,"unknown"],[76,24,"unknown"],[76,25,"unknown"],[76,26,"unknown"],[76,27,"unknown"],[76,28,"unknown"],[76,29,"unknown"],[76,30,"unknown"],[76,31,"unknown"],[76,32,"unknown"],[76,37,"unknown"],[76,38,"unknown"],[76,39,"unknown"],[76,40,"unknown"],[76,41,"unknown"],[76,42,"unknown"],[76,43,"unknown"],[76,44,"unknown"],[76,45,"unknown"],[76,46,"unknown"],[76,47,"unknown"],[76,48,"unknown"],[76,52,"unknown"],[76,53,"unknown"],[77,1,"catchable"],[77,2,"catchable"],[77,3,"catchable"],[77,4,"catchable"],[77,5,"catchable"],[77,6,"catchable"],[77,7,"unknown"],[77,8,"unknown"],[77,9,"unknown"],[77,10,"catchable"],[77,11,"catchable"],[77,12,"catchable"],[77,13,"catchable"],[77,14,"catchable"],[77,15,"catchable"],[77,16,"catchable"],[77,17,"unknown"],[77,18,"unknown"],[77,21,"unknown"],[77,22,"unknown"],[77,23,"catchable"],[77,24,"catchable"],[77,25,"unknown"],[77,26,"unknown"],[77,27,"unknown"],[77,28,"unknown"],[77,29,"unknown"],[77,30,"unknown"],[77,31,"catchable"],[77,32,"catchable"],[77,33,"unknown"],[77,34,"catchable"],[77,35,"unknown"],[77,36,"unknown"],[77,37,"unknown"],[77,38,"unknown"],[77,39,"unknown"],[77,44,"catchable"],[77,45,"catchable"],[77,46,"unknown"],[77,50,"catchable"],[77,51,"catchable"],[78,1,"unknown"],[78,2,"unknown"],[78,3,"unknown"],[78,4,"catchable"],[78,5,"catchable"],[78,6,"catchable"],[78,7,"unknown"],[78,8,"unknown"],[78,9,"unknown"],[78,10,"catchable"],[78,11,"catchable"],[78,12,"unknown"],[78,13,"unknown"],[78,14,"unknown"],[78,15,"catchable"],[78,16,"catchable"],[78,17,"catchable"],[78,18,"catchable"],[78,20,"catchable"],[78,21,"unknown"],[78,22,"unknown"],[78,23,"unknown"],[78,24,"unknown"],[78,25,"unknown"],[78,26,"unknown"],[78,27,"unknown"],[78,28,"unknown"],[78,29,"unknown"],[78,30,"unknown"],[78,31,"catchable"],[78,32,"catchable"],[78,33,"unknown"],[78,34,"catchable"],[78,35,"unknown"],[78,36,"unknown"],[78,37,"unknown"],[78,38,"unknown"],[78,39,"unknown"],[78,44,"unknown"],[78,45,"unknown"],[78,46,"unknown"],[78,51,"catchable"],[79,1,"catchable"],[79,2,"catchable"],[79,3,"catchable"],[79,4,"catchable"],[79,5,"catchable"],[79,6,"catchable"],[79,7,"unknown"],[79,8,"unknown"],[79,9,"unknown"],[79,10,"unknown"],[79,11,"catchable"],[79,12,"unknown"],[79,13,"catchable"],[79,14,"catchable"],[79,15,"catchable"],[79,16,"catchable"],[79,17,"catchable"],[79,18,"catchable"],[79,21,"unknown"],[79,22,"unknown"],[79,23,"catchable"],[79,24,"catchable"],[79,25,"catchable"],[79,26,"catchable"],[79,27,"catchable"],[79,28,"catchable"],[79,29,"catchable"],[79,30,"catchable"],[79,31,"catchable"],[79,32,"catchable"],[79,33,"catchable"],[79,34,"catchable"],[79,35,"catchable"],[79,36,"catchable"],[79,37,"unknown"],[79,38,"unknown"],[79,39,"unknown"],[79,40,"unknown"],[79,41,"unknown"],[79,42,"unknown"],[79,43,"unknown"],[79,44,"catchable"],[79,45,"catchable"],[79,46,"unknown"],[79,47,"unknown"],[79,48,"unknown"],[79,50,"catchable"],[79,51,"catchable"],[79,53,"unknown"],[80,1,"catchable"],[80,2,"catchable"],[80,3,"catchable"],[80,4,"catchable"],[80,5,"catchable"],[80,6,"catchable"],[80,7,"unknown"],[80,8,"unknown"],[80,9,"unknown"],[80,10,"unknown"],[80,11,"catchable"],[80,12,"unknown"],[80,13,"unknown"],[80,14,"unknown"],[80,15,"catchable"],[80,16,"catchable"],[80,17,"catchable"],[80,18,"catchable"],[80,21,"unknown"],[80,22,"unknown"],[80,23,"unknown"],[80,24,"unknown"],[80,25,"unknown"],[80,26,"unknown"],[80,27,"catchable"],[80,28,"catchable"],[80,29,"catchable"],[80,30,"catchable"],[80,31,"catchable"],[80,32,"catchable"],[80,33,"unknown"],[80,34,"unknown"],[80,35,"unknown"],[80,36,"catchable"],[80,37,"unknown"],[80,38,"unknown"],[80,39,"unknown"],[80,40,"unknown"],[80,41,"unknown"],[80,42,"unknown"],[80,43,"unknown"],[80,44,"catchable"],[80,45,"catchable"],[80,46,"unknown"],[80,47,"unknown"],[80,48,"unknown"],[80,49,"unknown"],[80,50,"unknown"],[80,51,"catchable"],[80,53,"unknown"],[81,1,"catchable"],[81,2,"catchable"],[81,3,"catchable"],[81,4,"catchable"],[81,5,"catchable"],[81,6,"catchable"],[81,7,"catchable"],[81,8,"catchable"],[81,9,"catchable"],[81,10,"catchable"],[81,11,"catchable"],[81,12,"catchable"],[81,13,"catchable"],[81,14,"catchable"],[81,15,"catchable"],[81,16,"catchable"],[81,17,"unknown"],[81,18,"unknown"],[81,21,"catchable"],[81,22,"catchable"],[81,23,"unknown"],[81,24,"unknown"],[81,25,"catchable"],[81,26,"catchable"],[81,27,"catchable"],[81,28,"catchable"],[81,29,"catchable"],[81,30,"catchable"],[81,31,"catchable"],[81,32,"catchable"],[81,33,"unknown"],[81,34,"unknown"],[81,35,"catchable"],[81,36,"unknown"],[81,37,"unknown"],[81,38,"unknown"],[81,39,"unknown"],[81,40,"unknown"],[81,41,"unknown"],[81,42,"unknown"],[81,43,"unknown"],[81,44,"catchable"],[81,45,"catchable"],[81,46,"unknown"],[81,47,"unknown"],[81,48,"unknown"],[81,50,"catchable"],[81,53,"unknown"],[82,1,"catchable"],[82,2,"catchable"],[82,3,"catchable"],[82,4,"unknown"],[82,5,"unknown"],[82,6,"catchable"],[82,7,"catchable"],[82,8,"catchable"],[82,9,"catchable"],[82,10,"catchable"],[82,11,"catchable"],[82,12,"unknown"],[82,13,"unknown"],[82,14,"catchable"],[82,15,"catchable"],[82,16,"catchable"],[82,17,"unknown"],[82,18,"unknown"],[82,20,"catchable"],[82,21,"catchable"],[82,22,"catchable"],[82,23,"catchable"],[82,24,"catchable"],[82,25,"unknown"],[82,26,"unknown"],[82,27,"unknown"],[82,28,"unknown"],[82,29,"unknown"],[82,30,"unknown"],[82,31,"catchable"],[82,32,"catchable"],[82,33,"unknown"],[82,34,"unknown"],[82,35,"catchable"],[82,36,"catchable"],[82,37,"unknown"],[82,38,"unknown"],[82,39,"unknown"],[82,40,"unknown"],[82,41,"unknown"],[82,42,"unknown"],[82,43,"unknown"],[82,44,"catchable"],[82,45,"catchable"],[82,46,"unknown"],[82,47,"unknown"],[82,48,"unknown"],[82,50,"catchable"],[82,51,"catchable"],[82,53,"unknown"],[83,1,"catchable"],[83,2,"catchable"],[83,3,"catchable"],[83,4,"catchable"],[83,5,"catchable"],[83,6,"catchable"],[83,7,"unknown"],[83,8,"unknown"],[83,9,"unknown"],[83,10,"catchable"],[83,11,"catchable"],[83,12,"catchable"],[83,13,"catchable"],[83,14,"catchable"],[83,15,"catchable"],[83,16,"catchable"],[83,17,"unknown"],[83,18,"unknown"],[83,20,"catchable"],[83,21,"unknown"],[83,22,"unknown"],[83,23,"catchable"],[83,24,"catchable"],[83,25,"unknown"],[83,26,"unknown"],[83,27,"unknown"],[83,28,"unknown"],[83,29,"unknown"],[83,30,"unknown"],[83,31,"catchable"],[83,32,"catchable"],[83,33,"catchable"],[83,34,"unknown"],[83,35,"catchable"],[83,36,"catchable"],[83,37,"unknown"],[83,38,"unknown"],[83,39,"unknown"],[83,44,"unknown"],[83,45,"unknown"],[83,46,"unknown"],[83,47,"unknown"],[83,48,"unknown"],[83,49,"unknown"],[84,1,"catchable"],[84,2,"catchable"],[84,3,"catchable"],[84,4,"catchable"],[84,5,"catchable"],[84,6,"catchable"],[84,7,"catchable"],[84,8,"catchable"],[84,9,"catchable"],[84,10,"catchable"],[84,11,"catchable"],[84,12,"catchable"],[84,13,"catchable"],[84,14,"catchable"],[84,15,"catchable"],[84,16,"catchable"],[84,17,"unknown"],[84,18,"unknown"],[84,21,"unknown"],[84,22,"unknown"],[84,23,"catchable"],[84,24,"catchable"],[84,25,"catchable"],[84,26,"catchable"],[84,27,"unknown"],[84,28,"unknown"],[84,29,"unknown"],[84,30,"unknown"],[84,31,"catchable"],[84,32,"catchable"],[84,40,"unknown"],[84,41,"unknown"],[84,42,"unknown"],[84,43,"unknown"],[84,44,"catchable"],[84,45,"catchable"],[84,46,"unknown"],[84,47,"unknown"],[84,48,"unknown"],[84,53,"unknown"],[85,1,"catchable"],[85,2,"catchable"],[85,3,"catchable"],[85,4,"catchable"],[85,5,"catchable"],[85,6,"catchable"],[85,7,"catchable"],[85,8,"catchable"],[85,9,"catchable"],[85,10,"unknown"],[85,11,"unknown"],[85,12,"unknown"],[85,13,"unknown"],[85,14,"unknown"],[85,15,"catchable"],[85,16,"catchable"],[85,17,"unknown"],[85,18,"unknown"],[85,20,"catchable"],[85,21,"unknown"],[85,22,"unknown"],[85,23,"unknown"],[85,24,"unknown"],[85,25,"unknown"],[85,26,"unknown"],[85,27,"unknown"],[85,28,"unknown"],[85,29,"unknown"],[85,30,"unknown"],[85,31,"catchable"],[85,32,"catchable"],[85,40,"unknown"],[85,41,"unknown"],[85,42,"unknown"],[85,43,"unknown"],[85,44,"catchable"],[85,45,"catchable"],[85,46,"unknown"],[85,47,"unknown"],[85,48,"unknown"],[85,53,"unknown"],[86,1,"catchable"],[86,2,"catchable"],[86,3,"catchable"],[86,4,"catchable"],[86,5,"catchable"],[86,6,"catchable"],[86,7,"unknown"],[86,8,"unknown"],[86,9,"unknown"],[86,10,"catchable"],[86,11,"catchable"],[86,12,"catchable"],[86,13,"unknown"],[86,14,"unknown"],[86,15,"catchable"],[86,16,"catchable"],[86,17,"catchable"],[86,18,"catchable"],[86,20,"catchable"],[86,21,"catchable"],[86,22,"catchable"],[86,23,"unknown"],[86,24,"unknown"],[86,25,"unknown"],[86,26,"unknown"],[86,27,"unknown"],[86,28,"unknown"],[86,29,"catchable"],[86,30,"catchable"],[86,31,"catchable"],[86,32,"catchable"],[86,40,"unknown"],[86,41,"unknown"],[86,42,"unknown"],[86,43,"unknown"],[86,44,"catchable"],[86,45,"catchable"],[86,46,"unknown"],[86,47,"unknown"],[86,48,"unknown"],[86,53,"unknown"],[87,1,"catchable"],[87,2,"catchable"],[87,3,"catchable"],[87,4,"unknown"],[87,5,"unknown"],[87,6,"unknown"],[87,7,"unknown"],[87,8,"unknown"],[87,9,"unknown"],[87,10,"catchable"],[87,11,"catchable"],[87,12,"catchable"],[87,13,"unknown"],[87,14,"catchable"],[87,15,"catchable"],[87,16,"catchable"],[87,17,"catchable"],[87,18,"catchable"],[87,21,"catchable"],[87,22,"catchable"],[87,23,"catchable"],[87,24,"catchable"],[87,25,"unknown"],[87,26,"unknown"],[87,27,"unknown"],[87,28,"unknown"],[87,29,"unknown"],[87,30,"unknown"],[87,31,"catchable"],[87,32,"catchable"],[87,40,"unknown"],[87,41,"unknown"],[87,42,"unknown"],[87,43,"unknown"],[87,44,"catchable"],[87,45,"catchable"],[87,46,"unknown"],[87,47,"unknown"],[87,48,"unknown"],[87,53,"unknown"],[88,1,"catchable"],[88,2,"catchable"],[88,3,"catchable"],[88,4,"catchable"],[88,5,"catchable"],[88,6,"catchable"],[88,7,"catchable"],[88,8,"catchable"],[88,9,"catchable"],[88,10,"catchable"],[88,11,"catchable"],[88,12,"catchable"],[88,13,"catchable"],[88,14,"catchable"],[88,15,"catchable"],[88,16,"catchable"],[88,17,"unknown"],[88,18,"unknown"],[88,20,"catchable"],[88,21,"catchable"],[88,22,"catchable"],[88,23,"unknown"],[88,24,"unknown"],[88,25,"unknown"],[88,26,"catchable"],[88,27,"catchable"],[88,28,"catchable"],[88,29,"catchable"],[88,30,"catchable"],[88,31,"catchable"],[88,32,"unknown"],[88,40,"unknown"],[88,41,"unknown"],[88,42,"unknown"],[88,43,"unknown"],[88,44,"catchable"],[88,45,"catchable"],[88,46,"unknown"],[88,47,"unknown"],[88,48,"unknown"],[88,53,"unknown"],[89,1,"catchable"],[89,2,"catchable"],[89,3,"catchable"],[89,4,"catchable"],[89,5,"catchable"],[89,6,"catchable"],[89,7,"unknown"],[89,8,"unknown"],[89,9,"unknown"],[89,10,"unknown"],[89,11,"catchable"],[89,12,"unknown"],[89,13,"unknown"],[89,14,"unknown"],[89,15,"catchable"],[89,16,"catchable"],[89,17,"unknown"],[89,18,"unknown"],[89,21,"catchable"],[89,22,"catchable"],[89,23,"catchable"],[89,24,"catchable"],[89,25,"unknown"],[89,26,"unknown"],[89,27,"unknown"],[89,28,"unknown"],[89,29,"unknown"],[89,30,"unknown"],[89,31,"catchable"],[89,32,"unknown"],[89,40,"unknown"],[89,41,"unknown"],[89,42,"unknown"],[89,43,"unknown"],[89,44,"catchable"],[89,45,"catchable"],[89,46,"unknown"],[89,47,"unknown"],[89,48,"unknown"],[89,53,"unknown"],[90,1,"catchable"],[90,2,"catchable"],[90,3,"catchable"],[90,4,"catchable"],[90,5,"catchable"],[90,6,"catchable"],[90,7,"unknown"],[90,8,"unknown"],[90,9,"unknown"],[90,10,"catchable"],[90,11,"unknown"],[90,12,"catchable"],[90,13,"catchable"],[90,14,"catchable"],[90,15,"catchable"],[90,16,"catchable"],[90,17,"catchable"],[90,18,"catchable"],[90,20,"catchable"],[90,21,"catchable"],[90,22,"catchable"],[90,23,"unknown"],[90,24,"catchable"],[90,25,"unknown"],[90,26,"unknown"],[90,27,"catchable"],[90,28,"catchable"],[90,29,"catchable"],[90,30,"catchable"],[90,31,"catchable"],[90,32,"catchable"],[90,33,"catchable"],[90,34,"catchable"],[90,35,"catchable"],[90,36,"unknown"],[90,37,"unknown"],[90,38,"unknown"],[90,39,"unknown"],[90,40,"unknown"],[90,41,"unknown"],[90,42,"unknown"],[90,43,"unknown"],[90,44,"catchable"],[90,45,"catchable"],[90,46,"unknown"],[90,47,"unknown"],[90,48,"unknown"],[90,50,"catchable"],[91,1,"unknown"],[91,2,"unknown"],[91,3,"unknown"],[91,4,"unknown"],[91,5,"unknown"],[91,6,"unknown"],[91,7,"unknown"],[91,8,"unknown"],[91,9,"unknown"],[91,10,"unknown"],[91,11,"unknown"],[91,12,"unknown"],[91,13,"unknown"],[91,14,"unknown"],[91,15,"unknown"],[91,16,"unknown"],[91,17,"catchable"],[91,18,"catchable"],[91,21,"catchable"],[91,22,"catchable"],[91,23,"catchable"],[91,24,"catchable"],[91,25,"unknown"],[91,26,"unknown"],[91,27,"unknown"],[91,28,"unknown"],[91,29,"unknown"],[91,30,"unknown"],[91,31,"catchable"],[91,32,"catchable"],[91,33,"catchable"],[91,34,"catchable"],[91,35,"catchable"],[91,36,"unknown"],[91,37,"unknown"],[91,38,"unknown"],[91,39,"unknown"],[91,40,"unknown"],[91,41,"unknown"],[91,42,"unknown"],[91,43,"unknown"],[91,44,"unknown"],[91,45,"unknown"],[91,46,"unknown"],[91,47,"unknown"],[91,48,"unknown"],[91,50,"catchable"],[92,1,"catchable"],[92,2,"catchable"],[92,3,"catchable"],[92,4,"catchable"],[92,5,"catchable"],[92,6,"catchable"],[92,7,"unknown"],[92,8,"unknown"],[92,9,"unknown"],[92,10,"catchable"],[92,11,"catchable"],[92,12,"catchable"],[92,13,"catchable"],[92,14,"catchable"],[92,15,"catchable"],[92,16,"catchable"],[92,17,"unknown"],[92,18,"unknown"],[92,21,"unknown"],[92,22,"unknown"],[92,23,"unknown"],[92,24,"unknown"],[92,25,"unknown"],[92,26,"unknown"],[92,27,"catchable"],[92,28,"catchable"],[92,29,"catchable"],[92,30,"catchable"],[92,31,"catchable"],[92,32,"catchable"],[92,33,"catchable"],[92,34,"catchable"],[92,35,"unknown"],[92,36,"unknown"],[92,37,"unknown"],[92,38,"unknown"],[92,39,"unknown"],[92,40,"unknown"],[92,41,"unknown"],[92,42,"unknown"],[92,43,"unknown"],[92,44,"catchable"],[92,45,"catchable"],[92,46,"unknown"],[92,47,"unknown"],[92,48,"unknown"],[92,52,"unknown"],[93,1,"catchable"],[93,2,"catchable"],[93,3,"catchable"],[93,4,"catchable"],[93,5,"catchable"],[93,6,"catchable"],[93,7,"unknown"],[93,8,"unknown"],[93,9,"unknown"],[93,10,"catchable"],[93,11,"catchable"],[93,12,"catchable"],[93,13,"catchable"],[93,14,"catchable"],[93,15,"catchable"],[93,16,"catchable"],[93,17,"unknown"],[93,18,"unknown"],[93,21,"unknown"],[93,22,"unknown"],[93,23,"catchable"],[93,24,"catchable"],[93,25,"unknown"],[93,26,"unknown"],[93,27,"catchable"],[93,28,"catchable"],[93,29,"catchable"],[93,30,"catchable"],[93,31,"catchable"],[93,32,"catchable"],[93,33,"catchable"],[93,34,"catchable"],[93,35,"unknown"],[93,36,"catchable"],[93,37,"unknown"],[93,38,"unknown"],[93,39,"unknown"],[93,40,"unknown"],[93,41,"unknown"],[93,42,"unknown"],[93,43,"unknown"],[93,44,"catchable"],[93,45,"catchable"],[93,46,"unknown"],[93,47,"unknown"],[93,48,"unknown"],[93,51,"catchable"],[93,52,"unknown"],[94,1,"unknown"],[94,2,"unknown"],[94,3,"unknown"],[94,4,"unknown"],[94,5,"unknown"],[94,6,"unknown"],[94,7,"unknown"],[94,8,"unknown"],[94,9,"unknown"],[94,10,"unknown"],[94,11,"unknown"],[94,12,"catchable"],[94,13,"catchable"],[94,14,"catchable"],[94,15,"unknown"],[94,16,"unknown"],[94,17,"unknown"],[94,18,"unknown"],[94,21,"unknown"],[94,22,"unknown"],[94,23,"unknown"],[94,24,"unknown"],[94,25,"unknown"],[94,26,"unknown"],[94,27,"catchable"],[94,28,"catchable"],[94,29,"catchable"],[94,30,"catchable"],[94,31,"unknown"],[94,32,"unknown"],[94,33,"catchable"],[94,34,"catchable"],[94,35,"unknown"],[94,36,"catchable"],[94,37,"unknown"],[94,38,"unknown"],[94,39,"unknown"],[94,40,"unknown"],[94,41,"unknown"],[94,42,"unknown"],[94,43,"unknown"],[94,44,"unknown"],[94,45,"unknown"],[94,46,"unknown"],[94,47,"unknown"],[94,48,"unknown"],[94,49,"unknown"],[94,51,"catchable"],[94,52,"unknown"],[95,1,"catchable"],[95,2,"catchable"],[95,3,"catchable"],[95,4,"catchable"],[95,5,"catchable"],[95,6,"catchable"],[95,7,"unknown"],[95,8,"unknown"],[95,9,"unknown"],[95,10,"catchable"],[95,11,"catchable"],[95,12,"catchable"],[95,13,"catchable"],[95,14,"catchable"],[95,15,"catchable"],[95,16,"catchable"],[95,17,"catchable"],[95,18,"catchable"],[95,21,"catchable"],[95,22,"catchable"],[95,23,"catchable"],[95,24,"catchable"],[95,25,"catchable"],[95,26,"catchable"],[95,27,"unknown"],[95,28,"unknown"],[95,29,"catchable"],[95,30,"catchable"],[95,31,"catchable"],[95,32,"catchable"],[95,33,"catchable"],[95,34,"catchable"],[95,35,"unknown"],[95,36,"unknown"],[95,37,"unknown"],[95,38,"unknown"],[95,39,"unknown"],[95,44,"catchable"],[95,45,"catchable"],[95,46,"unknown"],[95,47,"unknown"],[96,1,"catchable"],[96,2,"catchable"],[96,3,"catchable"],[96,4,"catchable"],[96,5,"catchable"],[96,6,"catchable"],[96,7,"unknown"],[96,8,"unknown"],[96,9,"unknown"],[96,10,"catchable"],[96,11,"catchable"],[96,12,"catchable"],[96,13,"catchable"],[96,14,"catchable"],[96,15,"catchable"],[96,16,"catchable"],[96,17,"unknown"],[96,18,"unknown"],[96,21,"unknown"],[96,22,"unknown"],[96,23,"catchable"],[96,24,"catchable"],[96,25,"unknown"],[96,26,"unknown"],[96,27,"catchable"],[96,28,"catchable"],[96,29,"catchable"],[96,30,"catchable"],[96,31,"catchable"],[96,32,"catchable"],[96,40,"unknown"],[96,41,"unknown"],[96,42,"unknown"],[96,43,"unknown"],[96,44,"catchable"],[96,45,"catchable"],[96,46,"unknown"],[96,47,"unknown"],[96,48,"unknown"],[97,1,"catchable"],[97,2,"catchable"],[97,3,"unknown"],[97,4,"catchable"],[97,5,"catchable"],[97,6,"catchable"],[97,7,"unknown"],[97,8,"unknown"],[97,9,"unknown"],[97,10,"catchable"],[97,11,"catchable"],[97,12,"unknown"],[97,13,"unknown"],[97,14,"unknown"],[97,15,"catchable"],[97,16,"catchable"],[97,17,"unknown"],[97,18,"unknown"],[97,20,"catchable"],[97,21,"unknown"],[97,22,"unknown"],[97,23,"unknown"],[97,24,"unknown"],[97,25,"unknown"],[97,26,"unknown"],[97,27,"catchable"],[97,28,"catchable"],[97,29,"catchable"],[97,30,"catchable"],[97,31,"unknown"],[97,32,"unknown"],[97,40,"unknown"],[97,41,"unknown"],[97,42,"unknown"],[97,43,"unknown"],[97,44,"catchable"],[97,45,"catchable"],[97,46,"unknown"],[97,47,"unknown"],[97,48,"unknown"],[98,1,"catchable"],[98,2,"catchable"],[98,3,"catchable"],[98,4,"catchable"],[98,5,"catchable"],[98,6,"catchable"],[98,7,"unknown"],[98,8,"unknown"],[98,9,"unknown"],[98,10,"catchable"],[98,11,"catchable"],[98,12,"catchable"],[98,13,"catchable"],[98,14,"catchable"],[98,15,"catchable"],[98,16,"catchable"],[98,17,"catchable"],[98,18,"catchable"],[98,21,"catchable"],[98,22,"catchable"],[98,23,"catchable"],[98,24,"catchable"],[98,25,"unknown"],[98,26,"unknown"],[98,27,"unknown"],[98,28,"unknown"],[98,29,"unknown"],[98,30,"unknown"],[98,31,"catchable"],[98,32,"catchable"],[98,33,"catchable"],[98,34,"catchable"],[98,35,"catchable"],[98,36,"unknown"],[98,37,"unknown"],[98,38,"unknown"],[98,39,"unknown"],[98,44,"catchable"],[98,45,"catchable"],[98,46,"unknown"],[98,50,"catchable"],[99,1,"catchable"],[99,2,"catchable"],[99,3,"catchable"],[99,4,"catchable"],[99,5,"catchable"],[99,6,"catchable"],[99,7,"unknown"],[99,8,"unknown"],[99,9,"unknown"],[99,10,"unknown"],[99,11,"catchable"],[99,12,"unknown"],[99,13,"unknown"],[99,14,"unknown"],[99,15,"catchable"],[99,16,"catchable"],[99,17,"catchable"],[99,18,"catchable"],[99,21,"catchable"],[99,22,"catchable"],[99,23,"unknown"],[99,24,"unknown"],[99,25,"unknown"],[99,26,"unknown"],[99,27,"unknown"],[99,28,"unknown"],[99,29,"unknown"],[99,30,"unknown"],[99,31,"catchable"],[99,32,"catchable"],[99,33,"catchable"],[99,34,"catchable"],[99,35,"catchable"],[99,36,"catchable"],[99,37,"unknown"],[99,38,"unknown"],[99,39,"unknown"],[99,44,"catchable"],[99,45,"catchable"],[99,46,"unknown"],[99,50,"catchable"],[99,51,"catchable"],[100,1,"catchable"],[100,2,"catchable"],[100,3,"catchable"],[100,4,"catchable"],[100,5,"catchable"],[100,6,"catchable"],[100,7,"catchable"],[100,8,"catchable"],[100,9,"catchable"],[100,10,"catchable"],[100,11,"catchable"],[100,12,"catchable"],[100,13,"catchable"],[100,14,"catchable"],[100,15,"catchable"],[100,16,"catchable"],[100,17,"unknown"],[100,18,"unknown"],[100,20,"catchable"],[100,21,"unknown"],[100,22,"unknown"],[100,23,"unknown"],[100,24,"unknown"],[100,25,"catchable"],[100,26,"catchable"],[100,27,"catchable"],[100,28,"unknown"],[100,29,"unknown"],[100,30,"unknown"],[100,31,"catchable"],[100,32,"catchable"],[100,39,"unknown"],[100,40,"unknown"],[100,41,"unknown"],[100,42,"unknown"],[100,43,"unknown"],[100,44,"catchable"],[100,45,"catchable"],[100,46,"unknown"],[100,47,"unknown"],[100,48,"unknown"],[101,1,"catchable"],[101,2,"catchable"],[101,3,"catchable"],[101,4,"catchable"],[101,5,"catchable"],[101,6,"catchable"],[101,7,"catchable"],[101,8,"catchable"],[101,9,"catchable"],[101,10,"catchable"],[101,11,"catchable"],[101,12,"unknown"],[101,13,"unknown"],[101,14,"unknown"],[101,15,"catchable"],[101,16,"catchable"],[101,17,"unknown"],[101,18,"unknown"],[101,21,"unknown"],[101,22,"unknown"],[101,23,"catchable"],[101,24,"catchable"],[101,25,"catchable"],[101,26,"catchable"],[101,27,"catchable"],[101,28,"unknown"],[101,29,"catchable"],[101,30,"catchable"],[101,31,"catchable"],[101,32,"catchable"],[101,39,"unknown"],[101,40,"unknown"],[101,41,"unknown"],[101,42,"unknown"],[101,43,"unknown"],[101,44,"catchable"],[101,45,"catchable"],[101,46,"unknown"],[101,47,"unknown"],[101,48,"unknown"],[102,1,"catchable"],[102,2,"catchable"],[102,3,"catchable"],[102,4,"catchable"],[102,5,"catchable"],[102,6,"catchable"],[102,7,"unknown"],[102,8,"unknown"],[102,9,"unknown"],[102,10,"catchable"],[102,11,"catchable"],[102,12,"catchable"],[102,13,"catchable"],[102,14,"catchable"],[102,15,"catchable"],[102,16,"catchable"],[102,17,"unknown"],[102,18,"unknown"],[102,21,"unknown"],[102,22,"unknown"],[102,23,"catchable"],[102,24,"catchable"],[102,25,"unknown"],[102,26,"unknown"],[102,27,"catchable"],[102,28,"catchable"],[102,29,"catchable"],[102,30,"catchable"],[102,31,"catchable"],[102,32,"catchable"],[102,33,"unknown"],[102,34,"unknown"],[102,35,"catchable"],[102,36,"unknown"],[102,37,"unknown"],[102,38,"unknown"],[102,39,"unknown"],[102,40,"unknown"],[102,41,"unknown"],[102,42,"unknown"],[102,43,"unknown"],[102,44,"catchable"],[102,45,"catchable"],[102,46,"unknown"],[102,47,"unknown"],[102,48,"unknown"],[102,50,"catchable"],[102,53,"unknown"],[103,1,"unknown"],[103,2,"unknown"],[103,3,"unknown"],[103,4,"unknown"],[103,5,"unknown"],[103,6,"unknown"],[103,7,"unknown"],[103,8,"unknown"],[103,9,"unknown"],[103,10,"unknown"],[103,11,"unknown"],[103,12,"unknown"],[103,13,"unknown"],[103,14,"unknown"],[103,15,"unknown"],[103,16,"unknown"],[103,17,"unknown"],[103,18,"unknown"],[103,20,"catchable"],[103,21,"unknown"],[103,22,"unknown"],[103,23,"unknown"],[103,24,"unknown"],[103,25,"unknown"],[103,26,"unknown"],[103,27,"catchable"],[103,28,"catchable"],[103,29,"catchable"],[103,30,"catchable"],[103,31,"catchable"],[103,32,"catchable"],[103,33,"unknown"],[103,34,"unknown"],[103,35,"catchable"],[103,36,"catchable"],[103,37,"unknown"],[103,38,"unknown"],[103,39,"unknown"],[103,40,"unknown"],[103,41,"unknown"],[103,42,"unknown"],[103,43,"unknown"],[103,44,"unknown"],[103,45,"unknown"],[103,46,"unknown"],[103,47,"unknown"],[103,48,"unknown"],[103,50,"catchable"],[103,51,"catchable"],[103,53,"unknown"],[104,1,"catchable"],[104,2,"catchable"],[104,3,"catchable"],[104,4,"catchable"],[104,5,"catchable"],[104,6,"catchable"],[104,7,"unknown"],[104,8,"unknown"],[104,9,"unknown"],[104,10,"catchable"],[104,11,"catchable"],[104,12,"catchable"],[104,13,"catchable"],[104,14,"catchable"],[104,15,"catchable"],[104,16,"catchable"],[104,17,"unknown"],[104,18,"unknown"],[104,21,"unknown"],[104,22,"unknown"],[104,23,"catchable"],[104,24,"catchable"],[104,25,"unknown"],[104,26,"unknown"],[104,27,"catchable"],[104,28,"catchable"],[104,29,"catchable"],[104,30,"catchable"],[104,31,"catchable"],[104,32,"catchable"],[104,33,"unknown"],[104,34,"unknown"],[104,35,"catchable"],[104,36,"unknown"],[104,37,"unknown"],[104,38,"unknown"],[104,39,"unknown"],[104,44,"catchable"],[104,45,"catchable"],[104,46,"unknown"],[104,47,"unknown"],[104,48,"unknown"],[104,50,"catchable"],[105,1,"catchable"],[105,2,"catchable"],[105,3,"catchable"],[105,4,"catchable"],[105,5,"catchable"],[105,6,"catchable"],[105,7,"unknown"],[105,8,"unknown"],[105,9,"unknown"],[105,10,"catchable"],[105,11,"catchable"],[105,12,"unknown"],[105,13,"unknown"],[105,14,"unknown"],[105,15,"catchable"],[105,16,"catchable"],[105,17,"catchable"],[105,18,"catchable"],[105,20,"catchable"],[105,21,"unknown"],[105,22,"unknown"],[105,23,"catchable"],[105,24,"catchable"],[105,25,"unknown"],[105,26,"unknown"],[105,27,"unknown"],[105,28,"unknown"],[105,29,"catchable"],[105,30,"unknown"],[105,31,"catchable"],[105,32,"catchable"],[105,33,"unknown"],[105,34,"unknown"],[105,35,"catchable"],[105,36,"catchable"],[105,37,"unknown"],[105,38,"unknown"],[105,39,"unknown"],[105,44,"catchable"],[105,45,"catchable"],[105,46,"unknown"],[105,47,"unknown"],[105,48,"unknown"],[105,50,"catchable"],[105,51,"catchable"],[106,1,"catchable"],[106,2,"catchable"],[106,3,"catchable"],[106,4,"unknown"],[106,5,"unknown"],[106,6,"unknown"],[106,7,"unknown"],[106,8,"unknown"],[106,9,"unknown"],[106,10,"catchable"],[106,11,"catchable"],[106,12,"unknown"],[106,13,"unknown"],[106,14,"unknown"],[106,15,"unknown"],[106,16,"unknown"],[106,17,"unknown"],[106,18,"unknown"],[106,20,"catchable"],[106,21,"unknown"],[106,22,"unknown"],[106,23,"unknown"],[106,24,"unknown"],[106,25,"unknown"],[106,26,"unknown"],[106,27,"unknown"],[106,28,"unknown"],[106,29,"unknown"],[106,30,"unknown"],[106,31,"catchable"],[106,32,"catchable"],[106,33,"catchable"],[106,34,"catchable"],[106,35,"unknown"],[106,36,"catchable"],[106,37,"unknown"],[106,38,"unknown"],[106,39,"unknown"],[106,40,"unknown"],[106,41,"unknown"],[106,42,"unknown"],[106,43,"unknown"],[106,44,"catchable"],[106,45,"catchable"],[106,46,"unknown"],[106,47,"unknown"],[106,48,"unknown"],[106,51,"catchable"],[106,53,"unknown"],[107,1,"catchable"],[107,2,"catchable"],[107,3,"catchable"],[107,4,"unknown"],[107,5,"unknown"],[107,6,"unknown"],[107,7,"unknown"],[107,8,"unknown"],[107,9,"unknown"],[107,10,"catchable"],[107,11,"catchable"],[107,12,"unknown"],[107,13,"unknown"],[107,14,"unknown"],[107,15,"unknown"],[107,16,"unknown"],[107,17,"unknown"],[107,18,"unknown"],[107,20,"catchable"],[107,21,"unknown"],[107,22,"unknown"],[107,23,"unknown"],[107,24,"unknown"],[107,25,"unknown"],[107,26,"unknown"],[107,27,"unknown"],[107,28,"unknown"],[107,29,"unknown"],[107,30,"unknown"],[107,31,"catchable"],[107,32,"catchable"],[107,33,"catchable"],[107,34,"catchable"],[107,35,"unknown"],[107,36,"catchable"],[107,37,"unknown"],[107,38,"unknown"],[107,39,"unknown"],[107,40,"unknown"],[107,41,"unknown"],[107,42,"unknown"],[107,43,"unknown"],[107,44,"catchable"],[107,45,"catchable"],[107,46,"unknown"],[107,47,"unknown"],[107,48,"unknown"],[107,51,"catchable"],[107,53,"unknown"],[108,1,"catchable"],[108,2,"catchable"],[108,3,"catchable"],[108,4,"catchable"],[108,5,"catchable"],[108,6,"catchable"],[108,7,"unknown"],[108,8,"unknown"],[108,9,"unknown"],[108,10,"catchable"],[108,11,"catchable"],[108,12,"catchable"],[108,13,"catchable"],[108,14,"catchable"],[108,15,"catchable"],[108,16,"catchable"],[108,17,"catchable"],[108,18,"catchable"],[108,20,"catchable"],[108,21,"catchable"],[108,22,"catchable"],[108,23,"catchable"],[108,24,"catchable"],[108,25,"unknown"],[108,26,"unknown"],[108,27,"unknown"],[108,28,"unknown"],[108,29,"catchable"],[108,30,"catchable"],[108,31,"catchable"],[108,32,"catchable"],[108,33,"unknown"],[108,34,"unknown"],[108,35,"catchable"],[108,36,"catchable"],[108,37,"unknown"],[108,38,"unknown"],[108,39,"unknown"],[108,44,"unknown"],[108,45,"unknown"],[108,46,"unknown"],[108,50,"catchable"],[108,51,"catchable"],[109,1,"catchable"],[109,2,"catchable"],[109,3,"unknown"],[109,4,"catchable"],[109,5,"catchable"],[109,6,"catchable"],[109,7,"catchable"],[109,8,"catchable"],[109,9,"catchable"],[109,10,"catchable"],[109,11,"catchable"],[109,12,"unknown"],[109,13,"unknown"],[109,14,"catchable"],[109,15,"catchable"],[109,16,"catchable"],[109,17,"unknown"],[109,18,"unknown"],[109,21,"catchable"],[109,22,"catchable"],[109,23,"unknown"],[109,24,"unknown"],[109,25,"catchable"],[109,26,"unknown"],[109,27,"unknown"],[109,28,"unknown"],[109,29,"unknown"],[109,30,"unknown"],[109,31,"unknown"],[109,32,"catchable"],[109,33,"catchable"],[109,34,"catchable"],[109,35,"unknown"],[109,36,"unknown"],[109,37,"unknown"],[109,38,"unknown"],[109,39,"unknown"],[109,40,"unknown"],[109,41,"unknown"],[109,42,"unknown"],[109,43,"unknown"],[109,44,"catchable"],[109,45,"catchable"],[109,46,"unknown"],[109,47,"unknown"],[109,48,"unknown"],[109,52,"unknown"],[110,1,"catchable"],[110,2,"catchable"],[110,3,"unknown"],[110,4,"unknown"],[110,5,"unknown"],[110,6,"catchable"],[110,7,"unknown"],[110,8,"unknown"],[110,9,"unknown"],[110,10,"catchable"],[110,11,"unknown"],[110,12,"catchable"],[110,13,"catchable"],[110,14,"catchable"],[110,15,"catchable"],[110,16,"catchable"],[110,17,"unknown"],[110,18,"unknown"],[110,21,"catchable"],[110,22,"catchable"],[110,23,"unknown"],[110,24,"unknown"],[110,25,"unknown"],[110,26,"unknown"],[110,27,"unknown"],[110,28,"unknown"],[110,29,"unknown"],[110,30,"unknown"],[110,31,"unknown"],[110,32,"catchable"],[110,33,"catchable"],[110,34,"catchable"],[110,35,"catchable"],[110,36,"catchable"],[110,37,"unknown"],[110,38,"unknown"],[110,39,"unknown"],[110,40,"unknown"],[110,41,"unknown"],[110,42,"unknown"],[110,43,"unknown"],[110,44,"catchable"],[110,45,"catchable"],[110,46,"unknown"],[110,47,"unknown"],[110,48,"unknown"],[110,50,"catchable"],[110,51,"catchable"],[110,52,"unknown"],[111,1,"catchable"],[111,2,"catchable"],[111,3,"catchable"],[111,4,"catchable"],[111,5,"catchable"],[111,6,"catchable"],[111,7,"catchable"],[111,8,"catchable"],[111,9,"catchable"],[111,10,"catchable"],[111,11,"catchable"],[111,12,"catchable"],[111,13,"catchable"],[111,14,"catchable"],[111,15,"catchable"],[111,16,"catchable"],[111,17,"unknown"],[111,18,"unknown"],[111,21,"unknown"],[111,22,"unknown"],[111,23,"catchable"],[111,24,"catchable"],[111,25,"unknown"],[111,26,"unknown"],[111,27,"catchable"],[111,28,"catchable"],[111,29,"catchable"],[111,30,"catchable"],[111,31,"catchable"],[111,32,"catchable"],[111,33,"catchable"],[111,34,"catchable"],[111,35,"catchable"],[111,36,"unknown"],[111,37,"unknown"],[111,38,"unknown"],[111,39,"unknown"],[111,40,"unknown"],[111,41,"unknown"],[111,42,"unknown"],[111,43,"unknown"],[111,44,"catchable"],[111,45,"catchable"],[111,46,"unknown"],[111,47,"unknown"],[111,48,"unknown"],[111,50,"catchable"],[111,53,"unknown"],[112,1,"catchable"],[112,2,"catchable"],[112,3,"catchable"],[112,4,"catchable"],[112,5,"catchable"],[112,6,"catchable"],[112,7,"unknown"],[112,8,"unknown"],[112,9,"unknown"],[112,10,"unknown"],[112,11,"unknown"],[112,12,"catchable"],[112,13,"catchable"],[112,14,"catchable"],[112,15,"catchable"],[112,16,"catchable"],[112,17,"unknown"],[112,18,"unknown"],[112,20,"catchable"],[112,21,"unknown"],[112,22,"unknown"],[112,23,"catchable"],[112,24,"catchable"],[112,25,"unknown"],[112,26,"unknown"],[112,27,"unknown"],[112,28,"unknown"],[112,29,"unknown"],[112,30,"unknown"],[112,31,"catchable"],[112,32,"catchable"],[112,33,"catchable"],[112,34,"catchable"],[112,35,"catchable"],[112,36,"catchable"],[112,37,"unknown"],[112,38,"unknown"],[112,39,"unknown"],[112,40,"unknown"],[112,41,"unknown"],[112,42,"unknown"],[112,43,"unknown"],[112,44,"catchable"],[112,45,"catchable"],[112,46,"unknown"],[112,47,"unknown"],[112,48,"unknown"],[112,50,"catchable"],[112,51,"catchable"],[112,53,"unknown"],[113,1,"catchable"],[113,2,"catchable"],[113,3,"catchable"],[113,4,"catchable"],[113,5,"catchable"],[113,6,"catchable"],[113,7,"unknown"],[113,8,"unknown"],[113,9,"unknown"],[113,10,"catchable"],[113,11,"catchable"],[113,12,"catchable"],[113,13,"catchable"],[113,14,"catchable"],[113,15,"catchable"],[113,16,"catchable"],[113,17,"unknown"],[113,18,"unknown"],[113,20,"catchable"],[113,21,"unknown"],[113,22,"unknown"],[113,23,"catchable"],[113,24,"catchable"],[113,25,"unknown"],[113,26,"unknown"],[113,27,"catchable"],[113,28,"catchable"],[113,29,"catchable"],[113,30,"catchable"],[113,31,"catchable"],[113,32,"catchable"],[113,33,"unknown"],[113,34,"unknown"],[113,35,"catchable"],[113,36,"catchable"],[113,37,"unknown"],[113,38,"unknown"],[113,39,"unknown"],[113,40,"unknown"],[113,41,"unknown"],[113,42,"unknown"],[113,43,"unknown"],[113,44,"catchable"],[113,45,"catchable"],[113,46,"unknown"],[113,47,"unknown"],[113,48,"unknown"],[113,50,"catchable"],[113,51,"catchable"],[113,53,"unknown"],[114,1,"catchable"],[114,2,"catchable"],[114,3,"catchable"],[114,4,"catchable"],[114,5,"catchable"],[114,6,"catchable"],[114,7,"unknown"],[114,8,"unknown"],[114,9,"unknown"],[114,10,"catchable"],[114,11,"catchable"],[114,12,"unknown"],[114,13,"unknown"],[114,14,"catchable"],[114,15,"catchable"],[114,16,"catchable"],[114,17,"catchable"],[114,18,"catchable"],[114,20,"catchable"],[114,21,"catchable"],[114,22,"catchable"],[114,23,"catchable"],[114,24,"catchable"],[114,25,"catchable"],[114,26,"catchable"],[114,27,"unknown"],[114,28,"unknown"],[114,29,"unknown"],[114,30,"unknown"],[114,31,"catchable"],[114,32,"catchable"],[114,33,"unknown"],[114,34,"unknown"],[114,35,"catchable"],[114,36,"catchable"],[114,37,"unknown"],[114,38,"unknown"],[114,39,"unknown"],[114,44,"catchable"],[114,45,"catchable"],[114,46,"unknown"],[114,50,"catchable"],[114,51,"catchable"],[115,1,"catchable"],[115,2,"catchable"],[115,3,"catchable"],[115,4,"catchable"],[115,5,"catchable"],[115,6,"catchable"],[115,7,"unknown"],[115,8,"unknown"],[115,9,"unknown"],[115,10,"catchable"],[115,11,"catchable"],[115,12,"catchable"],[115,13,"catchable"],[115,14,"catchable"],[115,15,"catchable"],[115,16,"catchable"],[115,17,"catchable"],[115,18,"catchable"],[115,20,"catchable"],[115,21,"unknown"],[115,22,"unknown"],[115,23,"catchable"],[115,24,"catchable"],[115,25,"unknown"],[115,26,"unknown"],[115,27,"catchable"],[115,28,"catchable"],[115,29,"catchable"],[115,30,"catchable"],[115,31,"catchable"],[115,32,"catchable"],[115,33,"unknown"],[115,34,"unknown"],[115,35,"catchable"],[115,36,"catchable"],[115,37,"unknown"],[115,38,"unknown"],[115,39,"unknown"],[115,44,"catchable"],[115,45,"catchable"],[115,46,"unknown"],[115,47,"unknown"],[115,49,"unknown"],[115,50,"catchable"],[115,51,"catchable"],[116,1,"catchable"],[116,2,"catchable"],[116,3,"catchable"],[116,4,"catchable"],[116,5,"catchable"],[116,6,"catchable"],[116,7,"catchable"],[116,8,"catchable"],[116,9,"catchable"],[116,10,"catchable"],[116,11,"catchable"],[116,12,"catchable"],[116,13,"catchable"],[116,14,"catchable"],[116,15,"catchable"],[116,16,"catchable"],[116,17,"catchable"],[116,18,"catchable"],[116,21,"catchable"],[116,22,"catchable"],[116,23,"catchable"],[116,24,"catchable"],[116,25,"unknown"],[116,26,"unknown"],[116,27,"catchable"],[116,28,"catchable"],[116,29,"catchable"],[116,30,"catchable"],[116,31,"catchable"],[116,32,"catchable"],[116,33,"unknown"],[116,34,"unknown"],[116,35,"catchable"],[116,36,"unknown"],[116,37,"unknown"],[116,38,"unknown"],[116,39,"unknown"],[116,40,"unknown"],[116,41,"unknown"],[116,42,"unknown"],[116,43,"unknown"],[116,44,"catchable"],[116,45,"catchable"],[116,46,"catchable"],[116,47,"unknown"],[116,48,"unknown"],[116,50,"catchable"],[116,53,"unknown"],[117,1,"catchable"],[117,2,"catchable"],[117,3,"catchable"],[117,4,"catchable"],[117,5,"catchable"],[117,6,"catchable"],[117,7,"unknown"],[117,8,"unknown"],[117,9,"unknown"],[117,10,"catchable"],[117,11,"unknown"],[117,12,"catchable"],[117,13,"catchable"],[117,14,"catchable"],[117,15,"catchable"],[117,16,"catchable"],[117,17,"catchable"],[117,18,"catchable"],[117,21,"catchable"],[117,22,"catchable"],[117,23,"catchable"],[117,24,"catchable"],[117,25,"unknown"],[117,26,"unknown"],[117,27,"unknown"],[117,28,"unknown"],[117,29,"unknown"],[117,30,"unknown"],[117,31,"catchable"],[117,32,"catchable"],[117,33,"unknown"],[117,34,"unknown"],[117,35,"catchable"],[117,36,"catchable"],[117,37,"unknown"],[117,38,"unknown"],[117,39,"unknown"],[117,40,"unknown"],[117,41,"unknown"],[117,42,"unknown"],[117,43,"unknown"],[117,44,"catchable"],[117,45,"catchable"],[117,46,"unknown"],[117,47,"unknown"],[117,48,"unknown"],[117,50,"catchable"],[117,51,"catchable"],[117,53,"unknown"],[118,1,"catchable"],[118,2,"catchable"],[118,3,"catchable"],[118,4,"catchable"],[118,5,"catchable"],[118,6,"catchable"],[118,7,"catchable"],[118,8,"catchable"],[118,9,"catchable"],[118,10,"catchable"],[118,11,"catchable"],[118,12,"catchable"],[118,13,"catchable"],[118,14,"catchable"],[118,15,"catchable"],[118,16,"catchable"],[118,17,"catchable"],[118,18,"catchable"],[118,21,"catchable"],[118,22,"catchable"],[118,23,"catchable"],[118,24,"catchable"],[118,25,"unknown"],[118,26,"unknown"],[118,27,"catchable"],[118,28,"catchable"],[118,29,"catchable"],[118,30,"catchable"],[118,31,"catchable"],[118,32,"catchable"],[118,33,"catchable"],[118,34,"catchable"],[118,35,"catchable"],[118,36,"unknown"],[118,37,"unknown"],[118,38,"unknown"],[118,39,"unknown"],[118,44,"catchable"],[118,45,"catchable"],[118,46,"unknown"],[118,50,"catchable"],[119,1,"catchable"],[119,2,"catchable"],[119,3,"catchable"],[119,4,"catchable"],[119,5,"catchable"],[119,6,"catchable"],[119,7,"catchable"],[119,8,"catchable"],[119,9,"catchable"],[119,10,"catchable"],[119,11,"catchable"],[119,12,"catchable"],[119,13,"catchable"],[119,14,"catchable"],[119,15,"catchable"],[119,16,"catchable"],[119,17,"catchable"],[119,18,"catchable"],[119,21,"catchable"],[119,22,"catchable"],[119,23,"catchable"],[119,24,"catchable"],[119,25,"unknown"],[119,26,"unknown"],[119,27,"catchable"],[119,28,"catchable"],[119,29,"catchable"],[119,30,"catchable"],[119,31,"catchable"],[119,32,"catchable"],[119,33,"catchable"],[119,34,"catchable"],[119,35,"catchable"],[119,36,"catchable"],[119,37,"unknown"],[119,38,"unknown"],[119,39,"unknown"],[119,44,"catchable"],[119,45,"catchable"],[119,46,"unknown"],[119,50,"catchable"],[119,51,"catchable"],[120,1,"catchable"],[120,2,"catchable"],[120,3,"catchable"],[120,4,"catchable"],[120,5,"catchable"],[120,6,"catchable"],[120,7,"catchable"],[120,8,"catchable"],[120,9,"catchable"],[120,10,"unknown"],[120,11,"catchable"],[120,12,"catchable"],[120,13,"catchable"],[120,14,"catchable"],[120,15,"catchable"],[120,16,"catchable"],[120,17,"catchable"],[120,18,"catchable"],[120,21,"catchable"],[120,22,"catchable"],[120,23,"catchable"],[120,24,"unknown"],[120,25,"unknown"],[120,26,"unknown"],[120,27,"catchable"],[120,28,"catchable"],[120,29,"catchable"],[120,30,"catchable"],[120,31,"catchable"],[120,32,"catchable"],[120,33,"unknown"],[120,34,"unknown"],[120,35,"catchable"],[120,36,"unknown"],[120,37,"unknown"],[120,38,"unknown"],[120,39,"unknown"],[120,44,"catchable"],[120,45,"catchable"],[120,46,"unknown"],[120,47,"unknown"],[120,50,"catchable"],[121,1,"unknown"],[121,2,"unknown"],[121,3,"unknown"],[121,4,"unknown"],[121,5,"unknown"],[121,6,"unknown"],[121,7,"unknown"],[121,8,"unknown"],[121,9,"unknown"],[121,10,"unknown"],[121,11,"unknown"],[121,12,"unknown"],[121,13,"unknown"],[121,14,"unknown"],[121,15,"unknown"],[121,16,"unknown"],[121,17,"catchable"],[121,18,"catchable"],[121,20,"catchable"],[121,21,"catchable"],[121,22,"catchable"],[121,23,"catchable"],[121,24,"unknown"],[121,25,"unknown"],[121,26,"unknown"],[121,27,"catchable"],[121,28,"catchable"],[121,29,"catchable"],[121,30,"catchable"],[121,31,"catchable"],[121,32,"catchable"],[121,33,"unknown"],[121,34,"unknown"],[121,35,"catchable"],[121,36,"catchable"],[121,37,"unknown"],[121,38,"unknown"],[121,39,"unknown"],[121,44,"unknown"],[121,45,"unknown"],[121,46,"unknown"],[121,47,"unknown"],[121,49,"unknown"],[121,50,"catchable"],[121,51,"catchable"],[122,1,"catchable"],[122,2,"catchable"],[122,3,"catchable"],[122,4,"catchable"],[122,5,"catchable"],[122,6,"catchable"],[122,7,"unknown"],[122,8,"unknown"],[122,9,"unknown"],[122,10,"catchable"],[122,11,"catchable"],[122,12,"catchable"],[122,13,"unknown"],[122,14,"catchable"],[122,15,"catchable"],[122,16,"catchable"],[122,17,"unknown"],[122,18,"unknown"],[122,20,"catchable"],[122,21,"unknown"],[122,22,"unknown"],[122,23,"catchable"],[122,24,"catchable"],[122,25,"unknown"],[122,26,"unknown"],[122,27,"unknown"],[122,28,"unknown"],[122,29,"catchable"],[122,30,"catchable"],[122,31,"catchable"],[122,32,"catchable"],[122,33,"catchable"],[122,34,"catchable"],[122,35,"catchable"],[122,36,"catchable"],[122,37,"unknown"],[122,38,"unknown"],[122,39,"unknown"],[122,44,"unknown"],[122,45,"unknown"],[122,46,"unknown"],[122,47,"unknown"],[122,48,"unknown"],[122,49,"unknown"],[122,50,"catchable"],[122,51,"catchable"],[123,1,"catchable"],[123,2,"unknown"],[123,3,"catchable"],[123,4,"unknown"],[123,5,"unknown"],[123,6,"unknown"],[123,7,"unknown"],[123,8,"unknown"],[123,9,"unknown"],[123,10,"catchable"],[123,11,"unknown"],[123,12,"catchable"],[123,13,"unknown"],[123,14,"catchable"],[123,15,"catchable"],[123,16,"catchable"],[123,17,"unknown"],[123,18,"unknown"],[123,20,"catchable"],[123,21,"unknown"],[123,22,"unknown"],[123,23,"catchable"],[123,24,"catchable"],[123,25,"unknown"],[123,26,"unknown"],[123,27,"catchable"],[123,28,"catchable"],[123,29,"catchable"],[123,30,"catchable"],[123,31,"catchable"],[123,32,"unknown"],[123,33,"unknown"],[123,34,"unknown"],[123,35,"catchable"],[123,36,"catchable"],[123,37,"unknown"],[123,38,"unknown"],[123,39,"unknown"],[123,40,"unknown"],[123,41,"unknown"],[123,42,"unknown"],[123,43,"unknown"],[123,44,"catchable"],[123,45,"unknown"],[123,46,"unknown"],[123,47,"unknown"],[123,48,"unknown"],[123,50,"catchable"],[123,51,"catchable"],[123,53,"unknown"],[124,1,"catchable"],[124,2,"catchable"],[124,3,"unknown"],[124,4,"catchable"],[124,5,"catchable"],[124,6,"catchable"],[124,7,"unknown"],[124,8,"unknown"],[124,9,"unknown"],[124,10,"catchable"],[124,11,"catchable"],[124,12,"unknown"],[124,13,"unknown"],[124,14,"catchable"],[124,15,"catchable"],[124,16,"catchable"],[124,17,"catchable"],[124,18,"catchable"],[124,21,"unknown"],[124,22,"unknown"],[124,23,"catchable"],[124,24,"catchable"],[124,25,"unknown"],[124,26,"unknown"],[124,27,"unknown"],[124,28,"unknown"],[124,29,"catchable"],[124,30,"catchable"],[124,31,"catchable"],[124,32,"catchable"],[124,33,"unknown"],[124,34,"unknown"],[124,35,"unknown"],[124,36,"catchable"],[124,37,"unknown"],[124,38,"unknown"],[124,39,"unknown"],[124,44,"unknown"],[124,45,"unknown"],[124,46,"unknown"],[124,51,"catchable"],[125,1,"catchable"],[125,2,"unknown"],[125,3,"unknown"],[125,4,"catchable"],[125,5,"catchable"],[125,6,"catchable"],[125,7,"unknown"],[125,8,"unknown"],[125,9,"unknown"],[125,10,"catchable"],[125,11,"unknown"],[125,12,"unknown"],[125,13,"unknown"],[125,14,"catchable"],[125,15,"catchable"],[125,16,"catchable"],[125,17,"unknown"],[125,18,"unknown"],[125,20,"catchable"],[125,21,"unknown"],[125,22,"unknown"],[125,23,"catchable"],[125,24,"catchable"],[125,25,"unknown"],[125,26,"unknown"],[125,27,"catchable"],[125,28,"catchable"],[125,29,"catchable"],[125,30,"catchable"],[125,31,"catchable"],[125,32,"catchable"],[125,33,"unknown"],[125,34,"unknown"],[125,35,"unknown"],[125,36,"catchable"],[125,37,"unknown"],[125,38,"unknown"],[125,39,"unknown"],[125,40,"unknown"],[125,41,"unknown"],[125,42,"unknown"],[125,43,"unknown"],[125,44,"catchable"],[125,45,"unknown"],[125,46,"unknown"],[125,47,"unknown"],[125,48,"unknown"],[125,51,"catchable"],[125,53,"unknown"],[126,1,"unknown"],[126,2,"catchable"],[126,3,"unknown"],[126,4,"catchable"],[126,5,"catchable"],[126,6,"catchable"],[126,7,"unknown"],[126,8,"unknown"],[126,9,"unknown"],[126,10,"unknown"],[126,11,"catchable"],[126,12,"unknown"],[126,13,"unknown"],[126,14,"catchable"],[126,15,"catchable"],[126,16,"catchable"],[126,17,"unknown"],[126,18,"unknown"],[126,20,"catchable"],[126,21,"unknown"],[126,22,"unknown"],[126,23,"catchable"],[126,24,"catchable"],[126,25,"unknown"],[126,26,"unknown"],[126,27,"catchable"],[126,28,"catchable"],[126,29,"catchable"],[126,30,"catchable"],[126,31,"catchable"],[126,32,"catchable"],[126,33,"unknown"],[126,34,"unknown"],[126,35,"unknown"],[126,36,"catchable"],[126,37,"unknown"],[126,38,"unknown"],[126,39,"unknown"],[126,40,"unknown"],[126,41,"unknown"],[126,42,"unknown"],[126,43,"unknown"],[126,44,"unknown"],[126,45,"catchable"],[126,46,"unknown"],[126,47,"unknown"],[126,48,"unknown"],[126,51,"catchable"],[126,53,"unknown"],[127,1,"unknown"],[127,2,"catchable"],[127,3,"catchable"],[127,4,"unknown"],[127,5,"unknown"],[127,6,"unknown"],[127,7,"catchable"],[127,8,"catchable"],[127,9,"catchable"],[127,10,"unknown"],[127,11,"catchable"],[127,12,"unknown"],[127,13,"catchable"],[127,14,"catchable"],[127,15,"catchable"],[127,16,"catchable"],[127,17,"catchable"],[127,18,"catchable"],[127,20,"catchable"],[127,21,"catchable"],[127,22,"catchable"],[127,23,"catchable"],[127,24,"catchable"],[127,25,"unknown"],[127,26,"unknown"],[127,27,"catchable"],[127,28,"catchable"],[127,29,"catchable"],[127,30,"catchable"],[127,31,"unknown"],[127,32,"catchable"],[127,33,"unknown"],[127,34,"unknown"],[127,35,"catchable"],[127,36,"unknown"],[127,37,"unknown"],[127,38,"unknown"],[127,39,"unknown"],[127,44,"unknown"],[127,45,"catchable"],[127,46,"unknown"],[127,47,"unknown"],[127,49,"unknown"],[127,50,"unknown"],[128,1,"catchable"],[128,2,"catchable"],[128,3,"catchable"],[128,4,"catchable"],[128,5,"catchable"],[128,6,"catchable"],[128,7,"unknown"],[128,8,"unknown"],[128,9,"unknown"],[128,10,"catchable"],[128,11,"catchable"],[128,12,"catchable"],[128,13,"catchable"],[128,14,"catchable"],[128,15,"catchable"],[128,16,"catchable"],[128,17,"unknown"],[128,18,"unknown"],[128,20,"catchable"],[128,21,"unknown"],[128,22,"unknown"],[128,23,"catchable"],[128,24,"catchable"],[128,25,"unknown"],[128,26,"unknown"],[128,27,"catchable"],[128,28,"catchable"],[128,29,"catchable"],[128,30,"catchable"],[128,31,"catchable"],[128,32,"catchable"],[128,33,"unknown"],[128,34,"unknown"],[128,35,"catchable"],[128,36,"catchable"],[128,37,"unknown"],[128,38,"unknown"],[128,39,"unknown"],[128,40,"unknown"],[128,41,"unknown"],[128,42,"unknown"],[128,43,"unknown"],[128,44,"catchable"],[128,45,"catchable"],[128,46,"unknown"],[128,47,"unknown"],[128,48,"unknown"],[128,49,"unknown"],[128,50,"catchable"],[128,51,"catchable"],[128,53,"unknown"],[129,1,"catchable"],[129,2,"catchable"],[129,3,"catchable"],[129,4,"catchable"],[129,5,"catchable"],[129,6,"catchable"],[129,7,"catchable"],[129,8,"catchable"],[129,9,"catchable"],[129,10,"catchable"],[129,11,"catchable"],[129,12,"catchable"],[129,13,"catchable"],[129,14,"catchable"],[129,15,"catchable"],[129,16,"catchable"],[129,17,"catchable"],[129,18,"catchable"],[129,21,"catchable"],[129,22,"catchable"],[129,23,"catchable"],[129,24,"catchable"],[129,25,"unknown"],[129,26,"unknown"],[129,27,"catchable"],[129,28,"catchable"],[129,29,"catchable"],[129,30,"catchable"],[129,31,"catchable"],[129,32,"catchable"],[129,33,"catchable"],[129,34,"catchable"],[129,35,"catchable"],[129,36,"catchable"],[129,37,"unknown"],[129,38,"unknown"],[129,39,"unknown"],[129,40,"unknown"],[129,41,"unknown"],[129,42,"unknown"],[129,43,"unknown"],[129,44,"catchable"],[129,45,"catchable"],[129,46,"unknown"],[129,47,"unknown"],[129,48,"unknown"],[129,50,"catchable"],[129,51,"catchable"],[129,52,"unknown"],[130,1,"unknown"],[130,2,"unknown"],[130,3,"catchable"],[130,4,"catchable"],[130,5,"catchable"],[130,6,"catchable"],[130,7,"catchable"],[130,8,"catchable"],[130,9,"catchable"],[130,10,"catchable"],[130,11,"catchable"],[130,12,"catchable"],[130,13,"catchable"],[130,14,"catchable"],[130,15,"catchable"],[130,16,"catchable"],[130,17,"unknown"],[130,18,"unknown"],[130,21,"catchable"],[130,22,"catchable"],[130,23,"catchable"],[130,24,"catchable"],[130,25,"unknown"],[130,26,"unknown"],[130,27,"catchable"],[130,28,"catchable"],[130,29,"catchable"],[130,30,"catchable"],[130,31,"catchable"],[130,32,"catchable"],[130,33,"catchable"],[130,34,"catchable"],[130,35,"catchable"],[130,36,"catchable"],[130,37,"unknown"],[130,38,"unknown"],[130,39,"unknown"],[130,40,"unknown"],[130,41,"unknown"],[130,42,"unknown"],[130,43,"unknown"],[130,44,"unknown"],[130,45,"unknown"],[130,46,"unknown"],[130,47,"unknown"],[130,48,"unknown"],[130,49,"unknown"],[130,50,"catchable"],[130,51,"catchable"],[130,52,"unknown"],[131,1,"catchable"],[131,2,"catchable"],[131,3,"catchable"],[131,4,"catchable"],[131,5,"catchable"],[131,6,"catchable"],[131,7,"unknown"],[131,8,"unknown"],[131,9,"unknown"],[131,10,"catchable"],[131,11,"catchable"],[131,12,"catchable"],[131,13,"catchable"],[131,14,"catchable"],[131,15,"catchable"],[131,16,"catchable"],[131,17,"catchable"],[131,18,"catchable"],[131,20,"catchable"],[131,21,"catchable"],[131,22,"catchable"],[131,23,"catchable"],[131,24,"catchable"],[131,25,"unknown"],[131,26,"unknown"],[131,27,"catchable"],[131,28,"catchable"],[131,29,"catchable"],[131,30,"catchable"],[131,31,"catchable"],[131,32,"catchable"],[131,33,"catchable"],[131,34,"catchable"],[131,35,"unknown"],[131,36,"catchable"],[131,37,"unknown"],[131,38,"unknown"],[131,39,"unknown"],[131,40,"unknown"],[131,41,"unknown"],[131,42,"unknown"],[131,43,"unknown"],[131,44,"catchable"],[131,45,"catchable"],[131,46,"unknown"],[131,47,"unknown"],[131,48,"unknown"],[131,51,"catchable"],[131,53,"unknown"],[132,1,"catchable"],[132,2,"catchable"],[132,3,"catchable"],[132,4,"catchable"],[132,5,"catchable"],[132,6,"catchable"],[132,7,"unknown"],[132,8,"unknown"],[132,9,"catchable"],[132,10,"catchable"],[132,11,"catchable"],[132,12,"catchable"],[132,13,"catchable"],[132,14,"catchable"],[132,15,"catchable"],[132,16,"catchable"],[132,17,"catchable"],[132,18,"catchable"],[132,21,"catchable"],[132,22,"catchable"],[132,23,"catchable"],[132,24,"catchable"],[132,25,"catchable"],[132,26,"catchable"],[132,27,"catchable"],[132,28,"catchable"],[132,29,"catchable"],[132,30,"catchable"],[132,31,"catchable"],[132,32,"catchable"],[132,33,"catchable"],[132,34,"catchable"],[132,35,"catchable"],[132,36,"catchable"],[132,37,"unknown"],[132,38,"unknown"],[132,39,"unknown"],[132,40,"unknown"],[132,41,"unknown"],[132,42,"unknown"],[132,43,"unknown"],[132,44,"catchable"],[132,45,"catchable"],[132,46,"unknown"],[132,47,"unknown"],[132,48,"unknown"],[132,49,"unknown"],[132,50,"catchable"],[132,51,"catchable"],[133,1,"catchable"],[133,2,"catchable"],[133,3,"catchable"],[133,4,"catchable"],[133,5,"catchable"],[133,6,"catchable"],[133,7,"unknown"],[133,8,"unknown"],[133,9,"unknown"],[133,10,"catchable"],[133,11,"catchable"],[133,12,"catchable"],[133,13,"catchable"],[133,14,"catchable"],[133,15,"catchable"],[133,16,"catchable"],[133,17,"unknown"],[133,18,"unknown"],[133,20,"catchable"],[133,21,"catchable"],[133,22,"catchable"],[133,23,"catchable"],[133,24,"catchable"],[133,25,"unknown"],[133,26,"unknown"],[133,27,"catchable"],[133,28,"catchable"],[133,29,"catchable"],[133,30,"catchable"],[133,31,"catchable"],[133,32,"catchable"],[133,33,"catchable"],[133,34,"catchable"],[133,35,"unknown"],[133,36,"catchable"],[133,37,"unknown"],[133,38,"unknown"],[133,39,"unknown"],[133,40,"unknown"],[133,41,"unknown"],[133,42,"unknown"],[133,43,"unknown"],[133,44,"catchable"],[133,45,"catchable"],[133,46,"unknown"],[133,47,"unknown"],[133,48,"unknown"],[133,51,"catchable"],[134,1,"unknown"],[134,2,"unknown"],[134,3,"unknown"],[134,4,"unknown"],[134,5,"unknown"],[134,6,"unknown"],[134,7,"unknown"],[134,8,"unknown"],[134,9,"unknown"],[134,10,"unknown"],[134,11,"unknown"],[134,12,"unknown"],[134,13,"unknown"],[134,14,"unknown"],[134,15,"unknown"],[134,16,"unknown"],[134,17,"unknown"],[134,18,"unknown"],[134,21,"unknown"],[134,22,"unknown"],[134,23,"unknown"],[134,24,"unknown"],[134,25,"unknown"],[134,26,"unknown"],[134,27,"unknown"],[134,28,"unknown"],[134,29,"unknown"],[134,30,"unknown"],[134,31,"unknown"],[134,32,"unknown"],[134,33,"catchable"],[134,34,"catchable"],[134,35,"unknown"],[134,36,"catchable"],[134,37,"unknown"],[134,38,"unknown"],[134,39,"unknown"],[134,40,"unknown"],[134,41,"unknown"],[134,42,"unknown"],[134,43,"unknown"],[134,44,"unknown"],[134,45,"unknown"],[134,46,"unknown"],[134,47,"unknown"],[134,48,"unknown"],[134,49,"unknown"],[134,51,"catchable"],[135,1,"unknown"],[135,2,"unknown"],[135,3,"unknown"],[135,4,"unknown"],[135,5,"unknown"],[135,6,"unknown"],[135,7,"unknown"],[135,8,"unknown"],[135,9,"unknown"],[135,10,"unknown"],[135,11,"unknown"],[135,12,"unknown"],[135,13,"unknown"],[135,14,"unknown"],[135,15,"unknown"],[135,16,"unknown"],[135,17,"unknown"],[135,18,"unknown"],[135,21,"unknown"],[135,22,"unknown"],[135,23,"unknown"],[135,24,"unknown"],[135,25,"unknown"],[135,26,"unknown"],[135,27,"unknown"],[135,28,"unknown"],[135,29,"unknown"],[135,30,"unknown"],[135,31,"unknown"],[135,32,"unknown"],[135,33,"catchable"],[135,34,"catchable"],[135,35,"unknown"],[135,36,"catchable"],[135,37,"unknown"],[135,38,"unknown"],[135,39,"unknown"],[135,40,"unknown"],[135,41,"unknown"],[135,42,"unknown"],[135,43,"unknown"],[135,44,"unknown"],[135,45,"unknown"],[135,46,"unknown"],[135,47,"unknown"],[135,48,"unknown"],[135,49,"unknown"],[135,51,"catchable"],[136,1,"unknown"],[136,2,"unknown"],[136,3,"unknown"],[136,4,"unknown"],[136,5,"unknown"],[136,6,"unknown"],[136,7,"unknown"],[136,8,"unknown"],[136,9,"unknown"],[136,10,"unknown"],[136,11,"unknown"],[136,12,"unknown"],[136,13,"unknown"],[136,14,"unknown"],[136,15,"unknown"],[136,16,"unknown"],[136,17,"unknown"],[136,18,"unknown"],[136,21,"unknown"],[136,22,"unknown"],[136,23,"unknown"],[136,24,"unknown"],[136,25,"unknown"],[136,26,"unknown"],[136,27,"unknown"],[136,28,"unknown"],[136,29,"unknown"],[136,30,"unknown"],[136,31,"unknown"],[136,32,"unknown"],[136,33,"catchable"],[136,34,"catchable"],[136,35,"unknown"],[136,36,"catchable"],[136,37,"unknown"],[136,38,"unknown"],[136,39,"unknown"],[136,40,"unknown"],[136,41,"unknown"],[136,42,"unknown"],[136,43,"unknown"],[136,44,"unknown"],[136,45,"unknown"],[136,46,"unknown"],[136,47,"unknown"],[136,48,"unknown"],[136,49,"unknown"],[136,51,"catchable"],[137,1,"catchable"],[137,2,"catchable"],[137,3,"catchable"],[137,4,"catchable"],[137,5,"catchable"],[137,6,"catchable"],[137,7,"unknown"],[137,8,"unknown"],[137,9,"unknown"],[137,10,"catchable"],[137,11,"catchable"],[137,12,"catchable"],[137,13,"catchable"],[137,14,"catchable"],[137,15,"catchable"],[137,16,"catchable"],[137,17,"unknown"],[137,18,"unknown"],[137,21,"unknown"],[137,22,"unknown"],[137,23,"unknown"],[137,24,"unknown"],[137,25,"catchable"],[137,26,"catchable"],[137,27,"catchable"],[137,28,"catchable"],[137,29,"catchable"],[137,30,"catchable"],[137,31,"catchable"],[137,32,"catchable"],[137,33,"unknown"],[137,34,"unknown"],[137,35,"catchable"],[137,36,"catchable"],[137,37,"unknown"],[137,38,"unknown"],[137,39,"unknown"],[137,40,"unknown"],[137,41,"unknown"],[137,42,"unknown"],[137,43,"unknown"],[137,44,"catchable"],[137,45,"catchable"],[137,46,"catchable"],[137,47,"unknown"],[137,48,"unknown"],[137,50,"catchable"],[137,51,"catchable"],[137,53,"unknown"],[138,1,"catchable"],[138,2,"catchable"],[138,3,"catchable"],[138,4,"unknown"],[138,5,"unknown"],[138,6,"unknown"],[138,7,"unknown"],[138,8,"unknown"],[138,9,"unknown"],[138,10,"catchable"],[138,11,"catchable"],[138,12,"catchable"],[138,13,"catchable"],[138,14,"catchable"],[138,15,"catchable"],[138,16,"catchable"],[138,17,"catchable"],[138,18,"catchable"],[138,21,"catchable"],[138,22,"catchable"],[138,23,"unknown"],[138,24,"unknown"],[138,25,"unknown"],[138,26,"unknown"],[138,27,"unknown"],[138,28,"unknown"],[138,29,"catchable"],[138,30,"catchable"],[138,31,"catchable"],[138,32,"catchable"],[138,33,"unknown"],[138,34,"unknown"],[138,35,"unknown"],[138,36,"catchable"],[138,37,"unknown"],[138,38,"unknown"],[138,39,"unknown"],[138,44,"catchable"],[138,45,"catchable"],[138,46,"unknown"],[138,51,"unknown"],[139,1,"unknown"],[139,2,"unknown"],[139,3,"unknown"],[139,4,"unknown"],[139,5,"unknown"],[139,6,"unknown"],[139,7,"unknown"],[139,8,"unknown"],[139,9,"unknown"],[139,10,"unknown"],[139,11,"unknown"],[139,12,"unknown"],[139,13,"unknown"],[139,14,"unknown"],[139,15,"unknown"],[139,16,"unknown"],[139,17,"unknown"],[139,18,"unknown"],[139,21,"unknown"],[139,22,"unknown"],[139,23,"unknown"],[139,24,"unknown"],[139,25,"unknown"],[139,26,"unknown"],[139,27,"unknown"],[139,28,"unknown"],[139,29,"unknown"],[139,30,"unknown"],[139,31,"unknown"],[139,32,"unknown"],[139,33,"unknown"],[139,34,"unknown"],[139,35,"unknown"],[139,36,"catchable"],[139,37,"unknown"],[139,38,"unknown"],[139,39,"unknown"],[139,44,"unknown"],[139,45,"unknown"],[139,46,"unknown"],[139,51,"unknown"],[140,1,"catchable"],[140,2,"catchable"],[140,3,"catchable"],[140,4,"unknown"],[140,5,"unknown"],[140,6,"unknown"],[140,7,"unknown"],[140,8,"unknown"],[140,9,"unknown"],[140,10,"catchable"],[140,11,"catchable"],[140,12,"catchable"],[140,13,"catchable"],[140,14,"catchable"],[140,15,"catchable"],[140,16,"catchable"],[140,17,"catchable"],[140,18,"catchable"],[140,21,"catchable"],[140,22,"catchable"],[140,23,"unknown"],[140,24,"unknown"],[140,25,"unknown"],[140,26,"unknown"],[140,27,"unknown"],[140,28,"unknown"],[140,29,"catchable"],[140,30,"catchable"],[140,31,"catchable"],[140,32,"catchable"],[140,33,"unknown"],[140,34,"unknown"],[140,35,"unknown"],[140,36,"unknown"],[140,37,"unknown"],[140,38,"unknown"],[140,39,"unknown"],[140,44,"catchable"],[140,45,"catchable"],[140,46,"unknown"],[140,51,"catchable"],[141,1,"unknown"],[141,2,"unknown"],[141,3,"unknown"],[141,4,"unknown"],[141,5,"unknown"],[141,6,"unknown"],[141,7,"unknown"],[141,8,"unknown"],[141,9,"unknown"],[141,10,"unknown"],[141,11,"unknown"],[141,12,"unknown"],[141,13,"unknown"],[141,14,"unknown"],[141,15,"unknown"],[141,16,"unknown"],[141,17,"unknown"],[141,18,"unknown"],[141,21,"unknown"],[141,22,"unknown"],[141,23,"unknown"],[141,24,"unknown"],[141,25,"unknown"],[141,26,"unknown"],[141,27,"unknown"],[141,28,"unknown"],[141,29,"unknown"],[141,30,"unknown"],[141,31,"unknown"],[141,32,"unknown"],[141,33,"unknown"],[141,34,"unknown"],[141,35,"unknown"],[141,36,"unknown"],[141,37,"unknown"],[141,38,"unknown"],[141,39,"unknown"],[141,44,"unknown"],[141,45,"unknown"],[141,46,"unknown"],[141,51,"catchable"],[142,1,"catchable"],[142,2,"catchable"],[142,3,"catchable"],[142,4,"catchable"],[142,5,"catchable"],[142,6,"catchable"],[142,7,"unknown"],[142,8,"unknown"],[142,9,"unknown"],[142,10,"catchable"],[142,11,"catchable"],[142,12,"catchable"],[142,13,"catchable"],[142,14,"catchable"],[142,15,"catchable"],[142,16,"catchable"],[142,17,"catchable"],[142,18,"catchable"],[142,21,"catchable"],[142,22,"catchable"],[142,23,"unknown"],[142,24,"unknown"],[142,25,"unknown"],[142,26,"unknown"],[142,27,"catchable"],[142,28,"catchable"],[142,29,"catchable"],[142,30,"catchable"],[142,31,"catchable"],[142,32,"catchable"],[142,33,"unknown"],[142,34,"unknown"],[142,35,"unknown"],[142,36,"catchable"],[142,37,"unknown"],[142,38,"unknown"],[142,39,"unknown"],[142,44,"catchable"],[142,45,"catchable"],[142,46,"unknown"],[142,47,"unknown"],[142,49,"unknown"],[142,51,"catchable"],[143,1,"catchable"],[143,2,"catchable"],[143,3,"catchable"],[143,4,"catchable"],[143,5,"catchable"],[143,6,"catchable"],[143,7,"unknown"],[143,8,"unknown"],[143,9,"unknown"],[143,10,"catchable"],[143,11,"catchable"],[143,12,"unknown"],[143,13,"unknown"],[143,14,"unknown"],[143,15,"catchable"],[143,16,"catchable"],[143,17,"unknown"],[143,18,"unknown"],[143,20,"catchable"],[143,21,"unknown"],[143,22,"unknown"],[143,23,"catchable"],[143,24,"catchable"],[143,25,"unknown"],[143,26,"unknown"],[143,27,"catchable"],[143,28,"catchable"],[143,29,"unknown"],[143,30,"unknown"],[143,31,"catchable"],[143,32,"catchable"],[143,33,"catchable"],[143,34,"catchable"],[143,35,"unknown"],[143,36,"catchable"],[143,37,"unknown"],[143,38,"unknown"],[143,39,"unknown"],[143,40,"unknown"],[143,41,"unknown"],[143,42,"unknown"],[143,43,"unknown"],[143,44,"catchable"],[143,45,"catchable"],[143,46,"unknown"],[143,47,"unknown"],[143,48,"unknown"],[143,49,"unknown"],[143,51,"catchable"],[143,52,"unknown"],[144,1,"catchable"],[144,2,"catchable"],[144,3,"catchable"],[144,4,"unknown"],[144,5,"unknown"],[144,6,"unknown"],[144,7,"unknown"],[144,8,"unknown"],[144,9,"unknown"],[144,10,"catchable"],[144,11,"catchable"],[144,12,"unknown"],[144,13,"unknown"],[144,14,"catchable"],[144,15,"catchable"],[144,16,"catchable"],[144,17,"unknown"],[144,18,"unknown"],[144,20,"catchable"],[144,21,"unknown"],[144,22,"unknown"],[144,23,"catchable"],[144,24,"catchable"],[144,25,"unknown"],[144,26,"unknown"],[144,27,"unknown"],[144,28,"unknown"],[144,29,"catchable"],[144,30,"catchable"],[144,31,"catchable"],[144,32,"catchable"],[144,33,"unknown"],[144,34,"unknown"],[144,35,"unknown"],[144,36,"catchable"],[144,37,"unknown"],[144,38,"unknown"],[144,39,"unknown"],[144,40,"unknown"],[144,41,"unknown"],[144,42,"unknown"],[144,43,"unknown"],[144,44,"catchable"],[144,45,"catchable"],[144,46,"unknown"],[144,47,"unknown"],[144,48,"unknown"],[144,51,"catchable"],[145,1,"catchable"],[145,2,"catchable"],[145,3,"catchable"],[145,4,"unknown"],[145,5,"unknown"],[145,6,"unknown"],[145,7,"unknown"],[145,8,"unknown"],[145,9,"unknown"],[145,10,"catchable"],[145,11,"catchable"],[145,12,"unknown"],[145,13,"unknown"],[145,14,"catchable"],[145,15,"catchable"],[145,16,"catchable"],[145,17,"unknown"],[145,18,"unknown"],[145,20,"catchable"],[145,21,"unknown"],[145,22,"unknown"],[145,23,"catchable"],[145,24,"catchable"],[145,25,"unknown"],[145,26,"unknown"],[145,27,"unknown"],[145,28,"unknown"],[145,29,"catchable"],[145,30,"catchable"],[145,31,"catchable"],[145,32,"catchable"],[145,33,"unknown"],[145,34,"unknown"],[145,35,"unknown"],[145,36,"catchable"],[145,37,"unknown"],[145,38,"unknown"],[145,39,"unknown"],[145,40,"unknown"],[145,41,"unknown"],[145,42,"unknown"],[145,43,"unknown"],[145,44,"catchable"],[145,45,"catchable"],[145,46,"unknown"],[145,47,"unknown"],[145,48,"unknown"],[145,51,"catchable"],[146,1,"catchable"],[146,2,"catchable"],[146,3,"catchable"],[146,4,"unknown"],[146,5,"unknown"],[146,6,"unknown"],[146,7,"unknown"],[146,8,"unknown"],[146,9,"unknown"],[146,10,"catchable"],[146,11,"catchable"],[146,12,"unknown"],[146,13,"unknown"],[146,14,"catchable"],[146,15,"catchable"],[146,16,"catchable"],[146,17,"unknown"],[146,18,"unknown"],[146,20,"catchable"],[146,21,"unknown"],[146,22,"unknown"],[146,23,"catchable"],[146,24,"catchable"],[146,25,"unknown"],[146,26,"unknown"],[146,27,"unknown"],[146,28,"unknown"],[146,29,"catchable"],[146,30,"catchable"],[146,31,"catchable"],[146,32,"catchable"],[146,33,"unknown"],[146,34,"unknown"],[146,35,"unknown"],[146,36,"catchable"],[146,37,"unknown"],[146,38,"unknown"],[146,39,"unknown"],[146,40,"unknown"],[146,41,"unknown"],[146,42,"unknown"],[146,43,"unknown"],[146,44,"catchable"],[146,45,"catchable"],[146,46,"unknown"],[146,47,"unknown"],[146,48,"unknown"],[146,51,"catchable"],[147,1,"catchable"],[147,2,"catchable"],[147,3,"catchable"],[147,4,"catchable"],[147,5,"catchable"],[147,6,"catchable"],[147,7,"unknown"],[147,8,"unknown"],[147,9,"unknown"],[147,10,"catchable"],[147,11,"catchable"],[147,12,"catchable"],[147,13,"catchable"],[147,14,"catchable"],[147,15,"catchable"],[147,16,"catchable"],[147,17,"catchable"],[147,18,"catchable"],[147,21,"catchable"],[147,22,"catchable"],[147,23,"catchable"],[147,24,"catchable"],[147,25,"unknown"],[147,26,"unknown"],[147,27,"catchable"],[147,28,"catchable"],[147,29,"catchable"],[147,30,"catchable"],[147,31,"catchable"],[147,32,"catchable"],[147,33,"unknown"],[147,34,"unknown"],[147,35,"unknown"],[147,36,"catchable"],[147,37,"unknown"],[147,38,"unknown"],[147,39,"unknown"],[147,40,"unknown"],[147,41,"unknown"],[147,42,"unknown"],[147,43,"unknown"],[147,44,"catchable"],[147,45,"catchable"],[147,46,"unknown"],[147,47,"unknown"],[147,48,"unknown"],[147,51,"catchable"],[148,1,"unknown"],[148,2,"unknown"],[148,3,"catchable"],[148,4,"catchable"],[148,5,"catchable"],[148,6,"catchable"],[148,7,"unknown"],[148,8,"unknown"],[148,9,"unknown"],[148,10,"catchable"],[148,11,"catchable"],[148,12,"catchable"],[148,13,"catchable"],[148,14,"catchable"],[148,15,"catchable"],[148,16,"catchable"],[148,17,"catchable"],[148,18,"catchable"],[148,21,"catchable"],[148,22,"catchable"],[148,23,"catchable"],[148,24,"catchable"],[148,25,"unknown"],[148,26,"unknown"],[148,27,"catchable"],[148,28,"catchable"],[148,29,"catchable"],[148,30,"catchable"],[148,31,"catchable"],[148,32,"catchable"],[148,33,"unknown"],[148,34,"unknown"],[148,35,"unknown"],[148,36,"catchable"],[148,37,"unknown"],[148,38,"unknown"],[148,39,"unknown"],[148,40,"unknown"],[148,41,"unknown"],[148,42,"unknown"],[148,43,"unknown"],[148,44,"unknown"],[148,45,"unknown"],[148,46,"catchable"],[148,47,"unknown"],[148,48,"unknown"],[148,51,"catchable"],[149,1,"unknown"],[149,2,"unknown"],[149,3,"unknown"],[149,4,"unknown"],[149,5,"unknown"],[149,6,"unknown"],[149,7,"unknown"],[149,8,"unknown"],[149,9,"unknown"],[149,10,"unknown"],[149,11,"unknown"],[149,12,"unknown"],[149,13,"unknown"],[149,14,"unknown"],[149,15,"unknown"],[149,16,"unknown"],[149,17,"catchable"],[149,18,"catchable"],[149,20,"catchable"],[149,21,"catchable"],[149,22,"catchable"],[149,23,"unknown"],[149,24,"unknown"],[149,25,"unknown"],[149,26,"unknown"],[149,27,"catchable"],[149,28,"catchable"],[149,29,"catchable"],[149,30,"catchable"],[149,31,"catchable"],[149,32,"catchable"],[149,33,"unknown"],[149,34,"unknown"],[149,35,"unknown"],[149,36,"catchable"],[149,37,"unknown"],[149,38,"unknown"],[149,39,"unknown"],[149,40,"unknown"],[149,41,"unknown"],[149,42,"unknown"],[149,43,"unknown"],[149,44,"unknown"],[149,45,"unknown"],[149,46,"unknown"],[149,47,"unknown"],[149,48,"unknown"],[149,49,"unknown"],[149,51,"catchable"],[150,1,"catchable"],[150,2,"catchable"],[150,3,"catchable"],[150,4,"unknown"],[150,5,"unknown"],[150,6,"unknown"],[150,7,"unknown"],[150,8,"unknown"],[150,9,"unknown"],[150,10,"catchable"],[150,11,"catchable"],[150,12,"unknown"],[150,13,"unknown"],[150,14,"unknown"],[150,15,"catchable"],[150,16,"catchable"],[150,17,"unknown"],[150,18,"unknown"],[150,21,"unknown"],[150,22,"unknown"],[150,23,"catchable"],[150,24,"catchable"],[150,25,"unknown"],[150,26,"unknown"],[150,27,"unknown"],[150,28,"unknown"],[150,29,"catchable"],[150,30,"catchable"],[150,31,"catchable"],[150,32,"catchable"],[150,33,"unknown"],[150,34,"unknown"],[150,35,"unknown"],[150,36,"catchable"],[150,37,"unknown"],[150,38,"unknown"],[150,39,"unknown"],[150,40,"unknown"],[150,41,"unknown"],[150,42,"unknown"],[150,43,"unknown"],[150,44,"catchable"],[150,45,"catchable"],[150,46,"unknown"],[150,47,"unknown"],[150,48,"unknown"],[150,51,"catchable"],[151,1,"unknown"],[151,2,"unknown"],[151,3,"unknown"],[151,4,"unknown"],[151,5,"unknown"],[151,6,"unknown"],[151,7,"unknown"],[151,8,"unknown"],[151,9,"catchable"],[151,10,"unknown"],[151,11,"unknown"],[151,12,"unknown"],[151,13,"unknown"],[151,14,"unknown"],[151,15,"unknown"],[151,16,"unknown"],[151,17,"unknown"],[151,18,"unknown"],[151,21,"unknown"],[151,22,"unknown"],[151,23,"unknown"],[151,24,"unknown"],[151,25,"unknown"],[151,26,"unknown"],[151,27,"unknown"],[151,28,"unknown"],[151,29,"unknown"],[151,30,"unknown"],[151,31,"unknown"],[151,32,"unknown"],[151,33,"unknown"],[151,34,"unknown"],[151,35,"unknown"],[151,36,"unknown"],[151,37,"unknown"],[151,38,"unknown"],[151,39,"unknown"],[151,40,"unknown"],[151,41,"unknown"],[151,42,"unknown"],[151,43,"unknown"],[151,44,"unknown"],[151,45,"unknown"],[151,46,"unknown"],[151,47,"unknown"],[151,48,"unknown"],[152,4,"catchable"],[152,5,"catchable"],[152,6,"catchable"],[152,7,"unknown"],[152,8,"unknown"],[152,9,"catchable"],[152,10,"unknown"],[152,11,"unknown"],[152,12,"unknown"],[152,13,"unknown"],[152,14,"unknown"],[152,15,"catchable"],[152,16,"catchable"],[152,17,"unknown"],[152,18,"unknown"],[152,20,"catchable"],[152,21,"unknown"],[152,22,"unknown"],[152,23,"unknown"],[152,24,"unknown"],[152,25,"catchable"],[152,26,"catchable"],[152,27,"catchable"],[152,28,"catchable"],[152,29,"unknown"],[152,30,"unknown"],[152,31,"unknown"],[152,32,"unknown"],[152,40,"unknown"],[152,41,"unknown"],[152,42,"unknown"],[152,43,"unknown"],[152,47,"unknown"],[152,48,"unknown"],[152,53,"unknown"],[153,4,"unknown"],[153,5,"unknown"],[153,6,"unknown"],[153,7,"unknown"],[153,8,"unknown"],[153,9,"unknown"],[153,10,"unknown"],[153,11,"unknown"],[153,12,"unknown"],[153,13,"unknown"],[153,14,"unknown"],[153,15,"unknown"],[153,16,"unknown"],[153,17,"unknown"],[153,18,"unknown"],[153,19,"catchable"],[153,21,"unknown"],[153,22,"unknown"],[153,23,"unknown"],[153,24,"unknown"],[153,25,"unknown"],[153,26,"unknown"],[153,27,"unknown"],[153,28,"unknown"],[153,29,"unknown"],[153,30,"unknown"],[153,31,"unknown"],[153,32,"unknown"],[153,40,"unknown"],[153,41,"unknown"],[153,42,"unknown"],[153,43,"unknown"],[153,47,"unknown"],[153,48,"unknown"],[153,53,"unknown"],[154,4,"unknown"],[154,5,"unknown"],[154,6,"unknown"],[154,7,"unknown"],[154,8,"unknown"],[154,9,"unknown"],[154,10,"unknown"],[154,11,"unknown"],[154,12,"unknown"],[154,13,"unknown"],[154,14,"unknown"],[154,15,"unknown"],[154,16,"unknown"],[154,17,"unknown"],[154,18,"unknown"],[154,21,"unknown"],[154,22,"unknown"],[154,23,"unknown"],[154,24,"unknown"],[154,25,"unknown"],[154,26,"unknown"],[154,27,"unknown"],[154,28,"unknown"],[154,29,"unknown"],[154,30,"unknown"],[154,31,"unknown"],[154,32,"unknown"],[154,40,"unknown"],[154,41,"unknown"],[154,42,"unknown"],[154,43,"unknown"],[154,47,"unknown"],[154,48,"unknown"],[154,49,"unknown"],[154,53,"unknown"],[155,4,"catchable"],[155,5,"catchable"],[155,6,"catchable"],[155,7,"unknown"],[155,8,"unknown"],[155,9,"catchable"],[155,10,"unknown"],[155,11,"unknown"],[155,12,"unknown"],[155,13,"unknown"],[155,14,"unknown"],[155,15,"catchable"],[155,16,"catchable"],[155,17,"unknown"],[155,18,"unknown"],[155,20,"catchable"],[155,21,"unknown"],[155,22,"unknown"],[155,23,"unknown"],[155,24,"unknown"],[155,25,"catchable"],[155,26,"catchable"],[155,27,"catchable"],[155,28,"catchable"],[155,29,"unknown"],[155,30,"unknown"],[155,31,"unknown"],[155,32,"unknown"],[155,39,"unknown"],[155,40,"unknown"],[155,41,"unknown"],[155,42,"unknown"],[155,43,"unknown"],[155,47,"unknown"],[155,48,"unknown"],[155,53,"unknown"],[156,4,"unknown"],[156,5,"unknown"],[156,6,"unknown"],[156,7,"unknown"],[156,8,"unknown"],[156,9,"unknown"],[156,10,"unknown"],[156,11,"unknown"],[156,12,"unknown"],[156,13,"unknown"],[156,14,"unknown"],[156,15,"unknown"],[156,16,"unknown"],[156,17,"unknown"],[156,18,"unknown"],[156,19,"catchable"],[156,21,"unknown"],[156,22,"unknown"],[156,23,"unknown"],[156,24,"unknown"],[156,25,"unknown"],[156,26,"unknown"],[156,27,"unknown"],[156,28,"unknown"],[156,29,"unknown"],[156,30,"unknown"],[156,31,"unknown"],[156,32,"unknown"],[156,39,"unknown"],[156,40,"unknown"],[156,41,"unknown"],[156,42,"unknown"],[156,43,"unknown"],[156,47,"unknown"],[156,48,"unknown"],[156,53,"unknown"],[157,4,"unknown"],[157,5,"unknown"],[157,6,"unknown"],[157,7,"unknown"],[157,8,"unknown"],[157,9,"unknown"],[157,10,"unknown"],[157,11,"unknown"],[157,12,"unknown"],[157,13,"unknown"],[157,14,"unknown"],[157,15,"unknown"],[157,16,"unknown"],[157,17,"unknown"],[157,18,"unknown"],[157,21,"unknown"],[157,22,"unknown"],[157,23,"unknown"],[157,24,"unknown"],[157,25,"unknown"],[157,26,"unknown"],[157,27,"unknown"],[157,28,"unknown"],[157,29,"unknown"],[157,30,"unknown"],[157,31,"unknown"],[157,32,"unknown"],[157,39,"unknown"],[157,40,"unknown"],[157,41,"unknown"],[157,42,"unknown"],[157,43,"unknown"],[157,47,"unknown"],[157,48,"unknown"],[157,49,"unknown"],[157,53,"unknown"],[158,4,"catchable"],[158,5,"catchable"],[158,6,"catchable"],[158,7,"unknown"],[158,8,"unknown"],[158,9,"catchable"],[158,10,"unknown"],[158,11,"unknown"],[158,12,"unknown"],[158,13,"unknown"],[158,14,"unknown"],[158,15,"catchable"],[158,16,"catchable"],[158,17,"unknown"],[158,18,"unknown"],[158,20,"catchable"],[158,21,"unknown"],[158,22,"unknown"],[158,23,"unknown"],[158,24,"unknown"],[158,25,"catchable"],[158,26,"catchable"],[158,27,"catchable"],[158,28,"catchable"],[158,29,"unknown"],[158,30,"unknown"],[158,31,"unknown"],[158,32,"unknown"],[158,40,"unknown"],[158,41,"unknown"],[158,42,"unknown"],[158,43,"unknown"],[158,47,"unknown"],[158,48,"unknown"],[158,53,"unknown"],[159,4,"unknown"],[159,5,"unknown"],[159,6,"unknown"],[159,7,"unknown"],[159,8,"unknown"],[159,9,"unknown"],[159,10,"unknown"],[159,11,"unknown"],[159,12,"unknown"],[159,13,"unknown"],[159,14,"unknown"],[159,15,"unknown"],[159,16,"unknown"],[159,17,"unknown"],[159,18,"unknown"],[159,19,"catchable"],[159,21,"unknown"],[159,22,"unknown"],[159,23,"unknown"],[159,24,"unknown"],[159,25,"unknown"],[159,26,"unknown"],[159,27,"unknown"],[159,28,"unknown"],[159,29,"unknown"],[159,30,"unknown"],[159,31,"unknown"],[159,32,"unknown"],[159,40,"unknown"],[159,41,"unknown"],[159,42,"unknown"],[159,43,"unknown"],[159,47,"unknown"],[159,48,"unknown"],[159,53,"unknown"],[160,4,"unknown"],[160,5,"unknown"],[160,6,"unknown"],[160,7,"unknown"],[160,8,"unknown"],[160,9,"unknown"],[160,10,"unknown"],[160,11,"unknown"],[160,12,"unknown"],[160,13,"unknown"],[160,14,"unknown"],[160,15,"unknown"],[160,16,"unknown"],[160,17,"unknown"],[160,18,"unknown"],[160,21,"unknown"],[160,22,"unknown"],[160,23,"unknown"],[160,24,"unknown"],[160,25,"unknown"],[160,26,"unknown"],[160,27,"unknown"],[160,28,"unknown"],[160,29,"unknown"],[160,30,"unknown"],[160,31,"unknown"],[160,32,"unknown"],[160,40,"unknown"],[160,41,"unknown"],[160,42,"unknown"],[160,43,"unknown"],[160,47,"unknown"],[160,48,"unknown"],[160,49,"unknown"],[160,53,"unknown"],[161,4,"catchable"],[161,5,"catchable"],[161,6,"catchable"],[161,7,"unknown"],[161,8,"unknown"],[161,9,"unknown"],[161,10,"catchable"],[161,11,"catchable"],[161,12,"catchable"],[161,13,"catchable"],[161,14,"catchable"],[161,15,"catchable"],[161,16,"catchable"],[161,17,"unknown"],[161,18,"unknown"],[161,21,"unknown"],[161,22,"unknown"],[161,23,"catchable"],[161,24,"catchable"],[161,25,"unknown"],[161,26,"unknown"],[161,27,"unknown"],[161,28,"unknown"],[161,29,"unknown"],[161,30,"unknown"],[161,31,"unknown"],[161,32,"unknown"],[161,40,"unknown"],[161,41,"unknown"],[161,42,"unknown"],[161,43,"unknown"],[161,47,"unknown"],[161,48,"unknown"],[161,52,"unknown"],[162,4,"catchable"],[162,5,"catchable"],[162,6,"catchable"],[162,7,"unknown"],[162,8,"unknown"],[162,9,"unknown"],[162,10,"unknown"],[162,11,"unknown"],[162,12,"unknown"],[162,13,"unknown"],[162,14,"unknown"],[162,15,"catchable"],[162,16,"catchable"],[162,17,"unknown"],[162,18,"unknown"],[162,19,"catchable"],[162,21,"unknown"],[162,22,"unknown"],[162,23,"unknown"],[162,24,"unknown"],[162,25,"unknown"],[162,26,"unknown"],[162,27,"unknown"],[162,28,"unknown"],[162,29,"unknown"],[162,30,"unknown"],[162,31,"unknown"],[162,32,"unknown"],[162,40,"unknown"],[162,41,"unknown"],[162,42,"unknown"],[162,43,"unknown"],[162,47,"unknown"],[162,48,"unknown"],[162,52,"unknown"],[163,4,"catchable"],[163,5,"catchable"],[163,6,"catchable"],[163,7,"unknown"],[163,8,"unknown"],[163,9,"catchable"],[163,10,"unknown"],[163,11,"unknown"],[163,12,"catchable"],[163,13,"catchable"],[163,14,"catchable"],[163,15,"catchable"],[163,16,"catchable"],[163,17,"unknown"],[163,18,"unknown"],[163,21,"unknown"],[163,22,"unknown"],[163,23,"catchable"],[163,24,"catchable"],[163,25,"unknown"],[163,26,"unknown"],[163,27,"unknown"],[163,28,"unknown"],[163,29,"catchable"],[163,30,"catchable"],[163,31,"unknown"],[163,32,"unknown"],[163,33,"catchable"],[163,34,"catchable"],[163,35,"catchable"],[163,36,"unknown"],[163,37,"unknown"],[163,38,"unknown"],[163,39,"unknown"],[163,40,"unknown"],[163,41,"unknown"],[163,42,"unknown"],[163,43,"unknown"],[163,47,"unknown"],[163,48,"unknown"],[163,50,"catchable"],[163,52,"unknown"],[164,4,"catchable"],[164,5,"catchable"],[164,6,"catchable"],[164,7,"unknown"],[164,8,"unknown"],[164,9,"unknown"],[164,10,"unknown"],[164,11,"unknown"],[164,12,"catchable"],[164,13,"catchable"],[164,14,"catchable"],[164,15,"catchable"],[164,16,"catchable"],[164,17,"catchable"],[164,18,"catchable"],[164,19,"catchable"],[164,21,"catchable"],[164,22,"catchable"],[164,23,"catchable"],[164,24,"catchable"],[164,25,"unknown"],[164,26,"unknown"],[164,27,"unknown"],[164,28,"unknown"],[164,29,"catchable"],[164,30,"catchable"],[164,31,"unknown"],[164,32,"unknown"],[164,33,"catchable"],[164,34,"catchable"],[164,35,"catchable"],[164,36,"catchable"],[164,37,"unknown"],[164,38,"unknown"],[164,39,"unknown"],[164,40,"unknown"],[164,41,"unknown"],[164,42,"unknown"],[164,43,"unknown"],[164,47,"unknown"],[164,48,"unknown"],[164,50,"catchable"],[164,51,"catchable"],[164,52,"unknown"],[165,4,"unknown"],[165,5,"catchable"],[165,6,"catchable"],[165,7,"unknown"],[165,8,"unknown"],[165,9,"catchable"],[165,10,"catchable"],[165,11,"catchable"],[165,12,"unknown"],[165,13,"unknown"],[165,14,"unknown"],[165,15,"unknown"],[165,16,"catchable"],[165,17,"unknown"],[165,18,"unknown"],[165,20,"catchable"],[165,21,"unknown"],[165,22,"unknown"],[165,23,"catchable"],[165,24,"catchable"],[165,25,"unknown"],[165,26,"unknown"],[165,27,"catchable"],[165,28,"catchable"],[165,29,"catchable"],[165,30,"catchable"],[165,31,"unknown"],[165,32,"unknown"],[166,4,"unknown"],[166,5,"catchable"],[166,6,"catchable"],[166,7,"unknown"],[166,8,"unknown"],[166,9,"unknown"],[166,10,"unknown"],[166,11,"unknown"],[166,12,"catchable"],[166,13,"catchable"],[166,14,"catchable"],[166,15,"unknown"],[166,16,"catchable"],[166,17,"catchable"],[166,18,"catchable"],[166,19,"catchable"],[166,21,"unknown"],[166,22,"unknown"],[166,23,"unknown"],[166,24,"unknown"],[166,25,"unknown"],[166,26,"unknown"],[166,27,"catchable"],[166,28,"catchable"],[166,29,"catchable"],[166,30,"catchable"],[166,31,"unknown"],[166,32,"unknown"],[167,4,"catchable"],[167,5,"unknown"],[167,6,"catchable"],[167,7,"unknown"],[167,8,"unknown"],[167,9,"catchable"],[167,10,"catchable"],[167,11,"catchable"],[167,12,"unknown"],[167,13,"unknown"],[167,14,"unknown"],[167,15,"catchable"],[167,16,"unknown"],[167,17,"unknown"],[167,18,"unknown"],[167,20,"catchable"],[167,21,"unknown"],[167,22,"unknown"],[167,23,"unknown"],[167,24,"unknown"],[167,25,"unknown"],[167,26,"unknown"],[167,27,"catchable"],[167,28,"catchable"],[167,29,"catchable"],[167,30,"catchable"],[167,31,"unknown"],[167,32,"unknown"],[167,40,"unknown"],[167,41,"unknown"],[167,42,"unknown"],[167,43,"unknown"],[167,47,"unknown"],[167,48,"unknown"],[167,52,"unknown"],[168,4,"catchable"],[168,5,"unknown"],[168,6,"catchable"],[168,7,"unknown"],[168,8,"unknown"],[168,9,"unknown"],[168,10,"unknown"],[168,11,"unknown"],[168,12,"catchable"],[168,13,"catchable"],[168,14,"catchable"],[168,15,"catchable"],[168,16,"unknown"],[168,17,"catchable"],[168,18,"catchable"],[168,19,"catchable"],[168,21,"unknown"],[168,22,"unknown"],[168,23,"catchable"],[168,24,"catchable"],[168,25,"catchable"],[168,26,"catchable"],[168,27,"catchable"],[168,28,"catchable"],[168,29,"catchable"],[168,30,"catchable"],[168,31,"unknown"],[168,32,"unknown"],[168,40,"unknown"],[168,41,"unknown"],[168,42,"unknown"],[168,43,"unknown"],[168,47,"unknown"],[168,48,"unknown"],[168,49,"unknown"],[168,52,"unknown"],[169,4,"unknown"],[169,5,"unknown"],[169,6,"unknown"],[169,7,"unknown"],[169,8,"unknown"],[169,9,"unknown"],[169,10,"unknown"],[169,11,"unknown"],[169,12,"unknown"],[169,13,"unknown"],[169,14,"unknown"],[169,15,"unknown"],[169,16,"unknown"],[169,17,"catchable"],[169,18,"catchable"],[169,21,"catchable"],[169,22,"catchable"],[169,23,"unknown"],[169,24,"unknown"],[169,25,"unknown"],[169,26,"unknown"],[169,27,"catchable"],[169,28,"catchable"],[169,29,"catchable"],[169,30,"catchable"],[169,31,"unknown"],[169,32,"unknown"],[169,33,"unknown"],[169,34,"unknown"],[169,35,"unknown"],[169,36,"catchable"],[169,37,"unknown"],[169,38,"unknown"],[169,39,"unknown"],[169,47,"unknown"],[169,48,"unknown"],[169,51,"catchable"],[170,4,"catchable"],[170,5,"catchable"],[170,6,"catchable"],[170,7,"catchable"],[170,8,"catchable"],[170,9,"catchable"],[170,10,"unknown"],[170,11,"unknown"],[170,12,"catchable"],[170,13,"catchable"],[170,14,"catchable"],[170,15,"catchable"],[170,16,"catchable"],[170,17,"catchable"],[170,18,"catchable"],[170,21,"catchable"],[170,22,"catchable"],[170,23,"catchable"],[170,24,"catchable"],[170,25,"unknown"],[170,26,"unknown"],[170,27,"catchable"],[170,28,"catchable"],[170,29,"catchable"],[170,30,"catchable"],[170,31,"unknown"],[170,32,"unknown"],[170,33,"catchable"],[170,34,"catchable"],[170,35,"catchable"],[170,36,"unknown"],[170,37,"unknown"],[170,38,"unknown"],[170,39,"unknown"],[170,40,"unknown"],[170,41,"unknown"],[170,42,"unknown"],[170,43,"unknown"],[170,47,"unknown"],[170,48,"unknown"],[170,50,"catchable"],[170,53,"unknown"],[171,4,"catchable"],[171,5,"catchable"],[171,6,"catchable"],[171,7,"unknown"],[171,8,"unknown"],[171,9,"unknown"],[171,10,"unknown"],[171,11,"unknown"],[171,12,"catchable"],[171,13,"catchable"],[171,14,"unknown"],[171,15,"catchable"],[171,16,"catchable"],[171,17,"catchable"],[171,18,"catchable"],[171,21,"catchable"],[171,22,"catchable"],[171,23,"catchable"],[171,24,"catchable"],[171,25,"unknown"],[171,26,"unknown"],[171,27,"unknown"],[171,28,"unknown"],[171,29,"catchable"],[171,30,"catchable"],[171,31,"unknown"],[171,32,"unknown"],[171,33,"catchable"],[171,34,"catchable"],[171,35,"catchable"],[171,36,"catchable"],[171,37,"unknown"],[171,38,"unknown"],[171,39,"unknown"],[171,40,"unknown"],[171,41,"unknown"],[171,42,"unknown"],[171,43,"unknown"],[171,47,"unknown"],[171,48,"unknown"],[171,50,"catchable"],[171,51,"catchable"],[171,53,"unknown"],[172,4,"unknown"],[172,5,"unknown"],[172,6,"catchable"],[172,7,"unknown"],[172,8,"unknown"],[172,9,"unknown"],[172,10,"unknown"],[172,11,"unknown"],[172,12,"catchable"],[172,13,"catchable"],[172,14,"catchable"],[172,15,"unknown"],[172,16,"unknown"],[172,17,"unknown"],[172,18,"unknown"],[172,21,"unknown"],[172,22,"unknown"],[172,23,"unknown"],[172,24,"unknown"],[172,25,"unknown"],[172,26,"unknown"],[172,27,"catchable"],[172,28,"catchable"],[172,29,"catchable"],[172,30,"catchable"],[172,31,"unknown"],[172,32,"unknown"],[172,33,"catchable"],[172,34,"catchable"],[172,35,"catchable"],[172,36,"unknown"],[172,37,"unknown"],[172,38,"unknown"],[172,39,"unknown"],[172,40,"unknown"],[172,41,"unknown"],[172,42,"unknown"],[172,43,"unknown"],[172,47,"unknown"],[172,48,"unknown"],[172,50,"catchable"],[172,52,"unknown"],[173,4,"unknown"],[173,5,"unknown"],[173,6,"catchable"],[173,7,"unknown"],[173,8,"unknown"],[173,9,"unknown"],[173,10,"unknown"],[173,11,"unknown"],[173,12,"catchable"],[173,13,"catchable"],[173,14,"catchable"],[173,15,"unknown"],[173,16,"unknown"],[173,17,"unknown"],[173,18,"unknown"],[173,21,"unknown"],[173,22,"unknown"],[173,23,"unknown"],[173,24,"unknown"],[173,25,"unknown"],[173,26,"unknown"],[173,27,"catchable"],[173,28,"catchable"],[173,29,"catchable"],[173,30,"catchable"],[173,31,"unknown"],[173,32,"unknown"],[173,33,"catchable"],[173,34,"catchable"],[173,35,"catchable"],[173,36,"catchable"],[173,37,"unknown"],[173,38,"unknown"],[173,39,"unknown"],[173,40,"unknown"],[173,41,"unknown"],[173,42,"unknown"],[173,43,"unknown"],[173,47,"unknown"],[173,48,"unknown"],[173,50,"catchable"],[173,51,"catchable"],[173,52,"unknown"],[174,4,"unknown"],[174,5,"unknown"],[174,6,"catchable"],[174,7,"unknown"],[174,8,"unknown"],[174,9,"unknown"],[174,10,"unknown"],[174,11,"unknown"],[174,12,"catchable"],[174,13,"catchable"],[174,14,"catchable"],[174,15,"unknown"],[174,16,"unknown"],[174,17,"unknown"],[174,18,"unknown"],[174,21,"unknown"],[174,22,"unknown"],[174,23,"unknown"],[174,24,"unknown"],[174,25,"unknown"],[174,26,"unknown"],[174,27,"catchable"],[174,28,"catchable"],[174,29,"catchable"],[174,30,"catchable"],[174,31,"unknown"],[174,32,"unknown"],[174,33,"unknown"],[174,34,"unknown"],[174,35,"catchable"],[174,36,"unknown"],[174,37,"unknown"],[174,38,"unknown"],[174,39,"unknown"],[174,40,"unknown"],[174,41,"unknown"],[174,42,"unknown"],[174,43,"unknown"],[174,47,"unknown"],[174,48,"unknown"],[174,50,"catchable"],[175,4,"catchable"],[175,5,"catchable"],[175,6,"catchable"],[175,7,"unknown"],[175,8,"unknown"],[175,9,"unknown"],[175,10,"catchable"],[175,11,"catchable"],[175,12,"catchable"],[175,13,"catchable"],[175,14,"catchable"],[175,15,"catchable"],[175,16,"catchable"],[175,17,"unknown"],[175,18,"unknown"],[175,19,"catchable"],[175,20,"catchable"],[175,21,"unknown"],[175,22,"unknown"],[175,23,"catchable"],[175,24,"catchable"],[175,25,"catchable"],[175,26,"catchable"],[175,27,"unknown"],[175,28,"unknown"],[175,29,"unknown"],[175,30,"unknown"],[175,31,"unknown"],[175,32,"unknown"],[175,33,"catchable"],[175,34,"catchable"],[175,35,"unknown"],[175,36,"unknown"],[175,37,"unknown"],[175,38,"unknown"],[175,39,"unknown"],[176,4,"unknown"],[176,5,"unknown"],[176,6,"unknown"],[176,7,"unknown"],[176,8,"unknown"],[176,9,"unknown"],[176,10,"unknown"],[176,11,"unknown"],[176,12,"unknown"],[176,13,"unknown"],[176,14,"unknown"],[176,15,"unknown"],[176,16,"unknown"],[176,17,"unknown"],[176,18,"unknown"],[176,19,"catchable"],[176,21,"unknown"],[176,22,"unknown"],[176,23,"unknown"],[176,24,"unknown"],[176,25,"unknown"],[176,26,"unknown"],[176,27,"unknown"],[176,28,"unknown"],[176,29,"unknown"],[176,30,"unknown"],[176,31,"unknown"],[176,32,"unknown"],[176,33,"catchable"],[176,34,"catchable"],[176,35,"unknown"],[176,36,"catchable"],[176,37,"unknown"],[176,38,"unknown"],[176,39,"unknown"],[176,51,"catchable"],[177,4,"catchable"],[177,5,"catchable"],[177,6,"catchable"],[177,7,"catchable"],[177,8,"catchable"],[177,9,"catchable"],[177,10,"catchable"],[177,11,"catchable"],[177,12,"catchable"],[177,13,"catchable"],[177,14,"catchable"],[177,15,"catchable"],[177,16,"catchable"],[177,17,"unknown"],[177,18,"unknown"],[177,20,"catchable"],[177,21,"unknown"],[177,22,"unknown"],[177,23,"unknown"],[177,24,"unknown"],[177,25,"unknown"],[177,26,"unknown"],[177,27,"unknown"],[177,28,"unknown"],[177,29,"catchable"],[177,30,"catchable"],[177,31,"unknown"],[177,32,"unknown"],[177,33,"catchable"],[177,34,"catchable"],[177,35,"unknown"],[177,36,"unknown"],[177,37,"unknown"],[177,38,"unknown"],[177,39,"unknown"],[178,4,"unknown"],[178,5,"unknown"],[178,6,"catchable"],[178,7,"catchable"],[178,8,"catchable"],[178,9,"catchable"],[178,10,"unknown"],[178,11,"unknown"],[178,12,"unknown"],[178,13,"unknown"],[178,14,"unknown"],[178,15,"catchable"],[178,16,"catchable"],[178,17,"unknown"],[178,18,"unknown"],[178,21,"unknown"],[178,22,"unknown"],[178,23,"catchable"],[178,24,"catchable"],[178,25,"catchable"],[178,26,"catchable"],[178,27,"unknown"],[178,28,"unknown"],[178,29,"catchable"],[178,30,"catchable"],[178,31,"unknown"],[178,32,"unknown"],[178,33,"catchable"],[178,34,"catchable"],[178,35,"unknown"],[178,36,"catchable"],[178,37,"unknown"],[178,38,"unknown"],[178,39,"unknown"],[178,51,"catchable"],[179,4,"catchable"],[179,5,"catchable"],[179,6,"unknown"],[179,7,"unknown"],[179,8,"unknown"],[179,9,"catchable"],[179,10,"catchable"],[179,11,"catchable"],[179,12,"catchable"],[179,13,"catchable"],[179,14,"catchable"],[179,15,"catchable"],[179,16,"catchable"],[179,17,"unknown"],[179,18,"unknown"],[179,19,"catchable"],[179,20,"catchable"],[179,21,"catchable"],[179,22,"catchable"],[179,23,"catchable"],[179,24,"catchable"],[179,25,"unknown"],[179,26,"unknown"],[179,27,"unknown"],[179,28,"unknown"],[179,29,"catchable"],[179,30,"catchable"],[179,31,"unknown"],[179,32,"unknown"],[179,40,"unknown"],[179,41,"unknown"],[179,42,"unknown"],[179,43,"unknown"],[179,47,"unknown"],[179,48,"unknown"],[180,4,"catchable"],[180,5,"catchable"],[180,6,"unknown"],[180,7,"unknown"],[180,8,"unknown"],[180,9,"unknown"],[180,10,"unknown"],[180,11,"unknown"],[180,12,"catchable"],[180,13,"catchable"],[180,14,"catchable"],[180,15,"catchable"],[180,16,"catchable"],[180,17,"unknown"],[180,18,"unknown"],[180,19,"catchable"],[180,21,"unknown"],[180,22,"unknown"],[180,23,"unknown"],[180,24,"unknown"],[180,25,"unknown"],[180,26,"unknown"],[180,27,"unknown"],[180,28,"unknown"],[180,29,"catchable"],[180,30,"catchable"],[180,31,"unknown"],[180,32,"unknown"],[180,40,"unknown"],[180,41,"unknown"],[180,42,"unknown"],[180,43,"unknown"],[180,47,"unknown"],[180,48,"unknown"],[181,4,"unknown"],[181,5,"unknown"],[181,6,"unknown"],[181,7,"unknown"],[181,8,"unknown"],[181,9,"unknown"],[181,10,"unknown"],[181,11,"unknown"],[181,12,"unknown"],[181,13,"unknown"],[181,14,"unknown"],[181,15,"unknown"],[181,16,"unknown"],[181,17,"unknown"],[181,18,"unknown"],[181,21,"unknown"],[181,22,"unknown"],[181,23,"unknown"],[181,24,"unknown"],[181,25,"unknown"],[181,26,"unknown"],[181,27,"unknown"],[181,28,"unknown"],[181,29,"unknown"],[181,30,"unknown"],[181,31,"unknown"],[181,32,"unknown"],[181,40,"unknown"],[181,41,"unknown"],[181,42,"unknown"],[181,43,"unknown"],[181,47,"unknown"],[181,48,"unknown"],[181,49,"unknown"],[182,4,"unknown"],[182,5,"unknown"],[182,6,"unknown"],[182,7,"unknown"],[182,8,"unknown"],[182,9,"unknown"],[182,10,"unknown"],[182,11,"unknown"],[182,12,"unknown"],[182,13,"unknown"],[182,14,"unknown"],[182,15,"unknown"],[182,16,"unknown"],[182,17,"unknown"],[182,18,"unknown"],[182,21,"unknown"],[182,22,"unknown"],[182,23,"unknown"],[182,24,"unknown"],[182,25,"unknown"],[182,26,"unknown"],[182,27,"unknown"],[182,28,"unknown"],[182,29,"unknown"],[182,30,"unknown"],[182,31,"unknown"],[182,32,"unknown"],[182,33,"catchable"],[182,34,"catchable"],[182,35,"unknown"],[182,36,"catchable"],[182,37,"unknown"],[182,38,"unknown"],[182,39,"unknown"],[182,40,"unknown"],[182,41,"unknown"],[182,42,"unknown"],[182,43,"unknown"],[182,47,"unknown"],[182,48,"unknown"],[182,51,"catchable"],[182,53,"unknown"],[183,4,"catchable"],[183,5,"catchable"],[183,6,"catchable"],[183,7,"catchable"],[183,8,"catchable"],[183,9,"catchable"],[183,10,"unknown"],[183,11,"catchable"],[183,12,"catchable"],[183,13,"catchable"],[183,14,"catchable"],[183,15,"catchable"],[183,16,"catchable"],[183,17,"unknown"],[183,18,"unknown"],[183,21,"catchable"],[183,22,"catchable"],[183,23,"catchable"],[183,24,"catchable"],[183,25,"catchable"],[183,26,"catchable"],[183,27,"catchable"],[183,28,"catchable"],[183,29,"unknown"],[183,30,"unknown"],[183,31,"unknown"],[183,32,"unknown"],[183,33,"unknown"],[183,34,"unknown"],[183,35,"catchable"],[183,36,"unknown"],[183,37,"unknown"],[183,38,"unknown"],[183,39,"unknown"],[183,40,"unknown"],[183,41,"unknown"],[183,42,"unknown"],[183,43,"unknown"],[183,47,"unknown"],[183,48,"unknown"],[183,50,"catchable"],[184,4,"unknown"],[184,5,"unknown"],[184,6,"unknown"],[184,7,"unknown"],[184,8,"unknown"],[184,9,"unknown"],[184,10,"unknown"],[184,11,"unknown"],[184,12,"unknown"],[184,13,"unknown"],[184,14,"catchable"],[184,15,"unknown"],[184,16,"unknown"],[184,17,"unknown"],[184,18,"unknown"],[184,21,"catchable"],[184,22,"catchable"],[184,23,"catchable"],[184,24,"catchable"],[184,25,"unknown"],[184,26,"unknown"],[184,27,"unknown"],[184,28,"unknown"],[184,29,"unknown"],[184,30,"unknown"],[184,31,"unknown"],[184,32,"unknown"],[184,33,"unknown"],[184,34,"unknown"],[184,35,"catchable"],[184,36,"catchable"],[184,37,"unknown"],[184,38,"unknown"],[184,39,"unknown"],[184,40,"unknown"],[184,41,"unknown"],[184,42,"unknown"],[184,43,"unknown"],[184,47,"unknown"],[184,48,"unknown"],[184,49,"unknown"],[184,50,"catchable"],[184,51,"catchable"],[185,4,"catchable"],[185,5,"catchable"],[185,6,"catchable"],[185,7,"unknown"],[185,8,"unknown"],[185,9,"catchable"],[185,10,"unknown"],[185,11,"unknown"],[185,12,"unknown"],[185,13,"catchable"],[185,14,"catchable"],[185,15,"catchable"],[185,16,"catchable"],[185,17,"unknown"],[185,18,"unknown"],[185,19,"catchable"],[185,21,"unknown"],[185,22,"unknown"],[185,23,"catchable"],[185,24,"catchable"],[185,25,"unknown"],[185,26,"unknown"],[185,27,"catchable"],[185,28,"catchable"],[185,29,"catchable"],[185,30,"catchable"],[185,31,"unknown"],[185,32,"unknown"],[185,33,"catchable"],[185,34,"catchable"],[185,35,"catchable"],[185,36,"catchable"],[185,37,"unknown"],[185,38,"unknown"],[185,39,"unknown"],[185,40,"unknown"],[185,41,"unknown"],[185,42,"unknown"],[185,43,"unknown"],[185,47,"unknown"],[185,48,"unknown"],[185,50,"catchable"],[185,51,"catchable"],[185,52,"unknown"],[186,4,"unknown"],[186,5,"unknown"],[186,6,"unknown"],[186,7,"unknown"],[186,8,"unknown"],[186,9,"unknown"],[186,10,"unknown"],[186,11,"unknown"],[186,12,"unknown"],[186,13,"unknown"],[186,14,"unknown"],[186,15,"unknown"],[186,16,"unknown"],[186,17,"catchable"],[186,18,"catchable"],[186,21,"catchable"],[186,22,"catchable"],[186,23,"catchable"],[186,24,"catchable"],[186,25,"unknown"],[186,26,"unknown"],[186,27,"catchable"],[186,28,"catchable"],[186,29,"catchable"],[186,30,"catchable"],[186,31,"unknown"],[186,32,"unknown"],[186,33,"unknown"],[186,34,"unknown"],[186,35,"catchable"],[186,36,"catchable"],[186,37,"unknown"],[186,38,"unknown"],[186,39,"unknown"],[186,40,"unknown"],[186,41,"unknown"],[186,42,"unknown"],[186,43,"unknown"],[186,47,"unknown"],[186,48,"unknown"],[186,49,"unknown"],[186,50,"catchable"],[186,51,"catchable"],[186,52,"unknown"],[187,4,"catchable"],[187,5,"catchable"],[187,6,"catchable"],[187,7,"unknown"],[187,8,"unknown"],[187,9,"unknown"],[187,10,"catchable"],[187,11,"catchable"],[187,12,"catchable"],[187,13,"catchable"],[187,14,"catchable"],[187,15,"catchable"],[187,16,"catchable"],[187,17,"unknown"],[187,18,"unknown"],[187,20,"catchable"],[187,21,"unknown"],[187,22,"unknown"],[187,23,"catchable"],[187,24,"catchable"],[187,25,"unknown"],[187,26,"unknown"],[187,27,"unknown"],[187,28,"unknown"],[187,29,"unknown"],[187,30,"unknown"],[187,31,"unknown"],[187,32,"unknown"],[187,40,"unknown"],[187,41,"unknown"],[187,42,"unknown"],[187,43,"unknown"],[187,47,"unknown"],[187,48,"unknown"],[188,4,"catchable"],[188,5,"catchable"],[188,6,"catchable"],[188,7,"unknown"],[188,8,"unknown"],[188,9,"unknown"],[188,10,"unknown"],[188,11,"unknown"],[188,12,"catchable"],[188,13,"catchable"],[188,14,"unknown"],[188,15,"catchable"],[188,16,"catchable"],[188,17,"unknown"],[188,18,"unknown"],[188,19,"catchable"],[188,21,"unknown"],[188,22,"unknown"],[188,23,"unknown"],[188,24,"unknown"],[188,25,"unknown"],[188,26,"unknown"],[188,27,"unknown"],[188,28,"unknown"],[188,29,"unknown"],[188,30,"unknown"],[188,31,"unknown"],[188,32,"unknown"],[188,40,"unknown"],[188,41,"unknown"],[188,42,"unknown"],[188,43,"unknown"],[188,47,"unknown"],[188,48,"unknown"],[189,4,"unknown"],[189,5,"unknown"],[189,6,"unknown"],[189,7,"unknown"],[189,8,"unknown"],[189,9,"unknown"],[189,10,"unknown"],[189,11,"unknown"],[189,12,"unknown"],[189,13,"unknown"],[189,14,"unknown"],[189,15,"catchable"],[189,16,"catchable"],[189,17,"unknown"],[189,18,"unknown"],[189,21,"unknown"],[189,22,"unknown"],[189,23,"unknown"],[189,24,"unknown"],[189,25,"unknown"],[189,26,"unknown"],[189,27,"unknown"],[189,28,"unknown"],[189,29,"unknown"],[189,30,"unknown"],[189,31,"unknown"],[189,32,"unknown"],[189,40,"unknown"],[189,41,"unknown"],[189,42,"unknown"],[189,43,"unknown"],[189,47,"unknown"],[189,48,"unknown"],[190,4,"catchable"],[190,5,"catchable"],[190,6,"catchable"],[190,7,"unknown"],[190,8,"unknown"],[190,9,"catchable"],[190,10,"catchable"],[190,11,"catchable"],[190,12,"catchable"],[190,13,"catchable"],[190,14,"catchable"],[190,15,"catchable"],[190,16,"catchable"],[190,17,"unknown"],[190,18,"unknown"],[190,19,"catchable"],[190,21,"unknown"],[190,22,"unknown"],[190,23,"catchable"],[190,24,"catchable"],[190,25,"unknown"],[190,26,"unknown"],[190,27,"unknown"],[190,28,"unknown"],[190,29,"catchable"],[190,30,"catchable"],[190,31,"unknown"],[190,32,"unknown"],[190,37,"unknown"],[190,38,"unknown"],[190,39,"unknown"],[190,40,"unknown"],[190,41,"unknown"],[190,42,"unknown"],[190,43,"unknown"],[190,47,"unknown"],[190,48,"unknown"],[190,52,"unknown"],[191,4,"catchable"],[191,5,"catchable"],[191,6,"catchable"],[191,7,"unknown"],[191,8,"unknown"],[191,9,"catchable"],[191,10,"unknown"],[191,11,"unknown"],[191,12,"catchable"],[191,13,"catchable"],[191,14,"catchable"],[191,15,"catchable"],[191,16,"catchable"],[191,17,"catchable"],[191,18,"catchable"],[191,21,"catchable"],[191,22,"catchable"],[191,23,"catchable"],[191,24,"catchable"],[191,25,"catchable"],[191,26,"catchable"],[191,27,"unknown"],[191,28,"unknown"],[191,29,"unknown"],[191,30,"unknown"],[191,31,"unknown"],[191,32,"unknown"],[191,40,"unknown"],[191,41,"unknown"],[191,42,"unknown"],[191,43,"unknown"],[191,47,"unknown"],[191,48,"unknown"],[192,4,"unknown"],[192,5,"unknown"],[192,6,"unknown"],[192,7,"unknown"],[192,8,"unknown"],[192,9,"unknown"],[192,10,"unknown"],[192,11,"unknown"],[192,12,"unknown"],[192,13,"unknown"],[192,14,"unknown"],[192,15,"unknown"],[192,16,"unknown"],[192,17,"catchable"],[192,18,"catchable"],[192,19,"catchable"],[192,21,"unknown"],[192,22,"unknown"],[192,23,"unknown"],[192,24,"unknown"],[192,25,"unknown"],[192,26,"unknown"],[192,27,"unknown"],[192,28,"unknown"],[192,29,"unknown"],[192,30,"unknown"],[192,31,"unknown"],[192,32,"unknown"],[192,40,"unknown"],[192,41,"unknown"],[192,42,"unknown"],[192,43,"unknown"],[192,47,"unknown"],[192,48,"unknown"],[193,4,"catchable"],[193,5,"catchable"],[193,6,"catchable"],[193,7,"unknown"],[193,8,"unknown"],[193,9,"unknown"],[193,10,"catchable"],[193,11,"catchable"],[193,12,"catchable"],[193,13,"catchable"],[193,14,"catchable"],[193,15,"catchable"],[193,16,"catchable"],[193,17,"unknown"],[193,18,"unknown"],[193,19,"catchable"],[193,21,"catchable"],[193,22,"catchable"],[193,23,"catchable"],[193,24,"catchable"],[193,25,"unknown"],[193,26,"unknown"],[193,27,"unknown"],[193,28,"unknown"],[193,29,"unknown"],[193,30,"unknown"],[193,31,"unknown"],[193,32,"unknown"],[193,39,"unknown"],[193,40,"unknown"],[193,41,"unknown"],[193,42,"unknown"],[193,43,"unknown"],[193,47,"unknown"],[193,48,"unknown"],[193,52,"unknown"],[194,4,"catchable"],[194,5,"catchable"],[194,6,"catchable"],[194,7,"unknown"],[194,8,"unknown"],[194,9,"catchable"],[194,10,"catchable"],[194,11,"unknown"],[194,12,"catchable"],[194,13,"catchable"],[194,14,"catchable"],[194,15,"catchable"],[194,16,"catchable"],[194,17,"unknown"],[194,18,"unknown"],[194,20,"catchable"],[194,21,"unknown"],[194,22,"unknown"],[194,23,"catchable"],[194,24,"catchable"],[194,25,"unknown"],[194,26,"unknown"],[194,27,"unknown"],[194,28,"unknown"],[194,29,"unknown"],[194,30,"unknown"],[194,31,"unknown"],[194,32,"unknown"],[194,33,"catchable"],[194,34,"catchable"],[194,35,"catchable"],[194,36,"unknown"],[194,37,"unknown"],[194,38,"unknown"],[194,39,"unknown"],[194,40,"unknown"],[194,41,"unknown"],[194,42,"unknown"],[194,43,"unknown"],[194,47,"unknown"],[194,48,"unknown"],[194,50,"catchable"],[194,52,"unknown"],[195,4,"catchable"],[195,5,"catchable"],[195,6,"catchable"],[195,7,"unknown"],[195,8,"unknown"],[195,9,"catchable"],[195,10,"unknown"],[195,11,"unknown"],[195,12,"catchable"],[195,13,"catchable"],[195,14,"catchable"],[195,15,"catchable"],[195,16,"catchable"],[195,17,"unknown"],[195,18,"unknown"],[195,19,"catchable"],[195,21,"unknown"],[195,22,"unknown"],[195,23,"catchable"],[195,24,"catchable"],[195,25,"unknown"],[195,26,"unknown"],[195,27,"unknown"],[195,28,"unknown"],[195,29,"catchable"],[195,30,"catchable"],[195,31,"unknown"],[195,32,"unknown"],[195,33,"catchable"],[195,34,"catchable"],[195,35,"catchable"],[195,36,"catchable"],[195,37,"unknown"],[195,38,"unknown"],[195,39,"unknown"],[195,40,"unknown"],[195,41,"unknown"],[195,42,"unknown"],[195,43,"unknown"],[195,47,"unknown"],[195,48,"unknown"],[195,50,"catchable"],[195,51,"catchable"],[195,52,"unknown"],[196,4,"unknown"],[196,5,"unknown"],[196,6,"unknown"],[196,7,"unknown"],[196,8,"unknown"],[196,9,"unknown"],[196,10,"unknown"],[196,11,"unknown"],[196,12,"unknown"],[196,13,"unknown"],[196,14,"unknown"],[196,15,"unknown"],[196,16,"unknown"],[196,17,"unknown"],[196,18,"unknown"],[196,19,"catchable"],[196,21,"unknown"],[196,22,"unknown"],[196,23,"unknown"],[196,24,"unknown"],[196,25,"unknown"],[196,26,"unknown"],[196,27,"catchable"],[196,28,"catchable"],[196,29,"catchable"],[196,30,"catchable"],[196,31,"unknown"],[196,32,"unknown"],[196,33,"catchable"],[196,34,"catchable"],[196,35,"unknown"],[196,36,"catchable"],[196,37,"unknown"],[196,38,"unknown"],[196,39,"unknown"],[196,40,"unknown"],[196,41,"unknown"],[196,42,"unknown"],[196,43,"unknown"],[196,47,"unknown"],[196,48,"unknown"],[196,49,"unknown"],[196,51,"catchable"],[197,4,"unknown"],[197,5,"unknown"],[197,6,"unknown"],[197,7,"unknown"],[197,8,"unknown"],[197,9,"unknown"],[197,10,"unknown"],[197,11,"unknown"],[197,12,"unknown"],[197,13,"unknown"],[197,14,"unknown"],[197,15,"unknown"],[197,16,"unknown"],[197,17,"unknown"],[197,18,"unknown"],[197,19,"catchable"],[197,21,"unknown"],[197,22,"unknown"],[197,23,"unknown"],[197,24,"unknown"],[197,25,"unknown"],[197,26,"unknown"],[197,27,"catchable"],[197,28,"catchable"],[197,29,"catchable"],[197,30,"catchable"],[197,31,"unknown"],[197,32,"unknown"],[197,33,"catchable"],[197,34,"catchable"],[197,35,"unknown"],[197,36,"catchable"],[197,37,"unknown"],[197,38,"unknown"],[197,39,"unknown"],[197,40,"unknown"],[197,41,"unknown"],[197,42,"unknown"],[197,43,"unknown"],[197,47,"unknown"],[197,48,"unknown"],[197,49,"unknown"],[197,51,"catchable"],[198,4,"catchable"],[198,5,"catchable"],[198,6,"catchable"],[198,7,"unknown"],[198,8,"unknown"],[198,9,"unknown"],[198,10,"catchable"],[198,11,"unknown"],[198,12,"catchable"],[198,13,"unknown"],[198,14,"unknown"],[198,15,"catchable"],[198,16,"catchable"],[198,17,"catchable"],[198,18,"unknown"],[198,19,"catchable"],[198,21,"catchable"],[198,22,"catchable"],[198,23,"catchable"],[198,24,"catchable"],[198,25,"unknown"],[198,26,"unknown"],[198,27,"catchable"],[198,28,"catchable"],[198,29,"catchable"],[198,30,"catchable"],[198,31,"unknown"],[198,32,"unknown"],[198,37,"unknown"],[198,38,"unknown"],[198,39,"unknown"],[198,40,"unknown"],[198,41,"unknown"],[198,42,"unknown"],[198,43,"unknown"],[198,47,"unknown"],[198,48,"unknown"],[199,4,"unknown"],[199,5,"unknown"],[199,6,"unknown"],[199,7,"unknown"],[199,8,"unknown"],[199,9,"unknown"],[199,10,"unknown"],[199,11,"unknown"],[199,12,"unknown"],[199,13,"unknown"],[199,14,"unknown"],[199,15,"unknown"],[199,16,"unknown"],[199,17,"catchable"],[199,18,"catchable"],[199,21,"unknown"],[199,22,"unknown"],[199,23,"unknown"],[199,24,"unknown"],[199,25,"unknown"],[199,26,"unknown"],[199,27,"unknown"],[199,28,"unknown"],[199,29,"catchable"],[199,30,"catchable"],[199,31,"unknown"],[199,32,"unknown"],[199,33,"unknown"],[199,34,"unknown"],[199,35,"unknown"],[199,36,"catchable"],[199,37,"unknown"],[199,38,"unknown"],[199,39,"unknown"],[199,40,"unknown"],[199,41,"unknown"],[199,42,"unknown"],[199,43,"unknown"],[199,47,"unknown"],[199,48,"unknown"],[199,49,"unknown"],[199,50,"unknown"],[199,51,"catchable"],[199,53,"unknown"],[200,4,"catchable"],[200,5,"catchable"],[200,6,"catchable"],[200,7,"unknown"],[200,8,"unknown"],[200,9,"unknown"],[200,10,"unknown"],[200,11,"catchable"],[200,12,"unknown"],[200,13,"catchable"],[200,14,"unknown"],[200,15,"catchable"],[200,16,"catchable"],[200,17,"unknown"],[200,18,"catchable"],[200,19,"catchable"],[200,21,"unknown"],[200,22,"unknown"],[200,23,"unknown"],[200,24,"unknown"],[200,25,"unknown"],[200,26,"unknown"],[200,27,"catchable"],[200,28,"catchable"],[200,29,"catchable"],[200,30,"catchable"],[200,31,"unknown"],[200,32,"unknown"],[200,37,"unknown"],[200,38,"unknown"],[200,39,"unknown"],[200,40,"unknown"],[200,41,"unknown"],[200,42,"unknown"],[200,43,"unknown"],[200,47,"unknown"],[200,48,"unknown"],[201,4,"catchable"],[201,5,"catchable"],[201,6,"catchable"],[201,7,"unknown"],[201,8,"unknown"],[201,9,"unknown"],[201,10,"catchable"],[201,11,"catchable"],[201,12,"catchable"],[201,13,"catchable"],[201,14,"catchable"],[201,15,"catchable"],[201,16,"catchable"],[201,17,"unknown"],[201,18,"unknown"],[201,21,"unknown"],[201,22,"unknown"],[201,23,"unknown"],[201,24,"unknown"],[201,25,"catchable"],[201,26,"catchable"],[201,27,"unknown"],[201,28,"unknown"],[201,29,"unknown"],[201,30,"unknown"],[201,31,"unknown"],[201,32,"unknown"],[201,37,"unknown"],[201,38,"unknown"],[201,39,"unknown"],[202,4,"catchable"],[202,5,"catchable"],[202,6,"catchable"],[202,7,"catchable"],[202,8,"catchable"],[202,9,"catchable"],[202,10,"catchable"],[202,11,"catchable"],[202,12,"catchable"],[202,13,"catchable"],[202,14,"catchable"],[202,15,"catchable"],[202,16,"catchable"],[202,17,"unknown"],[202,18,"unknown"],[202,21,"unknown"],[202,22,"unknown"],[202,23,"catchable"],[202,24,"catchable"],[202,25,"unknown"],[202,26,"unknown"],[202,27,"unknown"],[202,28,"unknown"],[202,29,"unknown"],[202,30,"unknown"],[202,31,"unknown"],[202,32,"unknown"],[202,33,"catchable"],[202,34,"catchable"],[202,35,"unknown"],[202,36,"unknown"],[202,37,"unknown"],[202,38,"unknown"],[202,39,"unknown"],[203,4,"catchable"],[203,5,"catchable"],[203,6,"unknown"],[203,7,"catchable"],[203,8,"catchable"],[203,9,"catchable"],[203,10,"unknown"],[203,11,"unknown"],[203,12,"catchable"],[203,13,"catchable"],[203,14,"catchable"],[203,15,"catchable"],[203,16,"catchable"],[203,17,"unknown"],[203,18,"unknown"],[203,21,"catchable"],[203,22,"catchable"],[203,23,"catchable"],[203,24,"catchable"],[203,25,"catchable"],[203,26,"catchable"],[203,27,"unknown"],[203,28,"unknown"],[203,29,"unknown"],[203,30,"unknown"],[203,31,"unknown"],[203,32,"unknown"],[203,37,"unknown"],[203,38,"unknown"],[203,40,"unknown"],[203,41,"unknown"],[203,42,"unknown"],[203,43,"unknown"],[203,47,"unknown"],[203,48,"unknown"],[203,53,"unknown"],[204,4,"catchable"],[204,5,"catchable"],[204,6,"catchable"],[204,7,"unknown"],[204,8,"unknown"],[204,9,"catchable"],[204,10,"catchable"],[204,11,"catchable"],[204,12,"catchable"],[204,13,"catchable"],[204,14,"catchable"],[204,15,"catchable"],[204,16,"catchable"],[204,17,"unknown"],[204,18,"unknown"],[204,20,"catchable"],[204,21,"unknown"],[204,22,"unknown"],[204,23,"unknown"],[204,24,"unknown"],[204,25,"unknown"],[204,26,"unknown"],[204,27,"unknown"],[204,28,"unknown"],[204,29,"catchable"],[204,30,"catchable"],[204,31,"unknown"],[204,32,"unknown"],[204,40,"unknown"],[204,41,"unknown"],[204,42,"unknown"],[204,43,"unknown"],[204,47,"unknown"],[204,48,"unknown"],[205,4,"unknown"],[205,5,"unknown"],[205,6,"unknown"],[205,7,"unknown"],[205,8,"unknown"],[205,9,"unknown"],[205,10,"unknown"],[205,11,"unknown"],[205,12,"unknown"],[205,13,"unknown"],[205,14,"unknown"],[205,15,"unknown"],[205,16,"unknown"],[205,17,"unknown"],[205,18,"unknown"],[205,19,"catchable"],[205,21,"unknown"],[205,22,"unknown"],[205,23,"catchable"],[205,24,"catchable"],[205,25,"catchable"],[205,26,"catchable"],[205,27,"unknown"],[205,28,"unknown"],[205,29,"unknown"],[205,30,"unknown"],[205,31,"unknown"],[205,32,"unknown"],[205,40,"unknown"],[205,41,"unknown"],[205,42,"unknown"],[205,43,"unknown"],[205,47,"unknown"],[205,48,"unknown"],[205,49,"unknown"],[206,4,"catchable"],[206,5,"catchable"],[206,6,"catchable"],[206,7,"unknown"],[206,8,"unknown"],[206,9,"unknown"],[206,10,"catchable"],[206,11,"catchable"],[206,12,"catchable"],[206,13,"catchable"],[206,14,"catchable"],[206,15,"catchable"],[206,16,"catchable"],[206,17,"catchable"],[206,18,"catchable"],[206,19,"catchable"],[206,21,"catchable"],[206,22,"catchable"],[206,23,"catchable"],[206,24,"catchable"],[206,25,"unknown"],[206,26,"unknown"],[206,27,"unknown"],[206,28,"unknown"],[206,29,"catchable"],[206,30,"catchable"],[206,31,"unknown"],[206,32,"unknown"],[206,33,"unknown"],[206,34,"unknown"],[206,35,"catchable"],[206,36,"catchable"],[206,37,"unknown"],[206,38,"unknown"],[206,39,"unknown"],[206,40,"unknown"],[206,41,"unknown"],[206,42,"unknown"],[206,43,"unknown"],[206,47,"unknown"],[206,48,"unknown"],[206,50,"catchable"],[206,51,"catchable"],[206,52,"unknown"],[207,4,"catchable"],[207,5,"unknown"],[207,6,"catchable"],[207,7,"unknown"],[207,8,"unknown"],[207,9,"catchable"],[207,10,"unknown"],[207,11,"unknown"],[207,12,"catchable"],[207,13,"catchable"],[207,14,"catchable"],[207,15,"catchable"],[207,16,"unknown"],[207,17,"catchable"],[207,18,"catchable"],[207,19,"catchable"],[207,20,"catchable"],[207,21,"catchable"],[207,22,"catchable"],[207,23,"catchable"],[207,24,"catchable"],[207,25,"unknown"],[207,26,"unknown"],[207,27,"unknown"],[207,28,"unknown"],[207,29,"unknown"],[207,30,"unknown"],[207,31,"unknown"],[207,32,"unknown"],[207,39,"unknown"],[207,40,"unknown"],[207,41,"unknown"],[207,42,"unknown"],[207,43,"unknown"],[207,47,"unknown"],[207,48,"unknown"],[207,52,"unknown"],[208,4,"unknown"],[208,5,"unknown"],[208,6,"unknown"],[208,7,"unknown"],[208,8,"unknown"],[208,9,"unknown"],[208,10,"unknown"],[208,11,"unknown"],[208,12,"catchable"],[208,13,"catchable"],[208,14,"catchable"],[208,15,"catchable"],[208,16,"catchable"],[208,17,"unknown"],[208,18,"unknown"],[208,21,"catchable"],[208,22,"catchable"],[208,23,"unknown"],[208,24,"unknown"],[208,25,"unknown"],[208,26,"unknown"],[208,27,"unknown"],[208,28,"unknown"],[208,29,"unknown"],[208,30,"unknown"],[208,31,"unknown"],[208,32,"unknown"],[208,33,"catchable"],[208,34,"catchable"],[208,35,"unknown"],[208,36,"unknown"],[208,37,"unknown"],[208,38,"unknown"],[208,39,"unknown"],[208,47,"unknown"],[208,49,"unknown"],[209,4,"catchable"],[209,5,"catchable"],[209,6,"catchable"],[209,7,"unknown"],[209,8,"unknown"],[209,9,"catchable"],[209,10,"unknown"],[209,11,"unknown"],[209,12,"catchable"],[209,13,"catchable"],[209,14,"catchable"],[209,15,"catchable"],[209,16,"catchable"],[209,17,"unknown"],[209,18,"unknown"],[209,21,"unknown"],[209,22,"unknown"],[209,23,"catchable"],[209,24,"catchable"],[209,25,"unknown"],[209,26,"unknown"],[209,27,"unknown"],[209,28,"unknown"],[209,29,"catchable"],[209,30,"catchable"],[209,31,"unknown"],[209,32,"unknown"],[209,40,"unknown"],[209,41,"unknown"],[209,42,"unknown"],[209,43,"unknown"],[209,47,"unknown"],[209,48,"unknown"],[209,53,"unknown"],[210,4,"unknown"],[210,5,"unknown"],[210,6,"catchable"],[210,7,"unknown"],[210,8,"unknown"],[210,9,"unknown"],[210,10,"unknown"],[210,11,"unknown"],[210,12,"unknown"],[210,13,"unknown"],[210,14,"unknown"],[210,15,"unknown"],[210,16,"unknown"],[210,17,"unknown"],[210,18,"unknown"],[210,19,"catchable"],[210,21,"catchable"],[210,22,"catchable"],[210,23,"unknown"],[210,24,"unknown"],[210,25,"unknown"],[210,26,"unknown"],[210,27,"catchable"],[210,28,"catchable"],[210,29,"catchable"],[210,30,"catchable"],[210,31,"unknown"],[210,32,"unknown"],[210,40,"unknown"],[210,41,"unknown"],[210,42,"unknown"],[210,43,"unknown"],[210,47,"unknown"],[210,48,"unknown"],[210,53,"unknown"],[211,4,"catchable"],[211,5,"catchable"],[211,6,"catchable"],[211,7,"unknown"],[211,8,"unknown"],[211,9,"unknown"],[211,10,"catchable"],[211,11,"unknown"],[211,12,"catchable"],[211,13,"catchable"],[211,14,"catchable"],[211,15,"catchable"],[211,16,"catchable"],[211,17,"catchable"],[211,18,"catchable"],[211,19,"catchable"],[211,21,"catchable"],[211,22,"catchable"],[211,23,"catchable"],[211,24,"catchable"],[211,25,"unknown"],[211,26,"unknown"],[211,27,"unknown"],[211,28,"unknown"],[211,29,"unknown"],[211,30,"unknown"],[211,31,"unknown"],[211,32,"unknown"],[211,33,"catchable"],[211,34,"catchable"],[211,35,"catchable"],[211,36,"catchable"],[211,37,"unknown"],[211,38,"unknown"],[211,39,"unknown"],[211,40,"unknown"],[211,41,"unknown"],[211,42,"unknown"],[211,43,"unknown"],[211,47,"unknown"],[211,48,"unknown"],[211,49,"unknown"],[211,50,"catchable"],[211,51,"catchable"],[211,53,"unknown"],[212,4,"unknown"],[212,5,"unknown"],[212,6,"unknown"],[212,7,"unknown"],[212,8,"unknown"],[212,9,"unknown"],[212,10,"unknown"],[212,11,"unknown"],[212,12,"unknown"],[212,13,"unknown"],[212,14,"unknown"],[212,15,"unknown"],[212,16,"unknown"],[212,17,"unknown"],[212,18,"unknown"],[212,19,"catchable"],[212,21,"unknown"],[212,22,"unknown"],[212,23,"unknown"],[212,24,"unknown"],[212,25,"unknown"],[212,26,"unknown"],[212,27,"unknown"],[212,28,"unknown"],[212,29,"unknown"],[212,30,"unknown"],[212,31,"unknown"],[212,32,"unknown"],[212,33,"unknown"],[212,34,"unknown"],[212,35,"catchable"],[212,36,"unknown"],[212,37,"unknown"],[212,38,"unknown"],[212,39,"unknown"],[212,40,"unknown"],[212,41,"unknown"],[212,42,"unknown"],[212,43,"unknown"],[212,47,"unknown"],[212,48,"unknown"],[212,49,"unknown"],[212,50,"catchable"],[212,53,"unknown"],[213,4,"catchable"],[213,5,"catchable"],[213,6,"catchable"],[213,7,"unknown"],[213,8,"unknown"],[213,9,"catchable"],[213,10,"catchable"],[213,11,"catchable"],[213,12,"catchable"],[213,13,"catchable"],[213,14,"catchable"],[213,15,"catchable"],[213,16,"catchable"],[213,17,"catchable"],[213,18,"catchable"],[213,19,"catchable"],[213,20,"catchable"],[213,21,"catchable"],[213,22,"catchable"],[213,23,"catchable"],[213,24,"catchable"],[213,25,"unknown"],[213,26,"unknown"],[213,27,"unknown"],[213,28,"unknown"],[213,29,"unknown"],[213,30,"unknown"],[213,31,"unknown"],[213,32,"unknown"],[213,33,"catchable"],[213,34,"catchable"],[213,35,"catchable"],[213,36,"catchable"],[213,37,"unknown"],[213,38,"unknown"],[213,39,"unknown"],[213,50,"catchable"],[213,51,"catchable"],[214,4,"catchable"],[214,5,"catchable"],[214,6,"catchable"],[214,7,"catchable"],[214,8,"catchable"],[214,9,"catchable"],[214,10,"catchable"],[214,11,"catchable"],[214,12,"catchable"],[214,13,"catchable"],[214,14,"catchable"],[214,15,"catchable"],[214,16,"catchable"],[214,17,"catchable"],[214,18,"catchable"],[214,19,"catchable"],[214,21,"catchable"],[214,22,"catchable"],[214,23,"catchable"],[214,24,"catchable"],[214,25,"unknown"],[214,26,"unknown"],[214,27,"unknown"],[214,28,"unknown"],[214,29,"catchable"],[214,30,"catchable"],[214,31,"unknown"],[214,32,"unknown"],[214,33,"unknown"],[214,34,"unknown"],[214,35,"unknown"],[214,36,"unknown"],[214,37,"unknown"],[214,38,"unknown"],[214,39,"unknown"],[214,40,"unknown"],[214,41,"unknown"],[214,42,"unknown"],[214,43,"unknown"],[214,47,"unknown"],[214,48,"unknown"],[214,49,"unknown"],[214,50,"catchable"],[214,52,"unknown"],[215,4,"catchable"],[215,5,"catchable"],[215,6,"catchable"],[215,7,"unknown"],[215,8,"unknown"],[215,9,"unknown"],[215,10,"unknown"],[215,11,"catchable"],[215,12,"catchable"],[215,13,"catchable"],[215,14,"catchable"],[215,15,"catchable"],[215,16,"catchable"],[215,17,"catchable"],[215,18,"catchable"],[215,19,"catchable"],[215,21,"catchable"],[215,22,"catchable"],[215,23,"catchable"],[215,24,"catchable"],[215,25,"unknown"],[215,26,"unknown"],[215,27,"catchable"],[215,28,"catchable"],[215,29,"catchable"],[215,30,"catchable"],[215,31,"unknown"],[215,32,"unknown"],[215,33,"catchable"],[215,34,"catchable"],[215,35,"unknown"],[215,36,"catchable"],[215,37,"unknown"],[215,38,"unknown"],[215,39,"unknown"],[215,40,"unknown"],[215,41,"unknown"],[215,42,"unknown"],[215,43,"unknown"],[215,47,"unknown"],[215,48,"unknown"],[215,51,"catchable"],[215,52,"unknown"],[216,4,"catchable"],[216,5,"unknown"],[216,6,"catchable"],[216,7,"unknown"],[216,8,"unknown"],[216,9,"catchable"],[216,10,"catchable"],[216,11,"catchable"],[216,12,"catchable"],[216,13,"catchable"],[216,14,"catchable"],[216,15,"unknown"],[216,16,"catchable"],[216,17,"unknown"],[216,18,"unknown"],[216,20,"catchable"],[216,21,"unknown"],[216,22,"unknown"],[216,23,"catchable"],[216,24,"catchable"],[216,25,"unknown"],[216,26,"unknown"],[216,27,"unknown"],[216,28,"unknown"],[216,29,"unknown"],[216,30,"unknown"],[216,31,"unknown"],[216,32,"unknown"],[216,39,"unknown"],[216,40,"unknown"],[216,41,"unknown"],[216,42,"unknown"],[216,43,"unknown"],[216,47,"unknown"],[216,48,"unknown"],[217,4,"catchable"],[217,5,"unknown"],[217,6,"catchable"],[217,7,"unknown"],[217,8,"unknown"],[217,9,"unknown"],[217,10,"unknown"],[217,11,"unknown"],[217,12,"catchable"],[217,13,"catchable"],[217,14,"catchable"],[217,15,"unknown"],[217,16,"catchable"],[217,17,"unknown"],[217,18,"unknown"],[217,19,"catchable"],[217,21,"unknown"],[217,22,"unknown"],[217,23,"catchable"],[217,24,"catchable"],[217,25,"unknown"],[217,26,"unknown"],[217,27,"unknown"],[217,28,"unknown"],[217,29,"unknown"],[217,30,"unknown"],[217,31,"unknown"],[217,32,"unknown"],[217,39,"unknown"],[217,40,"unknown"],[217,41,"unknown"],[217,42,"unknown"],[217,43,"unknown"],[217,47,"unknown"],[217,48,"unknown"],[218,4,"catchable"],[218,5,"catchable"],[218,6,"catchable"],[218,7,"catchable"],[218,8,"catchable"],[218,9,"catchable"],[218,10,"catchable"],[218,11,"catchable"],[218,12,"catchable"],[218,13,"catchable"],[218,14,"catchable"],[218,15,"catchable"],[218,16,"catchable"],[218,17,"unknown"],[218,18,"unknown"],[218,19,"catchable"],[218,21,"unknown"],[218,22,"unknown"],[218,23,"catchable"],[218,24,"catchable"],[218,25,"catchable"],[218,26,"catchable"],[218,27,"unknown"],[218,28,"unknown"],[218,29,"unknown"],[218,30,"unknown"],[218,31,"unknown"],[218,32,"unknown"],[218,40,"unknown"],[218,41,"unknown"],[218,42,"unknown"],[218,43,"unknown"],[218,47,"unknown"],[218,48,"unknown"],[218,52,"unknown"],[219,4,"unknown"],[219,5,"unknown"],[219,6,"unknown"],[219,7,"unknown"],[219,8,"unknown"],[219,9,"unknown"],[219,10,"catchable"],[219,11,"catchable"],[219,12,"catchable"],[219,13,"catchable"],[219,14,"catchable"],[219,15,"unknown"],[219,16,"unknown"],[219,17,"unknown"],[219,18,"unknown"],[219,20,"catchable"],[219,21,"unknown"],[219,22,"unknown"],[219,23,"catchable"],[219,24,"catchable"],[219,25,"unknown"],[219,26,"unknown"],[219,27,"unknown"],[219,28,"unknown"],[219,29,"catchable"],[219,30,"catchable"],[219,31,"unknown"],[219,32,"unknown"],[219,40,"unknown"],[219,41,"unknown"],[219,42,"unknown"],[219,43,"unknown"],[219,47,"unknown"],[219,48,"unknown"],[219,52,"unknown"],[220,4,"catchable"],[220,5,"catchable"],[220,6,"catchable"],[220,7,"unknown"],[220,8,"unknown"],[220,9,"unknown"],[220,10,"catchable"],[220,11,"catchable"],[220,12,"catchable"],[220,13,"catchable"],[220,14,"catchable"],[220,15,"catchable"],[220,16,"catchable"],[220,17,"unknown"],[220,18,"unknown"],[220,20,"catchable"],[220,21,"unknown"],[220,22,"unknown"],[220,23,"unknown"],[220,24,"unknown"],[220,25,"unknown"],[220,26,"unknown"],[220,27,"catchable"],[220,28,"catchable"],[220,29,"catchable"],[220,30,"catchable"],[220,31,"unknown"],[220,32,"unknown"],[220,33,"catchable"],[220,34,"catchable"],[220,35,"unknown"],[220,36,"catchable"],[220,37,"unknown"],[220,38,"unknown"],[220,39,"unknown"],[220,40,"unknown"],[220,41,"unknown"],[220,42,"unknown"],[220,43,"unknown"],[220,47,"unknown"],[220,48,"unknown"],[220,51,"catchable"],[220,52,"unknown"],[221,4,"unknown"],[221,5,"unknown"],[221,6,"unknown"],[221,7,"unknown"],[221,8,"unknown"],[221,9,"unknown"],[221,10,"unknown"],[221,11,"unknown"],[221,12,"unknown"],[221,13,"unknown"],[221,14,"catchable"],[221,15,"unknown"],[221,16,"unknown"],[221,17,"catchable"],[221,18,"catchable"],[221,19,"catchable"],[221,21,"catchable"],[221,22,"catchable"],[221,23,"catchable"],[221,24,"catchable"],[221,25,"unknown"],[221,26,"unknown"],[221,27,"unknown"],[221,28,"unknown"],[221,29,"unknown"],[221,30,"unknown"],[221,31,"unknown"],[221,32,"unknown"],[221,33,"catchable"],[221,34,"catchable"],[221,35,"unknown"],[221,36,"catchable"],[221,37,"unknown"],[221,38,"unknown"],[221,39,"unknown"],[221,40,"unknown"],[221,41,"unknown"],[221,42,"unknown"],[221,43,"unknown"],[221,47,"unknown"],[221,48,"unknown"],[221,51,"catchable"],[221,52,"unknown"],[222,4,"catchable"],[222,5,"catchable"],[222,6,"catchable"],[222,7,"catchable"],[222,8,"catchable"],[222,9,"catchable"],[222,10,"unknown"],[222,11,"unknown"],[222,12,"catchable"],[222,13,"catchable"],[222,14,"catchable"],[222,15,"catchable"],[222,16,"catchable"],[222,17,"catchable"],[222,18,"catchable"],[222,21,"catchable"],[222,22,"catchable"],[222,23,"catchable"],[222,24,"catchable"],[222,25,"unknown"],[222,26,"unknown"],[222,27,"catchable"],[222,28,"catchable"],[222,29,"catchable"],[222,30,"catchable"],[222,31,"unknown"],[222,32,"unknown"],[222,33,"unknown"],[222,34,"catchable"],[222,35,"unknown"],[222,36,"unknown"],[222,37,"unknown"],[222,38,"unknown"],[222,39,"unknown"],[222,50,"catchable"],[222,51,"catchable"],[223,4,"catchable"],[223,5,"catchable"],[223,6,"unknown"],[223,7,"unknown"],[223,8,"unknown"],[223,9,"catchable"],[223,10,"unknown"],[223,11,"catchable"],[223,12,"catchable"],[223,13,"catchable"],[223,14,"catchable"],[223,15,"catchable"],[223,16,"catchable"],[223,17,"catchable"],[223,18,"catchable"],[223,19,"catchable"],[223,21,"catchable"],[223,22,"catchable"],[223,23,"catchable"],[223,24,"catchable"],[223,25,"unknown"],[223,26,"unknown"],[223,27,"unknown"],[223,28,"unknown"],[223,29,"catchable"],[223,30,"catchable"],[223,31,"unknown"],[223,32,"unknown"],[223,33,"catchable"],[223,34,"catchable"],[223,35,"catchable"],[223,36,"unknown"],[223,37,"unknown"],[223,38,"unknown"],[223,39,"unknown"],[223,50,"catchable"],[224,4,"unknown"],[224,5,"unknown"],[224,6,"unknown"],[224,7,"unknown"],[224,8,"unknown"],[224,9,"catchable"],[224,10,"unknown"],[224,11,"unknown"],[224,12,"catchable"],[224,13,"catchable"],[224,14,"catchable"],[224,15,"unknown"],[224,16,"unknown"],[224,17,"catchable"],[224,18,"catchable"],[224,21,"catchable"],[224,22,"catchable"],[224,23,"catchable"],[224,24,"catchable"],[224,25,"unknown"],[224,26,"unknown"],[224,27,"unknown"],[224,28,"unknown"],[224,29,"catchable"],[224,30,"catchable"],[224,31,"unknown"],[224,32,"unknown"],[224,33,"catchable"],[224,34,"catchable"],[224,35,"catchable"],[224,36,"catchable"],[224,37,"unknown"],[224,38,"unknown"],[224,39,"unknown"],[224,50,"catchable"],[224,51,"catchable"],[225,4,"unknown"],[225,5,"catchable"],[225,6,"catchable"],[225,7,"unknown"],[225,8,"unknown"],[225,9,"unknown"],[225,10,"catchable"],[225,11,"unknown"],[225,12,"catchable"],[225,13,"catchable"],[225,14,"catchable"],[225,15,"unknown"],[225,16,"catchable"],[225,17,"catchable"],[225,18,"catchable"],[225,19,"catchable"],[225,21,"catchable"],[225,22,"catchable"],[225,23,"catchable"],[225,24,"catchable"],[225,25,"unknown"],[225,26,"unknown"],[225,27,"catchable"],[225,28,"catchable"],[225,29,"catchable"],[225,30,"catchable"],[225,31,"unknown"],[225,32,"unknown"],[225,33,"catchable"],[225,34,"catchable"],[225,35,"unknown"],[225,36,"catchable"],[225,37,"unknown"],[225,38,"unknown"],[225,39,"unknown"],[225,40,"unknown"],[225,41,"unknown"],[225,42,"unknown"],[225,43,"unknown"],[225,47,"unknown"],[225,48,"unknown"],[225,51,"catchable"],[226,4,"catchable"],[226,5,"unknown"],[226,6,"catchable"],[226,7,"unknown"],[226,8,"unknown"],[226,9,"unknown"],[226,10,"unknown"],[226,11,"catchable"],[226,12,"unknown"],[226,13,"unknown"],[226,14,"unknown"],[226,15,"catchable"],[226,16,"unknown"],[226,17,"catchable"],[226,18,"catchable"],[226,19,"catchable"],[226,21,"catchable"],[226,22,"catchable"],[226,23,"unknown"],[226,24,"unknown"],[226,25,"unknown"],[226,26,"unknown"],[226,27,"unknown"],[226,28,"unknown"],[226,29,"unknown"],[226,30,"unknown"],[226,31,"unknown"],[226,32,"unknown"],[226,33,"catchable"],[226,34,"catchable"],[226,35,"catchable"],[226,36,"catchable"],[226,37,"unknown"],[226,38,"unknown"],[226,39,"unknown"],[226,50,"catchable"],[226,51,"catchable"],[227,4,"unknown"],[227,5,"catchable"],[227,6,"catchable"],[227,7,"catchable"],[227,8,"catchable"],[227,9,"catchable"],[227,10,"catchable"],[227,11,"unknown"],[227,12,"catchable"],[227,13,"catchable"],[227,14,"catchable"],[227,15,"unknown"],[227,16,"catchable"],[227,17,"unknown"],[227,18,"unknown"],[227,19,"catchable"],[227,21,"catchable"],[227,22,"catchable"],[227,23,"catchable"],[227,24,"catchable"],[227,25,"catchable"],[227,26,"catchable"],[227,27,"catchable"],[227,28,"catchable"],[227,29,"catchable"],[227,30,"catchable"],[227,31,"unknown"],[227,32,"unknown"],[227,33,"unknown"],[227,34,"unknown"],[227,35,"catchable"],[227,36,"catchable"],[227,37,"unknown"],[227,38,"unknown"],[227,39,"unknown"],[227,40,"unknown"],[227,41,"unknown"],[227,42,"unknown"],[227,43,"unknown"],[227,47,"unknown"],[227,48,"unknown"],[227,49,"unknown"],[227,50,"catchable"],[227,51,"catchable"],[227,53,"unknown"],[228,4,"catchable"],[228,5,"catchable"],[228,6,"catchable"],[228,7,"unknown"],[228,8,"unknown"],[228,9,"catchable"],[228,10,"catchable"],[228,11,"catchable"],[228,12,"unknown"],[228,13,"unknown"],[228,14,"catchable"],[228,15,"catchable"],[228,16,"catchable"],[228,17,"unknown"],[228,18,"unknown"],[228,20,"catchable"],[228,21,"unknown"],[228,22,"unknown"],[228,23,"catchable"],[228,24,"unknown"],[228,25,"unknown"],[228,26,"unknown"],[228,27,"unknown"],[228,28,"unknown"],[228,29,"catchable"],[228,30,"unknown"],[228,31,"unknown"],[228,32,"unknown"],[228,40,"unknown"],[228,41,"unknown"],[228,42,"unknown"],[228,43,"unknown"],[228,47,"unknown"],[228,48,"unknown"],[228,52,"unknown"],[229,4,"unknown"],[229,5,"unknown"],[229,6,"unknown"],[229,7,"unknown"],[229,8,"unknown"],[229,9,"unknown"],[229,10,"unknown"],[229,11,"unknown"],[229,12,"unknown"],[229,13,"catchable"],[229,14,"unknown"],[229,15,"catchable"],[229,16,"catchable"],[229,17,"unknown"],[229,18,"unknown"],[229,19,"catchable"],[229,21,"unknown"],[229,22,"unknown"],[229,23,"unknown"],[229,24,"unknown"],[229,25,"unknown"],[229,26,"unknown"],[229,27,"unknown"],[229,28,"unknown"],[229,29,"catchable"],[229,30,"unknown"],[229,31,"unknown"],[229,32,"unknown"],[229,40,"unknown"],[229,41,"unknown"],[229,42,"unknown"],[229,43,"unknown"],[229,47,"unknown"],[229,48,"unknown"],[229,49,"unknown"],[229,52,"unknown"],[230,4,"unknown"],[230,5,"unknown"],[230,6,"unknown"],[230,7,"unknown"],[230,8,"unknown"],[230,9,"unknown"],[230,10,"unknown"],[230,11,"unknown"],[230,12,"unknown"],[230,13,"unknown"],[230,14,"unknown"],[230,15,"unknown"],[230,16,"unknown"],[230,17,"catchable"],[230,18,"catchable"],[230,21,"catchable"],[230,22,"catchable"],[230,23,"unknown"],[230,24,"unknown"],[230,25,"unknown"],[230,26,"unknown"],[230,27,"unknown"],[230,28,"unknown"],[230,29,"unknown"],[230,30,"unknown"],[230,31,"unknown"],[230,32,"unknown"],[230,33,"unknown"],[230,34,"unknown"],[230,35,"catchable"],[230,36,"unknown"],[230,37,"unknown"],[230,38,"unknown"],[230,39,"unknown"],[230,40,"unknown"],[230,41,"unknown"],[230,42,"unknown"],[230,43,"unknown"],[230,47,"unknown"],[230,48,"unknown"],[230,50,"catchable"],[230,53,"unknown"],[231,4,"unknown"],[231,5,"catchable"],[231,6,"catchable"],[231,7,"catchable"],[231,8,"catchable"],[231,9,"catchable"],[231,10,"catchable"],[231,11,"catchable"],[231,12,"catchable"],[231,13,"catchable"],[231,14,"catchable"],[231,15,"catchable"],[231,16,"unknown"],[231,17,"unknown"],[231,18,"unknown"],[231,20,"catchable"],[231,21,"unknown"],[231,22,"unknown"],[231,23,"catchable"],[231,24,"catchable"],[231,25,"unknown"],[231,26,"unknown"],[231,27,"unknown"],[231,28,"unknown"],[231,29,"unknown"],[231,30,"unknown"],[231,31,"unknown"],[231,32,"unknown"],[231,40,"unknown"],[231,41,"unknown"],[231,42,"unknown"],[231,43,"unknown"],[231,47,"unknown"],[231,48,"unknown"],[232,4,"unknown"],[232,5,"catchable"],[232,6,"catchable"],[232,7,"unknown"],[232,8,"unknown"],[232,9,"unknown"],[232,10,"unknown"],[232,11,"unknown"],[232,12,"unknown"],[232,13,"unknown"],[232,14,"unknown"],[232,15,"catchable"],[232,16,"unknown"],[232,17,"unknown"],[232,18,"unknown"],[232,21,"unknown"],[232,22,"unknown"],[232,23,"unknown"],[232,24,"unknown"],[232,25,"catchable"],[232,26,"catchable"],[232,27,"unknown"],[232,28,"unknown"],[232,29,"unknown"],[232,30,"unknown"],[232,31,"unknown"],[232,32,"unknown"],[232,40,"unknown"],[232,41,"unknown"],[232,42,"unknown"],[232,43,"unknown"],[232,47,"unknown"],[232,48,"unknown"],[233,4,"unknown"],[233,5,"unknown"],[233,6,"unknown"],[233,7,"unknown"],[233,8,"unknown"],[233,9,"unknown"],[233,10,"unknown"],[233,11,"unknown"],[233,12,"unknown"],[233,13,"unknown"],[233,14,"unknown"],[233,15,"unknown"],[233,16,"unknown"],[233,17,"unknown"],[233,18,"unknown"],[233,21,"unknown"],[233,22,"unknown"],[233,23,"unknown"],[233,24,"unknown"],[233,25,"unknown"],[233,26,"unknown"],[233,27,"unknown"],[233,28,"unknown"],[233,29,"unknown"],[233,30,"unknown"],[233,31,"unknown"],[233,32,"unknown"],[233,33,"unknown"],[233,34,"unknown"],[233,35,"unknown"],[233,36,"unknown"],[233,37,"unknown"],[233,38,"unknown"],[233,39,"unknown"],[233,40,"unknown"],[233,41,"unknown"],[233,42,"unknown"],[233,43,"unknown"],[233,47,"unknown"],[233,48,"unknown"],[233,50,"unknown"],[233,53,"unknown"],[234,4,"catchable"],[234,5,"catchable"],[234,6,"catchable"],[234,7,"unknown"],[234,8,"unknown"],[234,9,"catchable"],[234,10,"catchable"],[234,11,"catchable"],[234,12,"unknown"],[234,13,"catchable"],[234,14,"catchable"],[234,15,"catchable"],[234,16,"catchable"],[234,17,"catchable"],[234,18,"catchable"],[234,19,"catchable"],[234,21,"unknown"],[234,22,"unknown"],[234,23,"unknown"],[234,24,"unknown"],[234,25,"catchable"],[234,26,"catchable"],[234,27,"unknown"],[234,28,"unknown"],[234,29,"unknown"],[234,30,"unknown"],[234,31,"unknown"],[234,32,"unknown"],[234,39,"unknown"],[234,40,"unknown"],[234,41,"unknown"],[234,42,"unknown"],[234,43,"unknown"],[234,47,"unknown"],[234,48,"unknown"],[234,52,"unknown"],[235,4,"catchable"],[235,5,"catchable"],[235,6,"catchable"],[235,7,"unknown"],[235,8,"unknown"],[235,9,"catchable"],[235,10,"catchable"],[235,11,"catchable"],[235,12,"catchable"],[235,13,"catchable"],[235,14,"catchable"],[235,15,"catchable"],[235,16,"catchable"],[235,17,"unknown"],[235,18,"unknown"],[235,19,"catchable"],[235,21,"unknown"],[235,22,"unknown"],[235,23,"catchable"],[235,24,"catchable"],[235,25,"unknown"],[235,26,"unknown"],[235,27,"catchable"],[235,28,"catchable"],[235,29,"catchable"],[235,30,"catchable"],[235,31,"unknown"],[235,32,"unknown"],[235,40,"unknown"],[235,41,"unknown"],[235,42,"unknown"],[235,43,"unknown"],[235,47,"unknown"],[235,48,"unknown"],[235,53,"unknown"],[236,4,"catchable"],[236,5,"catchable"],[236,6,"catchable"],[236,7,"unknown"],[236,8,"unknown"],[236,9,"unknown"],[236,10,"unknown"],[236,11,"unknown"],[236,12,"catchable"],[236,13,"catchable"],[236,14,"catchable"],[236,15,"catchable"],[236,16,"catchable"],[236,17,"unknown"],[236,18,"unknown"],[236,21,"unknown"],[236,22,"unknown"],[236,23,"catchable"],[236,24,"catchable"],[236,25,"unknown"],[236,26,"unknown"],[236,27,"unknown"],[236,28,"unknown"],[236,29,"unknown"],[236,30,"unknown"],[236,31,"unknown"],[236,32,"unknown"],[236,33,"catchable"],[236,34,"catchable"],[236,35,"unknown"],[236,36,"catchable"],[236,37,"unknown"],[236,38,"unknown"],[236,39,"unknown"],[236,40,"unknown"],[236,41,"unknown"],[236,42,"unknown"],[236,43,"unknown"],[236,47,"unknown"],[236,48,"unknown"],[236,51,"catchable"],[236,53,"unknown"],[237,4,"unknown"],[237,5,"unknown"],[237,6,"unknown"],[237,7,"unknown"],[237,8,"unknown"],[237,9,"unknown"],[237,10,"unknown"],[237,11,"unknown"],[237,12,"unknown"],[237,13,"unknown"],[237,14,"unknown"],[237,15,"unknown"],[237,16,"unknown"],[237,17,"unknown"],[237,18,"unknown"],[237,19,"catchable"],[237,21,"unknown"],[237,22,"unknown"],[237,23,"unknown"],[237,24,"unknown"],[237,25,"unknown"],[237,26,"unknown"],[237,27,"unknown"],[237,28,"unknown"],[237,29,"unknown"],[237,30,"unknown"],[237,31,"unknown"],[237,32,"unknown"],[237,33,"catchable"],[237,34,"catchable"],[237,35,"unknown"],[237,36,"catchable"],[237,37,"unknown"],[237,38,"unknown"],[237,39,"unknown"],[237,40,"unknown"],[237,41,"unknown"],[237,42,"unknown"],[237,43,"unknown"],[237,47,"unknown"],[237,48,"unknown"],[237,51,"catchable"],[237,53,"unknown"],[238,4,"unknown"],[238,5,"unknown"],[238,6,"catchable"],[238,7,"unknown"],[238,8,"unknown"],[238,9,"unknown"],[238,10,"unknown"],[238,11,"unknown"],[238,12,"catchable"],[238,13,"catchable"],[238,14,"catchable"],[238,15,"unknown"],[238,16,"unknown"],[238,17,"unknown"],[238,18,"unknown"],[238,21,"unknown"],[238,22,"unknown"],[238,23,"catchable"],[238,24,"catchable"],[238,25,"unknown"],[238,26,"unknown"],[238,27,"unknown"],[238,28,"unknown"],[238,29,"catchable"],[238,30,"catchable"],[238,31,"unknown"],[238,32,"unknown"],[238,33,"unknown"],[238,34,"unknown"],[238,35,"unknown"],[238,36,"catchable"],[238,37,"unknown"],[238,38,"unknown"],[238,39,"unknown"],[238,51,"catchable"],[239,4,"unknown"],[239,5,"unknown"],[239,6,"catchable"],[239,7,"unknown"],[239,8,"unknown"],[239,9,"unknown"],[239,10,"unknown"],[239,11,"unknown"],[239,12,"catchable"],[239,13,"catchable"],[239,14,"unknown"],[239,15,"unknown"],[239,16,"unknown"],[239,17,"unknown"],[239,18,"unknown"],[239,20,"catchable"],[239,21,"unknown"],[239,22,"catchable"],[239,23,"unknown"],[239,24,"unknown"],[239,25,"catchable"],[239,26,"catchable"],[239,27,"catchable"],[239,28,"catchable"],[239,29,"catchable"],[239,30,"catchable"],[239,31,"unknown"],[239,32,"unknown"],[239,33,"unknown"],[239,34,"unknown"],[239,35,"unknown"],[239,36,"catchable"],[239,37,"unknown"],[239,38,"unknown"],[239,39,"unknown"],[239,40,"unknown"],[239,41,"unknown"],[239,42,"unknown"],[239,43,"unknown"],[239,47,"unknown"],[239,48,"unknown"],[239,51,"catchable"],[239,53,"unknown"],[240,4,"unknown"],[240,5,"unknown"],[240,6,"catchable"],[240,7,"unknown"],[240,8,"unknown"],[240,9,"unknown"],[240,10,"unknown"],[240,11,"unknown"],[240,12,"catchable"],[240,13,"catchable"],[240,14,"unknown"],[240,15,"unknown"],[240,16,"unknown"],[240,17,"unknown"],[240,18,"unknown"],[240,21,"catchable"],[240,22,"unknown"],[240,23,"unknown"],[240,24,"unknown"],[240,25,"catchable"],[240,26,"catchable"],[240,27,"catchable"],[240,28,"catchable"],[240,29,"catchable"],[240,30,"catchable"],[240,31,"unknown"],[240,32,"unknown"],[240,33,"unknown"],[240,34,"unknown"],[240,35,"unknown"],[240,36,"catchable"],[240,37,"unknown"],[240,38,"unknown"],[240,39,"unknown"],[240,40,"unknown"],[240,41,"unknown"],[240,42,"unknown"],[240,43,"unknown"],[240,47,"unknown"],[240,48,"unknown"],[240,51,"catchable"],[240,53,"unknown"],[241,4,"catchable"],[241,5,"catchable"],[241,6,"catchable"],[241,7,"unknown"],[241,8,"unknown"],[241,9,"catchable"],[241,10,"unknown"],[241,11,"unknown"],[241,12,"catchable"],[241,13,"catchable"],[241,14,"catchable"],[241,15,"catchable"],[241,16,"catchable"],[241,17,"unknown"],[241,18,"unknown"],[241,19,"catchable"],[241,21,"unknown"],[241,22,"unknown"],[241,23,"catchable"],[241,24,"catchable"],[241,25,"unknown"],[241,26,"unknown"],[241,27,"catchable"],[241,28,"catchable"],[241,29,"catchable"],[241,30,"catchable"],[241,31,"unknown"],[241,32,"unknown"],[241,33,"unknown"],[241,34,"unknown"],[241,35,"catchable"],[241,36,"catchable"],[241,37,"unknown"],[241,38,"unknown"],[241,39,"unknown"],[241,50,"catchable"],[241,51,"catchable"],[242,4,"unknown"],[242,5,"unknown"],[242,6,"unknown"],[242,7,"unknown"],[242,8,"unknown"],[242,9,"unknown"],[242,10,"unknown"],[242,11,"unknown"],[242,12,"unknown"],[242,13,"unknown"],[242,14,"unknown"],[242,15,"unknown"],[242,16,"unknown"],[242,17,"unknown"],[242,18,"unknown"],[242,21,"unknown"],[242,22,"unknown"],[242,23,"unknown"],[242,24,"unknown"],[242,25,"unknown"],[242,26,"unknown"],[242,27,"unknown"],[242,28,"unknown"],[242,29,"catchable"],[242,30,"catchable"],[242,31,"unknown"],[242,32,"unknown"],[242,33,"unknown"],[242,34,"unknown"],[242,35,"catchable"],[242,36,"unknown"],[242,37,"unknown"],[242,38,"unknown"],[242,39,"unknown"],[242,40,"unknown"],[242,41,"unknown"],[242,42,"unknown"],[242,43,"unknown"],[242,47,"unknown"],[242,48,"unknown"],[242,50,"catchable"],[242,53,"unknown"],[243,4,"catchable"],[243,5,"catchable"],[243,6,"catchable"],[243,7,"unknown"],[243,8,"unknown"],[243,9,"unknown"],[243,10,"catchable"],[243,11,"catchable"],[243,12,"unknown"],[243,13,"unknown"],[243,14,"unknown"],[243,15,"catchable"],[243,16,"catchable"],[243,17,"unknown"],[243,18,"unknown"],[243,19,"catchable"],[243,21,"unknown"],[243,22,"unknown"],[243,23,"unknown"],[243,24,"unknown"],[243,25,"catchable"],[243,26,"catchable"],[243,27,"unknown"],[243,28,"unknown"],[243,29,"catchable"],[243,30,"unknown"],[243,31,"unknown"],[243,32,"unknown"],[243,33,"unknown"],[243,34,"unknown"],[243,35,"unknown"],[243,36,"catchable"],[243,37,"unknown"],[243,38,"unknown"],[243,39,"unknown"],[243,40,"unknown"],[243,41,"unknown"],[243,42,"unknown"],[243,43,"unknown"],[243,47,"unknown"],[243,48,"unknown"],[243,51,"catchable"],[244,4,"catchable"],[244,5,"catchable"],[244,6,"catchable"],[244,7,"unknown"],[244,8,"unknown"],[244,9,"unknown"],[244,10,"catchable"],[244,11,"catchable"],[244,12,"unknown"],[244,13,"unknown"],[244,14,"unknown"],[244,15,"catchable"],[244,16,"catchable"],[244,17,"unknown"],[244,18,"unknown"],[244,19,"catchable"],[244,21,"unknown"],[244,22,"unknown"],[244,23,"unknown"],[244,24,"unknown"],[244,25,"catchable"],[244,26,"catchable"],[244,27,"unknown"],[244,28,"unknown"],[244,29,"unknown"],[244,30,"catchable"],[244,31,"unknown"],[244,32,"unknown"],[244,33,"unknown"],[244,34,"unknown"],[244,35,"unknown"],[244,36,"catchable"],[244,37,"unknown"],[244,38,"unknown"],[244,39,"unknown"],[244,40,"unknown"],[244,41,"unknown"],[244,42,"unknown"],[244,43,"unknown"],[244,47,"unknown"],[244,48,"unknown"],[244,51,"catchable"],[245,4,"catchable"],[245,5,"catchable"],[245,6,"catchable"],[245,7,"unknown"],[245,8,"unknown"],[245,9,"unknown"],[245,10,"catchable"],[245,11,"catchable"],[245,12,"unknown"],[245,13,"unknown"],[245,14,"unknown"],[245,15,"catchable"],[245,16,"catchable"],[245,17,"unknown"],[245,18,"unknown"],[245,19,"catchable"],[245,21,"unknown"],[245,22,"unknown"],[245,23,"unknown"],[245,24,"unknown"],[245,25,"catchable"],[245,26,"catchable"],[245,27,"unknown"],[245,28,"unknown"],[245,29,"catchable"],[245,30,"catchable"],[245,31,"unknown"],[245,32,"unknown"],[245,33,"unknown"],[245,34,"unknown"],[245,35,"unknown"],[245,36,"catchable"],[245,37,"unknown"],[245,38,"unknown"],[245,39,"unknown"],[245,40,"unknown"],[245,41,"unknown"],[245,42,"unknown"],[245,43,"unknown"],[245,47,"unknown"],[245,48,"unknown"],[245,51,"catchable"],[246,4,"catchable"],[246,5,"catchable"],[246,6,"catchable"],[246,7,"unknown"],[246,8,"unknown"],[246,9,"unknown"],[246,10,"catchable"],[246,11,"catchable"],[246,12,"catchable"],[246,13,"unknown"],[246,14,"catchable"],[246,15,"catchable"],[246,16,"catchable"],[246,17,"unknown"],[246,18,"unknown"],[246,20,"catchable"],[246,21,"unknown"],[246,22,"unknown"],[246,23,"unknown"],[246,24,"catchable"],[246,25,"unknown"],[246,26,"unknown"],[246,27,"unknown"],[246,28,"unknown"],[246,29,"catchable"],[246,30,"catchable"],[246,31,"unknown"],[246,32,"unknown"],[246,33,"unknown"],[246,34,"catchable"],[246,35,"unknown"],[246,36,"unknown"],[246,37,"unknown"],[246,38,"unknown"],[246,39,"unknown"],[246,40,"unknown"],[246,41,"unknown"],[246,42,"unknown"],[246,43,"unknown"],[246,47,"unknown"],[246,48,"unknown"],[246,51,"catchable"],[247,4,"unknown"],[247,5,"unknown"],[247,6,"catchable"],[247,7,"unknown"],[247,8,"unknown"],[247,9,"unknown"],[247,10,"unknown"],[247,11,"unknown"],[247,12,"unknown"],[247,13,"unknown"],[247,14,"unknown"],[247,15,"catchable"],[247,16,"catchable"],[247,17,"catchable"],[247,18,"catchable"],[247,21,"catchable"],[247,22,"catchable"],[247,23,"catchable"],[247,24,"catchable"],[247,25,"unknown"],[247,26,"unknown"],[247,27,"unknown"],[247,28,"unknown"],[247,29,"unknown"],[247,30,"unknown"],[247,31,"unknown"],[247,32,"unknown"],[247,33,"unknown"],[247,34,"catchable"],[247,35,"unknown"],[247,36,"unknown"],[247,37,"unknown"],[247,38,"unknown"],[247,39,"unknown"],[247,40,"unknown"],[247,41,"unknown"],[247,42,"unknown"],[247,43,"unknown"],[247,47,"unknown"],[247,48,"unknown"],[247,51,"unknown"],[248,4,"unknown"],[248,5,"unknown"],[248,6,"unknown"],[248,7,"unknown"],[248,8,"unknown"],[248,9,"unknown"],[248,10,"unknown"],[248,11,"unknown"],[248,12,"unknown"],[248,13,"unknown"],[248,14,"unknown"],[248,15,"unknown"],[248,16,"unknown"],[248,17,"catchable"],[248,18,"catchable"],[248,19,"catchable"],[248,21,"catchable"],[248,22,"catchable"],[248,23,"unknown"],[248,24,"unknown"],[248,25,"unknown"],[248,26,"unknown"],[248,27,"unknown"],[248,28,"unknown"],[248,29,"unknown"],[248,30,"unknown"],[248,31,"unknown"],[248,32,"unknown"],[248,33,"unknown"],[248,34,"catchable"],[248,35,"unknown"],[248,36,"unknown"],[248,37,"unknown"],[248,38,"unknown"],[248,39,"unknown"],[248,40,"unknown"],[248,41,"unknown"],[248,42,"unknown"],[248,43,"unknown"],[248,47,"unknown"],[248,48,"unknown"],[248,49,"unknown"],[248,51,"catchable"],[249,4,"catchable"],[249,5,"catchable"],[249,6,"catchable"],[249,7,"unknown"],[249,8,"unknown"],[249,9,"catchable"],[249,10,"catchable"],[249,11,"catchable"],[249,12,"unknown"],[249,13,"unknown"],[249,14,"unknown"],[249,15,"catchable"],[249,16,"catchable"],[249,17,"unknown"],[249,18,"unknown"],[249,20,"catchable"],[249,21,"unknown"],[249,22,"unknown"],[249,23,"unknown"],[249,24,"unknown"],[249,25,"unknown"],[249,26,"catchable"],[249,27,"unknown"],[249,28,"unknown"],[249,29,"unknown"],[249,30,"catchable"],[249,31,"unknown"],[249,32,"unknown"],[249,33,"unknown"],[249,34,"unknown"],[249,35,"unknown"],[249,36,"unknown"],[249,37,"unknown"],[249,38,"unknown"],[249,39,"unknown"],[249,40,"unknown"],[249,41,"unknown"],[249,42,"unknown"],[249,43,"unknown"],[249,47,"unknown"],[249,48,"unknown"],[249,51,"catchable"],[250,4,"catchable"],[250,5,"catchable"],[250,6,"catchable"],[250,7,"unknown"],[250,8,"unknown"],[250,9,"catchable"],[250,10,"catchable"],[250,11,"catchable"],[250,12,"unknown"],[250,13,"unknown"],[250,14,"unknown"],[250,15,"catchable"],[250,16,"catchable"],[250,17,"unknown"],[250,18,"unknown"],[250,19,"catchable"],[250,21,"unknown"],[250,22,"unknown"],[250,23,"unknown"],[250,24,"unknown"],[250,25,"catchable"],[250,26,"unknown"],[250,27,"unknown"],[250,28,"unknown"],[250,29,"catchable"],[250,30,"unknown"],[250,31,"unknown"],[250,32,"unknown"],[250,33,"unknown"],[250,34,"unknown"],[250,35,"unknown"],[250,36,"catchable"],[250,37,"unknown"],[250,38,"unknown"],[250,39,"unknown"],[250,40,"unknown"],[250,41,"unknown"],[250,42,"unknown"],[250,43,"unknown"],[250,47,"unknown"],[250,48,"unknown"],[251,4,"unknown"],[251,5,"unknown"],[251,6,"catchable"],[251,7,"catchable"],[251,8,"catchable"],[251,9,"catchable"],[251,10,"catchable"],[251,11,"catchable"],[251,12,"unknown"],[251,13,"unknown"],[251,14,"unknown"],[251,15,"unknown"],[251,16,"unknown"],[251,17,"unknown"],[251,18,"unknown"],[251,21,"unknown"],[251,22,"unknown"],[251,23,"unknown"],[251,24,"unknown"],[251,25,"unknown"],[251,26,"unknown"],[251,27,"unknown"],[251,28,"unknown"],[251,29,"unknown"],[251,30,"unknown"],[251,31,"unknown"],[251,32,"unknown"],[251,33,"unknown"],[251,34,"unknown"],[251,35,"unknown"],[251,36,"unknown"],[251,37,"unknown"],[251,38,"unknown"],[251,39,"unknown"],[252,7,"catchable"],[252,8,"catchable"],[252,9,"catchable"],[252,10,"unknown"],[252,11,"unknown"],[252,12,"unknown"],[252,13,"unknown"],[252,14,"unknown"],[252,15,"catchable"],[252,16,"catchable"],[252,17,"unknown"],[252,18,"unknown"],[252,21,"unknown"],[252,22,"unknown"],[252,23,"unknown"],[252,24,"unknown"],[252,25,"catchable"],[252,26,"catchable"],[252,27,"unknown"],[252,28,"unknown"],[252,29,"unknown"],[252,30,"unknown"],[252,31,"unknown"],[252,32,"unknown"],[252,33,"unknown"],[252,34,"unknown"],[252,35,"unknown"],[252,36,"unknown"],[252,37,"unknown"],[252,38,"unknown"],[252,39,"unknown"],[252,40,"unknown"],[252,41,"unknown"],[252,42,"unknown"],[252,43,"unknown"],[252,47,"unknown"],[252,48,"unknown"],[252,53,"unknown"],[253,7,"unknown"],[253,8,"unknown"],[253,9,"unknown"],[253,10,"unknown"],[253,11,"unknown"],[253,12,"unknown"],[253,13,"unknown"],[253,14,"unknown"],[253,15,"unknown"],[253,16,"unknown"],[253,17,"unknown"],[253,18,"unknown"],[253,21,"unknown"],[253,22,"unknown"],[253,23,"unknown"],[253,24,"unknown"],[253,25,"unknown"],[253,26,"unknown"],[253,27,"unknown"],[253,28,"unknown"],[253,29,"catchable"],[253,30,"catchable"],[253,31,"unknown"],[253,32,"unknown"],[253,33,"unknown"],[253,34,"unknown"],[253,35,"unknown"],[253,36,"catchable"],[253,37,"unknown"],[253,38,"unknown"],[253,39,"unknown"],[253,40,"unknown"],[253,41,"unknown"],[253,42,"unknown"],[253,43,"unknown"],[253,47,"unknown"],[253,48,"unknown"],[253,51,"catchable"],[253,53,"unknown"],[254,7,"unknown"],[254,8,"unknown"],[254,9,"unknown"],[254,10,"unknown"],[254,11,"unknown"],[254,12,"unknown"],[254,13,"unknown"],[254,14,"unknown"],[254,15,"unknown"],[254,16,"unknown"],[254,17,"unknown"],[254,18,"unknown"],[254,21,"unknown"],[254,22,"unknown"],[254,23,"unknown"],[254,24,"unknown"],[254,25,"unknown"],[254,26,"unknown"],[254,27,"unknown"],[254,28,"unknown"],[254,29,"unknown"],[254,30,"unknown"],[254,31,"unknown"],[254,32,"unknown"],[254,33,"unknown"],[254,34,"unknown"],[254,35,"unknown"],[254,36,"catchable"],[254,37,"unknown"],[254,38,"unknown"],[254,39,"unknown"],[254,40,"unknown"],[254,41,"unknown"],[254,42,"unknown"],[254,43,"unknown"],[254,47,"unknown"],[254,48,"unknown"],[254,49,"unknown"],[254,51,"catchable"],[254,53,"unknown"],[255,7,"catchable"],[255,8,"catchable"],[255,9,"catchable"],[255,10,"unknown"],[255,11,"unknown"],[255,12,"unknown"],[255,13,"unknown"],[255,14,"unknown"],[255,15,"catchable"],[255,16,"catchable"],[255,17,"unknown"],[255,18,"unknown"],[255,21,"unknown"],[255,22,"unknown"],[255,23,"unknown"],[255,24,"unknown"],[255,25,"catchable"],[255,26,"catchable"],[255,27,"unknown"],[255,28,"unknown"],[255,29,"unknown"],[255,30,"unknown"],[255,31,"unknown"],[255,32,"unknown"],[255,33,"unknown"],[255,34,"unknown"],[255,35,"unknown"],[255,36,"unknown"],[255,37,"unknown"],[255,38,"unknown"],[255,39,"unknown"],[255,40,"unknown"],[255,41,"unknown"],[255,42,"unknown"],[255,43,"unknown"],[255,47,"unknown"],[255,48,"unknown"],[255,53,"unknown"],[256,7,"unknown"],[256,8,"unknown"],[256,9,"unknown"],[256,10,"unknown"],[256,11,"unknown"],[256,12,"unknown"],[256,13,"unknown"],[256,14,"unknown"],[256,15,"unknown"],[256,16,"unknown"],[256,17,"unknown"],[256,18,"unknown"],[256,21,"unknown"],[256,22,"unknown"],[256,23,"unknown"],[256,24,"unknown"],[256,25,"unknown"],[256,26,"unknown"],[256,27,"unknown"],[256,28,"unknown"],[256,29,"catchable"],[256,30,"catchable"],[256,31,"unknown"],[256,32,"unknown"],[256,33,"unknown"],[256,34,"unknown"],[256,35,"unknown"],[256,36,"catchable"],[256,37,"unknown"],[256,38,"unknown"],[256,39,"unknown"],[256,40,"unknown"],[256,41,"unknown"],[256,42,"unknown"],[256,43,"unknown"],[256,47,"unknown"],[256,48,"unknown"],[256,51,"catchable"],[256,53,"unknown"],[257,7,"unknown"],[257,8,"unknown"],[257,9,"unknown"],[257,10,"unknown"],[257,11,"unknown"],[257,12,"unknown"],[257,13,"unknown"],[257,14,"unknown"],[257,15,"unknown"],[257,16,"unknown"],[257,17,"unknown"],[257,18,"unknown"],[257,21,"unknown"],[257,22,"unknown"],[257,23,"unknown"],[257,24,"unknown"],[257,25,"unknown"],[257,26,"unknown"],[257,27,"unknown"],[257,28,"unknown"],[257,29,"unknown"],[257,30,"unknown"],[257,31,"unknown"],[257,32,"unknown"],[257,33,"unknown"],[257,34,"unknown"],[257,35,"unknown"],[257,36,"catchable"],[257,37,"unknown"],[257,38,"unknown"],[257,39,"unknown"],[257,40,"unknown"],[257,41,"unknown"],[257,42,"unknown"],[257,43,"unknown"],[257,47,"unknown"],[257,48,"unknown"],[257,49,"unknown"],[257,51,"catchable"],[257,53,"unknown"],[258,7,"catchable"],[258,8,"catchable"],[258,9,"catchable"],[258,10,"unknown"],[258,11,"unknown"],[258,12,"unknown"],[258,13,"unknown"],[258,14,"unknown"],[258,15,"catchable"],[258,16,"catchable"],[258,17,"unknown"],[258,18,"unknown"],[258,21,"unknown"],[258,22,"unknown"],[258,23,"unknown"],[258,24,"unknown"],[258,25,"catchable"],[258,26,"catchable"],[258,27,"unknown"],[258,28,"unknown"],[258,29,"unknown"],[258,30,"unknown"],[258,31,"unknown"],[258,32,"unknown"],[258,33,"unknown"],[258,34,"unknown"],[258,35,"unknown"],[258,36,"unknown"],[258,37,"unknown"],[258,38,"unknown"],[258,39,"unknown"],[258,40,"unknown"],[258,41,"unknown"],[258,42,"unknown"],[258,43,"unknown"],[258,47,"unknown"],[258,48,"unknown"],[258,53,"unknown"],[259,7,"unknown"],[259,8,"unknown"],[259,9,"unknown"],[259,10,"unknown"],[259,11,"unknown"],[259,12,"unknown"],[259,13,"unknown"],[259,14,"unknown"],[259,15,"unknown"],[259,16,"unknown"],[259,17,"unknown"],[259,18,"unknown"],[259,21,"unknown"],[259,22,"unknown"],[259,23,"unknown"],[259,24,"unknown"],[259,25,"unknown"],[259,26,"unknown"],[259,27,"unknown"],[259,28,"unknown"],[259,29,"catchable"],[259,30,"catchable"],[259,31,"unknown"],[259,32,"unknown"],[259,33,"unknown"],[259,34,"unknown"],[259,35,"unknown"],[259,36,"catchable"],[259,37,"unknown"],[259,38,"unknown"],[259,39,"unknown"],[259,40,"unknown"],[259,41,"unknown"],[259,42,"unknown"],[259,43,"unknown"],[259,47,"unknown"],[259,48,"unknown"],[259,51,"catchable"],[259,53,"unknown"],[260,7,"unknown"],[260,8,"unknown"],[260,9,"unknown"],[260,10,"unknown"],[260,11,"unknown"],[260,12,"unknown"],[260,13,"unknown"],[260,14,"unknown"],[260,15,"unknown"],[260,16,"unknown"],[260,17,"unknown"],[260,18,"unknown"],[260,21,"unknown"],[260,22,"unknown"],[260,23,"unknown"],[260,24,"unknown"],[260,25,"unknown"],[260,26,"unknown"],[260,27,"unknown"],[260,28,"unknown"],[260,29,"unknown"],[260,30,"unknown"],[260,31,"unknown"],[260,32,"unknown"],[260,33,"unknown"],[260,34,"unknown"],[260,35,"unknown"],[260,36,"catchable"],[260,37,"unknown"],[260,38,"unknown"],[260,39,"unknown"],[260,40,"unknown"],[260,41,"unknown"],[260,42,"unknown"],[260,43,"unknown"],[260,47,"unknown"],[260,48,"unknown"],[260,49,"unknown"],[260,51,"catchable"],[260,53,"unknown"],[261,7,"catchable"],[261,8,"catchable"],[261,9,"catchable"],[261,10,"unknown"],[261,11,"unknown"],[261,12,"unknown"],[261,13,"unknown"],[261,14,"catchable"],[261,15,"catchable"],[261,16,"catchable"],[261,17,"unknown"],[261,18,"unknown"],[261,20,"catchable"],[261,21,"unknown"],[261,22,"unknown"],[261,23,"unknown"],[261,24,"unknown"],[261,25,"catchable"],[261,26,"catchable"],[261,27,"unknown"],[261,28,"unknown"],[261,29,"unknown"],[261,30,"unknown"],[261,31,"unknown"],[261,32,"unknown"],[261,40,"unknown"],[261,41,"unknown"],[261,42,"unknown"],[261,43,"unknown"],[261,47,"unknown"],[261,48,"unknown"],[261,52,"unknown"],[262,7,"unknown"],[262,8,"unknown"],[262,9,"catchable"],[262,10,"unknown"],[262,11,"unknown"],[262,12,"catchable"],[262,13,"unknown"],[262,14,"unknown"],[262,15,"unknown"],[262,16,"unknown"],[262,17,"unknown"],[262,18,"unknown"],[262,21,"unknown"],[262,22,"unknown"],[262,23,"catchable"],[262,24,"catchable"],[262,25,"unknown"],[262,26,"unknown"],[262,27,"unknown"],[262,28,"unknown"],[262,29,"unknown"],[262,30,"unknown"],[262,31,"unknown"],[262,32,"unknown"],[262,40,"unknown"],[262,41,"unknown"],[262,42,"unknown"],[262,43,"unknown"],[262,47,"unknown"],[262,48,"unknown"],[262,52,"unknown"],[263,7,"catchable"],[263,8,"catchable"],[263,9,"catchable"],[263,10,"unknown"],[263,11,"unknown"],[263,12,"catchable"],[263,13,"catchable"],[263,14,"catchable"],[263,15,"catchable"],[263,16,"catchable"],[263,17,"unknown"],[263,18,"unknown"],[263,21,"unknown"],[263,22,"unknown"],[263,23,"catchable"],[263,24,"catchable"],[263,25,"catchable"],[263,26,"catchable"],[263,27,"unknown"],[263,28,"unknown"],[263,29,"unknown"],[263,30,"unknown"],[263,31,"unknown"],[263,32,"unknown"],[263,33,"catchable"],[263,34,"catchable"],[263,35,"catchable"],[263,36,"unknown"],[263,37,"unknown"],[263,38,"unknown"],[263,39,"unknown"],[263,50,"catchable"],[263,51,"unknown"],[264,7,"catchable"],[264,8,"catchable"],[264,9,"catchable"],[264,10,"unknown"],[264,11,"unknown"],[264,12,"unknown"],[264,13,"unknown"],[264,14,"unknown"],[264,15,"catchable"],[264,16,"catchable"],[264,17,"unknown"],[264,18,"unknown"],[264,21,"unknown"],[264,22,"unknown"],[264,23,"unknown"],[264,24,"unknown"],[264,25,"unknown"],[264,26,"unknown"],[264,27,"unknown"],[264,28,"unknown"],[264,29,"unknown"],[264,30,"unknown"],[264,31,"unknown"],[264,32,"unknown"],[264,33,"catchable"],[264,34,"catchable"],[264,35,"unknown"],[264,36,"catchable"],[264,37,"unknown"],[264,38,"unknown"],[264,39,"unknown"],[264,51,"catchable"],[265,7,"catchable"],[265,8,"catchable"],[265,9,"catchable"],[265,10,"unknown"],[265,11,"unknown"],[265,12,"catchable"],[265,13,"catchable"],[265,14,"catchable"],[265,15,"catchable"],[265,16,"catchable"],[265,17,"unknown"],[265,18,"unknown"],[265,21,"unknown"],[265,22,"unknown"],[265,23,"unknown"],[265,24,"unknown"],[265,25,"catchable"],[265,26,"catchable"],[265,27,"unknown"],[265,28,"unknown"],[265,29,"unknown"],[265,30,"unknown"],[265,31,"unknown"],[265,32,"unknown"],[265,37,"unknown"],[265,38,"unknown"],[265,39,"unknown"],[266,7,"catchable"],[266,8,"catchable"],[266,9,"catchable"],[266,10,"unknown"],[266,11,"unknown"],[266,12,"catchable"],[266,13,"unknown"],[266,14,"catchable"],[266,15,"catchable"],[266,16,"catchable"],[266,17,"unknown"],[266,18,"unknown"],[266,21,"unknown"],[266,22,"unknown"],[266,23,"unknown"],[266,24,"unknown"],[266,25,"unknown"],[266,26,"unknown"],[266,27,"unknown"],[266,28,"unknown"],[266,29,"unknown"],[266,30,"unknown"],[266,31,"unknown"],[266,32,"unknown"],[266,37,"unknown"],[266,38,"unknown"],[266,39,"unknown"],[267,7,"unknown"],[267,8,"unknown"],[267,9,"unknown"],[267,10,"unknown"],[267,11,"unknown"],[267,12,"catchable"],[267,13,"catchable"],[267,14,"catchable"],[267,15,"catchable"],[267,16,"catchable"],[267,17,"unknown"],[267,18,"unknown"],[267,21,"unknown"],[267,22,"unknown"],[267,23,"catchable"],[267,24,"catchable"],[267,25,"unknown"],[267,26,"unknown"],[267,27,"unknown"],[267,28,"unknown"],[267,29,"unknown"],[267,30,"unknown"],[267,31,"unknown"],[267,32,"unknown"],[267,37,"unknown"],[267,38,"unknown"],[267,39,"unknown"],[268,7,"catchable"],[268,8,"catchable"],[268,9,"catchable"],[268,10,"unknown"],[268,11,"unknown"],[268,12,"unknown"],[268,13,"catchable"],[268,14,"catchable"],[268,15,"catchable"],[268,16,"catchable"],[268,17,"unknown"],[268,18,"unknown"],[268,21,"unknown"],[268,22,"unknown"],[268,23,"catchable"],[268,24,"catchable"],[268,25,"unknown"],[268,26,"unknown"],[268,27,"unknown"],[268,28,"unknown"],[268,29,"unknown"],[268,30,"unknown"],[268,31,"unknown"],[268,32,"unknown"],[268,37,"unknown"],[268,38,"unknown"],[268,39,"unknown"],[269,7,"unknown"],[269,8,"unknown"],[269,9,"unknown"],[269,10,"unknown"],[269,11,"unknown"],[269,12,"unknown"],[269,13,"catchable"],[269,14,"catchable"],[269,15,"catchable"],[269,16,"catchable"],[269,17,"unknown"],[269,18,"unknown"],[269,21,"unknown"],[269,22,"unknown"],[269,23,"unknown"],[269,24,"unknown"],[269,25,"unknown"],[269,26,"unknown"],[269,27,"unknown"],[269,28,"unknown"],[269,29,"unknown"],[269,30,"unknown"],[269,31,"unknown"],[269,32,"unknown"],[269,37,"unknown"],[269,38,"unknown"],[269,39,"unknown"],[270,7,"unknown"],[270,8,"catchable"],[270,9,"catchable"],[270,10,"unknown"],[270,11,"unknown"],[270,12,"catchable"],[270,13,"catchable"],[270,14,"catchable"],[270,15,"catchable"],[270,16,"catchable"],[270,17,"unknown"],[270,18,"unknown"],[270,21,"unknown"],[270,22,"unknown"],[270,23,"unknown"],[270,24,"unknown"],[270,25,"unknown"],[270,26,"catchable"],[270,27,"unknown"],[270,28,"unknown"],[270,29,"unknown"],[270,30,"unknown"],[270,31,"unknown"],[270,32,"unknown"],[270,33,"unknown"],[270,34,"catchable"],[270,35,"unknown"],[270,36,"unknown"],[270,37,"unknown"],[270,38,"unknown"],[270,39,"unknown"],[270,40,"unknown"],[270,41,"unknown"],[270,42,"unknown"],[270,43,"unknown"],[270,47,"unknown"],[270,48,"unknown"],[270,52,"unknown"],[271,7,"unknown"],[271,8,"catchable"],[271,9,"catchable"],[271,10,"unknown"],[271,11,"unknown"],[271,12,"catchable"],[271,13,"catchable"],[271,14,"catchable"],[271,15,"catchable"],[271,16,"catchable"],[271,17,"unknown"],[271,18,"unknown"],[271,21,"catchable"],[271,22,"catchable"],[271,23,"catchable"],[271,24,"catchable"],[271,25,"unknown"],[271,26,"unknown"],[271,27,"unknown"],[271,28,"unknown"],[271,29,"catchable"],[271,30,"catchable"],[271,31,"unknown"],[271,32,"unknown"],[271,33,"unknown"],[271,34,"catchable"],[271,35,"unknown"],[271,36,"unknown"],[271,37,"unknown"],[271,38,"unknown"],[271,39,"unknown"],[271,40,"unknown"],[271,41,"unknown"],[271,42,"unknown"],[271,43,"unknown"],[271,47,"unknown"],[271,48,"unknown"],[271,52,"unknown"],[272,7,"unknown"],[272,8,"unknown"],[272,9,"unknown"],[272,10,"unknown"],[272,11,"unknown"],[272,12,"unknown"],[272,13,"unknown"],[272,14,"unknown"],[272,15,"unknown"],[272,16,"unknown"],[272,17,"unknown"],[272,18,"unknown"],[272,21,"unknown"],[272,22,"unknown"],[272,23,"unknown"],[272,24,"unknown"],[272,25,"unknown"],[272,26,"unknown"],[272,27,"unknown"],[272,28,"unknown"],[272,29,"unknown"],[272,30,"unknown"],[272,31,"unknown"],[272,32,"unknown"],[272,33,"unknown"],[272,34,"catchable"],[272,35,"unknown"],[272,36,"unknown"],[272,37,"unknown"],[272,38,"unknown"],[272,39,"unknown"],[272,40,"unknown"],[272,41,"unknown"],[272,42,"unknown"],[272,43,"unknown"],[272,47,"unknown"],[272,48,"unknown"],[272,52,"unknown"],[273,7,"catchable"],[273,8,"unknown"],[273,9,"catchable"],[273,10,"unknown"],[273,11,"unknown"],[273,12,"catchable"],[273,13,"catchable"],[273,14,"catchable"],[273,15,"catchable"],[273,16,"catchable"],[273,17,"unknown"],[273,18,"unknown"],[273,20,"catchable"],[273,21,"unknown"],[273,22,"unknown"],[273,23,"unknown"],[273,24,"unknown"],[273,25,"catchable"],[273,26,"unknown"],[273,27,"unknown"],[273,28,"unknown"],[273,29,"unknown"],[273,30,"unknown"],[273,31,"unknown"],[273,32,"unknown"],[273,33,"catchable"],[273,34,"unknown"],[273,35,"unknown"],[273,36,"unknown"],[273,37,"unknown"],[273,38,"unknown"],[273,39,"unknown"],[273,40,"unknown"],[273,41,"unknown"],[273,42,"unknown"],[273,43,"unknown"],[273,47,"unknown"],[273,48,"unknown"],[273,52,"unknown"],[274,7,"catchable"],[274,8,"unknown"],[274,9,"catchable"],[274,10,"unknown"],[274,11,"unknown"],[274,12,"catchable"],[274,13,"catchable"],[274,14,"catchable"],[274,15,"catchable"],[274,16,"catchable"],[274,17,"unknown"],[274,18,"unknown"],[274,21,"catchable"],[274,22,"catchable"],[274,23,"catchable"],[274,24,"catchable"],[274,25,"unknown"],[274,26,"unknown"],[274,27,"unknown"],[274,28,"unknown"],[274,29,"catchable"],[274,30,"catchable"],[274,31,"unknown"],[274,32,"unknown"],[274,33,"catchable"],[274,34,"unknown"],[274,35,"unknown"],[274,36,"unknown"],[274,37,"unknown"],[274,38,"unknown"],[274,39,"unknown"],[274,40,"unknown"],[274,41,"unknown"],[274,42,"unknown"],[274,43,"unknown"],[274,47,"unknown"],[274,48,"unknown"],[274,52,"unknown"],[275,7,"unknown"],[275,8,"unknown"],[275,9,"unknown"],[275,10,"unknown"],[275,11,"unknown"],[275,12,"unknown"],[275,13,"unknown"],[275,14,"unknown"],[275,15,"unknown"],[275,16,"unknown"],[275,17,"unknown"],[275,18,"unknown"],[275,21,"catchable"],[275,22,"catchable"],[275,23,"unknown"],[275,24,"unknown"],[275,25,"unknown"],[275,26,"unknown"],[275,27,"unknown"],[275,28,"unknown"],[275,29,"unknown"],[275,30,"unknown"],[275,31,"unknown"],[275,32,"unknown"],[275,33,"catchable"],[275,34,"unknown"],[275,35,"unknown"],[275,36,"unknown"],[275,37,"unknown"],[275,38,"unknown"],[275,39,"unknown"],[275,40,"unknown"],[275,41,"unknown"],[275,42,"unknown"],[275,43,"unknown"],[275,47,"unknown"],[275,48,"unknown"],[275,52,"unknown"],[276,7,"catchable"],[276,8,"catchable"],[276,9,"catchable"],[276,10,"unknown"],[276,11,"unknown"],[276,12,"unknown"],[276,13,"unknown"],[276,14,"unknown"],[276,15,"catchable"],[276,16,"catchable"],[276,17,"unknown"],[276,18,"unknown"],[276,21,"unknown"],[276,22,"unknown"],[276,23,"catchable"],[276,24,"catchable"],[276,25,"catchable"],[276,26,"catchable"],[276,27,"unknown"],[276,28,"unknown"],[276,29,"unknown"],[276,30,"unknown"],[276,31,"unknown"],[276,32,"unknown"],[277,7,"catchable"],[277,8,"catchable"],[277,9,"catchable"],[277,10,"unknown"],[277,11,"unknown"],[277,12,"catchable"],[277,13,"catchable"],[277,14,"catchable"],[277,15,"unknown"],[277,16,"unknown"],[277,17,"catchable"],[277,18,"catchable"],[277,20,"catchable"],[277,21,"unknown"],[277,22,"unknown"],[277,23,"unknown"],[277,24,"unknown"],[277,25,"unknown"],[277,26,"unknown"],[277,27,"unknown"],[277,28,"unknown"],[277,29,"catchable"],[277,30,"catchable"],[277,31,"unknown"],[277,32,"unknown"],[278,7,"catchable"],[278,8,"catchable"],[278,9,"catchable"],[278,10,"unknown"],[278,11,"unknown"],[278,12,"catchable"],[278,13,"catchable"],[278,14,"catchable"],[278,15,"catchable"],[278,16,"catchable"],[278,17,"catchable"],[278,18,"catchable"],[278,21,"unknown"],[278,22,"unknown"],[278,23,"catchable"],[278,24,"catchable"],[278,25,"catchable"],[278,26,"catchable"],[278,27,"catchable"],[278,28,"catchable"],[278,29,"catchable"],[278,30,"catchable"],[278,31,"unknown"],[278,32,"unknown"],[278,33,"catchable"],[278,34,"catchable"],[278,35,"catchable"],[278,36,"unknown"],[278,37,"unknown"],[278,38,"unknown"],[278,39,"unknown"],[278,40,"unknown"],[278,41,"unknown"],[278,42,"unknown"],[278,43,"unknown"],[278,47,"unknown"],[278,48,"unknown"],[278,50,"catchable"],[279,7,"catchable"],[279,8,"catchable"],[279,9,"catchable"],[279,10,"unknown"],[279,11,"unknown"],[279,12,"catchable"],[279,13,"catchable"],[279,14,"catchable"],[279,15,"unknown"],[279,16,"unknown"],[279,17,"catchable"],[279,18,"catchable"],[279,21,"catchable"],[279,22,"catchable"],[279,23,"unknown"],[279,24,"unknown"],[279,25,"unknown"],[279,26,"unknown"],[279,27,"catchable"],[279,28,"catchable"],[279,29,"catchable"],[279,30,"catchable"],[279,31,"unknown"],[279,32,"unknown"],[279,33,"catchable"],[279,34,"catchable"],[279,35,"catchable"],[279,36,"catchable"],[279,37,"unknown"],[279,38,"unknown"],[279,39,"unknown"],[279,40,"unknown"],[279,41,"unknown"],[279,42,"unknown"],[279,43,"unknown"],[279,47,"unknown"],[279,48,"unknown"],[279,49,"unknown"],[279,50,"catchable"],[279,51,"catchable"],[280,7,"catchable"],[280,8,"catchable"],[280,9,"catchable"],[280,10,"unknown"],[280,11,"unknown"],[280,12,"catchable"],[280,13,"catchable"],[280,14,"catchable"],[280,15,"catchable"],[280,16,"catchable"],[280,17,"unknown"],[280,18,"unknown"],[280,20,"catchable"],[280,21,"unknown"],[280,22,"unknown"],[280,23,"catchable"],[280,24,"catchable"],[280,25,"catchable"],[280,26,"catchable"],[280,27,"unknown"],[280,28,"unknown"],[280,29,"catchable"],[280,30,"catchable"],[280,31,"unknown"],[280,32,"unknown"],[280,33,"catchable"],[280,34,"catchable"],[280,35,"catchable"],[280,36,"unknown"],[280,37,"unknown"],[280,38,"unknown"],[280,39,"unknown"],[280,40,"unknown"],[280,41,"unknown"],[280,42,"unknown"],[280,43,"unknown"],[280,47,"unknown"],[280,48,"unknown"],[280,50,"catchable"],[280,52,"unknown"],[281,7,"unknown"],[281,8,"unknown"],[281,9,"unknown"],[281,10,"unknown"],[281,11,"unknown"],[281,12,"catchable"],[281,13,"catchable"],[281,14,"catchable"],[281,15,"unknown"],[281,16,"unknown"],[281,17,"unknown"],[281,18,"unknown"],[281,21,"unknown"],[281,22,"unknown"],[281,23,"catchable"],[281,24,"catchable"],[281,25,"unknown"],[281,26,"unknown"],[281,27,"unknown"],[281,28,"unknown"],[281,29,"unknown"],[281,30,"unknown"],[281,31,"unknown"],[281,32,"unknown"],[281,33,"catchable"],[281,34,"catchable"],[281,35,"catchable"],[281,36,"unknown"],[281,37,"unknown"],[281,38,"unknown"],[281,39,"unknown"],[281,40,"unknown"],[281,41,"unknown"],[281,42,"unknown"],[281,43,"unknown"],[281,47,"unknown"],[281,48,"unknown"],[281,50,"catchable"],[281,52,"unknown"],[282,7,"unknown"],[282,8,"unknown"],[282,9,"unknown"],[282,10,"unknown"],[282,11,"unknown"],[282,12,"unknown"],[282,13,"unknown"],[282,14,"unknown"],[282,15,"unknown"],[282,16,"unknown"],[282,17,"unknown"],[282,18,"unknown"],[282,21,"unknown"],[282,22,"unknown"],[282,23,"unknown"],[282,24,"unknown"],[282,25,"unknown"],[282,26,"unknown"],[282,27,"unknown"],[282,28,"unknown"],[282,29,"unknown"],[282,30,"unknown"],[282,31,"unknown"],[282,32,"unknown"],[282,33,"catchable"],[282,34,"catchable"],[282,35,"catchable"],[282,36,"unknown"],[282,37,"unknown"],[282,38,"unknown"],[282,39,"unknown"],[282,40,"unknown"],[282,41,"unknown"],[282,42,"unknown"],[282,43,"unknown"],[282,47,"unknown"],[282,48,"unknown"],[282,49,"unknown"],[282,50,"catchable"],[282,52,"unknown"],[283,7,"catchable"],[283,8,"catchable"],[283,9,"unknown"],[283,10,"unknown"],[283,11,"unknown"],[283,12,"catchable"],[283,13,"catchable"],[283,14,"catchable"],[283,15,"catchable"],[283,16,"catchable"],[283,17,"unknown"],[283,18,"unknown"],[283,20,"catchable"],[283,21,"unknown"],[283,22,"unknown"],[283,23,"unknown"],[283,24,"unknown"],[283,25,"unknown"],[283,26,"unknown"],[283,27,"catchable"],[283,28,"catchable"],[283,29,"catchable"],[283,30,"catchable"],[283,31,"unknown"],[283,32,"unknown"],[283,40,"unknown"],[283,41,"unknown"],[283,42,"unknown"],[283,43,"unknown"],[283,47,"unknown"],[283,48,"unknown"],[283,52,"unknown"],[284,7,"unknown"],[284,8,"unknown"],[284,9,"unknown"],[284,10,"unknown"],[284,11,"unknown"],[284,12,"unknown"],[284,13,"unknown"],[284,14,"catchable"],[284,15,"catchable"],[284,16,"catchable"],[284,17,"unknown"],[284,18,"unknown"],[284,21,"unknown"],[284,22,"unknown"],[284,23,"catchable"],[284,24,"catchable"],[284,25,"unknown"],[284,26,"unknown"],[284,27,"catchable"],[284,28,"catchable"],[284,29,"catchable"],[284,30,"catchable"],[284,31,"unknown"],[284,32,"unknown"],[284,40,"unknown"],[284,41,"unknown"],[284,42,"unknown"],[284,43,"unknown"],[284,47,"unknown"],[284,48,"unknown"],[284,52,"unknown"],[285,7,"catchable"],[285,8,"catchable"],[285,9,"catchable"],[285,10,"unknown"],[285,11,"unknown"],[285,12,"catchable"],[285,13,"catchable"],[285,14,"catchable"],[285,15,"catchable"],[285,16,"catchable"],[285,17,"unknown"],[285,18,"unknown"],[285,20,"catchable"],[285,21,"unknown"],[285,22,"unknown"],[285,23,"unknown"],[285,24,"unknown"],[285,25,"catchable"],[285,26,"catchable"],[285,27,"unknown"],[285,28,"unknown"],[285,29,"unknown"],[285,30,"unknown"],[285,31,"unknown"],[285,32,"unknown"],[285,40,"unknown"],[285,41,"unknown"],[285,42,"unknown"],[285,43,"unknown"],[285,47,"unknown"],[285,48,"unknown"],[286,7,"unknown"],[286,8,"unknown"],[286,9,"unknown"],[286,10,"unknown"],[286,11,"unknown"],[286,12,"unknown"],[286,13,"unknown"],[286,14,"unknown"],[286,15,"catchable"],[286,16,"catchable"],[286,17,"unknown"],[286,18,"unknown"],[286,21,"catchable"],[286,22,"catchable"],[286,23,"catchable"],[286,24,"catchable"],[286,25,"unknown"],[286,26,"unknown"],[286,27,"unknown"],[286,28,"unknown"],[286,29,"unknown"],[286,30,"unknown"],[286,31,"unknown"],[286,32,"unknown"],[286,40,"unknown"],[286,41,"unknown"],[286,42,"unknown"],[286,43,"unknown"],[286,47,"unknown"],[286,48,"unknown"],[287,7,"catchable"],[287,8,"catchable"],[287,9,"catchable"],[287,10,"unknown"],[287,11,"unknown"],[287,12,"catchable"],[287,13,"catchable"],[287,14,"catchable"],[287,15,"catchable"],[287,16,"catchable"],[287,17,"unknown"],[287,18,"unknown"],[287,21,"unknown"],[287,22,"unknown"],[287,23,"unknown"],[287,24,"unknown"],[287,25,"unknown"],[287,26,"unknown"],[287,27,"unknown"],[287,28,"unknown"],[287,29,"unknown"],[287,30,"unknown"],[287,31,"unknown"],[287,32,"unknown"],[287,40,"unknown"],[287,41,"unknown"],[287,42,"unknown"],[287,43,"unknown"],[287,47,"unknown"],[287,48,"unknown"],[287,53,"unknown"],[288,7,"unknown"],[288,8,"unknown"],[288,9,"unknown"],[288,10,"unknown"],[288,11,"unknown"],[288,12,"unknown"],[288,13,"unknown"],[288,14,"unknown"],[288,15,"catchable"],[288,16,"catchable"],[288,17,"unknown"],[288,18,"unknown"],[288,21,"catchable"],[288,22,"catchable"],[288,23,"unknown"],[288,24,"unknown"],[288,25,"unknown"],[288,26,"unknown"],[288,27,"catchable"],[288,28,"catchable"],[288,29,"unknown"],[288,30,"unknown"],[288,31,"unknown"],[288,32,"unknown"],[288,40,"unknown"],[288,41,"unknown"],[288,42,"unknown"],[288,43,"unknown"],[288,47,"unknown"],[288,48,"unknown"],[288,53,"unknown"],[289,7,"unknown"],[289,8,"unknown"],[289,9,"unknown"],[289,10,"unknown"],[289,11,"unknown"],[289,12,"unknown"],[289,13,"unknown"],[289,14,"unknown"],[289,15,"unknown"],[289,16,"unknown"],[289,17,"unknown"],[289,18,"unknown"],[289,21,"catchable"],[289,22,"catchable"],[289,23,"unknown"],[289,24,"unknown"],[289,25,"unknown"],[289,26,"unknown"],[289,27,"unknown"],[289,28,"unknown"],[289,29,"unknown"],[289,30,"unknown"],[289,31,"unknown"],[289,32,"unknown"],[289,40,"unknown"],[289,41,"unknown"],[289,42,"unknown"],[289,43,"unknown"],[289,47,"unknown"],[289,48,"unknown"],[289,53,"unknown"],[290,7,"catchable"],[290,8,"catchable"],[290,9,"catchable"],[290,10,"unknown"],[290,11,"unknown"],[290,12,"catchable"],[290,13,"catchable"],[290,14,"catchable"],[290,15,"catchable"],[290,16,"catchable"],[290,17,"unknown"],[290,18,"unknown"],[290,21,"unknown"],[290,22,"unknown"],[290,23,"catchable"],[290,24,"catchable"],[290,25,"catchable"],[290,26,"catchable"],[290,27,"unknown"],[290,28,"unknown"],[290,29,"unknown"],[290,30,"unknown"],[290,31,"unknown"],[290,32,"unknown"],[290,33,"catchable"],[290,34,"catchable"],[290,35,"unknown"],[290,36,"unknown"],[290,37,"unknown"],[290,38,"unknown"],[290,39,"unknown"],[291,7,"unknown"],[291,8,"unknown"],[291,9,"unknown"],[291,10,"unknown"],[291,11,"unknown"],[291,12,"unknown"],[291,13,"unknown"],[291,14,"unknown"],[291,15,"unknown"],[291,16,"unknown"],[291,17,"unknown"],[291,18,"unknown"],[291,21,"unknown"],[291,22,"unknown"],[291,23,"unknown"],[291,24,"unknown"],[291,25,"unknown"],[291,26,"unknown"],[291,27,"unknown"],[291,28,"unknown"],[291,29,"unknown"],[291,30,"unknown"],[291,31,"unknown"],[291,32,"unknown"],[291,33,"catchable"],[291,34,"catchable"],[291,35,"catchable"],[291,36,"catchable"],[291,37,"unknown"],[291,38,"unknown"],[291,39,"unknown"],[291,50,"catchable"],[291,51,"catchable"],[292,7,"unknown"],[292,8,"unknown"],[292,9,"unknown"],[292,10,"unknown"],[292,11,"unknown"],[292,12,"unknown"],[292,13,"unknown"],[292,14,"unknown"],[292,15,"unknown"],[292,16,"unknown"],[292,17,"unknown"],[292,18,"unknown"],[292,21,"unknown"],[292,22,"unknown"],[292,23,"unknown"],[292,24,"unknown"],[292,25,"unknown"],[292,26,"unknown"],[292,27,"unknown"],[292,28,"unknown"],[292,29,"unknown"],[292,30,"unknown"],[292,31,"unknown"],[292,32,"unknown"],[292,33,"catchable"],[292,34,"catchable"],[292,35,"unknown"],[292,36,"unknown"],[292,37,"unknown"],[292,38,"unknown"],[292,39,"unknown"],[293,7,"catchable"],[293,8,"catchable"],[293,9,"catchable"],[293,10,"unknown"],[293,11,"unknown"],[293,12,"unknown"],[293,13,"unknown"],[293,14,"unknown"],[293,15,"catchable"],[293,16,"catchable"],[293,17,"unknown"],[293,18,"unknown"],[293,21,"unknown"],[293,22,"unknown"],[293,23,"catchable"],[293,24,"catchable"],[293,25,"catchable"],[293,26,"catchable"],[293,27,"unknown"],[293,28,"unknown"],[293,29,"unknown"],[293,30,"unknown"],[293,31,"unknown"],[293,32,"unknown"],[293,33,"unknown"],[293,34,"unknown"],[293,35,"catchable"],[293,36,"unknown"],[293,37,"unknown"],[293,38,"unknown"],[293,39,"unknown"],[293,50,"catchable"],[294,7,"catchable"],[294,8,"catchable"],[294,9,"catchable"],[294,10,"unknown"],[294,11,"unknown"],[294,12,"catchable"],[294,13,"catchable"],[294,14,"catchable"],[294,15,"unknown"],[294,16,"unknown"],[294,17,"unknown"],[294,18,"unknown"],[294,21,"unknown"],[294,22,"unknown"],[294,23,"catchable"],[294,24,"catchable"],[294,25,"catchable"],[294,26,"catchable"],[294,27,"unknown"],[294,28,"unknown"],[294,29,"unknown"],[294,30,"unknown"],[294,31,"unknown"],[294,32,"unknown"],[294,33,"unknown"],[294,34,"unknown"],[294,35,"catchable"],[294,36,"unknown"],[294,37,"unknown"],[294,38,"unknown"],[294,39,"unknown"],[294,50,"catchable"],[295,7,"unknown"],[295,8,"unknown"],[295,9,"unknown"],[295,10,"unknown"],[295,11,"unknown"],[295,12,"unknown"],[295,13,"unknown"],[295,14,"unknown"],[295,15,"unknown"],[295,16,"unknown"],[295,17,"unknown"],[295,18,"unknown"],[295,21,"unknown"],[295,22,"unknown"],[295,23,"unknown"],[295,24,"unknown"],[295,25,"unknown"],[295,26,"unknown"],[295,27,"unknown"],[295,28,"unknown"],[295,29,"unknown"],[295,30,"unknown"],[295,31,"unknown"],[295,32,"unknown"],[295,33,"unknown"],[295,34,"unknown"],[295,35,"catchable"],[295,36,"catchable"],[295,37,"unknown"],[295,38,"unknown"],[295,39,"unknown"],[295,50,"catchable"],[295,51,"catchable"],[296,7,"catchable"],[296,8,"catchable"],[296,9,"catchable"],[296,10,"unknown"],[296,11,"unknown"],[296,12,"catchable"],[296,13,"catchable"],[296,14,"catchable"],[296,15,"catchable"],[296,16,"catchable"],[296,17,"unknown"],[296,18,"unknown"],[296,19,"catchable"],[296,20,"catchable"],[296,21,"unknown"],[296,22,"unknown"],[296,23,"unknown"],[296,24,"unknown"],[296,25,"catchable"],[296,26,"catchable"],[296,27,"catchable"],[296,28,"catchable"],[296,29,"catchable"],[296,30,"catchable"],[296,31,"unknown"],[296,32,"unknown"],[296,40,"unknown"],[296,41,"unknown"],[296,42,"unknown"],[296,43,"unknown"],[296,47,"unknown"],[296,48,"unknown"],[297,7,"catchable"],[297,8,"catchable"],[297,9,"catchable"],[297,10,"unknown"],[297,11,"unknown"],[297,12,"unknown"],[297,13,"unknown"],[297,14,"unknown"],[297,15,"unknown"],[297,16,"unknown"],[297,17,"unknown"],[297,18,"unknown"],[297,21,"catchable"],[297,22,"catchable"],[297,23,"catchable"],[297,24,"catchable"],[297,25,"unknown"],[297,26,"unknown"],[297,27,"catchable"],[297,28,"catchable"],[297,29,"catchable"],[297,30,"catchable"],[297,31,"unknown"],[297,32,"unknown"],[297,40,"unknown"],[297,41,"unknown"],[297,42,"unknown"],[297,43,"unknown"],[297,47,"unknown"],[297,48,"unknown"],[298,7,"unknown"],[298,8,"unknown"],[298,9,"unknown"],[298,10,"unknown"],[298,11,"unknown"],[298,12,"catchable"],[298,13,"catchable"],[298,14,"catchable"],[298,15,"catchable"],[298,16,"catchable"],[298,17,"unknown"],[298,18,"unknown"],[298,21,"catchable"],[298,22,"catchable"],[298,23,"catchable"],[298,24,"catchable"],[298,25,"unknown"],[298,26,"unknown"],[298,27,"unknown"],[298,28,"unknown"],[298,29,"unknown"],[298,30,"unknown"],[298,31,"unknown"],[298,32,"unknown"],[298,33,"unknown"],[298,34,"unknown"],[298,35,"catchable"],[298,36,"unknown"],[298,37,"unknown"],[298,38,"unknown"],[298,39,"unknown"],[298,40,"unknown"],[298,41,"unknown"],[298,42,"unknown"],[298,43,"unknown"],[298,47,"unknown"],[298,48,"unknown"],[298,50,"catchable"],[299,7,"catchable"],[299,8,"catchable"],[299,9,"catchable"],[299,10,"unknown"],[299,11,"unknown"],[299,12,"catchable"],[299,13,"catchable"],[299,14,"catchable"],[299,15,"catchable"],[299,16,"catchable"],[299,17,"unknown"],[299,18,"unknown"],[299,20,"catchable"],[299,21,"catchable"],[299,22,"catchable"],[299,23,"catchable"],[299,24,"catchable"],[299,25,"unknown"],[299,26,"unknown"],[299,27,"catchable"],[299,28,"catchable"],[299,29,"catchable"],[299,30,"catchable"],[299,31,"unknown"],[299,32,"unknown"],[299,39,"unknown"],[299,40,"unknown"],[299,41,"unknown"],[299,42,"unknown"],[299,43,"unknown"],[299,47,"unknown"],[299,48,"unknown"],[299,52,"unknown"],[300,7,"catchable"],[300,8,"catchable"],[300,9,"catchable"],[300,10,"unknown"],[300,11,"unknown"],[300,12,"catchable"],[300,13,"catchable"],[300,14,"catchable"],[300,15,"unknown"],[300,16,"unknown"],[300,17,"unknown"],[300,18,"unknown"],[300,21,"unknown"],[300,22,"catchable"],[300,23,"catchable"],[300,24,"catchable"],[300,25,"catchable"],[300,26,"catchable"],[300,27,"unknown"],[300,28,"unknown"],[300,29,"unknown"],[300,30,"unknown"],[300,31,"unknown"],[300,32,"unknown"],[301,7,"unknown"],[301,8,"unknown"],[301,9,"unknown"],[301,10,"unknown"],[301,11,"unknown"],[301,12,"unknown"],[301,13,"unknown"],[301,14,"unknown"],[301,15,"unknown"],[301,16,"unknown"],[301,17,"unknown"],[301,18,"unknown"],[301,20,"catchable"],[301,21,"unknown"],[301,22,"catchable"],[301,23,"unknown"],[301,24,"unknown"],[301,25,"unknown"],[301,26,"unknown"],[301,27,"unknown"],[301,28,"unknown"],[301,29,"unknown"],[301,30,"unknown"],[301,31,"unknown"],[301,32,"unknown"],[302,7,"unknown"],[302,8,"catchable"],[302,9,"catchable"],[302,10,"unknown"],[302,11,"unknown"],[302,12,"catchable"],[302,13,"catchable"],[302,14,"catchable"],[302,15,"catchable"],[302,16,"unknown"],[302,17,"catchable"],[302,18,"catchable"],[302,20,"catchable"],[302,21,"unknown"],[302,22,"unknown"],[302,23,"catchable"],[302,24,"catchable"],[302,25,"unknown"],[302,26,"catchable"],[302,27,"catchable"],[302,28,"catchable"],[302,29,"catchable"],[302,30,"catchable"],[302,31,"unknown"],[302,32,"unknown"],[302,33,"unknown"],[302,34,"catchable"],[302,35,"unknown"],[302,36,"unknown"],[302,37,"unknown"],[302,38,"unknown"],[302,39,"unknown"],[302,40,"unknown"],[302,41,"unknown"],[302,42,"unknown"],[302,43,"unknown"],[302,47,"unknown"],[302,48,"unknown"],[302,49,"unknown"],[302,51,"catchable"],[303,7,"catchable"],[303,8,"unknown"],[303,9,"catchable"],[303,10,"unknown"],[303,11,"unknown"],[303,12,"catchable"],[303,13,"catchable"],[303,14,"catchable"],[303,15,"unknown"],[303,16,"catchable"],[303,17,"catchable"],[303,18,"catchable"],[303,20,"catchable"],[303,21,"unknown"],[303,22,"unknown"],[303,23,"catchable"],[303,24,"catchable"],[303,25,"catchable"],[303,26,"unknown"],[303,27,"unknown"],[303,28,"unknown"],[303,29,"catchable"],[303,30,"catchable"],[303,31,"unknown"],[303,32,"unknown"],[303,33,"catchable"],[303,34,"unknown"],[303,35,"unknown"],[303,36,"catchable"],[303,37,"unknown"],[303,38,"unknown"],[303,39,"unknown"],[303,47,"unknown"],[303,49,"unknown"],[303,51,"unknown"],[304,7,"catchable"],[304,8,"catchable"],[304,9,"catchable"],[304,10,"unknown"],[304,11,"unknown"],[304,12,"catchable"],[304,13,"unknown"],[304,14,"catchable"],[304,15,"catchable"],[304,16,"catchable"],[304,17,"unknown"],[304,18,"unknown"],[304,20,"catchable"],[304,21,"catchable"],[304,22,"catchable"],[304,23,"catchable"],[304,24,"unknown"],[304,25,"catchable"],[304,26,"catchable"],[304,27,"unknown"],[304,28,"unknown"],[304,29,"unknown"],[304,30,"unknown"],[304,31,"unknown"],[304,32,"unknown"],[304,33,"unknown"],[304,34,"unknown"],[304,35,"unknown"],[304,36,"catchable"],[304,37,"unknown"],[304,38,"unknown"],[304,39,"unknown"],[304,47,"unknown"],[304,51,"catchable"],[305,7,"catchable"],[305,8,"catchable"],[305,9,"catchable"],[305,10,"unknown"],[305,11,"unknown"],[305,12,"unknown"],[305,13,"unknown"],[305,14,"unknown"],[305,15,"catchable"],[305,16,"catchable"],[305,17,"unknown"],[305,18,"unknown"],[305,21,"catchable"],[305,22,"catchable"],[305,23,"catchable"],[305,24,"unknown"],[305,25,"unknown"],[305,26,"unknown"],[305,27,"unknown"],[305,28,"unknown"],[305,29,"unknown"],[305,30,"unknown"],[305,31,"unknown"],[305,32,"unknown"],[305,33,"unknown"],[305,34,"unknown"],[305,35,"unknown"],[305,36,"catchable"],[305,37,"unknown"],[305,38,"unknown"],[305,39,"unknown"],[305,47,"unknown"],[305,51,"catchable"],[306,7,"unknown"],[306,8,"unknown"],[306,9,"unknown"],[306,10,"unknown"],[306,11,"unknown"],[306,12,"unknown"],[306,13,"unknown"],[306,14,"unknown"],[306,15,"unknown"],[306,16,"unknown"],[306,17,"unknown"],[306,18,"unknown"],[306,21,"unknown"],[306,22,"unknown"],[306,23,"unknown"],[306,24,"unknown"],[306,25,"unknown"],[306,26,"unknown"],[306,27,"unknown"],[306,28,"unknown"],[306,29,"catchable"],[306,30,"catchable"],[306,31,"unknown"],[306,32,"unknown"],[306,33,"unknown"],[306,34,"unknown"],[306,35,"unknown"],[306,36,"catchable"],[306,37,"unknown"],[306,38,"unknown"],[306,39,"unknown"],[306,47,"unknown"],[306,49,"unknown"],[306,51,"catchable"],[307,7,"catchable"],[307,8,"catchable"],[307,9,"unknown"],[307,10,"unknown"],[307,11,"unknown"],[307,12,"catchable"],[307,13,"catchable"],[307,14,"catchable"],[307,15,"catchable"],[307,16,"catchable"],[307,17,"unknown"],[307,18,"unknown"],[307,19,"catchable"],[307,20,"catchable"],[307,21,"unknown"],[307,22,"unknown"],[307,23,"catchable"],[307,24,"catchable"],[307,25,"catchable"],[307,26,"catchable"],[307,27,"unknown"],[307,28,"unknown"],[307,29,"unknown"],[307,30,"unknown"],[307,31,"unknown"],[307,32,"unknown"],[307,37,"unknown"],[307,38,"unknown"],[307,40,"unknown"],[307,41,"unknown"],[307,42,"unknown"],[307,43,"unknown"],[307,47,"unknown"],[307,48,"unknown"],[308,7,"catchable"],[308,8,"catchable"],[308,9,"unknown"],[308,10,"unknown"],[308,11,"unknown"],[308,12,"catchable"],[308,13,"catchable"],[308,14,"catchable"],[308,15,"catchable"],[308,16,"catchable"],[308,17,"unknown"],[308,18,"unknown"],[308,21,"catchable"],[308,22,"catchable"],[308,23,"unknown"],[308,24,"unknown"],[308,25,"unknown"],[308,26,"unknown"],[308,27,"unknown"],[308,28,"unknown"],[308,29,"catchable"],[308,30,"catchable"],[308,31,"unknown"],[308,32,"unknown"],[308,37,"unknown"],[308,38,"unknown"],[308,40,"unknown"],[308,41,"unknown"],[308,42,"unknown"],[308,43,"unknown"],[308,47,"unknown"],[308,48,"unknown"],[308,49,"unknown"],[309,7,"catchable"],[309,8,"catchable"],[309,9,"catchable"],[309,10,"unknown"],[309,11,"unknown"],[309,12,"catchable"],[309,13,"catchable"],[309,14,"catchable"],[309,15,"catchable"],[309,16,"catchable"],[309,17,"unknown"],[309,18,"unknown"],[309,21,"unknown"],[309,22,"unknown"],[309,23,"unknown"],[309,24,"catchable"],[309,25,"catchable"],[309,26,"catchable"],[309,27,"unknown"],[309,28,"unknown"],[309,29,"unknown"],[309,30,"catchable"],[309,31,"unknown"],[309,32,"unknown"],[309,33,"catchable"],[309,34,"catchable"],[309,35,"unknown"],[309,36,"unknown"],[309,37,"unknown"],[309,38,"unknown"],[309,39,"unknown"],[309,47,"unknown"],[310,7,"catchable"],[310,8,"catchable"],[310,9,"catchable"],[310,10,"unknown"],[310,11,"unknown"],[310,12,"unknown"],[310,13,"unknown"],[310,14,"unknown"],[310,15,"catchable"],[310,16,"catchable"],[310,17,"unknown"],[310,18,"unknown"],[310,20,"catchable"],[310,21,"catchable"],[310,22,"catchable"],[310,23,"catchable"],[310,24,"catchable"],[310,25,"unknown"],[310,26,"unknown"],[310,27,"unknown"],[310,28,"unknown"],[310,29,"unknown"],[310,30,"catchable"],[310,31,"unknown"],[310,32,"unknown"],[310,33,"catchable"],[310,34,"catchable"],[310,35,"catchable"],[310,36,"catchable"],[310,37,"unknown"],[310,38,"unknown"],[310,39,"unknown"],[310,47,"unknown"],[310,49,"unknown"],[310,50,"catchable"],[310,51,"catchable"],[311,7,"catchable"],[311,8,"catchable"],[311,9,"catchable"],[311,10,"unknown"],[311,11,"unknown"],[311,12,"catchable"],[311,13,"catchable"],[311,14,"catchable"],[311,15,"catchable"],[311,16,"catchable"],[311,17,"unknown"],[311,18,"unknown"],[311,19,"catchable"],[311,21,"unknown"],[311,22,"unknown"],[311,23,"catchable"],[311,24,"catchable"],[311,25,"catchable"],[311,26,"catchable"],[311,27,"unknown"],[311,28,"unknown"],[311,29,"unknown"],[311,30,"unknown"],[311,31,"unknown"],[311,32,"unknown"],[311,40,"unknown"],[311,41,"unknown"],[311,42,"unknown"],[311,43,"unknown"],[311,47,"unknown"],[311,48,"unknown"],[311,53,"unknown"],[312,7,"catchable"],[312,8,"catchable"],[312,9,"catchable"],[312,10,"unknown"],[312,11,"unknown"],[312,12,"catchable"],[312,13,"catchable"],[312,14,"catchable"],[312,15,"catchable"],[312,16,"catchable"],[312,17,"unknown"],[312,18,"unknown"],[312,21,"unknown"],[312,22,"unknown"],[312,23,"catchable"],[312,24,"catchable"],[312,25,"catchable"],[312,26,"catchable"],[312,27,"unknown"],[312,28,"unknown"],[312,29,"unknown"],[312,30,"unknown"],[312,31,"unknown"],[312,32,"unknown"],[312,40,"unknown"],[312,41,"unknown"],[312,42,"unknown"],[312,43,"unknown"],[312,47,"unknown"],[312,48,"unknown"],[312,53,"unknown"],[313,7,"catchable"],[313,8,"catchable"],[313,9,"catchable"],[313,10,"unknown"],[313,11,"unknown"],[313,12,"catchable"],[313,13,"catchable"],[313,14,"catchable"],[313,15,"catchable"],[313,16,"catchable"],[313,17,"unknown"],[313,18,"unknown"],[313,21,"unknown"],[313,22,"unknown"],[313,23,"catchable"],[313,24,"catchable"],[313,25,"unknown"],[313,26,"unknown"],[313,27,"unknown"],[313,28,"unknown"],[313,29,"unknown"],[313,30,"unknown"],[313,31,"unknown"],[313,32,"unknown"],[313,40,"unknown"],[313,41,"unknown"],[313,42,"unknown"],[313,43,"unknown"],[313,47,"unknown"],[313,48,"unknown"],[313,52,"unknown"],[314,7,"catchable"],[314,8,"catchable"],[314,9,"catchable"],[314,10,"unknown"],[314,11,"unknown"],[314,12,"catchable"],[314,13,"catchable"],[314,14,"catchable"],[314,15,"catchable"],[314,16,"catchable"],[314,17,"unknown"],[314,18,"unknown"],[314,21,"unknown"],[314,22,"unknown"],[314,23,"catchable"],[314,24,"catchable"],[314,25,"unknown"],[314,26,"unknown"],[314,27,"unknown"],[314,28,"unknown"],[314,29,"unknown"],[314,30,"unknown"],[314,31,"unknown"],[314,32,"unknown"],[314,40,"unknown"],[314,41,"unknown"],[314,42,"unknown"],[314,43,"unknown"],[314,47,"unknown"],[314,48,"unknown"],[314,52,"unknown"],[315,7,"catchable"],[315,8,"catchable"],[315,9,"unknown"],[315,10,"unknown"],[315,11,"unknown"],[315,12,"catchable"],[315,13,"catchable"],[315,14,"catchable"],[315,15,"catchable"],[315,16,"catchable"],[315,17,"unknown"],[315,18,"unknown"],[315,20,"catchable"],[315,21,"catchable"],[315,22,"catchable"],[315,23,"catchable"],[315,24,"catchable"],[315,25,"catchable"],[315,26,"catchable"],[315,27,"catchable"],[315,28,"catchable"],[315,29,"unknown"],[315,30,"unknown"],[315,31,"unknown"],[315,32,"unknown"],[315,33,"catchable"],[315,34,"catchable"],[315,35,"catchable"],[315,36,"catchable"],[315,37,"unknown"],[315,38,"unknown"],[315,39,"unknown"],[315,47,"unknown"],[315,50,"catchable"],[315,51,"catchable"],[316,7,"catchable"],[316,8,"catchable"],[316,9,"catchable"],[316,10,"unknown"],[316,11,"unknown"],[316,12,"catchable"],[316,13,"catchable"],[316,14,"catchable"],[316,15,"unknown"],[316,16,"catchable"],[316,17,"unknown"],[316,18,"unknown"],[316,20,"catchable"],[316,21,"unknown"],[316,22,"unknown"],[316,23,"catchable"],[316,24,"catchable"],[316,25,"unknown"],[316,26,"unknown"],[316,27,"unknown"],[316,28,"unknown"],[316,29,"unknown"],[316,30,"unknown"],[316,31,"unknown"],[316,32,"unknown"],[316,40,"unknown"],[316,41,"unknown"],[316,42,"unknown"],[316,43,"unknown"],[316,47,"unknown"],[316,48,"unknown"],[317,7,"unknown"],[317,8,"unknown"],[317,9,"unknown"],[317,10,"unknown"],[317,11,"unknown"],[317,12,"unknown"],[317,13,"unknown"],[317,14,"unknown"],[317,15,"unknown"],[317,16,"unknown"],[317,17,"unknown"],[317,18,"unknown"],[317,21,"unknown"],[317,22,"unknown"],[317,23,"catchable"],[317,24,"catchable"],[317,25,"unknown"],[317,26,"unknown"],[317,27,"unknown"],[317,28,"unknown"],[317,29,"unknown"],[317,30,"unknown"],[317,31,"unknown"],[317,32,"unknown"],[317,40,"unknown"],[317,41,"unknown"],[317,42,"unknown"],[317,43,"unknown"],[317,47,"unknown"],[317,48,"unknown"],[317,49,"unknown"],[318,7,"catchable"],[318,8,"catchable"],[318,9,"catchable"],[318,10,"unknown"],[318,11,"unknown"],[318,12,"catchable"],[318,13,"catchable"],[318,14,"catchable"],[318,15,"unknown"],[318,16,"unknown"],[318,17,"catchable"],[318,18,"catchable"],[318,20,"catchable"],[318,21,"catchable"],[318,22,"catchable"],[318,23,"catchable"],[318,24,"catchable"],[318,25,"unknown"],[318,26,"unknown"],[318,27,"unknown"],[318,28,"unknown"],[318,29,"catchable"],[318,30,"catchable"],[318,31,"unknown"],[318,32,"unknown"],[318,33,"unknown"],[318,34,"unknown"],[318,35,"catchable"],[318,36,"unknown"],[318,37,"unknown"],[318,38,"unknown"],[318,39,"unknown"],[318,47,"unknown"],[318,50,"catchable"],[319,7,"catchable"],[319,8,"catchable"],[319,9,"catchable"],[319,10,"unknown"],[319,11,"unknown"],[319,12,"catchable"],[319,13,"catchable"],[319,14,"unknown"],[319,15,"unknown"],[319,16,"unknown"],[319,17,"catchable"],[319,18,"catchable"],[319,21,"catchable"],[319,22,"catchable"],[319,23,"catchable"],[319,24,"catchable"],[319,25,"catchable"],[319,26,"catchable"],[319,27,"catchable"],[319,28,"catchable"],[319,29,"catchable"],[319,30,"catchable"],[319,31,"unknown"],[319,32,"unknown"],[319,33,"unknown"],[319,34,"unknown"],[319,35,"catchable"],[319,36,"catchable"],[319,37,"unknown"],[319,38,"unknown"],[319,39,"unknown"],[319,47,"unknown"],[319,49,"unknown"],[319,50,"catchable"],[319,51,"catchable"],[320,7,"catchable"],[320,8,"catchable"],[320,9,"catchable"],[320,10,"unknown"],[320,11,"unknown"],[320,12,"catchable"],[320,13,"catchable"],[320,14,"catchable"],[320,15,"unknown"],[320,16,"unknown"],[320,17,"catchable"],[320,18,"catchable"],[320,21,"catchable"],[320,22,"catchable"],[320,23,"catchable"],[320,24,"catchable"],[320,25,"unknown"],[320,26,"unknown"],[320,27,"catchable"],[320,28,"catchable"],[320,29,"catchable"],[320,30,"catchable"],[320,31,"unknown"],[320,32,"unknown"],[320,33,"catchable"],[320,34,"catchable"],[320,35,"catchable"],[320,36,"catchable"],[320,37,"unknown"],[320,38,"unknown"],[320,39,"unknown"],[320,50,"catchable"],[320,51,"catchable"],[321,7,"catchable"],[321,8,"catchable"],[321,9,"catchable"],[321,10,"unknown"],[321,11,"unknown"],[321,12,"catchable"],[321,13,"catchable"],[321,14,"catchable"],[321,15,"unknown"],[321,16,"unknown"],[321,17,"catchable"],[321,18,"catchable"],[321,21,"catchable"],[321,22,"catchable"],[321,23,"unknown"],[321,24,"unknown"],[321,25,"unknown"],[321,26,"unknown"],[321,27,"catchable"],[321,28,"catchable"],[321,29,"catchable"],[321,30,"catchable"],[321,31,"unknown"],[321,32,"unknown"],[321,33,"catchable"],[321,34,"catchable"],[321,35,"catchable"],[321,36,"unknown"],[321,37,"unknown"],[321,38,"unknown"],[321,39,"unknown"],[321,50,"catchable"],[322,7,"catchable"],[322,8,"catchable"],[322,9,"catchable"],[322,10,"unknown"],[322,11,"unknown"],[322,12,"catchable"],[322,13,"catchable"],[322,14,"catchable"],[322,15,"catchable"],[322,16,"catchable"],[322,17,"unknown"],[322,18,"unknown"],[322,20,"catchable"],[322,21,"unknown"],[322,22,"catchable"],[322,23,"unknown"],[322,24,"unknown"],[322,25,"catchable"],[322,26,"catchable"],[322,27,"unknown"],[322,28,"unknown"],[322,29,"unknown"],[322,30,"unknown"],[322,31,"unknown"],[322,32,"unknown"],[322,40,"unknown"],[322,41,"unknown"],[322,42,"unknown"],[322,43,"unknown"],[322,47,"unknown"],[322,48,"unknown"],[322,53,"unknown"],[323,7,"unknown"],[323,8,"unknown"],[323,9,"unknown"],[323,10,"unknown"],[323,11,"unknown"],[323,12,"catchable"],[323,13,"catchable"],[323,14,"catchable"],[323,15,"unknown"],[323,16,"unknown"],[323,17,"unknown"],[323,18,"unknown"],[323,21,"unknown"],[323,22,"catchable"],[323,23,"catchable"],[323,24,"catchable"],[323,25,"catchable"],[323,26,"catchable"],[323,27,"unknown"],[323,28,"unknown"],[323,29,"unknown"],[323,30,"unknown"],[323,31,"unknown"],[323,32,"unknown"],[323,40,"unknown"],[323,41,"unknown"],[323,42,"unknown"],[323,43,"unknown"],[323,47,"unknown"],[323,48,"unknown"],[323,49,"unknown"],[323,53,"unknown"],[324,7,"catchable"],[324,8,"catchable"],[324,9,"catchable"],[324,10,"unknown"],[324,11,"unknown"],[324,12,"catchable"],[324,13,"catchable"],[324,14,"catchable"],[324,15,"catchable"],[324,16,"catchable"],[324,17,"unknown"],[324,18,"unknown"],[324,21,"unknown"],[324,22,"unknown"],[324,23,"catchable"],[324,24,"catchable"],[324,25,"unknown"],[324,26,"unknown"],[324,27,"catchable"],[324,28,"catchable"],[324,29,"catchable"],[324,30,"catchable"],[324,31,"unknown"],[324,32,"unknown"],[324,33,"catchable"],[324,34,"catchable"],[324,35,"catchable"],[324,36,"catchable"],[324,37,"unknown"],[324,38,"unknown"],[324,39,"unknown"],[324,40,"unknown"],[324,41,"unknown"],[324,42,"unknown"],[324,43,"unknown"],[324,47,"unknown"],[324,48,"unknown"],[324,49,"unknown"],[324,50,"catchable"],[324,51,"catchable"],[324,53,"unknown"],[325,7,"catchable"],[325,8,"catchable"],[325,9,"catchable"],[325,10,"unknown"],[325,11,"unknown"],[325,12,"catchable"],[325,13,"catchable"],[325,14,"catchable"],[325,15,"catchable"],[325,16,"catchable"],[325,17,"unknown"],[325,18,"unknown"],[325,21,"catchable"],[325,22,"unknown"],[325,23,"catchable"],[325,24,"catchable"],[325,25,"catchable"],[325,26,"catchable"],[325,27,"unknown"],[325,28,"unknown"],[325,29,"unknown"],[325,30,"unknown"],[325,31,"unknown"],[325,32,"unknown"],[325,40,"unknown"],[325,41,"unknown"],[325,42,"unknown"],[325,43,"unknown"],[325,47,"unknown"],[325,48,"unknown"],[325,52,"unknown"],[326,7,"unknown"],[326,8,"unknown"],[326,9,"unknown"],[326,10,"unknown"],[326,11,"unknown"],[326,12,"unknown"],[326,13,"unknown"],[326,14,"unknown"],[326,15,"unknown"],[326,16,"unknown"],[326,17,"unknown"],[326,18,"unknown"],[326,21,"catchable"],[326,22,"unknown"],[326,23,"catchable"],[326,24,"catchable"],[326,25,"unknown"],[326,26,"unknown"],[326,27,"unknown"],[326,28,"unknown"],[326,29,"catchable"],[326,30,"catchable"],[326,31,"unknown"],[326,32,"unknown"],[326,40,"unknown"],[326,41,"unknown"],[326,42,"unknown"],[326,43,"unknown"],[326,47,"unknown"],[326,48,"unknown"],[326,52,"unknown"],[327,7,"catchable"],[327,8,"catchable"],[327,9,"catchable"],[327,10,"unknown"],[327,11,"unknown"],[327,12,"catchable"],[327,13,"catchable"],[327,14,"catchable"],[327,15,"catchable"],[327,16,"catchable"],[327,17,"unknown"],[327,18,"unknown"],[327,21,"unknown"],[327,22,"unknown"],[327,23,"catchable"],[327,24,"catchable"],[327,25,"catchable"],[327,26,"catchable"],[327,27,"catchable"],[327,28,"catchable"],[327,29,"catchable"],[327,30,"catchable"],[327,31,"unknown"],[327,32,"unknown"],[328,7,"catchable"],[328,8,"catchable"],[328,9,"catchable"],[328,10,"unknown"],[328,11,"unknown"],[328,12,"catchable"],[328,13,"catchable"],[328,14,"unknown"],[328,15,"catchable"],[328,16,"catchable"],[328,17,"unknown"],[328,18,"unknown"],[328,20,"catchable"],[328,21,"catchable"],[328,22,"catchable"],[328,23,"catchable"],[328,24,"catchable"],[328,25,"unknown"],[328,26,"unknown"],[328,27,"catchable"],[328,28,"catchable"],[328,29,"catchable"],[328,30,"catchable"],[328,31,"unknown"],[328,32,"unknown"],[328,33,"catchable"],[328,34,"catchable"],[328,35,"catchable"],[328,36,"unknown"],[328,37,"unknown"],[328,38,"unknown"],[328,39,"unknown"],[328,40,"unknown"],[328,41,"unknown"],[328,42,"unknown"],[328,43,"unknown"],[328,47,"unknown"],[328,48,"unknown"],[328,50,"catchable"],[328,53,"unknown"],[329,7,"unknown"],[329,8,"unknown"],[329,9,"unknown"],[329,10,"unknown"],[329,11,"unknown"],[329,12,"catchable"],[329,13,"catchable"],[329,14,"unknown"],[329,15,"catchable"],[329,16,"catchable"],[329,17,"unknown"],[329,18,"unknown"],[329,19,"catchable"],[329,21,"catchable"],[329,22,"catchable"],[329,23,"unknown"],[329,24,"unknown"],[329,25,"unknown"],[329,26,"unknown"],[329,27,"unknown"],[329,28,"unknown"],[329,29,"unknown"],[329,30,"unknown"],[329,31,"unknown"],[329,32,"unknown"],[329,33,"catchable"],[329,34,"catchable"],[329,35,"unknown"],[329,36,"unknown"],[329,37,"unknown"],[329,38,"unknown"],[329,39,"unknown"],[329,40,"unknown"],[329,41,"unknown"],[329,42,"unknown"],[329,43,"unknown"],[329,47,"unknown"],[329,48,"unknown"],[329,53,"unknown"],[330,7,"unknown"],[330,8,"unknown"],[330,9,"unknown"],[330,10,"unknown"],[330,11,"unknown"],[330,12,"unknown"],[330,13,"unknown"],[330,14,"unknown"],[330,15,"unknown"],[330,16,"unknown"],[330,17,"unknown"],[330,18,"unknown"],[330,21,"unknown"],[330,22,"unknown"],[330,23,"unknown"],[330,24,"unknown"],[330,25,"unknown"],[330,26,"unknown"],[330,27,"unknown"],[330,28,"unknown"],[330,29,"unknown"],[330,30,"unknown"],[330,31,"unknown"],[330,32,"unknown"],[330,33,"catchable"],[330,34,"catchable"],[330,35,"catchable"],[330,36,"catchable"],[330,37,"unknown"],[330,38,"unknown"],[330,39,"unknown"],[330,40,"unknown"],[330,41,"unknown"],[330,42,"unknown"],[330,43,"unknown"],[330,47,"unknown"],[330,48,"unknown"],[330,50,"catchable"],[330,51,"catchable"],[330,53,"unknown"],[331,7,"catchable"],[331,8,"catchable"],[331,9,"catchable"],[331,10,"unknown"],[331,11,"unknown"],[331,12,"catchable"],[331,13,"catchable"],[331,14,"catchable"],[331,15,"catchable"],[331,16,"catchable"],[331,17,"unknown"],[331,18,"unknown"],[331,21,"unknown"],[331,22,"unknown"],[331,23,"unknown"],[331,24,"unknown"],[331,25,"unknown"],[331,26,"unknown"],[331,27,"unknown"],[331,28,"unknown"],[331,29,"unknown"],[331,30,"unknown"],[331,31,"unknown"],[331,32,"unknown"],[331,40,"unknown"],[331,41,"unknown"],[331,42,"unknown"],[331,43,"unknown"],[331,47,"unknown"],[331,48,"unknown"],[332,7,"unknown"],[332,8,"unknown"],[332,9,"unknown"],[332,10,"unknown"],[332,11,"unknown"],[332,12,"catchable"],[332,13,"catchable"],[332,14,"catchable"],[332,15,"catchable"],[332,16,"catchable"],[332,17,"unknown"],[332,18,"unknown"],[332,21,"unknown"],[332,22,"unknown"],[332,23,"catchable"],[332,24,"catchable"],[332,25,"unknown"],[332,26,"unknown"],[332,27,"unknown"],[332,28,"unknown"],[332,29,"unknown"],[332,30,"unknown"],[332,31,"unknown"],[332,32,"unknown"],[332,40,"unknown"],[332,41,"unknown"],[332,42,"unknown"],[332,43,"unknown"],[332,47,"unknown"],[332,48,"unknown"],[333,7,"catchable"],[333,8,"catchable"],[333,9,"catchable"],[333,10,"unknown"],[333,11,"unknown"],[333,12,"catchable"],[333,13,"catchable"],[333,14,"catchable"],[333,15,"catchable"],[333,16,"catchable"],[333,17,"unknown"],[333,18,"unknown"],[333,19,"catchable"],[333,21,"catchable"],[333,22,"catchable"],[333,23,"catchable"],[333,24,"catchable"],[333,25,"catchable"],[333,26,"catchable"],[333,27,"unknown"],[333,28,"unknown"],[333,29,"unknown"],[333,30,"unknown"],[333,31,"unknown"],[333,32,"unknown"],[333,33,"unknown"],[333,34,"unknown"],[333,35,"unknown"],[333,36,"catchable"],[333,37,"unknown"],[333,38,"unknown"],[333,39,"unknown"],[333,40,"unknown"],[333,41,"unknown"],[333,42,"unknown"],[333,43,"unknown"],[333,47,"unknown"],[333,48,"unknown"],[333,51,"catchable"],[333,53,"unknown"],[334,7,"catchable"],[334,8,"catchable"],[334,9,"catchable"],[334,10,"unknown"],[334,11,"unknown"],[334,12,"unknown"],[334,13,"unknown"],[334,14,"unknown"],[334,15,"unknown"],[334,16,"unknown"],[334,17,"catchable"],[334,18,"catchable"],[334,20,"catchable"],[334,21,"catchable"],[334,22,"catchable"],[334,23,"catchable"],[334,24,"catchable"],[334,25,"unknown"],[334,26,"unknown"],[334,27,"unknown"],[334,28,"unknown"],[334,29,"catchable"],[334,30,"catchable"],[334,31,"unknown"],[334,32,"unknown"],[334,33,"unknown"],[334,34,"unknown"],[334,35,"unknown"],[334,36,"catchable"],[334,37,"unknown"],[334,38,"unknown"],[334,39,"unknown"],[334,40,"unknown"],[334,41,"unknown"],[334,42,"unknown"],[334,43,"unknown"],[334,47,"unknown"],[334,48,"unknown"],[334,49,"unknown"],[334,51,"catchable"],[334,53,"unknown"],[335,7,"catchable"],[335,8,"unknown"],[335,9,"unknown"],[335,10,"unknown"],[335,11,"unknown"],[335,12,"catchable"],[335,13,"catchable"],[335,14,"catchable"],[335,15,"catchable"],[335,16,"catchable"],[335,17,"catchable"],[335,18,"catchable"],[335,20,"catchable"],[335,21,"catchable"],[335,22,"catchable"],[335,23,"catchable"],[335,24,"catchable"],[335,25,"unknown"],[335,26,"unknown"],[335,27,"unknown"],[335,28,"unknown"],[335,29,"unknown"],[335,30,"unknown"],[335,31,"unknown"],[335,32,"unknown"],[335,40,"unknown"],[335,41,"unknown"],[335,42,"unknown"],[335,43,"unknown"],[335,47,"unknown"],[335,48,"unknown"],[335,53,"unknown"],[336,7,"unknown"],[336,8,"catchable"],[336,9,"catchable"],[336,10,"unknown"],[336,11,"unknown"],[336,12,"catchable"],[336,13,"catchable"],[336,14,"catchable"],[336,15,"catchable"],[336,16,"catchable"],[336,17,"catchable"],[336,18,"catchable"],[336,21,"catchable"],[336,22,"catchable"],[336,23,"catchable"],[336,24,"catchable"],[336,25,"unknown"],[336,26,"unknown"],[336,27,"unknown"],[336,28,"unknown"],[336,29,"unknown"],[336,30,"unknown"],[336,31,"unknown"],[336,32,"unknown"],[336,40,"unknown"],[336,41,"unknown"],[336,42,"unknown"],[336,43,"unknown"],[336,47,"unknown"],[336,48,"unknown"],[336,53,"unknown"],[337,7,"unknown"],[337,8,"catchable"],[337,9,"unknown"],[337,10,"unknown"],[337,11,"unknown"],[337,12,"catchable"],[337,13,"catchable"],[337,14,"catchable"],[337,15,"catchable"],[337,16,"catchable"],[337,17,"catchable"],[337,18,"catchable"],[337,20,"catchable"],[337,21,"catchable"],[337,22,"catchable"],[337,23,"catchable"],[337,24,"catchable"],[337,25,"unknown"],[337,26,"unknown"],[337,27,"unknown"],[337,28,"unknown"],[337,29,"unknown"],[337,30,"unknown"],[337,31,"unknown"],[337,32,"unknown"],[337,33,"unknown"],[337,34,"catchable"],[337,35,"unknown"],[337,36,"unknown"],[337,37,"unknown"],[337,38,"unknown"],[337,39,"unknown"],[338,7,"catchable"],[338,8,"unknown"],[338,9,"catchable"],[338,10,"unknown"],[338,11,"unknown"],[338,12,"catchable"],[338,13,"catchable"],[338,14,"catchable"],[338,15,"catchable"],[338,16,"catchable"],[338,17,"catchable"],[338,18,"catchable"],[338,20,"catchable"],[338,21,"catchable"],[338,22,"catchable"],[338,23,"catchable"],[338,24,"catchable"],[338,25,"unknown"],[338,26,"unknown"],[338,27,"unknown"],[338,28,"unknown"],[338,29,"unknown"],[338,30,"unknown"],[338,31,"unknown"],[338,32,"unknown"],[338,33,"catchable"],[338,34,"unknown"],[338,35,"unknown"],[338,36,"unknown"],[338,37,"unknown"],[338,38,"unknown"],[338,39,"unknown"],[339,7,"catchable"],[339,8,"catchable"],[339,9,"catchable"],[339,10,"unknown"],[339,11,"unknown"],[339,12,"catchable"],[339,13,"catchable"],[339,14,"catchable"],[339,15,"catchable"],[339,16,"catchable"],[339,17,"catchable"],[339,18,"catchable"],[339,21,"catchable"],[339,22,"catchable"],[339,23,"catchable"],[339,24,"catchable"],[339,25,"unknown"],[339,26,"unknown"],[339,27,"catchable"],[339,28,"catchable"],[339,29,"catchable"],[339,30,"catchable"],[339,31,"unknown"],[339,32,"unknown"],[339,33,"catchable"],[339,34,"catchable"],[339,35,"catchable"],[339,36,"catchable"],[339,37,"unknown"],[339,38,"unknown"],[339,39,"unknown"],[339,40,"unknown"],[339,41,"unknown"],[339,42,"unknown"],[339,43,"unknown"],[339,47,"unknown"],[339,48,"unknown"],[339,50,"catchable"],[339,51,"catchable"],[339,52,"unknown"],[340,7,"catchable"],[340,8,"catchable"],[340,9,"catchable"],[340,10,"unknown"],[340,11,"unknown"],[340,12,"catchable"],[340,13,"catchable"],[340,14,"catchable"],[340,15,"catchable"],[340,16,"catchable"],[340,17,"catchable"],[340,18,"catchable"],[340,21,"catchable"],[340,22,"catchable"],[340,23,"catchable"],[340,24,"catchable"],[340,25,"unknown"],[340,26,"unknown"],[340,27,"catchable"],[340,28,"catchable"],[340,29,"catchable"],[340,30,"catchable"],[340,31,"unknown"],[340,32,"unknown"],[340,33,"catchable"],[340,34,"catchable"],[340,35,"catchable"],[340,36,"catchable"],[340,37,"unknown"],[340,38,"unknown"],[340,39,"unknown"],[340,40,"unknown"],[340,41,"unknown"],[340,42,"unknown"],[340,43,"unknown"],[340,47,"unknown"],[340,48,"unknown"],[340,50,"catchable"],[340,51,"catchable"],[340,52,"unknown"],[341,7,"catchable"],[341,8,"catchable"],[341,9,"catchable"],[341,10,"unknown"],[341,11,"unknown"],[341,12,"catchable"],[341,13,"catchable"],[341,14,"catchable"],[341,15,"catchable"],[341,16,"catchable"],[341,17,"unknown"],[341,18,"unknown"],[341,21,"catchable"],[341,22,"catchable"],[341,23,"catchable"],[341,24,"catchable"],[341,25,"unknown"],[341,26,"unknown"],[341,27,"unknown"],[341,28,"unknown"],[341,29,"catchable"],[341,30,"catchable"],[341,31,"unknown"],[341,32,"unknown"],[341,33,"catchable"],[341,34,"catchable"],[341,35,"catchable"],[341,36,"unknown"],[341,37,"unknown"],[341,38,"unknown"],[341,39,"unknown"],[341,40,"unknown"],[341,41,"unknown"],[341,42,"unknown"],[341,43,"unknown"],[341,47,"unknown"],[341,48,"unknown"],[341,50,"catchable"],[341,52,"unknown"],[342,7,"unknown"],[342,8,"unknown"],[342,9,"unknown"],[342,10,"unknown"],[342,11,"unknown"],[342,12,"catchable"],[342,13,"catchable"],[342,14,"catchable"],[342,15,"unknown"],[342,16,"unknown"],[342,17,"unknown"],[342,18,"unknown"],[342,21,"catchable"],[342,22,"catchable"],[342,23,"catchable"],[342,24,"catchable"],[342,25,"unknown"],[342,26,"unknown"],[342,27,"unknown"],[342,28,"unknown"],[342,29,"catchable"],[342,30,"catchable"],[342,31,"unknown"],[342,32,"unknown"],[342,33,"catchable"],[342,34,"catchable"],[342,35,"catchable"],[342,36,"catchable"],[342,37,"unknown"],[342,38,"unknown"],[342,39,"unknown"],[342,40,"unknown"],[342,41,"unknown"],[342,42,"unknown"],[342,43,"unknown"],[342,47,"unknown"],[342,48,"unknown"],[342,50,"catchable"],[342,51,"catchable"],[342,52,"unknown"],[343,7,"catchable"],[343,8,"catchable"],[343,9,"catchable"],[343,10,"unknown"],[343,11,"unknown"],[343,12,"catchable"],[343,13,"catchable"],[343,14,"catchable"],[343,15,"catchable"],[343,16,"unknown"],[343,17,"unknown"],[343,18,"unknown"],[343,20,"catchable"],[343,21,"catchable"],[343,22,"catchable"],[343,23,"unknown"],[343,24,"unknown"],[343,25,"unknown"],[343,26,"unknown"],[343,27,"unknown"],[343,28,"unknown"],[343,29,"unknown"],[343,30,"catchable"],[343,31,"unknown"],[343,32,"unknown"],[343,33,"catchable"],[343,34,"catchable"],[343,35,"unknown"],[343,36,"catchable"],[343,37,"unknown"],[343,38,"unknown"],[343,39,"unknown"],[343,51,"unknown"],[344,7,"catchable"],[344,8,"catchable"],[344,9,"catchable"],[344,10,"unknown"],[344,11,"unknown"],[344,12,"unknown"],[344,13,"unknown"],[344,14,"unknown"],[344,15,"unknown"],[344,16,"unknown"],[344,17,"catchable"],[344,18,"catchable"],[344,21,"unknown"],[344,22,"unknown"],[344,23,"unknown"],[344,24,"unknown"],[344,25,"unknown"],[344,26,"unknown"],[344,27,"unknown"],[344,28,"unknown"],[344,29,"unknown"],[344,30,"unknown"],[344,31,"unknown"],[344,32,"unknown"],[344,33,"catchable"],[344,34,"catchable"],[344,35,"unknown"],[344,36,"catchable"],[344,37,"unknown"],[344,38,"unknown"],[344,39,"unknown"],[344,51,"catchable"],[345,7,"catchable"],[345,8,"catchable"],[345,9,"catchable"],[345,10,"unknown"],[345,11,"unknown"],[345,12,"catchable"],[345,13,"catchable"],[345,14,"catchable"],[345,15,"catchable"],[345,16,"catchable"],[345,17,"catchable"],[345,18,"catchable"],[345,21,"catchable"],[345,22,"catchable"],[345,23,"unknown"],[345,24,"unknown"],[345,25,"unknown"],[345,26,"unknown"],[345,27,"unknown"],[345,28,"unknown"],[345,29,"catchable"],[345,30,"catchable"],[345,31,"unknown"],[345,32,"unknown"],[345,33,"unknown"],[345,34,"unknown"],[345,35,"unknown"],[345,36,"catchable"],[345,37,"unknown"],[345,38,"unknown"],[345,39,"unknown"],[345,51,"catchable"],[346,7,"unknown"],[346,8,"unknown"],[346,9,"unknown"],[346,10,"unknown"],[346,11,"unknown"],[346,12,"unknown"],[346,13,"unknown"],[346,14,"unknown"],[346,15,"unknown"],[346,16,"unknown"],[346,17,"unknown"],[346,18,"unknown"],[346,21,"unknown"],[346,22,"unknown"],[346,23,"unknown"],[346,24,"unknown"],[346,25,"unknown"],[346,26,"unknown"],[346,27,"unknown"],[346,28,"unknown"],[346,29,"unknown"],[346,30,"unknown"],[346,31,"unknown"],[346,32,"unknown"],[346,33,"unknown"],[346,34,"unknown"],[346,35,"unknown"],[346,36,"catchable"],[346,37,"unknown"],[346,38,"unknown"],[346,39,"unknown"],[346,51,"catchable"],[347,7,"catchable"],[347,8,"catchable"],[347,9,"catchable"],[347,10,"unknown"],[347,11,"unknown"],[347,12,"catchable"],[347,13,"catchable"],[347,14,"catchable"],[347,15,"catchable"],[347,16,"catchable"],[347,17,"catchable"],[347,18,"catchable"],[347,21,"catchable"],[347,22,"catchable"],[347,23,"unknown"],[347,24,"unknown"],[347,25,"unknown"],[347,26,"unknown"],[347,27,"unknown"],[347,28,"unknown"],[347,29,"catchable"],[347,30,"catchable"],[347,31,"unknown"],[347,32,"unknown"],[347,33,"unknown"],[347,34,"unknown"],[347,35,"unknown"],[347,36,"catchable"],[347,37,"unknown"],[347,38,"unknown"],[347,39,"unknown"],[347,51,"catchable"],[348,7,"unknown"],[348,8,"unknown"],[348,9,"unknown"],[348,10,"unknown"],[348,11,"unknown"],[348,12,"unknown"],[348,13,"unknown"],[348,14,"unknown"],[348,15,"unknown"],[348,16,"unknown"],[348,17,"unknown"],[348,18,"unknown"],[348,21,"unknown"],[348,22,"unknown"],[348,23,"unknown"],[348,24,"unknown"],[348,25,"unknown"],[348,26,"unknown"],[348,27,"unknown"],[348,28,"unknown"],[348,29,"unknown"],[348,30,"unknown"],[348,31,"unknown"],[348,32,"unknown"],[348,33,"unknown"],[348,34,"unknown"],[348,35,"unknown"],[348,36,"catchable"],[348,37,"unknown"],[348,38,"unknown"],[348,39,"unknown"],[348,51,"catchable"],[349,7,"catchable"],[349,8,"catchable"],[349,9,"catchable"],[349,10,"unknown"],[349,11,"unknown"],[349,12,"catchable"],[349,13,"catchable"],[349,14,"catchable"],[349,15,"unknown"],[349,16,"unknown"],[349,17,"catchable"],[349,18,"catchable"],[349,21,"catchable"],[349,22,"catchable"],[349,23,"unknown"],[349,24,"unknown"],[349,25,"unknown"],[349,26,"unknown"],[349,27,"catchable"],[349,28,"catchable"],[349,29,"catchable"],[349,30,"catchable"],[349,31,"unknown"],[349,32,"unknown"],[349,33,"catchable"],[349,34,"catchable"],[349,35,"unknown"],[349,36,"catchable"],[349,37,"unknown"],[349,38,"unknown"],[349,39,"unknown"],[349,40,"unknown"],[349,41,"unknown"],[349,42,"unknown"],[349,43,"unknown"],[349,47,"unknown"],[349,48,"unknown"],[349,51,"catchable"],[349,52,"unknown"],[350,7,"unknown"],[350,8,"unknown"],[350,9,"unknown"],[350,10,"unknown"],[350,11,"unknown"],[350,12,"unknown"],[350,13,"unknown"],[350,14,"unknown"],[350,15,"unknown"],[350,16,"unknown"],[350,17,"catchable"],[350,18,"catchable"],[350,21,"catchable"],[350,22,"catchable"],[350,23,"unknown"],[350,24,"unknown"],[350,25,"unknown"],[350,26,"unknown"],[350,27,"unknown"],[350,28,"unknown"],[350,29,"unknown"],[350,30,"unknown"],[350,31,"unknown"],[350,32,"unknown"],[350,33,"catchable"],[350,34,"catchable"],[350,35,"unknown"],[350,36,"catchable"],[350,37,"unknown"],[350,38,"unknown"],[350,39,"unknown"],[350,40,"unknown"],[350,41,"unknown"],[350,42,"unknown"],[350,43,"unknown"],[350,47,"unknown"],[350,48,"unknown"],[350,49,"unknown"],[350,51,"catchable"],[350,52,"unknown"],[351,7,"catchable"],[351,8,"catchable"],[351,9,"catchable"],[351,10,"unknown"],[351,11,"unknown"],[351,12,"catchable"],[351,13,"catchable"],[351,14,"catchable"],[351,15,"unknown"],[351,16,"unknown"],[351,17,"unknown"],[351,18,"unknown"],[351,21,"catchable"],[351,22,"catchable"],[351,23,"unknown"],[351,24,"unknown"],[351,25,"catchable"],[351,26,"catchable"],[351,27,"catchable"],[351,28,"catchable"],[351,29,"catchable"],[351,30,"catchable"],[351,31,"unknown"],[351,32,"unknown"],[351,49,"unknown"],[352,7,"catchable"],[352,8,"catchable"],[352,9,"catchable"],[352,10,"unknown"],[352,11,"unknown"],[352,12,"catchable"],[352,13,"unknown"],[352,14,"catchable"],[352,15,"unknown"],[352,16,"unknown"],[352,17,"unknown"],[352,18,"unknown"],[352,21,"catchable"],[352,22,"catchable"],[352,23,"catchable"],[352,24,"catchable"],[352,25,"catchable"],[352,26,"catchable"],[352,27,"unknown"],[352,28,"unknown"],[352,29,"catchable"],[352,30,"catchable"],[352,31,"unknown"],[352,32,"unknown"],[352,47,"unknown"],[352,48,"unknown"],[353,7,"catchable"],[353,8,"catchable"],[353,9,"catchable"],[353,10,"unknown"],[353,11,"unknown"],[353,12,"unknown"],[353,13,"unknown"],[353,14,"unknown"],[353,15,"catchable"],[353,16,"catchable"],[353,17,"unknown"],[353,18,"unknown"],[353,21,"unknown"],[353,22,"unknown"],[353,23,"catchable"],[353,24,"catchable"],[353,25,"catchable"],[353,26,"catchable"],[353,27,"unknown"],[353,28,"unknown"],[353,29,"catchable"],[353,30,"catchable"],[353,31,"unknown"],[353,32,"unknown"],[353,40,"unknown"],[353,41,"unknown"],[353,42,"unknown"],[353,43,"unknown"],[353,47,"unknown"],[353,48,"unknown"],[354,7,"unknown"],[354,8,"catchable"],[354,9,"catchable"],[354,10,"unknown"],[354,11,"unknown"],[354,12,"catchable"],[354,13,"catchable"],[354,14,"catchable"],[354,15,"catchable"],[354,16,"catchable"],[354,17,"unknown"],[354,18,"unknown"],[354,20,"catchable"],[354,21,"catchable"],[354,22,"catchable"],[354,23,"catchable"],[354,24,"catchable"],[354,25,"unknown"],[354,26,"unknown"],[354,27,"unknown"],[354,28,"unknown"],[354,29,"catchable"],[354,30,"catchable"],[354,31,"unknown"],[354,32,"unknown"],[354,40,"unknown"],[354,41,"unknown"],[354,42,"unknown"],[354,43,"unknown"],[354,47,"unknown"],[354,48,"unknown"],[354,49,"unknown"],[355,7,"catchable"],[355,8,"catchable"],[355,9,"catchable"],[355,10,"unknown"],[355,11,"unknown"],[355,12,"catchable"],[355,13,"catchable"],[355,14,"catchable"],[355,15,"catchable"],[355,16,"catchable"],[355,17,"unknown"],[355,18,"unknown"],[355,20,"catchable"],[355,21,"unknown"],[355,22,"unknown"],[355,23,"unknown"],[355,24,"unknown"],[355,25,"unknown"],[355,26,"unknown"],[355,27,"unknown"],[355,28,"unknown"],[355,29,"unknown"],[355,30,"unknown"],[355,31,"unknown"],[355,32,"unknown"],[355,33,"catchable"],[355,34,"catchable"],[355,35,"unknown"],[355,36,"unknown"],[355,37,"unknown"],[355,38,"unknown"],[355,39,"unknown"],[355,40,"unknown"],[355,41,"unknown"],[355,42,"unknown"],[355,43,"unknown"],[355,47,"unknown"],[355,48,"unknown"],[355,52,"unknown"],[356,7,"catchable"],[356,8,"unknown"],[356,9,"unknown"],[356,10,"unknown"],[356,11,"unknown"],[356,12,"catchable"],[356,13,"catchable"],[356,14,"catchable"],[356,15,"catchable"],[356,16,"catchable"],[356,17,"unknown"],[356,18,"unknown"],[356,21,"unknown"],[356,22,"unknown"],[356,23,"catchable"],[356,24,"catchable"],[356,25,"unknown"],[356,26,"unknown"],[356,27,"unknown"],[356,28,"unknown"],[356,29,"unknown"],[356,30,"unknown"],[356,31,"unknown"],[356,32,"unknown"],[356,33,"catchable"],[356,34,"catchable"],[356,35,"unknown"],[356,36,"catchable"],[356,37,"unknown"],[356,38,"unknown"],[356,39,"unknown"],[356,40,"unknown"],[356,41,"unknown"],[356,42,"unknown"],[356,43,"unknown"],[356,47,"unknown"],[356,48,"unknown"],[356,51,"catchable"],[356,52,"unknown"],[357,7,"catchable"],[357,8,"catchable"],[357,9,"catchable"],[357,10,"unknown"],[357,11,"unknown"],[357,12,"unknown"],[357,13,"unknown"],[357,14,"catchable"],[357,15,"unknown"],[357,16,"unknown"],[357,17,"catchable"],[357,18,"catchable"],[357,19,"catchable"],[357,21,"catchable"],[357,22,"catchable"],[357,23,"catchable"],[357,24,"catchable"],[357,25,"unknown"],[357,26,"unknown"],[357,27,"unknown"],[357,28,"unknown"],[357,29,"catchable"],[357,30,"catchable"],[357,31,"unknown"],[357,32,"unknown"],[357,40,"unknown"],[357,41,"unknown"],[357,42,"unknown"],[357,43,"unknown"],[357,47,"unknown"],[357,48,"unknown"],[358,7,"catchable"],[358,8,"catchable"],[358,9,"catchable"],[358,10,"unknown"],[358,11,"unknown"],[358,12,"catchable"],[358,13,"catchable"],[358,14,"catchable"],[358,15,"catchable"],[358,16,"catchable"],[358,17,"catchable"],[358,18,"catchable"],[358,21,"unknown"],[358,22,"unknown"],[358,23,"unknown"],[358,24,"unknown"],[358,25,"unknown"],[358,26,"unknown"],[358,27,"unknown"],[358,28,"unknown"],[358,29,"unknown"],[358,30,"unknown"],[358,31,"unknown"],[358,32,"unknown"],[358,37,"unknown"],[358,38,"unknown"],[358,39,"unknown"],[358,40,"unknown"],[358,41,"unknown"],[358,42,"unknown"],[358,43,"unknown"],[358,47,"unknown"],[358,48,"unknown"],[358,49,"unknown"],[358,52,"unknown"],[359,7,"catchable"],[359,8,"catchable"],[359,9,"catchable"],[359,10,"unknown"],[359,11,"unknown"],[359,12,"catchable"],[359,13,"catchable"],[359,14,"catchable"],[359,15,"catchable"],[359,16,"catchable"],[359,17,"catchable"],[359,18,"catchable"],[359,19,"catchable"],[359,21,"catchable"],[359,22,"catchable"],[359,23,"catchable"],[359,24,"catchable"],[359,25,"unknown"],[359,26,"unknown"],[359,27,"catchable"],[359,28,"catchable"],[359,29,"catchable"],[359,30,"catchable"],[359,31,"unknown"],[359,32,"unknown"],[359,33,"unknown"],[359,34,"unknown"],[359,35,"unknown"],[359,36,"catchable"],[359,37,"unknown"],[359,38,"unknown"],[359,39,"unknown"],[359,47,"unknown"],[359,49,"unknown"],[359,51,"catchable"],[360,7,"catchable"],[360,8,"catchable"],[360,9,"catchable"],[360,10,"unknown"],[360,11,"unknown"],[360,12,"unknown"],[360,13,"unknown"],[360,14,"unknown"],[360,15,"unknown"],[360,16,"unknown"],[360,17,"unknown"],[360,18,"unknown"],[360,21,"unknown"],[360,22,"unknown"],[360,23,"unknown"],[360,24,"unknown"],[360,25,"catchable"],[360,26,"catchable"],[360,27,"unknown"],[360,28,"unknown"],[360,29,"unknown"],[360,30,"unknown"],[360,31,"unknown"],[360,32,"unknown"],[360,33,"catchable"],[360,34,"catchable"],[360,35,"unknown"],[360,36,"unknown"],[360,37,"unknown"],[360,38,"unknown"],[360,39,"unknown"],[361,7,"catchable"],[361,8,"catchable"],[361,9,"catchable"],[361,10,"unknown"],[361,11,"unknown"],[361,12,"catchable"],[361,13,"catchable"],[361,14,"catchable"],[361,15,"unknown"],[361,16,"unknown"],[361,17,"unknown"],[361,18,"unknown"],[361,20,"catchable"],[361,21,"unknown"],[361,22,"unknown"],[361,23,"catchable"],[361,24,"catchable"],[361,25,"catchable"],[361,26,"catchable"],[361,27,"catchable"],[361,28,"catchable"],[361,29,"catchable"],[361,30,"catchable"],[361,31,"unknown"],[361,32,"unknown"],[361,33,"catchable"],[361,34,"catchable"],[361,35,"unknown"],[361,36,"catchable"],[361,37,"unknown"],[361,38,"unknown"],[361,39,"unknown"],[361,40,"unknown"],[361,41,"unknown"],[361,42,"unknown"],[361,43,"unknown"],[361,47,"unknown"],[361,48,"unknown"],[361,51,"catchable"],[361,52,"unknown"],[362,7,"unknown"],[362,8,"unknown"],[362,9,"unknown"],[362,10,"unknown"],[362,11,"unknown"],[362,12,"unknown"],[362,13,"unknown"],[362,14,"unknown"],[362,15,"unknown"],[362,16,"unknown"],[362,17,"unknown"],[362,18,"unknown"],[362,21,"unknown"],[362,22,"unknown"],[362,23,"unknown"],[362,24,"unknown"],[362,25,"unknown"],[362,26,"unknown"],[362,27,"catchable"],[362,28,"catchable"],[362,29,"catchable"],[362,30,"catchable"],[362,31,"unknown"],[362,32,"unknown"],[362,33,"catchable"],[362,34,"catchable"],[362,35,"unknown"],[362,36,"catchable"],[362,37,"unknown"],[362,38,"unknown"],[362,39,"unknown"],[362,40,"unknown"],[362,41,"unknown"],[362,42,"unknown"],[362,43,"unknown"],[362,47,"unknown"],[362,48,"unknown"],[362,49,"unknown"],[362,51,"catchable"],[362,52,"unknown"],[363,7,"catchable"],[363,8,"catchable"],[363,9,"catchable"],[363,10,"unknown"],[363,11,"unknown"],[363,12,"unknown"],[363,13,"catchable"],[363,14,"unknown"],[363,15,"catchable"],[363,16,"catchable"],[363,17,"catchable"],[363,18,"catchable"],[363,20,"catchable"],[363,21,"catchable"],[363,22,"catchable"],[363,23,"catchable"],[363,24,"catchable"],[363,25,"catchable"],[363,26,"catchable"],[363,27,"catchable"],[363,28,"catchable"],[363,29,"catchable"],[363,30,"catchable"],[363,31,"unknown"],[363,32,"unknown"],[363,33,"unknown"],[363,34,"unknown"],[363,35,"unknown"],[363,36,"catchable"],[363,37,"unknown"],[363,38,"unknown"],[363,39,"unknown"],[363,51,"catchable"],[364,7,"unknown"],[364,8,"unknown"],[364,9,"unknown"],[364,10,"unknown"],[364,11,"unknown"],[364,12,"unknown"],[364,13,"catchable"],[364,14,"catchable"],[364,15,"catchable"],[364,16,"catchable"],[364,17,"catchable"],[364,18,"catchable"],[364,21,"catchable"],[364,22,"catchable"],[364,23,"unknown"],[364,24,"unknown"],[364,25,"unknown"],[364,26,"unknown"],[364,27,"unknown"],[364,28,"unknown"],[364,29,"unknown"],[364,30,"unknown"],[364,31,"unknown"],[364,32,"unknown"],[364,33,"unknown"],[364,34,"unknown"],[364,35,"unknown"],[364,36,"catchable"],[364,37,"unknown"],[364,38,"unknown"],[364,39,"unknown"],[364,51,"catchable"],[365,7,"unknown"],[365,8,"unknown"],[365,9,"unknown"],[365,10,"unknown"],[365,11,"unknown"],[365,12,"unknown"],[365,13,"unknown"],[365,14,"unknown"],[365,15,"unknown"],[365,16,"unknown"],[365,17,"catchable"],[365,18,"catchable"],[365,21,"catchable"],[365,22,"catchable"],[365,23,"unknown"],[365,24,"unknown"],[365,25,"unknown"],[365,26,"unknown"],[365,27,"unknown"],[365,28,"unknown"],[365,29,"unknown"],[365,30,"unknown"],[365,31,"unknown"],[365,32,"unknown"],[365,33,"unknown"],[365,34,"unknown"],[365,35,"unknown"],[365,36,"catchable"],[365,37,"unknown"],[365,38,"unknown"],[365,39,"unknown"],[365,51,"catchable"],[366,7,"catchable"],[366,8,"catchable"],[366,9,"catchable"],[366,10,"unknown"],[366,11,"unknown"],[366,12,"catchable"],[366,13,"catchable"],[366,14,"unknown"],[366,15,"catchable"],[366,16,"catchable"],[366,17,"catchable"],[366,18,"catchable"],[366,21,"catchable"],[366,22,"catchable"],[366,23,"catchable"],[366,24,"catchable"],[366,25,"unknown"],[366,26,"unknown"],[366,27,"unknown"],[366,28,"unknown"],[366,29,"catchable"],[366,30,"catchable"],[366,31,"unknown"],[366,32,"unknown"],[367,7,"unknown"],[367,8,"unknown"],[367,9,"unknown"],[367,10,"unknown"],[367,11,"unknown"],[367,12,"unknown"],[367,13,"unknown"],[367,14,"unknown"],[367,15,"unknown"],[367,16,"unknown"],[367,17,"catchable"],[367,18,"unknown"],[367,21,"catchable"],[367,22,"unknown"],[367,23,"catchable"],[367,24,"unknown"],[367,25,"unknown"],[367,26,"unknown"],[367,27,"unknown"],[367,28,"unknown"],[367,29,"catchable"],[367,30,"catchable"],[367,31,"unknown"],[367,32,"unknown"],[368,7,"unknown"],[368,8,"unknown"],[368,9,"unknown"],[368,10,"unknown"],[368,11,"unknown"],[368,12,"unknown"],[368,13,"unknown"],[368,14,"unknown"],[368,15,"unknown"],[368,16,"unknown"],[368,17,"unknown"],[368,18,"catchable"],[368,21,"unknown"],[368,22,"catchable"],[368,23,"unknown"],[368,24,"catchable"],[368,25,"unknown"],[368,26,"unknown"],[368,27,"unknown"],[368,28,"unknown"],[368,29,"catchable"],[368,30,"catchable"],[368,31,"unknown"],[368,32,"unknown"],[369,7,"catchable"],[369,8,"catchable"],[369,9,"catchable"],[369,10,"unknown"],[369,11,"unknown"],[369,12,"catchable"],[369,13,"catchable"],[369,14,"catchable"],[369,15,"catchable"],[369,16,"catchable"],[369,17,"catchable"],[369,18,"catchable"],[369,21,"catchable"],[369,22,"catchable"],[369,23,"catchable"],[369,24,"catchable"],[369,25,"unknown"],[369,26,"unknown"],[369,27,"catchable"],[369,28,"catchable"],[369,29,"catchable"],[369,30,"catchable"],[369,31,"unknown"],[369,32,"unknown"],[369,33,"unknown"],[369,34,"unknown"],[369,35,"unknown"],[369,36,"catchable"],[369,37,"unknown"],[369,38,"unknown"],[369,39,"unknown"],[369,51,"catchable"],[370,7,"catchable"],[370,8,"catchable"],[370,9,"catchable"],[370,10,"unknown"],[370,11,"unknown"],[370,12,"catchable"],[370,13,"catchable"],[370,14,"catchable"],[370,15,"catchable"],[370,16,"catchable"],[370,17,"catchable"],[370,18,"catchable"],[370,21,"catchable"],[370,22,"catchable"],[370,23,"catchable"],[370,24,"catchable"],[370,25,"unknown"],[370,26,"unknown"],[370,27,"catchable"],[370,28,"catchable"],[370,29,"catchable"],[370,30,"catchable"],[370,31,"unknown"],[370,32,"unknown"],[370,40,"unknown"],[370,41,"unknown"],[370,42,"unknown"],[370,43,"unknown"],[370,47,"unknown"],[370,48,"unknown"],[370,53,"unknown"],[371,7,"catchable"],[371,8,"catchable"],[371,9,"catchable"],[371,10,"unknown"],[371,11,"unknown"],[371,12,"unknown"],[371,13,"catchable"],[371,14,"catchable"],[371,15,"catchable"],[371,16,"catchable"],[371,17,"unknown"],[371,18,"unknown"],[371,21,"catchable"],[371,22,"catchable"],[371,23,"catchable"],[371,24,"catchable"],[371,25,"catchable"],[371,26,"catchable"],[371,27,"catchable"],[371,28,"catchable"],[371,29,"catchable"],[371,30,"catchable"],[371,31,"unknown"],[371,32,"unknown"],[371,33,"unknown"],[371,34,"unknown"],[371,35,"unknown"],[371,36,"catchable"],[371,37,"unknown"],[371,38,"unknown"],[371,39,"unknown"],[371,40,"unknown"],[371,41,"unknown"],[371,42,"unknown"],[371,43,"unknown"],[371,47,"unknown"],[371,48,"unknown"],[371,51,"unknown"],[372,7,"unknown"],[372,8,"unknown"],[372,9,"unknown"],[372,10,"unknown"],[372,11,"unknown"],[372,12,"unknown"],[372,13,"unknown"],[372,14,"unknown"],[372,15,"catchable"],[372,16,"catchable"],[372,17,"unknown"],[372,18,"unknown"],[372,21,"unknown"],[372,22,"unknown"],[372,23,"catchable"],[372,24,"catchable"],[372,25,"unknown"],[372,26,"unknown"],[372,27,"catchable"],[372,28,"catchable"],[372,29,"catchable"],[372,30,"catchable"],[372,31,"unknown"],[372,32,"unknown"],[372,33,"unknown"],[372,34,"unknown"],[372,35,"unknown"],[372,36,"catchable"],[372,37,"unknown"],[372,38,"unknown"],[372,39,"unknown"],[372,40,"unknown"],[372,41,"unknown"],[372,42,"unknown"],[372,43,"unknown"],[372,47,"unknown"],[372,48,"unknown"],[372,51,"unknown"],[373,7,"unknown"],[373,8,"unknown"],[373,9,"unknown"],[373,10,"unknown"],[373,11,"unknown"],[373,12,"unknown"],[373,13,"unknown"],[373,14,"unknown"],[373,15,"unknown"],[373,16,"unknown"],[373,17,"unknown"],[373,18,"unknown"],[373,20,"catchable"],[373,21,"unknown"],[373,22,"unknown"],[373,23,"unknown"],[373,24,"unknown"],[373,25,"unknown"],[373,26,"unknown"],[373,27,"catchable"],[373,28,"catchable"],[373,29,"catchable"],[373,30,"catchable"],[373,31,"unknown"],[373,32,"unknown"],[373,33,"unknown"],[373,34,"unknown"],[373,35,"unknown"],[373,36,"catchable"],[373,37,"unknown"],[373,38,"unknown"],[373,39,"unknown"],[373,40,"unknown"],[373,41,"unknown"],[373,42,"unknown"],[373,43,"unknown"],[373,47,"unknown"],[373,48,"unknown"],[373,49,"unknown"],[373,51,"unknown"],[374,7,"catchable"],[374,8,"catchable"],[374,9,"catchable"],[374,10,"unknown"],[374,11,"unknown"],[374,12,"catchable"],[374,13,"catchable"],[374,14,"catchable"],[374,15,"catchable"],[374,16,"catchable"],[374,17,"unknown"],[374,18,"unknown"],[374,21,"unknown"],[374,22,"unknown"],[374,23,"unknown"],[374,24,"unknown"],[374,25,"catchable"],[374,26,"catchable"],[374,27,"catchable"],[374,28,"catchable"],[374,29,"catchable"],[374,30,"catchable"],[374,31,"unknown"],[374,32,"unknown"],[374,33,"unknown"],[374,34,"unknown"],[374,35,"unknown"],[374,36,"catchable"],[374,37,"unknown"],[374,38,"unknown"],[374,39,"unknown"],[374,40,"unknown"],[374,41,"unknown"],[374,42,"unknown"],[374,43,"unknown"],[374,47,"unknown"],[374,48,"unknown"],[374,51,"catchable"],[374,53,"unknown"],[375,7,"unknown"],[375,8,"unknown"],[375,9,"unknown"],[375,10,"unknown"],[375,11,"unknown"],[375,12,"unknown"],[375,13,"unknown"],[375,14,"unknown"],[375,15,"catchable"],[375,16,"catchable"],[375,17,"catchable"],[375,18,"catchable"],[375,21,"catchable"],[375,22,"catchable"],[375,23,"catchable"],[375,24,"catchable"],[375,25,"unknown"],[375,26,"unknown"],[375,27,"catchable"],[375,28,"catchable"],[375,29,"unknown"],[375,30,"unknown"],[375,31,"unknown"],[375,32,"unknown"],[375,33,"unknown"],[375,34,"unknown"],[375,35,"unknown"],[375,36,"catchable"],[375,37,"unknown"],[375,38,"unknown"],[375,39,"unknown"],[375,40,"unknown"],[375,41,"unknown"],[375,42,"unknown"],[375,43,"unknown"],[375,47,"unknown"],[375,48,"unknown"],[375,51,"catchable"],[375,53,"unknown"],[376,7,"unknown"],[376,8,"unknown"],[376,9,"unknown"],[376,10,"unknown"],[376,11,"unknown"],[376,12,"unknown"],[376,13,"unknown"],[376,14,"unknown"],[376,15,"unknown"],[376,16,"unknown"],[376,17,"catchable"],[376,18,"catchable"],[376,19,"catchable"],[376,21,"catchable"],[376,22,"catchable"],[376,23,"unknown"],[376,24,"unknown"],[376,25,"unknown"],[376,26,"unknown"],[376,27,"unknown"],[376,28,"unknown"],[376,29,"unknown"],[376,30,"unknown"],[376,31,"unknown"],[376,32,"unknown"],[376,33,"unknown"],[376,34,"unknown"],[376,35,"unknown"],[376,36,"catchable"],[376,37,"unknown"],[376,38,"unknown"],[376,39,"unknown"],[376,40,"unknown"],[376,41,"unknown"],[376,42,"unknown"],[376,43,"unknown"],[376,47,"unknown"],[376,48,"unknown"],[376,49,"unknown"],[376,51,"catchable"],[376,53,"unknown"],[377,7,"catchable"],[377,8,"catchable"],[377,9,"catchable"],[377,10,"unknown"],[377,11,"unknown"],[377,12,"unknown"],[377,13,"unknown"],[377,14,"unknown"],[377,15,"unknown"],[377,16,"unknown"],[377,17,"unknown"],[377,18,"unknown"],[377,21,"catchable"],[377,22,"catchable"],[377,23,"unknown"],[377,24,"unknown"],[377,25,"catchable"],[377,26,"catchable"],[377,27,"unknown"],[377,28,"unknown"],[377,29,"catchable"],[377,30,"catchable"],[377,31,"unknown"],[377,32,"unknown"],[377,33,"unknown"],[377,34,"unknown"],[377,35,"unknown"],[377,36,"catchable"],[377,37,"unknown"],[377,38,"unknown"],[377,39,"unknown"],[377,40,"unknown"],[377,41,"unknown"],[377,42,"unknown"],[377,43,"unknown"],[377,47,"unknown"],[377,48,"unknown"],[377,51,"catchable"],[378,7,"catchable"],[378,8,"catchable"],[378,9,"catchable"],[378,10,"unknown"],[378,11,"unknown"],[378,12,"unknown"],[378,13,"unknown"],[378,14,"unknown"],[378,15,"unknown"],[378,16,"unknown"],[378,17,"unknown"],[378,18,"unknown"],[378,21,"catchable"],[378,22,"catchable"],[378,23,"unknown"],[378,24,"unknown"],[378,25,"catchable"],[378,26,"catchable"],[378,27,"unknown"],[378,28,"unknown"],[378,29,"catchable"],[378,30,"catchable"],[378,31,"unknown"],[378,32,"unknown"],[378,33,"unknown"],[378,34,"unknown"],[378,35,"unknown"],[378,36,"catchable"],[378,37,"unknown"],[378,38,"unknown"],[378,39,"unknown"],[378,40,"unknown"],[378,41,"unknown"],[378,42,"unknown"],[378,43,"unknown"],[378,47,"unknown"],[378,48,"unknown"],[378,51,"catchable"],[379,7,"catchable"],[379,8,"catchable"],[379,9,"catchable"],[379,10,"unknown"],[379,11,"unknown"],[379,12,"unknown"],[379,13,"unknown"],[379,14,"unknown"],[379,15,"unknown"],[379,16,"unknown"],[379,17,"unknown"],[379,18,"unknown"],[379,21,"catchable"],[379,22,"catchable"],[379,23,"unknown"],[379,24,"unknown"],[379,25,"catchable"],[379,26,"catchable"],[379,27,"unknown"],[379,28,"unknown"],[379,29,"catchable"],[379,30,"catchable"],[379,31,"unknown"],[379,32,"unknown"],[379,33,"unknown"],[379,34,"unknown"],[379,35,"unknown"],[379,36,"catchable"],[379,37,"unknown"],[379,38,"unknown"],[379,39,"unknown"],[379,40,"unknown"],[379,41,"unknown"],[379,42,"unknown"],[379,43,"unknown"],[379,47,"unknown"],[379,48,"unknown"],[379,51,"catchable"],[380,7,"catchable"],[380,8,"catchable"],[380,9,"catchable"],[380,10,"unknown"],[380,11,"unknown"],[380,12,"unknown"],[380,13,"unknown"],[380,14,"unknown"],[380,15,"catchable"],[380,16,"unknown"],[380,17,"unknown"],[380,18,"unknown"],[380,21,"unknown"],[380,22,"catchable"],[380,23,"unknown"],[380,24,"unknown"],[380,25,"catchable"],[380,26,"catchable"],[380,27,"unknown"],[380,28,"unknown"],[380,29,"unknown"],[380,30,"catchable"],[380,31,"unknown"],[380,32,"unknown"],[380,33,"unknown"],[380,34,"unknown"],[380,35,"unknown"],[380,36,"unknown"],[380,37,"unknown"],[380,38,"unknown"],[380,39,"unknown"],[380,40,"unknown"],[380,41,"unknown"],[380,42,"unknown"],[380,43,"unknown"],[380,47,"unknown"],[380,48,"unknown"],[380,51,"catchable"],[381,7,"catchable"],[381,8,"catchable"],[381,9,"catchable"],[381,10,"unknown"],[381,11,"unknown"],[381,12,"unknown"],[381,13,"unknown"],[381,14,"unknown"],[381,15,"unknown"],[381,16,"catchable"],[381,17,"unknown"],[381,18,"unknown"],[381,21,"catchable"],[381,22,"unknown"],[381,23,"unknown"],[381,24,"unknown"],[381,25,"catchable"],[381,26,"catchable"],[381,27,"unknown"],[381,28,"unknown"],[381,29,"catchable"],[381,30,"unknown"],[381,31,"unknown"],[381,32,"unknown"],[381,33,"unknown"],[381,34,"unknown"],[381,35,"unknown"],[381,36,"catchable"],[381,37,"unknown"],[381,38,"unknown"],[381,39,"unknown"],[381,40,"unknown"],[381,41,"unknown"],[381,42,"unknown"],[381,43,"unknown"],[381,47,"unknown"],[381,48,"unknown"],[382,7,"unknown"],[382,8,"catchable"],[382,9,"catchable"],[382,10,"unknown"],[382,11,"unknown"],[382,12,"unknown"],[382,13,"unknown"],[382,14,"unknown"],[382,15,"catchable"],[382,16,"unknown"],[382,17,"unknown"],[382,18,"unknown"],[382,21,"unknown"],[382,22,"unknown"],[382,23,"unknown"],[382,24,"unknown"],[382,25,"unknown"],[382,26,"catchable"],[382,27,"unknown"],[382,28,"unknown"],[382,29,"unknown"],[382,30,"catchable"],[382,31,"unknown"],[382,32,"unknown"],[382,33,"unknown"],[382,34,"unknown"],[382,35,"unknown"],[382,36,"unknown"],[382,37,"unknown"],[382,38,"unknown"],[382,39,"unknown"],[382,40,"unknown"],[382,41,"unknown"],[382,42,"unknown"],[382,43,"unknown"],[382,47,"unknown"],[382,48,"unknown"],[382,51,"catchable"],[383,7,"catchable"],[383,8,"unknown"],[383,9,"catchable"],[383,10,"unknown"],[383,11,"unknown"],[383,12,"unknown"],[383,13,"unknown"],[383,14,"unknown"],[383,15,"unknown"],[383,16,"catchable"],[383,17,"unknown"],[383,18,"unknown"],[383,21,"unknown"],[383,22,"unknown"],[383,23,"unknown"],[383,24,"unknown"],[383,25,"catchable"],[383,26,"unknown"],[383,27,"unknown"],[383,28,"unknown"],[383,29,"catchable"],[383,30,"unknown"],[383,31,"unknown"],[383,32,"unknown"],[383,33,"unknown"],[383,34,"unknown"],[383,35,"unknown"],[383,36,"catchable"],[383,37,"unknown"],[383,38,"unknown"],[383,39,"unknown"],[383,40,"unknown"],[383,41,"unknown"],[383,42,"unknown"],[383,43,"unknown"],[383,47,"unknown"],[383,48,"unknown"],[384,7,"catchable"],[384,8,"catchable"],[384,9,"catchable"],[384,10,"unknown"],[384,11,"unknown"],[384,12,"unknown"],[384,13,"unknown"],[384,14,"unknown"],[384,15,"catchable"],[384,16,"catchable"],[384,17,"unknown"],[384,18,"unknown"],[384,21,"unknown"],[384,22,"unknown"],[384,23,"unknown"],[384,24,"unknown"],[384,25,"catchable"],[384,26,"catchable"],[384,27,"unknown"],[384,28,"unknown"],[384,29,"catchable"],[384,30,"catchable"],[384,31,"unknown"],[384,32,"unknown"],[384,33,"unknown"],[384,34,"unknown"],[384,35,"unknown"],[384,36,"catchable"],[384,37,"unknown"],[384,38,"unknown"],[384,39,"unknown"],[384,40,"unknown"],[384,41,"unknown"],[384,42,"unknown"],[384,43,"unknown"],[384,47,"unknown"],[384,48,"unknown"],[384,51,"catchable"],[385,7,"catchable"],[385,8,"catchable"],[385,9,"unknown"],[385,10,"unknown"],[385,11,"unknown"],[385,12,"unknown"],[385,13,"unknown"],[385,14,"unknown"],[385,15,"unknown"],[385,16,"unknown"],[385,17,"unknown"],[385,18,"unknown"],[385,21,"unknown"],[385,22,"unknown"],[385,23,"unknown"],[385,24,"unknown"],[385,25,"unknown"],[385,26,"unknown"],[385,27,"unknown"],[385,28,"unknown"],[385,29,"unknown"],[385,30,"unknown"],[385,31,"unknown"],[385,32,"unknown"],[385,33,"unknown"],[385,34,"unknown"],[385,35,"unknown"],[385,36,"unknown"],[385,37,"unknown"],[385,38,"unknown"],[385,39,"unknown"],[385,40,"unknown"],[385,41,"unknown"],[385,42,"unknown"],[385,43,"unknown"],[385,47,"unknown"],[385,48,"unknown"],[386,7,"unknown"],[386,8,"unknown"],[386,9,"catchable"],[386,10,"catchable"],[386,11,"catchable"],[386,12,"unknown"],[386,13,"unknown"],[386,14,"unknown"],[386,15,"unknown"],[386,16,"unknown"],[386,17,"unknown"],[386,18,"unknown"],[386,21,"unknown"],[386,22,"unknown"],[386,23,"unknown"],[386,24,"unknown"],[386,25,"catchable"],[386,26,"catchable"],[386,27,"unknown"],[386,28,"unknown"],[386,29,"unknown"],[386,30,"unknown"],[386,31,"unknown"],[386,32,"unknown"],[386,40,"unknown"],[386,41,"unknown"],[386,42,"unknown"],[386,43,"unknown"],[386,47,"unknown"],[386,48,"unknown"],[387,12,"catchable"],[387,13,"catchable"],[387,14,"catchable"],[387,15,"unknown"],[387,16,"unknown"],[387,17,"unknown"],[387,18,"unknown"],[387,21,"unknown"],[387,22,"unknown"],[387,23,"unknown"],[387,24,"unknown"],[387,25,"catchable"],[387,26,"catchable"],[387,27,"unknown"],[387,28,"unknown"],[387,29,"unknown"],[387,30,"unknown"],[387,31,"unknown"],[387,32,"unknown"],[387,37,"unknown"],[387,38,"unknown"],[387,39,"unknown"],[387,40,"unknown"],[387,41,"unknown"],[387,42,"unknown"],[387,43,"unknown"],[387,47,"unknown"],[387,48,"unknown"],[387,53,"unknown"],[388,12,"unknown"],[388,13,"unknown"],[388,14,"unknown"],[388,15,"unknown"],[388,16,"unknown"],[388,17,"unknown"],[388,18,"unknown"],[388,21,"unknown"],[388,22,"unknown"],[388,23,"unknown"],[388,24,"unknown"],[388,25,"unknown"],[388,26,"unknown"],[388,27,"unknown"],[388,28,"unknown"],[388,29,"catchable"],[388,30,"catchable"],[388,31,"unknown"],[388,32,"unknown"],[388,37,"unknown"],[388,38,"unknown"],[388,39,"unknown"],[388,40,"unknown"],[388,41,"unknown"],[388,42,"unknown"],[388,43,"unknown"],[388,47,"unknown"],[388,48,"unknown"],[388,53,"unknown"],[389,12,"unknown"],[389,13,"unknown"],[389,14,"unknown"],[389,15,"unknown"],[389,16,"unknown"],[389,17,"unknown"],[389,18,"unknown"],[389,21,"unknown"],[389,22,"unknown"],[389,23,"unknown"],[389,24,"unknown"],[389,25,"unknown"],[389,26,"unknown"],[389,27,"unknown"],[389,28,"unknown"],[389,29,"unknown"],[389,30,"unknown"],[389,31,"unknown"],[389,32,"unknown"],[389,37,"unknown"],[389,38,"unknown"],[389,39,"unknown"],[389,40,"unknown"],[389,41,"unknown"],[389,42,"unknown"],[389,43,"unknown"],[389,47,"unknown"],[389,48,"unknown"],[389,49,"unknown"],[389,53,"unknown"],[390,12,"catchable"],[390,13,"catchable"],[390,14,"catchable"],[390,15,"unknown"],[390,16,"unknown"],[390,17,"unknown"],[390,18,"unknown"],[390,21,"unknown"],[390,22,"unknown"],[390,23,"unknown"],[390,24,"unknown"],[390,25,"catchable"],[390,26,"catchable"],[390,27,"unknown"],[390,28,"unknown"],[390,29,"unknown"],[390,30,"unknown"],[390,31,"unknown"],[390,32,"unknown"],[390,37,"unknown"],[390,38,"unknown"],[390,39,"unknown"],[390,40,"unknown"],[390,41,"unknown"],[390,42,"unknown"],[390,43,"unknown"],[390,47,"unknown"],[390,48,"unknown"],[390,53,"unknown"],[391,12,"unknown"],[391,13,"unknown"],[391,14,"unknown"],[391,15,"unknown"],[391,16,"unknown"],[391,17,"unknown"],[391,18,"unknown"],[391,21,"unknown"],[391,22,"unknown"],[391,23,"unknown"],[391,24,"unknown"],[391,25,"unknown"],[391,26,"unknown"],[391,27,"unknown"],[391,28,"unknown"],[391,29,"catchable"],[391,30,"catchable"],[391,31,"unknown"],[391,32,"unknown"],[391,37,"unknown"],[391,38,"unknown"],[391,39,"unknown"],[391,40,"unknown"],[391,41,"unknown"],[391,42,"unknown"],[391,43,"unknown"],[391,47,"unknown"],[391,48,"unknown"],[391,53,"unknown"],[392,12,"unknown"],[392,13,"unknown"],[392,14,"unknown"],[392,15,"unknown"],[392,16,"unknown"],[392,17,"unknown"],[392,18,"unknown"],[392,21,"unknown"],[392,22,"unknown"],[392,23,"unknown"],[392,24,"unknown"],[392,25,"unknown"],[392,26,"unknown"],[392,27,"unknown"],[392,28,"unknown"],[392,29,"unknown"],[392,30,"unknown"],[392,31,"unknown"],[392,32,"unknown"],[392,37,"unknown"],[392,38,"unknown"],[392,39,"unknown"],[392,40,"unknown"],[392,41,"unknown"],[392,42,"unknown"],[392,43,"unknown"],[392,47,"unknown"],[392,48,"unknown"],[392,49,"unknown"],[392,53,"unknown"],[393,12,"catchable"],[393,13,"catchable"],[393,14,"catchable"],[393,15,"unknown"],[393,16,"unknown"],[393,17,"unknown"],[393,18,"unknown"],[393,21,"unknown"],[393,22,"unknown"],[393,23,"unknown"],[393,24,"unknown"],[393,25,"catchable"],[393,26,"catchable"],[393,27,"unknown"],[393,28,"unknown"],[393,29,"unknown"],[393,30,"unknown"],[393,31,"unknown"],[393,32,"unknown"],[393,37,"unknown"],[393,38,"unknown"],[393,39,"unknown"],[393,40,"unknown"],[393,41,"unknown"],[393,42,"unknown"],[393,43,"unknown"],[393,47,"unknown"],[393,48,"unknown"],[393,53,"unknown"],[394,12,"unknown"],[394,13,"unknown"],[394,14,"unknown"],[394,15,"unknown"],[394,16,"unknown"],[394,17,"unknown"],[394,18,"unknown"],[394,21,"unknown"],[394,22,"unknown"],[394,23,"unknown"],[394,24,"unknown"],[394,25,"unknown"],[394,26,"unknown"],[394,27,"unknown"],[394,28,"unknown"],[394,29,"catchable"],[394,30,"catchable"],[394,31,"unknown"],[394,32,"unknown"],[394,37,"unknown"],[394,38,"unknown"],[394,39,"unknown"],[394,40,"unknown"],[394,41,"unknown"],[394,42,"unknown"],[394,43,"unknown"],[394,47,"unknown"],[394,48,"unknown"],[394,53,"unknown"],[395,12,"unknown"],[395,13,"unknown"],[395,14,"unknown"],[395,15,"unknown"],[395,16,"unknown"],[395,17,"unknown"],[395,18,"unknown"],[395,21,"unknown"],[395,22,"unknown"],[395,23,"unknown"],[395,24,"unknown"],[395,25,"unknown"],[395,26,"unknown"],[395,27,"unknown"],[395,28,"unknown"],[395,29,"unknown"],[395,30,"unknown"],[395,31,"unknown"],[395,32,"unknown"],[395,37,"unknown"],[395,38,"unknown"],[395,39,"unknown"],[395,40,"unknown"],[395,41,"unknown"],[395,42,"unknown"],[395,43,"unknown"],[395,47,"unknown"],[395,48,"unknown"],[395,49,"unknown"],[395,53,"unknown"],[396,12,"catchable"],[396,13,"catchable"],[396,14,"catchable"],[396,15,"catchable"],[396,16,"catchable"],[396,17,"unknown"],[396,18,"unknown"],[396,21,"unknown"],[396,22,"unknown"],[396,23,"catchable"],[396,24,"catchable"],[396,25,"unknown"],[396,26,"unknown"],[396,27,"unknown"],[396,28,"unknown"],[396,29,"unknown"],[396,30,"unknown"],[396,31,"unknown"],[396,32,"unknown"],[396,37,"unknown"],[396,38,"unknown"],[396,39,"unknown"],[396,40,"unknown"],[396,41,"unknown"],[396,42,"unknown"],[396,43,"unknown"],[396,47,"unknown"],[396,48,"unknown"],[396,52,"unknown"],[397,12,"catchable"],[397,13,"catchable"],[397,14,"catchable"],[397,15,"unknown"],[397,16,"unknown"],[397,17,"unknown"],[397,18,"unknown"],[397,21,"unknown"],[397,22,"unknown"],[397,23,"catchable"],[397,24,"catchable"],[397,25,"unknown"],[397,26,"unknown"],[397,27,"catchable"],[397,28,"catchable"],[397,29,"unknown"],[397,30,"unknown"],[397,31,"unknown"],[397,32,"unknown"],[397,37,"unknown"],[397,38,"unknown"],[397,39,"unknown"],[397,40,"unknown"],[397,41,"unknown"],[397,42,"unknown"],[397,43,"unknown"],[397,47,"unknown"],[397,48,"unknown"],[397,52,"unknown"],[398,12,"unknown"],[398,13,"unknown"],[398,14,"unknown"],[398,15,"unknown"],[398,16,"unknown"],[398,17,"unknown"],[398,18,"unknown"],[398,21,"unknown"],[398,22,"unknown"],[398,23,"unknown"],[398,24,"unknown"],[398,25,"unknown"],[398,26,"unknown"],[398,27,"unknown"],[398,28,"unknown"],[398,29,"unknown"],[398,30,"unknown"],[398,31,"unknown"],[398,32,"unknown"],[398,37,"unknown"],[398,38,"unknown"],[398,39,"unknown"],[398,40,"unknown"],[398,41,"unknown"],[398,42,"unknown"],[398,43,"unknown"],[398,47,"unknown"],[398,48,"unknown"],[398,49,"unknown"],[398,52,"unknown"],[399,12,"catchable"],[399,13,"catchable"],[399,14,"catchable"],[399,15,"catchable"],[399,16,"catchable"],[399,17,"unknown"],[399,18,"unknown"],[399,21,"unknown"],[399,22,"unknown"],[399,23,"catchable"],[399,24,"catchable"],[399,25,"unknown"],[399,26,"unknown"],[399,27,"unknown"],[399,28,"unknown"],[399,29,"unknown"],[399,30,"unknown"],[399,31,"unknown"],[399,32,"unknown"],[399,37,"unknown"],[399,38,"unknown"],[399,39,"unknown"],[400,12,"catchable"],[400,13,"catchable"],[400,14,"catchable"],[400,15,"unknown"],[400,16,"unknown"],[400,17,"catchable"],[400,18,"catchable"],[400,21,"catchable"],[400,22,"catchable"],[400,23,"catchable"],[400,24,"catchable"],[400,25,"unknown"],[400,26,"unknown"],[400,27,"unknown"],[400,28,"unknown"],[400,29,"unknown"],[400,30,"unknown"],[400,31,"unknown"],[400,32,"unknown"],[400,37,"unknown"],[400,38,"unknown"],[400,39,"unknown"],[401,12,"catchable"],[401,13,"catchable"],[401,14,"catchable"],[401,15,"catchable"],[401,16,"catchable"],[401,17,"unknown"],[401,18,"unknown"],[401,21,"unknown"],[401,22,"unknown"],[401,23,"unknown"],[401,24,"unknown"],[401,25,"unknown"],[401,26,"unknown"],[401,27,"unknown"],[401,28,"unknown"],[401,29,"unknown"],[401,30,"unknown"],[401,31,"unknown"],[401,32,"unknown"],[401,37,"unknown"],[401,38,"unknown"],[401,39,"unknown"],[401,40,"unknown"],[401,41,"unknown"],[401,42,"unknown"],[401,43,"unknown"],[401,47,"unknown"],[401,48,"unknown"],[401,52,"unknown"],[402,12,"catchable"],[402,13,"catchable"],[402,14,"catchable"],[402,15,"catchable"],[402,16,"catchable"],[402,17,"catchable"],[402,18,"catchable"],[402,21,"unknown"],[402,22,"unknown"],[402,23,"unknown"],[402,24,"unknown"],[402,25,"catchable"],[402,26,"catchable"],[402,27,"unknown"],[402,28,"unknown"],[402,29,"unknown"],[402,30,"unknown"],[402,31,"unknown"],[402,32,"unknown"],[402,37,"unknown"],[402,38,"unknown"],[402,39,"unknown"],[402,40,"unknown"],[402,41,"unknown"],[402,42,"unknown"],[402,43,"unknown"],[402,47,"unknown"],[402,48,"unknown"],[402,52,"unknown"],[403,12,"catchable"],[403,13,"catchable"],[403,14,"catchable"],[403,15,"catchable"],[403,16,"catchable"],[403,17,"unknown"],[403,18,"unknown"],[403,21,"unknown"],[403,22,"unknown"],[403,23,"unknown"],[403,24,"unknown"],[403,25,"unknown"],[403,26,"unknown"],[403,27,"unknown"],[403,28,"unknown"],[403,29,"unknown"],[403,30,"unknown"],[403,31,"unknown"],[403,32,"unknown"],[403,33,"unknown"],[403,34,"unknown"],[403,35,"catchable"],[403,36,"unknown"],[403,37,"unknown"],[403,38,"unknown"],[403,39,"unknown"],[403,40,"unknown"],[403,41,"unknown"],[403,42,"unknown"],[403,43,"unknown"],[403,47,"unknown"],[403,48,"unknown"],[403,50,"catchable"],[403,52,"unknown"],[404,12,"catchable"],[404,13,"catchable"],[404,14,"catchable"],[404,15,"catchable"],[404,16,"catchable"],[404,17,"unknown"],[404,18,"unknown"],[404,21,"unknown"],[404,22,"unknown"],[404,23,"catchable"],[404,24,"catchable"],[404,25,"unknown"],[404,26,"unknown"],[404,27,"catchable"],[404,28,"catchable"],[404,29,"unknown"],[404,30,"unknown"],[404,31,"unknown"],[404,32,"unknown"],[404,33,"unknown"],[404,34,"unknown"],[404,35,"catchable"],[404,36,"unknown"],[404,37,"unknown"],[404,38,"unknown"],[404,39,"unknown"],[404,40,"unknown"],[404,41,"unknown"],[404,42,"unknown"],[404,43,"unknown"],[404,47,"unknown"],[404,48,"unknown"],[404,50,"catchable"],[404,52,"unknown"],[405,12,"unknown"],[405,13,"unknown"],[405,14,"unknown"],[405,15,"unknown"],[405,16,"unknown"],[405,17,"unknown"],[405,18,"unknown"],[405,21,"unknown"],[405,22,"unknown"],[405,23,"unknown"],[405,24,"unknown"],[405,25,"unknown"],[405,26,"unknown"],[405,27,"unknown"],[405,28,"unknown"],[405,29,"unknown"],[405,30,"unknown"],[405,31,"unknown"],[405,32,"unknown"],[405,33,"unknown"],[405,34,"unknown"],[405,35,"catchable"],[405,36,"catchable"],[405,37,"unknown"],[405,38,"unknown"],[405,39,"unknown"],[405,40,"unknown"],[405,41,"unknown"],[405,42,"unknown"],[405,43,"unknown"],[405,47,"unknown"],[405,48,"unknown"],[405,49,"unknown"],[405,50,"catchable"],[405,51,"catchable"],[405,52,"unknown"],[406,12,"catchable"],[406,13,"catchable"],[406,14,"catchable"],[406,15,"catchable"],[406,16,"catchable"],[406,17,"unknown"],[406,18,"unknown"],[406,21,"unknown"],[406,22,"unknown"],[406,23,"catchable"],[406,24,"catchable"],[406,25,"unknown"],[406,26,"unknown"],[406,27,"unknown"],[406,28,"unknown"],[406,29,"unknown"],[406,30,"unknown"],[406,31,"unknown"],[406,32,"unknown"],[406,33,"catchable"],[406,34,"catchable"],[406,35,"unknown"],[406,36,"unknown"],[406,37,"unknown"],[406,38,"unknown"],[406,39,"unknown"],[406,47,"unknown"],[407,12,"unknown"],[407,13,"unknown"],[407,14,"unknown"],[407,15,"unknown"],[407,16,"unknown"],[407,17,"unknown"],[407,18,"unknown"],[407,21,"catchable"],[407,22,"catchable"],[407,23,"unknown"],[407,24,"unknown"],[407,25,"unknown"],[407,26,"unknown"],[407,27,"unknown"],[407,28,"unknown"],[407,29,"unknown"],[407,30,"unknown"],[407,31,"unknown"],[407,32,"unknown"],[407,33,"catchable"],[407,34,"catchable"],[407,35,"catchable"],[407,36,"unknown"],[407,37,"unknown"],[407,38,"unknown"],[407,39,"unknown"],[407,47,"unknown"],[407,49,"unknown"],[407,50,"catchable"],[408,12,"catchable"],[408,13,"catchable"],[408,14,"catchable"],[408,15,"catchable"],[408,16,"catchable"],[408,17,"catchable"],[408,18,"catchable"],[408,21,"catchable"],[408,22,"catchable"],[408,23,"unknown"],[408,24,"unknown"],[408,25,"unknown"],[408,26,"unknown"],[408,27,"catchable"],[408,28,"catchable"],[408,29,"catchable"],[408,30,"catchable"],[408,31,"unknown"],[408,32,"unknown"],[408,37,"unknown"],[408,38,"unknown"],[408,39,"unknown"],[408,40,"unknown"],[408,41,"unknown"],[408,42,"unknown"],[408,43,"unknown"],[408,47,"unknown"],[408,48,"unknown"],[408,53,"unknown"],[409,12,"unknown"],[409,13,"unknown"],[409,14,"unknown"],[409,15,"unknown"],[409,16,"unknown"],[409,17,"unknown"],[409,18,"unknown"],[409,21,"unknown"],[409,22,"unknown"],[409,23,"unknown"],[409,24,"unknown"],[409,25,"unknown"],[409,26,"unknown"],[409,27,"unknown"],[409,28,"unknown"],[409,29,"unknown"],[409,30,"unknown"],[409,31,"unknown"],[409,32,"unknown"],[409,37,"unknown"],[409,38,"unknown"],[409,39,"unknown"],[409,40,"unknown"],[409,41,"unknown"],[409,42,"unknown"],[409,43,"unknown"],[409,47,"unknown"],[409,48,"unknown"],[409,49,"unknown"],[409,53,"unknown"],[410,12,"catchable"],[410,13,"catchable"],[410,14,"catchable"],[410,15,"catchable"],[410,16,"catchable"],[410,17,"catchable"],[410,18,"catchable"],[410,21,"catchable"],[410,22,"catchable"],[410,23,"unknown"],[410,24,"unknown"],[410,25,"unknown"],[410,26,"unknown"],[410,27,"catchable"],[410,28,"catchable"],[410,29,"catchable"],[410,30,"catchable"],[410,31,"unknown"],[410,32,"unknown"],[410,37,"unknown"],[410,38,"unknown"],[410,39,"unknown"],[410,40,"unknown"],[410,41,"unknown"],[410,42,"unknown"],[410,43,"unknown"],[410,47,"unknown"],[410,48,"unknown"],[410,53,"unknown"],[411,12,"unknown"],[411,13,"unknown"],[411,14,"unknown"],[411,15,"unknown"],[411,16,"unknown"],[411,17,"unknown"],[411,18,"unknown"],[411,21,"unknown"],[411,22,"unknown"],[411,23,"unknown"],[411,24,"unknown"],[411,25,"unknown"],[411,26,"unknown"],[411,27,"unknown"],[411,28,"unknown"],[411,29,"unknown"],[411,30,"unknown"],[411,31,"unknown"],[411,32,"unknown"],[411,37,"unknown"],[411,38,"unknown"],[411,39,"unknown"],[411,40,"unknown"],[411,41,"unknown"],[411,42,"unknown"],[411,43,"unknown"],[411,47,"unknown"],[411,48,"unknown"],[411,49,"unknown"],[411,53,"unknown"],[412,12,"catchable"],[412,13,"catchable"],[412,14,"catchable"],[412,15,"catchable"],[412,16,"catchable"],[412,17,"unknown"],[412,18,"unknown"],[412,21,"unknown"],[412,22,"unknown"],[412,23,"catchable"],[412,24,"catchable"],[412,25,"unknown"],[412,26,"unknown"],[412,27,"unknown"],[412,28,"unknown"],[412,29,"unknown"],[412,30,"unknown"],[412,31,"unknown"],[412,32,"unknown"],[412,37,"unknown"],[412,38,"unknown"],[412,39,"unknown"],[413,12,"unknown"],[413,13,"unknown"],[413,14,"unknown"],[413,15,"unknown"],[413,16,"unknown"],[413,17,"unknown"],[413,18,"unknown"],[413,21,"unknown"],[413,22,"unknown"],[413,23,"unknown"],[413,24,"unknown"],[413,25,"unknown"],[413,26,"unknown"],[413,27,"unknown"],[413,28,"unknown"],[413,29,"unknown"],[413,30,"unknown"],[413,31,"unknown"],[413,32,"unknown"],[413,37,"unknown"],[413,38,"unknown"],[413,39,"unknown"],[414,12,"unknown"],[414,13,"unknown"],[414,14,"unknown"],[414,15,"unknown"],[414,16,"unknown"],[414,17,"unknown"],[414,18,"unknown"],[414,21,"unknown"],[414,22,"unknown"],[414,23,"unknown"],[414,24,"unknown"],[414,25,"unknown"],[414,26,"unknown"],[414,27,"unknown"],[414,28,"unknown"],[414,29,"unknown"],[414,30,"unknown"],[414,31,"unknown"],[414,32,"unknown"],[414,37,"unknown"],[414,38,"unknown"],[414,39,"unknown"],[415,12,"catchable"],[415,13,"catchable"],[415,14,"catchable"],[415,15,"catchable"],[415,16,"catchable"],[415,17,"catchable"],[415,18,"catchable"],[415,21,"catchable"],[415,22,"catchable"],[415,23,"catchable"],[415,24,"catchable"],[415,25,"unknown"],[415,26,"unknown"],[415,27,"unknown"],[415,28,"unknown"],[415,29,"unknown"],[415,30,"unknown"],[415,31,"unknown"],[415,32,"unknown"],[415,33,"catchable"],[415,34,"catchable"],[415,35,"catchable"],[415,36,"unknown"],[415,37,"unknown"],[415,38,"unknown"],[415,39,"unknown"],[415,40,"unknown"],[415,41,"unknown"],[415,42,"unknown"],[415,43,"unknown"],[415,47,"unknown"],[415,48,"unknown"],[415,50,"catchable"],[416,12,"unknown"],[416,13,"unknown"],[416,14,"unknown"],[416,15,"unknown"],[416,16,"unknown"],[416,17,"catchable"],[416,18,"catchable"],[416,21,"catchable"],[416,22,"catchable"],[416,23,"unknown"],[416,24,"unknown"],[416,25,"unknown"],[416,26,"unknown"],[416,27,"unknown"],[416,28,"unknown"],[416,29,"unknown"],[416,30,"unknown"],[416,31,"unknown"],[416,32,"unknown"],[416,33,"catchable"],[416,34,"catchable"],[416,35,"catchable"],[416,36,"catchable"],[416,37,"unknown"],[416,38,"unknown"],[416,39,"unknown"],[416,40,"unknown"],[416,41,"unknown"],[416,42,"unknown"],[416,43,"unknown"],[416,47,"unknown"],[416,48,"unknown"],[416,50,"catchable"],[416,51,"catchable"],[417,12,"catchable"],[417,13,"catchable"],[417,14,"catchable"],[417,15,"catchable"],[417,16,"catchable"],[417,17,"unknown"],[417,18,"unknown"],[417,21,"catchable"],[417,22,"catchable"],[417,23,"catchable"],[417,24,"catchable"],[417,25,"unknown"],[417,26,"unknown"],[417,27,"unknown"],[417,28,"unknown"],[417,29,"unknown"],[417,30,"unknown"],[417,31,"unknown"],[417,32,"unknown"],[417,37,"unknown"],[417,38,"unknown"],[417,39,"unknown"],[417,40,"unknown"],[417,41,"unknown"],[417,42,"unknown"],[417,43,"unknown"],[417,47,"unknown"],[417,48,"unknown"],[417,52,"unknown"],[418,12,"catchable"],[418,13,"catchable"],[418,14,"catchable"],[418,15,"catchable"],[418,16,"catchable"],[418,17,"catchable"],[418,18,"catchable"],[418,21,"catchable"],[418,22,"catchable"],[418,23,"unknown"],[418,24,"unknown"],[418,25,"unknown"],[418,26,"unknown"],[418,27,"unknown"],[418,28,"unknown"],[418,29,"unknown"],[418,30,"unknown"],[418,31,"unknown"],[418,32,"unknown"],[418,37,"unknown"],[418,38,"unknown"],[418,39,"unknown"],[418,40,"unknown"],[418,41,"unknown"],[418,42,"unknown"],[418,43,"unknown"],[418,47,"unknown"],[418,48,"unknown"],[419,12,"catchable"],[419,13,"catchable"],[419,14,"catchable"],[419,15,"catchable"],[419,16,"catchable"],[419,17,"catchable"],[419,18,"catchable"],[419,21,"catchable"],[419,22,"catchable"],[419,23,"catchable"],[419,24,"catchable"],[419,25,"unknown"],[419,26,"unknown"],[419,27,"unknown"],[419,28,"unknown"],[419,29,"catchable"],[419,30,"catchable"],[419,31,"unknown"],[419,32,"unknown"],[419,37,"unknown"],[419,38,"unknown"],[419,39,"unknown"],[419,40,"unknown"],[419,41,"unknown"],[419,42,"unknown"],[419,43,"unknown"],[419,47,"unknown"],[419,48,"unknown"],[420,12,"catchable"],[420,13,"catchable"],[420,14,"catchable"],[420,15,"catchable"],[420,16,"catchable"],[420,17,"unknown"],[420,18,"unknown"],[420,21,"unknown"],[420,22,"unknown"],[420,23,"unknown"],[420,24,"unknown"],[420,25,"unknown"],[420,26,"unknown"],[420,27,"unknown"],[420,28,"unknown"],[420,29,"unknown"],[420,30,"unknown"],[420,31,"unknown"],[420,32,"unknown"],[420,33,"catchable"],[420,34,"catchable"],[420,35,"catchable"],[420,36,"unknown"],[420,37,"unknown"],[420,38,"unknown"],[420,39,"unknown"],[420,50,"catchable"],[421,12,"unknown"],[421,13,"unknown"],[421,14,"unknown"],[421,15,"unknown"],[421,16,"unknown"],[421,17,"catchable"],[421,18,"catchable"],[421,21,"unknown"],[421,22,"unknown"],[421,23,"unknown"],[421,24,"unknown"],[421,25,"catchable"],[421,26,"catchable"],[421,27,"unknown"],[421,28,"unknown"],[421,29,"unknown"],[421,30,"unknown"],[421,31,"unknown"],[421,32,"unknown"],[421,33,"catchable"],[421,34,"catchable"],[421,35,"unknown"],[421,36,"catchable"],[421,37,"unknown"],[421,38,"unknown"],[421,39,"unknown"],[421,51,"catchable"],[422,12,"catchable"],[422,13,"catchable"],[422,14,"catchable"],[422,15,"unknown"],[422,16,"unknown"],[422,17,"unknown"],[422,18,"unknown"],[422,21,"unknown"],[422,22,"unknown"],[422,23,"unknown"],[422,24,"unknown"],[422,25,"unknown"],[422,26,"unknown"],[422,27,"unknown"],[422,28,"unknown"],[422,29,"catchable"],[422,30,"catchable"],[422,31,"unknown"],[422,32,"unknown"],[422,33,"catchable"],[422,34,"catchable"],[422,35,"unknown"],[422,36,"unknown"],[422,37,"unknown"],[422,38,"unknown"],[422,39,"unknown"],[422,40,"unknown"],[422,41,"unknown"],[422,42,"unknown"],[422,43,"unknown"],[422,47,"unknown"],[422,48,"unknown"],[423,12,"catchable"],[423,13,"catchable"],[423,14,"catchable"],[423,15,"unknown"],[423,16,"unknown"],[423,17,"unknown"],[423,18,"unknown"],[423,21,"unknown"],[423,22,"unknown"],[423,23,"catchable"],[423,24,"catchable"],[423,25,"unknown"],[423,26,"unknown"],[423,27,"catchable"],[423,28,"catchable"],[423,29,"catchable"],[423,30,"catchable"],[423,31,"unknown"],[423,32,"unknown"],[423,33,"catchable"],[423,34,"catchable"],[423,35,"unknown"],[423,36,"catchable"],[423,37,"unknown"],[423,38,"unknown"],[423,39,"unknown"],[423,40,"unknown"],[423,41,"unknown"],[423,42,"unknown"],[423,43,"unknown"],[423,47,"unknown"],[423,48,"unknown"],[423,51,"catchable"],[424,12,"unknown"],[424,13,"unknown"],[424,14,"unknown"],[424,15,"unknown"],[424,16,"unknown"],[424,17,"unknown"],[424,18,"unknown"],[424,21,"catchable"],[424,22,"catchable"],[424,23,"unknown"],[424,24,"unknown"],[424,25,"unknown"],[424,26,"unknown"],[424,27,"unknown"],[424,28,"unknown"],[424,29,"catchable"],[424,30,"catchable"],[424,31,"unknown"],[424,32,"unknown"],[424,37,"unknown"],[424,38,"unknown"],[424,39,"unknown"],[424,40,"unknown"],[424,41,"unknown"],[424,42,"unknown"],[424,43,"unknown"],[424,47,"unknown"],[424,48,"unknown"],[424,52,"unknown"],[425,12,"catchable"],[425,13,"catchable"],[425,14,"catchable"],[425,15,"unknown"],[425,16,"unknown"],[425,17,"unknown"],[425,18,"unknown"],[425,21,"catchable"],[425,22,"catchable"],[425,23,"catchable"],[425,24,"catchable"],[425,25,"unknown"],[425,26,"unknown"],[425,27,"catchable"],[425,28,"catchable"],[425,29,"catchable"],[425,30,"catchable"],[425,31,"unknown"],[425,32,"unknown"],[425,33,"catchable"],[425,34,"catchable"],[425,35,"catchable"],[425,36,"unknown"],[425,37,"unknown"],[425,38,"unknown"],[425,39,"unknown"],[425,40,"unknown"],[425,41,"unknown"],[425,42,"unknown"],[425,43,"unknown"],[425,47,"unknown"],[425,48,"unknown"],[425,50,"catchable"],[426,12,"unknown"],[426,13,"unknown"],[426,14,"unknown"],[426,15,"unknown"],[426,16,"unknown"],[426,17,"catchable"],[426,18,"catchable"],[426,21,"catchable"],[426,22,"catchable"],[426,23,"catchable"],[426,24,"catchable"],[426,25,"unknown"],[426,26,"unknown"],[426,27,"catchable"],[426,28,"catchable"],[426,29,"unknown"],[426,30,"unknown"],[426,31,"unknown"],[426,32,"unknown"],[426,33,"catchable"],[426,34,"catchable"],[426,35,"catchable"],[426,36,"catchable"],[426,37,"unknown"],[426,38,"unknown"],[426,39,"unknown"],[426,40,"unknown"],[426,41,"unknown"],[426,42,"unknown"],[426,43,"unknown"],[426,47,"unknown"],[426,48,"unknown"],[426,50,"catchable"],[426,51,"catchable"],[427,12,"catchable"],[427,13,"catchable"],[427,14,"catchable"],[427,15,"catchable"],[427,16,"catchable"],[427,17,"unknown"],[427,18,"unknown"],[427,21,"catchable"],[427,22,"unknown"],[427,23,"unknown"],[427,24,"unknown"],[427,25,"unknown"],[427,26,"unknown"],[427,27,"unknown"],[427,28,"unknown"],[427,29,"catchable"],[427,30,"catchable"],[427,31,"unknown"],[427,32,"unknown"],[427,33,"unknown"],[427,34,"unknown"],[427,35,"catchable"],[427,36,"unknown"],[427,37,"unknown"],[427,38,"unknown"],[427,39,"unknown"],[427,47,"unknown"],[427,50,"catchable"],[428,12,"unknown"],[428,13,"unknown"],[428,14,"unknown"],[428,15,"unknown"],[428,16,"unknown"],[428,17,"unknown"],[428,18,"unknown"],[428,21,"catchable"],[428,22,"unknown"],[428,23,"unknown"],[428,24,"unknown"],[428,25,"unknown"],[428,26,"unknown"],[428,27,"unknown"],[428,28,"unknown"],[428,29,"catchable"],[428,30,"catchable"],[428,31,"unknown"],[428,32,"unknown"],[428,33,"unknown"],[428,34,"unknown"],[428,35,"catchable"],[428,36,"catchable"],[428,37,"unknown"],[428,38,"unknown"],[428,39,"unknown"],[428,47,"unknown"],[428,49,"unknown"],[428,50,"catchable"],[428,51,"catchable"],[429,12,"unknown"],[429,13,"unknown"],[429,14,"unknown"],[429,15,"unknown"],[429,16,"unknown"],[429,17,"unknown"],[429,18,"catchable"],[429,21,"unknown"],[429,22,"unknown"],[429,23,"unknown"],[429,24,"unknown"],[429,25,"unknown"],[429,26,"unknown"],[429,27,"catchable"],[429,28,"catchable"],[429,29,"unknown"],[429,30,"unknown"],[429,31,"unknown"],[429,32,"unknown"],[429,37,"unknown"],[429,38,"unknown"],[429,39,"unknown"],[429,40,"unknown"],[429,41,"unknown"],[429,42,"unknown"],[429,43,"unknown"],[429,47,"unknown"],[429,48,"unknown"],[430,12,"unknown"],[430,13,"unknown"],[430,14,"unknown"],[430,15,"unknown"],[430,16,"unknown"],[430,17,"catchable"],[430,18,"unknown"],[430,21,"unknown"],[430,22,"unknown"],[430,23,"unknown"],[430,24,"unknown"],[430,25,"unknown"],[430,26,"unknown"],[430,27,"unknown"],[430,28,"unknown"],[430,29,"catchable"],[430,30,"catchable"],[430,31,"unknown"],[430,32,"unknown"],[430,37,"unknown"],[430,38,"unknown"],[430,39,"unknown"],[430,40,"unknown"],[430,41,"unknown"],[430,42,"unknown"],[430,43,"unknown"],[430,47,"unknown"],[430,48,"unknown"],[431,12,"unknown"],[431,13,"catchable"],[431,14,"unknown"],[431,15,"unknown"],[431,16,"unknown"],[431,17,"unknown"],[431,18,"unknown"],[431,21,"unknown"],[431,22,"unknown"],[431,23,"unknown"],[431,24,"unknown"],[431,25,"catchable"],[431,26,"catchable"],[431,27,"unknown"],[431,28,"unknown"],[431,29,"unknown"],[431,30,"unknown"],[431,31,"unknown"],[431,32,"unknown"],[431,37,"unknown"],[431,38,"unknown"],[431,39,"unknown"],[432,12,"unknown"],[432,13,"catchable"],[432,14,"unknown"],[432,15,"unknown"],[432,16,"unknown"],[432,17,"unknown"],[432,18,"unknown"],[432,21,"unknown"],[432,22,"unknown"],[432,23,"unknown"],[432,24,"unknown"],[432,25,"catchable"],[432,26,"catchable"],[432,27,"unknown"],[432,28,"unknown"],[432,29,"unknown"],[432,30,"unknown"],[432,31,"unknown"],[432,32,"unknown"],[432,37,"unknown"],[432,38,"unknown"],[432,39,"unknown"],[433,12,"catchable"],[433,13,"catchable"],[433,14,"catchable"],[433,15,"catchable"],[433,16,"catchable"],[433,17,"unknown"],[433,18,"unknown"],[433,21,"unknown"],[433,22,"unknown"],[433,23,"catchable"],[433,24,"catchable"],[433,25,"unknown"],[433,26,"unknown"],[433,27,"unknown"],[433,28,"unknown"],[433,29,"unknown"],[433,30,"unknown"],[433,31,"unknown"],[433,32,"unknown"],[433,37,"unknown"],[433,38,"unknown"],[433,39,"unknown"],[433,40,"unknown"],[433,41,"unknown"],[433,42,"unknown"],[433,43,"unknown"],[433,47,"unknown"],[433,48,"unknown"],[433,52,"unknown"],[434,12,"catchable"],[434,13,"unknown"],[434,14,"unknown"],[434,15,"unknown"],[434,16,"unknown"],[434,17,"unknown"],[434,18,"unknown"],[434,21,"unknown"],[434,22,"unknown"],[434,23,"catchable"],[434,24,"catchable"],[434,25,"unknown"],[434,26,"unknown"],[434,27,"unknown"],[434,28,"unknown"],[434,29,"unknown"],[434,30,"unknown"],[434,31,"unknown"],[434,32,"unknown"],[434,33,"catchable"],[434,34,"catchable"],[434,35,"unknown"],[434,36,"unknown"],[434,37,"unknown"],[434,38,"unknown"],[434,39,"unknown"],[434,40,"unknown"],[434,41,"unknown"],[434,42,"unknown"],[434,43,"unknown"],[434,47,"unknown"],[434,48,"unknown"],[435,12,"catchable"],[435,13,"unknown"],[435,14,"unknown"],[435,15,"unknown"],[435,16,"unknown"],[435,17,"unknown"],[435,18,"unknown"],[435,21,"unknown"],[435,22,"unknown"],[435,23,"unknown"],[435,24,"unknown"],[435,25,"unknown"],[435,26,"unknown"],[435,27,"unknown"],[435,28,"unknown"],[435,29,"unknown"],[435,30,"unknown"],[435,31,"unknown"],[435,32,"unknown"],[435,33,"catchable"],[435,34,"catchable"],[435,35,"unknown"],[435,36,"catchable"],[435,37,"unknown"],[435,38,"unknown"],[435,39,"unknown"],[435,40,"unknown"],[435,41,"unknown"],[435,42,"unknown"],[435,43,"unknown"],[435,47,"unknown"],[435,48,"unknown"],[435,51,"catchable"],[436,12,"catchable"],[436,13,"catchable"],[436,14,"catchable"],[436,15,"catchable"],[436,16,"catchable"],[436,17,"unknown"],[436,18,"unknown"],[436,21,"catchable"],[436,22,"catchable"],[436,23,"unknown"],[436,24,"unknown"],[436,25,"unknown"],[436,26,"unknown"],[436,27,"unknown"],[436,28,"unknown"],[436,29,"unknown"],[436,30,"unknown"],[436,31,"unknown"],[436,32,"unknown"],[436,33,"catchable"],[436,34,"catchable"],[436,35,"catchable"],[436,36,"catchable"],[436,37,"unknown"],[436,38,"unknown"],[436,39,"unknown"],[436,40,"unknown"],[436,41,"unknown"],[436,42,"unknown"],[436,43,"unknown"],[436,47,"unknown"],[436,48,"unknown"],[436,50,"catchable"],[436,51,"catchable"],[436,52,"unknown"],[437,12,"catchable"],[437,13,"catchable"],[437,14,"catchable"],[437,15,"catchable"],[437,16,"catchable"],[437,17,"catchable"],[437,18,"catchable"],[437,21,"catchable"],[437,22,"catchable"],[437,23,"catchable"],[437,24,"catchable"],[437,25,"unknown"],[437,26,"unknown"],[437,27,"unknown"],[437,28,"unknown"],[437,29,"unknown"],[437,30,"unknown"],[437,31,"unknown"],[437,32,"unknown"],[437,33,"catchable"],[437,34,"catchable"],[437,35,"catchable"],[437,36,"catchable"],[437,37,"unknown"],[437,38,"unknown"],[437,39,"unknown"],[437,40,"unknown"],[437,41,"unknown"],[437,42,"unknown"],[437,43,"unknown"],[437,47,"unknown"],[437,48,"unknown"],[437,50,"catchable"],[437,51,"catchable"],[437,52,"unknown"],[438,12,"catchable"],[438,13,"catchable"],[438,14,"catchable"],[438,15,"unknown"],[438,16,"unknown"],[438,17,"unknown"],[438,18,"unknown"],[438,21,"unknown"],[438,22,"unknown"],[438,23,"unknown"],[438,24,"unknown"],[438,25,"unknown"],[438,26,"unknown"],[438,27,"catchable"],[438,28,"catchable"],[438,29,"catchable"],[438,30,"catchable"],[438,31,"unknown"],[438,32,"unknown"],[438,33,"catchable"],[438,34,"catchable"],[438,35,"catchable"],[438,36,"unknown"],[438,37,"unknown"],[438,38,"unknown"],[438,39,"unknown"],[438,40,"unknown"],[438,41,"unknown"],[438,42,"unknown"],[438,43,"unknown"],[438,47,"unknown"],[438,48,"unknown"],[438,50,"catchable"],[438,52,"unknown"],[439,12,"catchable"],[439,13,"catchable"],[439,14,"catchable"],[439,15,"unknown"],[439,16,"unknown"],[439,17,"unknown"],[439,18,"unknown"],[439,21,"unknown"],[439,22,"unknown"],[439,23,"catchable"],[439,24,"catchable"],[439,25,"unknown"],[439,26,"unknown"],[439,27,"unknown"],[439,28,"unknown"],[439,29,"catchable"],[439,30,"catchable"],[439,31,"unknown"],[439,32,"unknown"],[439,33,"catchable"],[439,34,"catchable"],[439,35,"unknown"],[439,36,"catchable"],[439,37,"unknown"],[439,38,"unknown"],[439,39,"unknown"],[439,47,"unknown"],[439,48,"unknown"],[439,51,"catchable"],[440,12,"catchable"],[440,13,"catchable"],[440,14,"catchable"],[440,15,"unknown"],[440,16,"unknown"],[440,17,"unknown"],[440,18,"unknown"],[440,21,"catchable"],[440,22,"catchable"],[440,23,"unknown"],[440,24,"unknown"],[440,25,"catchable"],[440,26,"catchable"],[440,27,"catchable"],[440,28,"catchable"],[440,29,"catchable"],[440,30,"catchable"],[440,31,"unknown"],[440,32,"unknown"],[440,33,"unknown"],[440,34,"unknown"],[440,35,"catchable"],[440,36,"unknown"],[440,37,"unknown"],[440,38,"unknown"],[440,39,"unknown"],[440,40,"unknown"],[440,41,"unknown"],[440,42,"unknown"],[440,43,"unknown"],[440,47,"unknown"],[440,48,"unknown"],[440,50,"catchable"],[440,53,"unknown"],[441,12,"catchable"],[441,13,"catchable"],[441,14,"catchable"],[441,15,"catchable"],[441,16,"catchable"],[441,17,"unknown"],[441,18,"unknown"],[441,21,"catchable"],[441,22,"catchable"],[441,23,"catchable"],[441,24,"catchable"],[441,25,"unknown"],[441,26,"unknown"],[441,27,"unknown"],[441,28,"unknown"],[441,29,"unknown"],[441,30,"unknown"],[441,31,"unknown"],[441,32,"unknown"],[441,37,"unknown"],[441,38,"unknown"],[441,39,"unknown"],[442,12,"catchable"],[442,13,"catchable"],[442,14,"catchable"],[442,15,"unknown"],[442,16,"unknown"],[442,17,"unknown"],[442,18,"unknown"],[442,21,"unknown"],[442,22,"unknown"],[442,23,"catchable"],[442,24,"catchable"],[442,25,"catchable"],[442,26,"catchable"],[442,27,"unknown"],[442,28,"unknown"],[442,29,"unknown"],[442,30,"unknown"],[442,31,"unknown"],[442,32,"unknown"],[442,33,"unknown"],[442,34,"unknown"],[442,35,"unknown"],[442,36,"catchable"],[442,37,"unknown"],[442,38,"unknown"],[442,39,"unknown"],[442,40,"unknown"],[442,41,"unknown"],[442,42,"unknown"],[442,43,"unknown"],[442,47,"unknown"],[442,48,"unknown"],[442,49,"unknown"],[442,51,"catchable"],[443,12,"catchable"],[443,13,"catchable"],[443,14,"catchable"],[443,15,"catchable"],[443,16,"catchable"],[443,17,"unknown"],[443,18,"unknown"],[443,21,"catchable"],[443,22,"unknown"],[443,23,"catchable"],[443,24,"catchable"],[443,25,"unknown"],[443,26,"unknown"],[443,27,"unknown"],[443,28,"unknown"],[443,29,"unknown"],[443,30,"unknown"],[443,31,"unknown"],[443,32,"unknown"],[443,33,"unknown"],[443,34,"unknown"],[443,35,"unknown"],[443,36,"unknown"],[443,37,"unknown"],[443,38,"unknown"],[443,39,"unknown"],[443,40,"unknown"],[443,41,"unknown"],[443,42,"unknown"],[443,43,"unknown"],[443,47,"unknown"],[443,48,"unknown"],[443,51,"catchable"],[443,52,"unknown"],[444,12,"unknown"],[444,13,"unknown"],[444,14,"catchable"],[444,15,"unknown"],[444,16,"unknown"],[444,17,"unknown"],[444,18,"unknown"],[444,21,"unknown"],[444,22,"unknown"],[444,23,"catchable"],[444,24,"catchable"],[444,25,"unknown"],[444,26,"unknown"],[444,27,"catchable"],[444,28,"catchable"],[444,29,"catchable"],[444,30,"catchable"],[444,31,"unknown"],[444,32,"unknown"],[444,33,"unknown"],[444,34,"unknown"],[444,35,"unknown"],[444,36,"unknown"],[444,37,"unknown"],[444,38,"unknown"],[444,39,"unknown"],[444,40,"unknown"],[444,41,"unknown"],[444,42,"unknown"],[444,43,"unknown"],[444,47,"unknown"],[444,48,"unknown"],[444,51,"catchable"],[444,52,"unknown"],[445,12,"unknown"],[445,13,"unknown"],[445,14,"unknown"],[445,15,"unknown"],[445,16,"unknown"],[445,17,"unknown"],[445,18,"unknown"],[445,21,"unknown"],[445,22,"unknown"],[445,23,"unknown"],[445,24,"unknown"],[445,25,"unknown"],[445,26,"unknown"],[445,27,"unknown"],[445,28,"unknown"],[445,29,"unknown"],[445,30,"unknown"],[445,31,"unknown"],[445,32,"unknown"],[445,33,"unknown"],[445,34,"unknown"],[445,35,"unknown"],[445,36,"unknown"],[445,37,"unknown"],[445,38,"unknown"],[445,39,"unknown"],[445,40,"unknown"],[445,41,"unknown"],[445,42,"unknown"],[445,43,"unknown"],[445,47,"unknown"],[445,48,"unknown"],[445,49,"unknown"],[445,51,"catchable"],[445,52,"unknown"],[446,12,"catchable"],[446,13,"catchable"],[446,14,"catchable"],[446,15,"unknown"],[446,16,"unknown"],[446,17,"unknown"],[446,18,"unknown"],[446,21,"unknown"],[446,22,"unknown"],[446,23,"unknown"],[446,24,"unknown"],[446,25,"unknown"],[446,26,"unknown"],[446,27,"catchable"],[446,28,"catchable"],[446,29,"catchable"],[446,30,"catchable"],[446,31,"unknown"],[446,32,"unknown"],[446,33,"catchable"],[446,34,"catchable"],[446,35,"unknown"],[446,36,"catchable"],[446,37,"unknown"],[446,38,"unknown"],[446,39,"unknown"],[446,40,"unknown"],[446,41,"unknown"],[446,42,"unknown"],[446,43,"unknown"],[446,47,"unknown"],[446,48,"unknown"],[446,51,"catchable"],[446,52,"unknown"],[447,12,"catchable"],[447,13,"catchable"],[447,14,"catchable"],[447,15,"catchable"],[447,16,"catchable"],[447,17,"catchable"],[447,18,"catchable"],[447,21,"catchable"],[447,22,"catchable"],[447,23,"catchable"],[447,24,"catchable"],[447,25,"unknown"],[447,26,"unknown"],[447,27,"catchable"],[447,28,"catchable"],[447,29,"catchable"],[447,30,"catchable"],[447,31,"unknown"],[447,32,"unknown"],[447,33,"catchable"],[447,34,"catchable"],[447,35,"unknown"],[447,36,"catchable"],[447,37,"unknown"],[447,38,"unknown"],[447,39,"unknown"],[447,40,"unknown"],[447,41,"unknown"],[447,42,"unknown"],[447,43,"unknown"],[447,47,"unknown"],[447,48,"unknown"],[447,51,"catchable"],[447,52,"unknown"],[448,12,"unknown"],[448,13,"unknown"],[448,14,"unknown"],[448,15,"unknown"],[448,16,"unknown"],[448,17,"unknown"],[448,18,"unknown"],[448,21,"unknown"],[448,22,"unknown"],[448,23,"catchable"],[448,24,"catchable"],[448,25,"unknown"],[448,26,"unknown"],[448,27,"catchable"],[448,28,"catchable"],[448,29,"catchable"],[448,30,"catchable"],[448,31,"unknown"],[448,32,"unknown"],[448,33,"catchable"],[448,34,"catchable"],[448,35,"catchable"],[448,36,"catchable"],[448,37,"unknown"],[448,38,"unknown"],[448,39,"unknown"],[448,40,"unknown"],[448,41,"unknown"],[448,42,"unknown"],[448,43,"unknown"],[448,47,"unknown"],[448,48,"unknown"],[448,49,"unknown"],[448,50,"catchable"],[448,51,"catchable"],[448,52,"unknown"],[449,12,"catchable"],[449,13,"catchable"],[449,14,"catchable"],[449,15,"catchable"],[449,16,"catchable"],[449,17,"unknown"],[449,18,"unknown"],[449,21,"unknown"],[449,22,"unknown"],[449,23,"catchable"],[449,24,"catchable"],[449,25,"unknown"],[449,26,"unknown"],[449,27,"unknown"],[449,28,"unknown"],[449,29,"unknown"],[449,30,"unknown"],[449,31,"unknown"],[449,32,"unknown"],[449,33,"catchable"],[449,34,"catchable"],[449,35,"unknown"],[449,36,"unknown"],[449,37,"unknown"],[449,38,"unknown"],[449,39,"unknown"],[449,40,"unknown"],[449,41,"unknown"],[449,42,"unknown"],[449,43,"unknown"],[449,47,"unknown"],[449,48,"unknown"],[450,12,"catchable"],[450,13,"catchable"],[450,14,"catchable"],[450,15,"unknown"],[450,16,"unknown"],[450,17,"unknown"],[450,18,"unknown"],[450,21,"unknown"],[450,22,"unknown"],[450,23,"unknown"],[450,24,"unknown"],[450,25,"unknown"],[450,26,"unknown"],[450,27,"unknown"],[450,28,"unknown"],[450,29,"catchable"],[450,30,"catchable"],[450,31,"unknown"],[450,32,"unknown"],[450,33,"catchable"],[450,34,"catchable"],[450,35,"unknown"],[450,36,"unknown"],[450,37,"unknown"],[450,38,"unknown"],[450,39,"unknown"],[450,40,"unknown"],[450,41,"unknown"],[450,42,"unknown"],[450,43,"unknown"],[450,47,"unknown"],[450,48,"unknown"],[450,49,"unknown"],[451,12,"catchable"],[451,13,"catchable"],[451,14,"catchable"],[451,15,"catchable"],[451,16,"catchable"],[451,17,"unknown"],[451,18,"unknown"],[451,21,"catchable"],[451,22,"catchable"],[451,23,"catchable"],[451,24,"catchable"],[451,25,"unknown"],[451,26,"unknown"],[451,27,"unknown"],[451,28,"unknown"],[451,29,"unknown"],[451,30,"unknown"],[451,31,"unknown"],[451,32,"unknown"],[451,33,"catchable"],[451,34,"catchable"],[451,35,"catchable"],[451,36,"unknown"],[451,37,"unknown"],[451,38,"unknown"],[451,39,"unknown"],[451,50,"catchable"],[452,12,"catchable"],[452,13,"catchable"],[452,14,"catchable"],[452,15,"unknown"],[452,16,"unknown"],[452,17,"unknown"],[452,18,"unknown"],[452,21,"unknown"],[452,22,"unknown"],[452,23,"catchable"],[452,24,"catchable"],[452,25,"unknown"],[452,26,"unknown"],[452,27,"unknown"],[452,28,"unknown"],[452,29,"catchable"],[452,30,"catchable"],[452,31,"unknown"],[452,32,"unknown"],[452,33,"catchable"],[452,34,"catchable"],[452,35,"catchable"],[452,36,"catchable"],[452,37,"unknown"],[452,38,"unknown"],[452,39,"unknown"],[452,50,"catchable"],[452,51,"catchable"],[453,12,"catchable"],[453,13,"catchable"],[453,14,"catchable"],[453,15,"catchable"],[453,16,"catchable"],[453,17,"unknown"],[453,18,"unknown"],[453,21,"catchable"],[453,22,"catchable"],[453,23,"catchable"],[453,24,"catchable"],[453,25,"unknown"],[453,26,"unknown"],[453,27,"unknown"],[453,28,"unknown"],[453,29,"unknown"],[453,30,"unknown"],[453,31,"unknown"],[453,32,"unknown"],[453,33,"unknown"],[453,34,"catchable"],[453,35,"unknown"],[453,36,"unknown"],[453,37,"unknown"],[453,38,"unknown"],[453,39,"unknown"],[453,40,"unknown"],[453,41,"unknown"],[453,42,"unknown"],[453,43,"unknown"],[453,47,"unknown"],[453,48,"unknown"],[453,50,"catchable"],[454,12,"catchable"],[454,13,"catchable"],[454,14,"catchable"],[454,15,"unknown"],[454,16,"unknown"],[454,17,"unknown"],[454,18,"unknown"],[454,21,"catchable"],[454,22,"catchable"],[454,23,"catchable"],[454,24,"catchable"],[454,25,"unknown"],[454,26,"unknown"],[454,27,"unknown"],[454,28,"unknown"],[454,29,"unknown"],[454,30,"unknown"],[454,31,"unknown"],[454,32,"unknown"],[454,33,"unknown"],[454,34,"catchable"],[454,35,"unknown"],[454,36,"unknown"],[454,37,"unknown"],[454,38,"unknown"],[454,39,"unknown"],[454,40,"unknown"],[454,41,"unknown"],[454,42,"unknown"],[454,43,"unknown"],[454,47,"unknown"],[454,48,"unknown"],[454,49,"unknown"],[454,50,"catchable"],[455,12,"catchable"],[455,13,"catchable"],[455,14,"catchable"],[455,15,"catchable"],[455,16,"catchable"],[455,17,"unknown"],[455,18,"unknown"],[455,21,"catchable"],[455,22,"catchable"],[455,23,"catchable"],[455,24,"catchable"],[455,25,"unknown"],[455,26,"unknown"],[455,27,"unknown"],[455,28,"unknown"],[455,29,"unknown"],[455,30,"unknown"],[455,31,"unknown"],[455,32,"unknown"],[455,37,"unknown"],[455,38,"unknown"],[455,39,"unknown"],[456,12,"catchable"],[456,13,"catchable"],[456,14,"catchable"],[456,15,"unknown"],[456,16,"unknown"],[456,17,"catchable"],[456,18,"catchable"],[456,21,"catchable"],[456,22,"catchable"],[456,23,"unknown"],[456,24,"unknown"],[456,25,"unknown"],[456,26,"unknown"],[456,27,"catchable"],[456,28,"catchable"],[456,29,"catchable"],[456,30,"catchable"],[456,31,"unknown"],[456,32,"unknown"],[456,37,"unknown"],[456,38,"unknown"],[456,39,"unknown"],[456,40,"unknown"],[456,41,"unknown"],[456,42,"unknown"],[456,43,"unknown"],[456,47,"unknown"],[456,48,"unknown"],[456,53,"unknown"],[457,12,"catchable"],[457,13,"catchable"],[457,14,"catchable"],[457,15,"unknown"],[457,16,"unknown"],[457,17,"catchable"],[457,18,"catchable"],[457,21,"catchable"],[457,22,"catchable"],[457,23,"unknown"],[457,24,"unknown"],[457,25,"unknown"],[457,26,"unknown"],[457,27,"catchable"],[457,28,"catchable"],[457,29,"catchable"],[457,30,"catchable"],[457,31,"unknown"],[457,32,"unknown"],[457,37,"unknown"],[457,38,"unknown"],[457,39,"unknown"],[457,40,"unknown"],[457,41,"unknown"],[457,42,"unknown"],[457,43,"unknown"],[457,47,"unknown"],[457,48,"unknown"],[457,53,"unknown"],[458,12,"catchable"],[458,13,"catchable"],[458,14,"catchable"],[458,15,"unknown"],[458,16,"unknown"],[458,17,"catchable"],[458,18,"catchable"],[458,21,"catchable"],[458,22,"catchable"],[458,23,"catchable"],[458,24,"catchable"],[458,25,"unknown"],[458,26,"unknown"],[458,27,"unknown"],[458,28,"unknown"],[458,29,"catchable"],[458,30,"catchable"],[458,31,"unknown"],[458,32,"unknown"],[458,33,"catchable"],[458,34,"catchable"],[458,35,"catchable"],[458,36,"unknown"],[458,37,"unknown"],[458,38,"unknown"],[458,39,"unknown"],[458,50,"catchable"],[459,12,"catchable"],[459,13,"catchable"],[459,14,"catchable"],[459,15,"unknown"],[459,16,"unknown"],[459,17,"unknown"],[459,18,"unknown"],[459,21,"unknown"],[459,22,"unknown"],[459,23,"catchable"],[459,24,"catchable"],[459,25,"unknown"],[459,26,"unknown"],[459,27,"unknown"],[459,28,"unknown"],[459,29,"unknown"],[459,30,"unknown"],[459,31,"unknown"],[459,32,"unknown"],[459,33,"catchable"],[459,34,"catchable"],[459,35,"unknown"],[459,36,"catchable"],[459,37,"unknown"],[459,38,"unknown"],[459,39,"unknown"],[459,40,"unknown"],[459,41,"unknown"],[459,42,"unknown"],[459,43,"unknown"],[459,47,"unknown"],[459,48,"unknown"],[459,51,"catchable"],[459,53,"unknown"],[460,12,"catchable"],[460,13,"catchable"],[460,14,"catchable"],[460,15,"unknown"],[460,16,"unknown"],[460,17,"unknown"],[460,18,"unknown"],[460,21,"unknown"],[460,22,"unknown"],[460,23,"catchable"],[460,24,"catchable"],[460,25,"unknown"],[460,26,"unknown"],[460,27,"unknown"],[460,28,"unknown"],[460,29,"catchable"],[460,30,"catchable"],[460,31,"unknown"],[460,32,"unknown"],[460,33,"catchable"],[460,34,"catchable"],[460,35,"catchable"],[460,36,"catchable"],[460,37,"unknown"],[460,38,"unknown"],[460,39,"unknown"],[460,40,"unknown"],[460,41,"unknown"],[460,42,"unknown"],[460,43,"unknown"],[460,47,"unknown"],[460,48,"unknown"],[460,49,"unknown"],[460,50,"catchable"],[460,51,"catchable"],[460,53,"unknown"],[461,12,"unknown"],[461,13,"unknown"],[461,14,"unknown"],[461,15,"unknown"],[461,16,"unknown"],[461,17,"unknown"],[461,18,"unknown"],[461,21,"unknown"],[461,22,"unknown"],[461,23,"unknown"],[461,24,"unknown"],[461,25,"unknown"],[461,26,"unknown"],[461,27,"unknown"],[461,28,"unknown"],[461,29,"unknown"],[461,30,"unknown"],[461,31,"unknown"],[461,32,"unknown"],[461,33,"catchable"],[461,34,"catchable"],[461,35,"unknown"],[461,36,"catchable"],[461,37,"unknown"],[461,38,"unknown"],[461,39,"unknown"],[461,40,"unknown"],[461,41,"unknown"],[461,42,"unknown"],[461,43,"unknown"],[461,47,"unknown"],[461,48,"unknown"],[461,49,"unknown"],[461,51,"catchable"],[461,52,"unknown"],[462,12,"unknown"],[462,13,"unknown"],[462,14,"unknown"],[462,15,"unknown"],[462,16,"unknown"],[462,17,"unknown"],[462,18,"unknown"],[462,21,"catchable"],[462,22,"catchable"],[462,23,"unknown"],[462,24,"unknown"],[462,25,"unknown"],[462,26,"unknown"],[462,27,"unknown"],[462,28,"unknown"],[462,29,"unknown"],[462,30,"unknown"],[462,31,"unknown"],[462,32,"unknown"],[462,33,"unknown"],[462,34,"unknown"],[462,35,"catchable"],[462,36,"unknown"],[462,37,"unknown"],[462,38,"unknown"],[462,39,"unknown"],[462,40,"unknown"],[462,41,"unknown"],[462,42,"unknown"],[462,43,"unknown"],[462,47,"unknown"],[462,48,"unknown"],[462,50,"catchable"],[462,53,"unknown"],[463,12,"unknown"],[463,13,"unknown"],[463,14,"unknown"],[463,15,"unknown"],[463,16,"unknown"],[463,17,"unknown"],[463,18,"unknown"],[463,21,"catchable"],[463,22,"catchable"],[463,23,"unknown"],[463,24,"unknown"],[463,25,"unknown"],[463,26,"unknown"],[463,27,"unknown"],[463,28,"unknown"],[463,29,"unknown"],[463,30,"unknown"],[463,31,"unknown"],[463,32,"unknown"],[463,33,"unknown"],[463,34,"unknown"],[463,35,"catchable"],[463,36,"unknown"],[463,37,"unknown"],[463,38,"unknown"],[463,39,"unknown"],[463,50,"catchable"],[464,12,"unknown"],[464,13,"unknown"],[464,14,"unknown"],[464,15,"unknown"],[464,16,"unknown"],[464,17,"unknown"],[464,18,"unknown"],[464,21,"unknown"],[464,22,"unknown"],[464,23,"unknown"],[464,24,"unknown"],[464,25,"unknown"],[464,26,"unknown"],[464,27,"unknown"],[464,28,"unknown"],[464,29,"unknown"],[464,30,"unknown"],[464,31,"unknown"],[464,32,"unknown"],[464,33,"catchable"],[464,34,"catchable"],[464,35,"catchable"],[464,36,"unknown"],[464,37,"unknown"],[464,38,"unknown"],[464,39,"unknown"],[464,40,"unknown"],[464,41,"unknown"],[464,42,"unknown"],[464,43,"unknown"],[464,47,"unknown"],[464,48,"unknown"],[464,49,"unknown"],[464,50,"catchable"],[464,53,"unknown"],[465,12,"unknown"],[465,13,"unknown"],[465,14,"unknown"],[465,15,"unknown"],[465,16,"unknown"],[465,17,"catchable"],[465,18,"catchable"],[465,21,"catchable"],[465,22,"catchable"],[465,23,"unknown"],[465,24,"unknown"],[465,25,"unknown"],[465,26,"unknown"],[465,27,"unknown"],[465,28,"unknown"],[465,29,"unknown"],[465,30,"unknown"],[465,31,"unknown"],[465,32,"unknown"],[465,33,"unknown"],[465,34,"unknown"],[465,35,"catchable"],[465,36,"unknown"],[465,37,"unknown"],[465,38,"unknown"],[465,39,"unknown"],[465,50,"catchable"],[466,12,"unknown"],[466,13,"unknown"],[466,14,"unknown"],[466,15,"unknown"],[466,16,"unknown"],[466,17,"unknown"],[466,18,"unknown"],[466,21,"unknown"],[466,22,"unknown"],[466,23,"unknown"],[466,24,"unknown"],[466,25,"unknown"],[466,26,"unknown"],[466,27,"unknown"],[466,28,"unknown"],[466,29,"unknown"],[466,30,"unknown"],[466,31,"unknown"],[466,32,"unknown"],[466,33,"unknown"],[466,34,"unknown"],[466,35,"unknown"],[466,36,"catchable"],[466,37,"unknown"],[466,38,"unknown"],[466,39,"unknown"],[466,40,"unknown"],[466,41,"unknown"],[466,42,"unknown"],[466,43,"unknown"],[466,47,"unknown"],[466,48,"unknown"],[466,51,"catchable"],[466,53,"unknown"],[467,12,"unknown"],[467,13,"unknown"],[467,14,"unknown"],[467,15,"unknown"],[467,16,"unknown"],[467,17,"unknown"],[467,18,"unknown"],[467,21,"unknown"],[467,22,"unknown"],[467,23,"unknown"],[467,24,"unknown"],[467,25,"unknown"],[467,26,"unknown"],[467,27,"unknown"],[467,28,"unknown"],[467,29,"unknown"],[467,30,"unknown"],[467,31,"unknown"],[467,32,"unknown"],[467,33,"unknown"],[467,34,"unknown"],[467,35,"unknown"],[467,36,"catchable"],[467,37,"unknown"],[467,38,"unknown"],[467,39,"unknown"],[467,40,"unknown"],[467,41,"unknown"],[467,42,"unknown"],[467,43,"unknown"],[467,47,"unknown"],[467,48,"unknown"],[467,51,"catchable"],[467,53,"unknown"],[468,12,"unknown"],[468,13,"unknown"],[468,14,"unknown"],[468,15,"unknown"],[468,16,"unknown"],[468,17,"unknown"],[468,18,"unknown"],[468,21,"unknown"],[468,22,"unknown"],[468,23,"unknown"],[468,24,"unknown"],[468,25,"unknown"],[468,26,"unknown"],[468,27,"catchable"],[468,28,"catchable"],[468,29,"unknown"],[468,30,"unknown"],[468,31,"unknown"],[468,32,"unknown"],[468,33,"catchable"],[468,34,"catchable"],[468,35,"unknown"],[468,36,"unknown"],[468,37,"unknown"],[468,38,"unknown"],[468,39,"unknown"],[469,12,"unknown"],[469,13,"unknown"],[469,14,"unknown"],[469,15,"unknown"],[469,16,"unknown"],[469,17,"unknown"],[469,18,"unknown"],[469,21,"catchable"],[469,22,"catchable"],[469,23,"unknown"],[469,24,"unknown"],[469,25,"unknown"],[469,26,"unknown"],[469,27,"unknown"],[469,28,"unknown"],[469,29,"catchable"],[469,30,"catchable"],[469,31,"unknown"],[469,32,"unknown"],[469,39,"unknown"],[469,40,"unknown"],[469,41,"unknown"],[469,42,"unknown"],[469,43,"unknown"],[469,47,"unknown"],[469,48,"unknown"],[469,52,"unknown"],[470,12,"unknown"],[470,13,"unknown"],[470,14,"unknown"],[470,15,"unknown"],[470,16,"unknown"],[470,17,"unknown"],[470,18,"unknown"],[470,21,"unknown"],[470,22,"unknown"],[470,23,"unknown"],[470,24,"unknown"],[470,25,"unknown"],[470,26,"unknown"],[470,27,"unknown"],[470,28,"unknown"],[470,29,"unknown"],[470,30,"unknown"],[470,31,"unknown"],[470,32,"unknown"],[470,33,"catchable"],[470,34,"catchable"],[470,35,"unknown"],[470,36,"catchable"],[470,37,"unknown"],[470,38,"unknown"],[470,39,"unknown"],[470,40,"unknown"],[470,41,"unknown"],[470,42,"unknown"],[470,43,"unknown"],[470,47,"unknown"],[470,48,"unknown"],[470,49,"unknown"],[470,51,"catchable"],[471,12,"unknown"],[471,13,"unknown"],[471,14,"unknown"],[471,15,"unknown"],[471,16,"unknown"],[471,17,"unknown"],[471,18,"unknown"],[471,21,"unknown"],[471,22,"unknown"],[471,23,"unknown"],[471,24,"unknown"],[471,25,"unknown"],[471,26,"unknown"],[471,27,"unknown"],[471,28,"unknown"],[471,29,"unknown"],[471,30,"unknown"],[471,31,"unknown"],[471,32,"unknown"],[471,33,"catchable"],[471,34,"catchable"],[471,35,"unknown"],[471,36,"catchable"],[471,37,"unknown"],[471,38,"unknown"],[471,39,"unknown"],[471,40,"unknown"],[471,41,"unknown"],[471,42,"unknown"],[471,43,"unknown"],[471,47,"unknown"],[471,48,"unknown"],[471,49,"unknown"],[471,51,"catchable"],[472,12,"unknown"],[472,13,"unknown"],[472,14,"unknown"],[472,15,"unknown"],[472,16,"unknown"],[472,17,"catchable"],[472,18,"catchable"],[472,21,"catchable"],[472,22,"catchable"],[472,23,"unknown"],[472,24,"unknown"],[472,25,"unknown"],[472,26,"unknown"],[472,27,"unknown"],[472,28,"unknown"],[472,29,"unknown"],[472,30,"unknown"],[472,31,"unknown"],[472,32,"unknown"],[472,39,"unknown"],[472,40,"unknown"],[472,41,"unknown"],[472,42,"unknown"],[472,43,"unknown"],[472,47,"unknown"],[472,48,"unknown"],[472,49,"unknown"],[472,52,"unknown"],[473,12,"unknown"],[473,13,"unknown"],[473,14,"unknown"],[473,15,"unknown"],[473,16,"unknown"],[473,17,"catchable"],[473,18,"catchable"],[473,21,"catchable"],[473,22,"catchable"],[473,23,"unknown"],[473,24,"unknown"],[473,25,"unknown"],[473,26,"unknown"],[473,27,"unknown"],[473,28,"unknown"],[473,29,"unknown"],[473,30,"unknown"],[473,31,"unknown"],[473,32,"unknown"],[473,33,"catchable"],[473,34,"catchable"],[473,35,"unknown"],[473,36,"catchable"],[473,37,"unknown"],[473,38,"unknown"],[473,39,"unknown"],[473,40,"unknown"],[473,41,"unknown"],[473,42,"unknown"],[473,43,"unknown"],[473,47,"unknown"],[473,48,"unknown"],[473,49,"unknown"],[473,51,"catchable"],[473,52,"unknown"],[474,12,"unknown"],[474,13,"unknown"],[474,14,"unknown"],[474,15,"unknown"],[474,16,"unknown"],[474,17,"unknown"],[474,18,"unknown"],[474,21,"unknown"],[474,22,"unknown"],[474,23,"unknown"],[474,24,"unknown"],[474,25,"unknown"],[474,26,"unknown"],[474,27,"unknown"],[474,28,"unknown"],[474,29,"unknown"],[474,30,"unknown"],[474,31,"unknown"],[474,32,"unknown"],[474,33,"unknown"],[474,34,"unknown"],[474,35,"unknown"],[474,36,"unknown"],[474,37,"unknown"],[474,38,"unknown"],[474,39,"unknown"],[474,40,"unknown"],[474,41,"unknown"],[474,42,"unknown"],[474,43,"unknown"],[474,47,"unknown"],[474,48,"unknown"],[474,50,"unknown"],[474,53,"unknown"],[475,12,"unknown"],[475,13,"unknown"],[475,14,"unknown"],[475,15,"unknown"],[475,16,"unknown"],[475,17,"unknown"],[475,18,"unknown"],[475,21,"unknown"],[475,22,"unknown"],[475,23,"unknown"],[475,24,"unknown"],[475,25,"unknown"],[475,26,"unknown"],[475,27,"unknown"],[475,28,"unknown"],[475,29,"unknown"],[475,30,"unknown"],[475,31,"unknown"],[475,32,"unknown"],[475,33,"catchable"],[475,34,"catchable"],[475,35,"catchable"],[475,36,"unknown"],[475,37,"unknown"],[475,38,"unknown"],[475,39,"unknown"],[475,40,"unknown"],[475,41,"unknown"],[475,42,"unknown"],[475,43,"unknown"],[475,47,"unknown"],[475,48,"unknown"],[475,49,"unknown"],[475,50,"catchable"],[475,52,"unknown"],[476,12,"unknown"],[476,13,"unknown"],[476,14,"unknown"],[476,15,"unknown"],[476,16,"unknown"],[476,17,"unknown"],[476,18,"unknown"],[476,21,"unknown"],[476,22,"unknown"],[476,23,"unknown"],[476,24,"unknown"],[476,25,"unknown"],[476,26,"unknown"],[476,27,"unknown"],[476,28,"unknown"],[476,29,"unknown"],[476,30,"unknown"],[476,31,"unknown"],[476,32,"unknown"],[476,39,"unknown"],[476,40,"unknown"],[476,41,"unknown"],[476,42,"unknown"],[476,43,"unknown"],[476,47,"unknown"],[476,48,"unknown"],[476,52,"unknown"],[477,12,"unknown"],[477,13,"unknown"],[477,14,"unknown"],[477,15,"unknown"],[477,16,"unknown"],[477,17,"unknown"],[477,18,"unknown"],[477,21,"unknown"],[477,22,"unknown"],[477,23,"unknown"],[477,24,"unknown"],[477,25,"unknown"],[477,26,"unknown"],[477,27,"unknown"],[477,28,"unknown"],[477,29,"unknown"],[477,30,"unknown"],[477,31,"unknown"],[477,32,"unknown"],[477,33,"catchable"],[477,34,"catchable"],[477,35,"unknown"],[477,36,"unknown"],[477,37,"unknown"],[477,38,"unknown"],[477,39,"unknown"],[477,40,"unknown"],[477,41,"unknown"],[477,42,"unknown"],[477,43,"unknown"],[477,47,"unknown"],[477,48,"unknown"],[477,52,"unknown"],[478,12,"unknown"],[478,13,"unknown"],[478,14,"unknown"],[478,15,"unknown"],[478,16,"unknown"],[478,17,"unknown"],[478,18,"unknown"],[478,21,"unknown"],[478,22,"unknown"],[478,23,"unknown"],[478,24,"unknown"],[478,25,"unknown"],[478,26,"unknown"],[478,27,"unknown"],[478,28,"unknown"],[478,29,"unknown"],[478,30,"unknown"],[478,31,"unknown"],[478,32,"unknown"],[478,33,"catchable"],[478,34,"catchable"],[478,35,"unknown"],[478,36,"catchable"],[478,37,"unknown"],[478,38,"unknown"],[478,39,"unknown"],[478,40,"unknown"],[478,41,"unknown"],[478,42,"unknown"],[478,43,"unknown"],[478,47,"unknown"],[478,48,"unknown"],[478,49,"unknown"],[478,51,"catchable"],[478,52,"unknown"],[479,12,"catchable"],[479,13,"catchable"],[479,14,"catchable"],[479,15,"unknown"],[479,16,"unknown"],[479,17,"unknown"],[479,18,"unknown"],[479,21,"catchable"],[479,22,"catchable"],[479,23,"catchable"],[479,24,"catchable"],[479,25,"unknown"],[479,26,"unknown"],[479,27,"unknown"],[479,28,"unknown"],[479,29,"catchable"],[479,30,"catchable"],[479,31,"unknown"],[479,32,"unknown"],[479,33,"catchable"],[479,34,"catchable"],[479,35,"catchable"],[479,36,"catchable"],[479,37,"unknown"],[479,38,"unknown"],[479,39,"unknown"],[479,40,"unknown"],[479,41,"unknown"],[479,42,"unknown"],[479,43,"unknown"],[479,47,"unknown"],[479,48,"unknown"],[479,49,"unknown"],[479,50,"catchable"],[479,51,"catchable"],[479,53,"unknown"],[480,12,"catchable"],[480,13,"catchable"],[480,14,"catchable"],[480,15,"unknown"],[480,16,"unknown"],[480,17,"unknown"],[480,18,"unknown"],[480,21,"catchable"],[480,22,"catchable"],[480,23,"unknown"],[480,24,"unknown"],[480,25,"catchable"],[480,26,"catchable"],[480,27,"unknown"],[480,28,"unknown"],[480,29,"catchable"],[480,30,"catchable"],[480,31,"unknown"],[480,32,"unknown"],[480,33,"unknown"],[480,34,"unknown"],[480,35,"unknown"],[480,36,"catchable"],[480,37,"unknown"],[480,38,"unknown"],[480,39,"unknown"],[480,40,"unknown"],[480,41,"unknown"],[480,42,"unknown"],[480,43,"unknown"],[480,47,"unknown"],[480,48,"unknown"],[480,51,"catchable"],[481,12,"catchable"],[481,13,"catchable"],[481,14,"catchable"],[481,15,"unknown"],[481,16,"unknown"],[481,17,"unknown"],[481,18,"unknown"],[481,21,"catchable"],[481,22,"catchable"],[481,23,"unknown"],[481,24,"unknown"],[481,25,"catchable"],[481,26,"catchable"],[481,27,"unknown"],[481,28,"unknown"],[481,29,"catchable"],[481,30,"catchable"],[481,31,"unknown"],[481,32,"unknown"],[481,33,"unknown"],[481,34,"unknown"],[481,35,"unknown"],[481,36,"catchable"],[481,37,"unknown"],[481,38,"unknown"],[481,39,"unknown"],[481,40,"unknown"],[481,41,"unknown"],[481,42,"unknown"],[481,43,"unknown"],[481,47,"unknown"],[481,48,"unknown"],[481,51,"catchable"],[482,12,"catchable"],[482,13,"catchable"],[482,14,"catchable"],[482,15,"unknown"],[482,16,"unknown"],[482,17,"unknown"],[482,18,"unknown"],[482,21,"catchable"],[482,22,"catchable"],[482,23,"unknown"],[482,24,"unknown"],[482,25,"catchable"],[482,26,"catchable"],[482,27,"unknown"],[482,28,"unknown"],[482,29,"catchable"],[482,30,"catchable"],[482,31,"unknown"],[482,32,"unknown"],[482,33,"unknown"],[482,34,"unknown"],[482,35,"unknown"],[482,36,"catchable"],[482,37,"unknown"],[482,38,"unknown"],[482,39,"unknown"],[482,40,"unknown"],[482,41,"unknown"],[482,42,"unknown"],[482,43,"unknown"],[482,47,"unknown"],[482,48,"unknown"],[482,51,"catchable"],[483,12,"catchable"],[483,13,"unknown"],[483,14,"catchable"],[483,15,"catchable"],[483,16,"catchable"],[483,17,"unknown"],[483,18,"unknown"],[483,21,"unknown"],[483,22,"unknown"],[483,23,"unknown"],[483,24,"unknown"],[483,25,"unknown"],[483,26,"catchable"],[483,27,"unknown"],[483,28,"unknown"],[483,29,"catchable"],[483,30,"unknown"],[483,31,"unknown"],[483,32,"unknown"],[483,33,"unknown"],[483,34,"unknown"],[483,35,"unknown"],[483,36,"catchable"],[483,37,"unknown"],[483,38,"unknown"],[483,39,"unknown"],[483,40,"unknown"],[483,41,"unknown"],[483,42,"unknown"],[483,43,"unknown"],[483,47,"unknown"],[483,48,"unknown"],[484,12,"unknown"],[484,13,"catchable"],[484,14,"catchable"],[484,15,"catchable"],[484,16,"catchable"],[484,17,"unknown"],[484,18,"unknown"],[484,21,"unknown"],[484,22,"unknown"],[484,23,"unknown"],[484,24,"unknown"],[484,25,"catchable"],[484,26,"unknown"],[484,27,"unknown"],[484,28,"unknown"],[484,29,"unknown"],[484,30,"catchable"],[484,31,"unknown"],[484,32,"unknown"],[484,33,"unknown"],[484,34,"unknown"],[484,35,"unknown"],[484,36,"unknown"],[484,37,"unknown"],[484,38,"unknown"],[484,39,"unknown"],[484,40,"unknown"],[484,41,"unknown"],[484,42,"unknown"],[484,43,"unknown"],[484,47,"unknown"],[484,48,"unknown"],[484,51,"catchable"],[485,12,"catchable"],[485,13,"catchable"],[485,14,"catchable"],[485,15,"unknown"],[485,16,"unknown"],[485,17,"unknown"],[485,18,"unknown"],[485,21,"catchable"],[485,22,"catchable"],[485,23,"unknown"],[485,24,"unknown"],[485,25,"catchable"],[485,26,"catchable"],[485,27,"unknown"],[485,28,"unknown"],[485,29,"catchable"],[485,30,"unknown"],[485,31,"unknown"],[485,32,"unknown"],[485,33,"unknown"],[485,34,"unknown"],[485,35,"unknown"],[485,36,"catchable"],[485,37,"unknown"],[485,38,"unknown"],[485,39,"unknown"],[485,40,"unknown"],[485,41,"unknown"],[485,42,"unknown"],[485,43,"unknown"],[485,47,"unknown"],[485,48,"unknown"],[485,51,"catchable"],[486,12,"catchable"],[486,13,"catchable"],[486,14,"catchable"],[486,15,"unknown"],[486,16,"unknown"],[486,17,"unknown"],[486,18,"unknown"],[486,21,"catchable"],[486,22,"catchable"],[486,23,"unknown"],[486,24,"unknown"],[486,25,"catchable"],[486,26,"catchable"],[486,27,"unknown"],[486,28,"unknown"],[486,29,"unknown"],[486,30,"catchable"],[486,31,"unknown"],[486,32,"unknown"],[486,33,"unknown"],[486,34,"unknown"],[486,35,"unknown"],[486,36,"catchable"],[486,37,"unknown"],[486,38,"unknown"],[486,39,"unknown"],[486,40,"unknown"],[486,41,"unknown"],[486,42,"unknown"],[486,43,"unknown"],[486,47,"unknown"],[486,48,"unknown"],[486,51,"catchable"],[487,12,"unknown"],[487,13,"unknown"],[487,14,"catchable"],[487,15,"catchable"],[487,16,"catchable"],[487,17,"unknown"],[487,18,"unknown"],[487,21,"unknown"],[487,22,"unknown"],[487,23,"unknown"],[487,24,"unknown"],[487,25,"catchable"],[487,26,"catchable"],[487,27,"unknown"],[487,28,"unknown"],[487,29,"catchable"],[487,30,"catchable"],[487,31,"unknown"],[487,32,"unknown"],[487,33,"unknown"],[487,34,"unknown"],[487,35,"unknown"],[487,36,"catchable"],[487,37,"unknown"],[487,38,"unknown"],[487,39,"unknown"],[487,40,"unknown"],[487,41,"unknown"],[487,42,"unknown"],[487,43,"unknown"],[487,47,"unknown"],[487,48,"unknown"],[487,51,"catchable"],[488,12,"catchable"],[488,13,"catchable"],[488,14,"catchable"],[488,15,"unknown"],[488,16,"unknown"],[488,17,"unknown"],[488,18,"unknown"],[488,21,"catchable"],[488,22,"catchable"],[488,23,"unknown"],[488,24,"unknown"],[488,25,"catchable"],[488,26,"catchable"],[488,27,"unknown"],[488,28,"unknown"],[488,29,"catchable"],[488,30,"catchable"],[488,31,"unknown"],[488,32,"unknown"],[488,33,"unknown"],[488,34,"unknown"],[488,35,"unknown"],[488,36,"catchable"],[488,37,"unknown"],[488,38,"unknown"],[488,39,"unknown"],[488,40,"unknown"],[488,41,"unknown"],[488,42,"unknown"],[488,43,"unknown"],[488,47,"unknown"],[488,48,"unknown"],[488,51,"catchable"],[489,12,"unknown"],[489,13,"unknown"],[489,14,"unknown"],[489,15,"unknown"],[489,16,"unknown"],[489,17,"unknown"],[489,18,"unknown"],[489,21,"unknown"],[489,22,"unknown"],[489,23,"unknown"],[489,24,"unknown"],[489,25,"unknown"],[489,26,"unknown"],[489,27,"unknown"],[489,28,"unknown"],[489,29,"unknown"],[489,30,"unknown"],[489,31,"unknown"],[489,32,"unknown"],[489,39,"unknown"],[489,40,"unknown"],[489,41,"unknown"],[489,42,"unknown"],[489,43,"unknown"],[489,47,"unknown"],[489,48,"unknown"],[490,12,"catchable"],[490,13,"catchable"],[490,14,"catchable"],[490,15,"catchable"],[490,16,"catchable"],[490,17,"unknown"],[490,18,"unknown"],[490,21,"unknown"],[490,22,"unknown"],[490,23,"unknown"],[490,24,"unknown"],[490,25,"unknown"],[490,26,"unknown"],[490,27,"unknown"],[490,28,"unknown"],[490,29,"unknown"],[490,30,"unknown"],[490,31,"unknown"],[490,32,"unknown"],[490,37,"unknown"],[490,38,"unknown"],[490,39,"unknown"],[490,40,"unknown"],[490,41,"unknown"],[490,42,"unknown"],[490,43,"unknown"],[490,47,"unknown"],[490,48,"unknown"],[491,12,"catchable"],[491,13,"catchable"],[491,14,"catchable"],[491,15,"unknown"],[491,16,"unknown"],[491,17,"unknown"],[491,18,"unknown"],[491,21,"unknown"],[491,22,"unknown"],[491,23,"unknown"],[491,24,"unknown"],[491,25,"unknown"],[491,26,"unknown"],[491,27,"unknown"],[491,28,"unknown"],[491,29,"unknown"],[491,30,"unknown"],[491,31,"unknown"],[491,32,"unknown"],[491,39,"unknown"],[491,40,"unknown"],[491,41,"unknown"],[491,42,"unknown"],[491,43,"unknown"],[491,47,"unknown"],[491,48,"unknown"],[492,12,"catchable"],[492,13,"catchable"],[492,14,"catchable"],[492,15,"unknown"],[492,16,"unknown"],[492,17,"unknown"],[492,18,"unknown"],[492,21,"unknown"],[492,22,"unknown"],[492,23,"unknown"],[492,24,"unknown"],[492,25,"unknown"],[492,26,"unknown"],[492,27,"unknown"],[492,28,"unknown"],[492,29,"unknown"],[492,30,"unknown"],[492,31,"unknown"],[492,32,"unknown"],[492,39,"unknown"],[492,40,"unknown"],[492,41,"unknown"],[492,42,"unknown"],[492,43,"unknown"],[492,47,"unknown"],[492,48,"unknown"],[493,12,"catchable"],[493,13,"catchable"],[493,14,"catchable"],[493,15,"unknown"],[493,16,"unknown"],[493,17,"unknown"],[493,18,"unknown"],[493,21,"unknown"],[493,22,"unknown"],[493,23,"unknown"],[493,24,"unknown"],[493,25,"unknown"],[493,26,"unknown"],[493,27,"unknown"],[493,28,"unknown"],[493,29,"unknown"],[493,30,"unknown"],[493,31,"unknown"],[493,32,"unknown"],[493,39,"unknown"],[493,40,"unknown"],[493,41,"unknown"],[493,42,"unknown"],[493,43,"unknown"],[493,47,"unknown"],[493,48,"unknown"],[494,17,"catchable"],[494,18,"catchable"],[494,21,"unknown"],[494,22,"unknown"],[494,23,"unknown"],[494,24,"unknown"],[494,25,"unknown"],[494,26,"unknown"],[494,27,"unknown"],[494,28,"unknown"],[494,29,"unknown"],[494,30,"unknown"],[494,31,"unknown"],[494,32,"unknown"],[494,33,"unknown"],[494,34,"unknown"],[494,35,"unknown"],[494,36,"unknown"],[494,37,"unknown"],[494,38,"unknown"],[494,39,"unknown"],[495,17,"catchable"],[495,18,"catchable"],[495,21,"catchable"],[495,22,"catchable"],[495,23,"unknown"],[495,24,"unknown"],[495,25,"catchable"],[495,26,"catchable"],[495,27,"unknown"],[495,28,"unknown"],[495,29,"unknown"],[495,30,"unknown"],[495,31,"unknown"],[495,32,"unknown"],[495,40,"unknown"],[495,41,"unknown"],[495,42,"unknown"],[495,43,"unknown"],[495,47,"unknown"],[495,48,"unknown"],[495,53,"unknown"],[496,17,"unknown"],[496,18,"unknown"],[496,21,"unknown"],[496,22,"unknown"],[496,23,"unknown"],[496,24,"unknown"],[496,25,"unknown"],[496,26,"unknown"],[496,27,"unknown"],[496,28,"unknown"],[496,29,"unknown"],[496,30,"unknown"],[496,31,"unknown"],[496,32,"unknown"],[496,40,"unknown"],[496,41,"unknown"],[496,42,"unknown"],[496,43,"unknown"],[496,47,"unknown"],[496,48,"unknown"],[496,53,"unknown"],[497,17,"unknown"],[497,18,"unknown"],[497,21,"unknown"],[497,22,"unknown"],[497,23,"unknown"],[497,24,"unknown"],[497,25,"unknown"],[497,26,"unknown"],[497,27,"catchable"],[497,28,"catchable"],[497,29,"unknown"],[497,30,"unknown"],[497,31,"unknown"],[497,32,"unknown"],[497,40,"unknown"],[497,41,"unknown"],[497,42,"unknown"],[497,43,"unknown"],[497,47,"unknown"],[497,48,"unknown"],[497,49,"unknown"],[497,53,"unknown"],[498,17,"catchable"],[498,18,"catchable"],[498,21,"catchable"],[498,22,"catchable"],[498,23,"unknown"],[498,24,"unknown"],[498,25,"catchable"],[498,26,"catchable"],[498,27,"unknown"],[498,28,"unknown"],[498,29,"unknown"],[498,30,"unknown"],[498,31,"unknown"],[498,32,"unknown"],[498,40,"unknown"],[498,41,"unknown"],[498,42,"unknown"],[498,43,"unknown"],[498,47,"unknown"],[498,48,"unknown"],[498,53,"unknown"],[499,17,"unknown"],[499,18,"unknown"],[499,21,"unknown"],[499,22,"unknown"],[499,23,"unknown"],[499,24,"unknown"],[499,25,"unknown"],[499,26,"unknown"],[499,27,"unknown"],[499,28,"unknown"],[499,29,"unknown"],[499,30,"unknown"],[499,31,"unknown"],[499,32,"unknown"],[499,40,"unknown"],[499,41,"unknown"],[499,42,"unknown"],[499,43,"unknown"],[499,47,"unknown"],[499,48,"unknown"],[499,53,"unknown"],[500,17,"unknown"],[500,18,"unknown"],[500,21,"unknown"],[500,22,"unknown"],[500,23,"unknown"],[500,24,"unknown"],[500,25,"unknown"],[500,26,"unknown"],[500,27,"catchable"],[500,28,"catchable"],[500,29,"unknown"],[500,30,"unknown"],[500,31,"unknown"],[500,32,"unknown"],[500,40,"unknown"],[500,41,"unknown"],[500,42,"unknown"],[500,43,"unknown"],[500,47,"unknown"],[500,48,"unknown"],[500,49,"unknown"],[500,53,"unknown"],[501,17,"catchable"],[501,18,"catchable"],[501,21,"catchable"],[501,22,"catchable"],[501,23,"unknown"],[501,24,"unknown"],[501,25,"catchable"],[501,26,"catchable"],[501,27,"unknown"],[501,28,"unknown"],[501,29,"unknown"],[501,30,"unknown"],[501,31,"unknown"],[501,32,"unknown"],[501,39,"unknown"],[501,40,"unknown"],[501,41,"unknown"],[501,42,"unknown"],[501,43,"unknown"],[501,47,"unknown"],[501,48,"unknown"],[501,53,"unknown"],[502,17,"unknown"],[502,18,"unknown"],[502,21,"unknown"],[502,22,"unknown"],[502,23,"unknown"],[502,24,"unknown"],[502,25,"unknown"],[502,26,"unknown"],[502,27,"unknown"],[502,28,"unknown"],[502,29,"unknown"],[502,30,"unknown"],[502,31,"unknown"],[502,32,"unknown"],[502,39,"unknown"],[502,40,"unknown"],[502,41,"unknown"],[502,42,"unknown"],[502,43,"unknown"],[502,47,"unknown"],[502,48,"unknown"],[502,53,"unknown"],[503,17,"unknown"],[503,18,"unknown"],[503,21,"unknown"],[503,22,"unknown"],[503,23,"unknown"],[503,24,"unknown"],[503,25,"unknown"],[503,26,"unknown"],[503,27,"catchable"],[503,28,"catchable"],[503,29,"unknown"],[503,30,"unknown"],[503,31,"unknown"],[503,32,"unknown"],[503,39,"unknown"],[503,40,"unknown"],[503,41,"unknown"],[503,42,"unknown"],[503,43,"unknown"],[503,47,"unknown"],[503,48,"unknown"],[503,49,"unknown"],[503,53,"unknown"],[504,17,"catchable"],[504,18,"catchable"],[504,21,"catchable"],[504,22,"catchable"],[504,23,"unknown"],[504,24,"unknown"],[504,25,"unknown"],[504,26,"unknown"],[504,27,"unknown"],[504,28,"unknown"],[504,29,"unknown"],[504,30,"unknown"],[504,31,"unknown"],[504,32,"unknown"],[504,47,"unknown"],[505,17,"catchable"],[505,18,"catchable"],[505,21,"catchable"],[505,22,"catchable"],[505,23,"catchable"],[505,24,"catchable"],[505,25,"unknown"],[505,26,"unknown"],[505,27,"unknown"],[505,28,"unknown"],[505,29,"unknown"],[505,30,"unknown"],[505,31,"unknown"],[505,32,"unknown"],[505,47,"unknown"],[505,49,"unknown"],[506,17,"catchable"],[506,18,"catchable"],[506,21,"catchable"],[506,22,"catchable"],[506,23,"catchable"],[506,24,"catchable"],[506,25,"unknown"],[506,26,"unknown"],[506,27,"catchable"],[506,28,"catchable"],[506,29,"catchable"],[506,30,"catchable"],[506,31,"unknown"],[506,32,"unknown"],[506,33,"unknown"],[506,34,"unknown"],[506,35,"catchable"],[506,36,"unknown"],[506,37,"unknown"],[506,38,"unknown"],[506,39,"unknown"],[506,50,"catchable"],[507,17,"catchable"],[507,18,"catchable"],[507,21,"catchable"],[507,22,"catchable"],[507,23,"unknown"],[507,24,"unknown"],[507,25,"unknown"],[507,26,"unknown"],[507,27,"unknown"],[507,28,"unknown"],[507,29,"unknown"],[507,30,"unknown"],[507,31,"unknown"],[507,32,"unknown"],[507,33,"unknown"],[507,34,"unknown"],[507,35,"catchable"],[507,36,"unknown"],[507,37,"unknown"],[507,38,"unknown"],[507,39,"unknown"],[507,50,"catchable"],[508,17,"catchable"],[508,18,"catchable"],[508,21,"catchable"],[508,22,"catchable"],[508,23,"unknown"],[508,24,"unknown"],[508,25,"unknown"],[508,26,"unknown"],[508,27,"unknown"],[508,28,"unknown"],[508,29,"unknown"],[508,30,"unknown"],[508,31,"unknown"],[508,32,"unknown"],[508,33,"unknown"],[508,34,"unknown"],[508,35,"catchable"],[508,36,"catchable"],[508,37,"unknown"],[508,38,"unknown"],[508,39,"unknown"],[508,50,"catchable"],[508,51,"catchable"],[509,17,"catchable"],[509,18,"catchable"],[509,21,"catchable"],[509,22,"catchable"],[509,23,"unknown"],[509,24,"unknown"],[509,25,"unknown"],[509,26,"unknown"],[509,27,"unknown"],[509,28,"unknown"],[509,29,"unknown"],[509,30,"unknown"],[509,31,"unknown"],[509,32,"unknown"],[509,33,"catchable"],[509,34,"catchable"],[509,35,"unknown"],[509,36,"unknown"],[509,37,"unknown"],[509,38,"unknown"],[509,39,"unknown"],[509,47,"unknown"],[509,48,"unknown"],[510,17,"catchable"],[510,18,"catchable"],[510,21,"catchable"],[510,22,"catchable"],[510,23,"catchable"],[510,24,"catchable"],[510,25,"unknown"],[510,26,"unknown"],[510,27,"unknown"],[510,28,"unknown"],[510,29,"unknown"],[510,30,"unknown"],[510,31,"unknown"],[510,32,"unknown"],[510,33,"catchable"],[510,34,"catchable"],[510,35,"catchable"],[510,36,"catchable"],[510,37,"unknown"],[510,38,"unknown"],[510,39,"unknown"],[510,47,"unknown"],[510,48,"unknown"],[510,49,"unknown"],[510,50,"catchable"],[510,51,"catchable"],[511,17,"catchable"],[511,18,"catchable"],[511,21,"catchable"],[511,22,"catchable"],[511,23,"catchable"],[511,24,"catchable"],[511,25,"unknown"],[511,26,"unknown"],[511,27,"unknown"],[511,28,"unknown"],[511,29,"unknown"],[511,30,"unknown"],[511,31,"unknown"],[511,32,"unknown"],[511,47,"unknown"],[512,17,"unknown"],[512,18,"unknown"],[512,21,"unknown"],[512,22,"unknown"],[512,23,"unknown"],[512,24,"unknown"],[512,25,"unknown"],[512,26,"unknown"],[512,27,"unknown"],[512,28,"unknown"],[512,29,"unknown"],[512,30,"unknown"],[512,31,"unknown"],[512,32,"unknown"],[512,47,"unknown"],[512,49,"unknown"],[513,17,"catchable"],[513,18,"catchable"],[513,21,"catchable"],[513,22,"catchable"],[513,23,"catchable"],[513,24,"catchable"],[513,25,"unknown"],[513,26,"unknown"],[513,27,"unknown"],[513,28,"unknown"],[513,29,"unknown"],[513,30,"unknown"],[513,31,"unknown"],[513,32,"unknown"],[513,47,"unknown"],[514,17,"unknown"],[514,18,"unknown"],[514,21,"unknown"],[514,22,"unknown"],[514,23,"unknown"],[514,24,"unknown"],[514,25,"unknown"],[514,26,"unknown"],[514,27,"unknown"],[514,28,"unknown"],[514,29,"unknown"],[514,30,"unknown"],[514,31,"unknown"],[514,32,"unknown"],[514,47,"unknown"],[514,49,"unknown"],[515,17,"catchable"],[515,18,"catchable"],[515,21,"catchable"],[515,22,"catchable"],[515,23,"catchable"],[515,24,"catchable"],[515,25,"unknown"],[515,26,"unknown"],[515,27,"unknown"],[515,28,"unknown"],[515,29,"unknown"],[515,30,"unknown"],[515,31,"unknown"],[515,32,"unknown"],[515,47,"unknown"],[516,17,"unknown"],[516,18,"unknown"],[516,21,"unknown"],[516,22,"unknown"],[516,23,"unknown"],[516,24,"unknown"],[516,25,"unknown"],[516,26,"unknown"],[516,27,"unknown"],[516,28,"unknown"],[516,29,"unknown"],[516,30,"unknown"],[516,31,"unknown"],[516,32,"unknown"],[516,47,"unknown"],[516,49,"unknown"],[517,17,"catchable"],[517,18,"catchable"],[517,21,"catchable"],[517,22,"catchable"],[517,23,"catchable"],[517,24,"catchable"],[517,25,"catchable"],[517,26,"catchable"],[517,27,"unknown"],[517,28,"unknown"],[517,29,"unknown"],[517,30,"unknown"],[517,31,"unknown"],[517,32,"unknown"],[517,33,"catchable"],[517,34,"catchable"],[517,35,"unknown"],[517,36,"unknown"],[517,37,"unknown"],[517,38,"unknown"],[517,39,"unknown"],[517,47,"unknown"],[517,48,"unknown"],[518,17,"catchable"],[518,18,"catchable"],[518,21,"catchable"],[518,22,"catchable"],[518,23,"unknown"],[518,24,"unknown"],[518,25,"unknown"],[518,26,"unknown"],[518,27,"unknown"],[518,28,"unknown"],[518,29,"unknown"],[518,30,"unknown"],[518,31,"unknown"],[518,32,"unknown"],[518,33,"catchable"],[518,34,"catchable"],[518,35,"catchable"],[518,36,"catchable"],[518,37,"unknown"],[518,38,"unknown"],[518,39,"unknown"],[518,47,"unknown"],[518,48,"unknown"],[518,49,"unknown"],[518,50,"catchable"],[518,51,"catchable"],[519,17,"catchable"],[519,18,"catchable"],[519,21,"catchable"],[519,22,"catchable"],[519,23,"unknown"],[519,24,"unknown"],[519,25,"unknown"],[519,26,"unknown"],[519,27,"unknown"],[519,28,"unknown"],[519,29,"unknown"],[519,30,"unknown"],[519,31,"unknown"],[519,32,"unknown"],[519,33,"catchable"],[519,34,"catchable"],[519,35,"catchable"],[519,36,"unknown"],[519,37,"unknown"],[519,38,"unknown"],[519,39,"unknown"],[519,50,"catchable"],[520,17,"catchable"],[520,18,"catchable"],[520,21,"catchable"],[520,22,"catchable"],[520,23,"catchable"],[520,24,"catchable"],[520,25,"unknown"],[520,26,"unknown"],[520,27,"unknown"],[520,28,"unknown"],[520,29,"unknown"],[520,30,"unknown"],[520,31,"unknown"],[520,32,"unknown"],[520,33,"catchable"],[520,34,"catchable"],[520,35,"catchable"],[520,36,"unknown"],[520,37,"unknown"],[520,38,"unknown"],[520,39,"unknown"],[520,50,"catchable"],[521,17,"catchable"],[521,18,"catchable"],[521,21,"catchable"],[521,22,"catchable"],[521,23,"unknown"],[521,24,"unknown"],[521,25,"unknown"],[521,26,"unknown"],[521,27,"unknown"],[521,28,"unknown"],[521,29,"unknown"],[521,30,"unknown"],[521,31,"unknown"],[521,32,"unknown"],[521,33,"catchable"],[521,34,"catchable"],[521,35,"catchable"],[521,36,"catchable"],[521,37,"unknown"],[521,38,"unknown"],[521,39,"unknown"],[521,50,"catchable"],[521,51,"catchable"],[522,17,"catchable"],[522,18,"catchable"],[522,21,"unknown"],[522,22,"unknown"],[522,23,"unknown"],[522,24,"unknown"],[522,25,"unknown"],[522,26,"unknown"],[522,27,"unknown"],[522,28,"unknown"],[522,29,"unknown"],[522,30,"unknown"],[522,31,"unknown"],[522,32,"unknown"],[522,40,"unknown"],[522,41,"unknown"],[522,42,"unknown"],[522,43,"unknown"],[522,47,"unknown"],[522,48,"unknown"],[522,53,"unknown"],[523,17,"catchable"],[523,18,"catchable"],[523,21,"catchable"],[523,22,"catchable"],[523,23,"catchable"],[523,24,"catchable"],[523,25,"catchable"],[523,26,"catchable"],[523,27,"unknown"],[523,28,"unknown"],[523,29,"unknown"],[523,30,"unknown"],[523,31,"unknown"],[523,32,"unknown"],[523,40,"unknown"],[523,41,"unknown"],[523,42,"unknown"],[523,43,"unknown"],[523,47,"unknown"],[523,48,"unknown"],[523,53,"unknown"],[524,17,"catchable"],[524,18,"catchable"],[524,21,"catchable"],[524,22,"catchable"],[524,23,"catchable"],[524,24,"catchable"],[524,25,"unknown"],[524,26,"unknown"],[524,27,"catchable"],[524,28,"catchable"],[524,29,"catchable"],[524,30,"catchable"],[524,31,"unknown"],[524,32,"unknown"],[524,33,"catchable"],[524,34,"catchable"],[524,35,"catchable"],[524,36,"unknown"],[524,37,"unknown"],[524,38,"unknown"],[524,39,"unknown"],[524,50,"catchable"],[525,17,"catchable"],[525,18,"catchable"],[525,21,"catchable"],[525,22,"catchable"],[525,23,"catchable"],[525,24,"catchable"],[525,25,"catchable"],[525,26,"catchable"],[525,27,"catchable"],[525,28,"catchable"],[525,29,"catchable"],[525,30,"catchable"],[525,31,"unknown"],[525,32,"unknown"],[525,33,"catchable"],[525,34,"catchable"],[525,35,"catchable"],[525,36,"catchable"],[525,37,"unknown"],[525,38,"unknown"],[525,39,"unknown"],[525,50,"catchable"],[525,51,"catchable"],[526,17,"unknown"],[526,18,"unknown"],[526,21,"catchable"],[526,22,"catchable"],[526,23,"unknown"],[526,24,"unknown"],[526,25,"unknown"],[526,26,"unknown"],[526,27,"unknown"],[526,28,"unknown"],[526,29,"unknown"],[526,30,"unknown"],[526,31,"unknown"],[526,32,"unknown"],[526,33,"catchable"],[526,34,"catchable"],[526,35,"catchable"],[526,36,"unknown"],[526,37,"unknown"],[526,38,"unknown"],[526,39,"unknown"],[526,50,"catchable"],[527,17,"catchable"],[527,18,"catchable"],[527,21,"catchable"],[527,22,"catchable"],[527,23,"catchable"],[527,24,"catchable"],[527,25,"unknown"],[527,26,"unknown"],[527,27,"unknown"],[527,28,"unknown"],[527,29,"unknown"],[527,30,"unknown"],[527,31,"unknown"],[527,32,"unknown"],[527,33,"catchable"],[527,34,"catchable"],[527,35,"catchable"],[527,36,"catchable"],[527,37,"unknown"],[527,38,"unknown"],[527,39,"unknown"],[527,50,"catchable"],[527,51,"catchable"],[528,17,"unknown"],[528,18,"unknown"],[528,21,"unknown"],[528,22,"unknown"],[528,23,"unknown"],[528,24,"unknown"],[528,25,"unknown"],[528,26,"unknown"],[528,27,"unknown"],[528,28,"unknown"],[528,29,"unknown"],[528,30,"unknown"],[528,31,"unknown"],[528,32,"unknown"],[528,33,"catchable"],[528,34,"catchable"],[528,35,"catchable"],[528,36,"catchable"],[528,37,"unknown"],[528,38,"unknown"],[528,39,"unknown"],[528,50,"catchable"],[528,51,"catchable"],[529,17,"catchable"],[529,18,"catchable"],[529,21,"catchable"],[529,22,"catchable"],[529,23,"unknown"],[529,24,"unknown"],[529,25,"unknown"],[529,26,"unknown"],[529,27,"unknown"],[529,28,"unknown"],[529,29,"unknown"],[529,30,"unknown"],[529,31,"unknown"],[529,32,"unknown"],[529,33,"catchable"],[529,34,"catchable"],[529,35,"unknown"],[529,36,"unknown"],[529,37,"unknown"],[529,38,"unknown"],[529,39,"unknown"],[529,40,"unknown"],[529,41,"unknown"],[529,42,"unknown"],[529,43,"unknown"],[529,47,"unknown"],[529,48,"unknown"],[529,53,"unknown"],[530,17,"catchable"],[530,18,"catchable"],[530,21,"catchable"],[530,22,"catchable"],[530,23,"catchable"],[530,24,"catchable"],[530,25,"catchable"],[530,26,"catchable"],[530,27,"unknown"],[530,28,"unknown"],[530,29,"unknown"],[530,30,"unknown"],[530,31,"unknown"],[530,32,"unknown"],[530,33,"catchable"],[530,34,"catchable"],[530,35,"unknown"],[530,36,"unknown"],[530,37,"unknown"],[530,38,"unknown"],[530,39,"unknown"],[530,40,"unknown"],[530,41,"unknown"],[530,42,"unknown"],[530,43,"unknown"],[530,47,"unknown"],[530,48,"unknown"],[530,49,"unknown"],[530,53,"unknown"],[531,17,"catchable"],[531,18,"catchable"],[531,21,"catchable"],[531,22,"catchable"],[531,23,"catchable"],[531,24,"catchable"],[531,25,"catchable"],[531,26,"catchable"],[531,27,"unknown"],[531,28,"unknown"],[531,29,"catchable"],[531,30,"catchable"],[531,31,"unknown"],[531,32,"unknown"],[531,33,"unknown"],[531,34,"unknown"],[531,35,"unknown"],[531,36,"catchable"],[531,37,"unknown"],[531,38,"unknown"],[531,39,"unknown"],[531,47,"unknown"],[531,49,"unknown"],[531,51,"catchable"],[532,17,"catchable"],[532,18,"catchable"],[532,21,"catchable"],[532,22,"catchable"],[532,23,"unknown"],[532,24,"unknown"],[532,25,"unknown"],[532,26,"unknown"],[532,27,"unknown"],[532,28,"unknown"],[532,29,"unknown"],[532,30,"unknown"],[532,31,"unknown"],[532,32,"unknown"],[532,33,"catchable"],[532,34,"catchable"],[532,35,"unknown"],[532,36,"catchable"],[532,37,"unknown"],[532,38,"unknown"],[532,39,"unknown"],[532,40,"unknown"],[532,41,"unknown"],[532,42,"unknown"],[532,43,"unknown"],[532,47,"unknown"],[532,48,"unknown"],[532,51,"catchable"],[532,52,"unknown"],[533,17,"catchable"],[533,18,"catchable"],[533,21,"catchable"],[533,22,"catchable"],[533,23,"catchable"],[533,24,"catchable"],[533,25,"unknown"],[533,26,"unknown"],[533,27,"unknown"],[533,28,"unknown"],[533,29,"unknown"],[533,30,"unknown"],[533,31,"unknown"],[533,32,"unknown"],[533,33,"catchable"],[533,34,"catchable"],[533,35,"unknown"],[533,36,"catchable"],[533,37,"unknown"],[533,38,"unknown"],[533,39,"unknown"],[533,40,"unknown"],[533,41,"unknown"],[533,42,"unknown"],[533,43,"unknown"],[533,47,"unknown"],[533,48,"unknown"],[533,51,"catchable"],[533,52,"unknown"],[534,17,"unknown"],[534,18,"unknown"],[534,21,"unknown"],[534,22,"unknown"],[534,23,"unknown"],[534,24,"unknown"],[534,25,"unknown"],[534,26,"unknown"],[534,27,"catchable"],[534,28,"catchable"],[534,29,"unknown"],[534,30,"unknown"],[534,31,"unknown"],[534,32,"unknown"],[534,33,"catchable"],[534,34,"catchable"],[534,35,"unknown"],[534,36,"catchable"],[534,37,"unknown"],[534,38,"unknown"],[534,39,"unknown"],[534,40,"unknown"],[534,41,"unknown"],[534,42,"unknown"],[534,43,"unknown"],[534,47,"unknown"],[534,48,"unknown"],[534,49,"unknown"],[534,51,"catchable"],[534,52,"unknown"],[535,17,"catchable"],[535,18,"catchable"],[535,21,"unknown"],[535,22,"unknown"],[535,23,"unknown"],[535,24,"unknown"],[535,25,"unknown"],[535,26,"unknown"],[535,27,"unknown"],[535,28,"unknown"],[535,29,"unknown"],[535,30,"unknown"],[535,31,"unknown"],[535,32,"unknown"],[535,33,"catchable"],[535,34,"catchable"],[535,35,"catchable"],[535,36,"unknown"],[535,37,"unknown"],[535,38,"unknown"],[535,39,"unknown"],[535,50,"catchable"],[536,17,"catchable"],[536,18,"catchable"],[536,21,"catchable"],[536,22,"catchable"],[536,23,"catchable"],[536,24,"catchable"],[536,25,"unknown"],[536,26,"unknown"],[536,27,"unknown"],[536,28,"unknown"],[536,29,"unknown"],[536,30,"unknown"],[536,31,"unknown"],[536,32,"unknown"],[536,33,"catchable"],[536,34,"catchable"],[536,35,"catchable"],[536,36,"catchable"],[536,37,"unknown"],[536,38,"unknown"],[536,39,"unknown"],[536,50,"catchable"],[536,51,"catchable"],[537,17,"catchable"],[537,18,"catchable"],[537,21,"catchable"],[537,22,"catchable"],[537,23,"unknown"],[537,24,"unknown"],[537,25,"unknown"],[537,26,"unknown"],[537,27,"unknown"],[537,28,"unknown"],[537,29,"unknown"],[537,30,"unknown"],[537,31,"unknown"],[537,32,"unknown"],[537,33,"catchable"],[537,34,"catchable"],[537,35,"catchable"],[537,36,"catchable"],[537,37,"unknown"],[537,38,"unknown"],[537,39,"unknown"],[537,50,"catchable"],[537,51,"catchable"],[538,17,"catchable"],[538,18,"catchable"],[538,21,"catchable"],[538,22,"catchable"],[538,23,"catchable"],[538,24,"catchable"],[538,25,"unknown"],[538,26,"unknown"],[538,27,"unknown"],[538,28,"unknown"],[538,29,"unknown"],[538,30,"unknown"],[538,31,"unknown"],[538,32,"unknown"],[538,33,"catchable"],[538,34,"catchable"],[538,35,"unknown"],[538,36,"unknown"],[538,37,"unknown"],[538,38,"unknown"],[538,39,"unknown"],[538,47,"unknown"],[538,48,"unknown"],[538,50,"catchable"],[539,17,"catchable"],[539,18,"catchable"],[539,21,"catchable"],[539,22,"catchable"],[539,23,"catchable"],[539,24,"catchable"],[539,25,"unknown"],[539,26,"unknown"],[539,27,"unknown"],[539,28,"unknown"],[539,29,"unknown"],[539,30,"unknown"],[539,31,"unknown"],[539,32,"unknown"],[539,33,"catchable"],[539,34,"catchable"],[539,35,"catchable"],[539,36,"unknown"],[539,37,"unknown"],[539,38,"unknown"],[539,39,"unknown"],[539,47,"unknown"],[539,48,"unknown"],[540,17,"catchable"],[540,18,"catchable"],[540,21,"catchable"],[540,22,"catchable"],[540,23,"unknown"],[540,24,"unknown"],[540,25,"unknown"],[540,26,"unknown"],[540,27,"unknown"],[540,28,"unknown"],[540,29,"unknown"],[540,30,"unknown"],[540,31,"unknown"],[540,32,"unknown"],[540,40,"unknown"],[540,41,"unknown"],[540,42,"unknown"],[540,43,"unknown"],[540,47,"unknown"],[540,48,"unknown"],[540,52,"unknown"],[541,17,"catchable"],[541,18,"catchable"],[541,21,"catchable"],[541,22,"catchable"],[541,23,"catchable"],[541,24,"catchable"],[541,25,"unknown"],[541,26,"unknown"],[541,27,"unknown"],[541,28,"unknown"],[541,29,"unknown"],[541,30,"unknown"],[541,31,"unknown"],[541,32,"unknown"],[541,40,"unknown"],[541,41,"unknown"],[541,42,"unknown"],[541,43,"unknown"],[541,47,"unknown"],[541,48,"unknown"],[541,52,"unknown"],[542,17,"catchable"],[542,18,"catchable"],[542,21,"catchable"],[542,22,"catchable"],[542,23,"unknown"],[542,24,"unknown"],[542,25,"unknown"],[542,26,"unknown"],[542,27,"catchable"],[542,28,"catchable"],[542,29,"catchable"],[542,30,"catchable"],[542,31,"unknown"],[542,32,"unknown"],[542,40,"unknown"],[542,41,"unknown"],[542,42,"unknown"],[542,43,"unknown"],[542,47,"unknown"],[542,48,"unknown"],[542,52,"unknown"],[543,17,"catchable"],[543,18,"catchable"],[543,21,"catchable"],[543,22,"catchable"],[543,23,"catchable"],[543,24,"catchable"],[543,25,"unknown"],[543,26,"unknown"],[543,27,"catchable"],[543,28,"catchable"],[543,29,"unknown"],[543,30,"unknown"],[543,31,"unknown"],[543,32,"unknown"],[543,33,"unknown"],[543,34,"unknown"],[543,35,"catchable"],[543,36,"unknown"],[543,37,"unknown"],[543,38,"unknown"],[543,39,"unknown"],[543,47,"unknown"],[543,50,"catchable"],[544,17,"catchable"],[544,18,"catchable"],[544,21,"catchable"],[544,22,"catchable"],[544,23,"catchable"],[544,24,"catchable"],[544,25,"unknown"],[544,26,"unknown"],[544,27,"unknown"],[544,28,"unknown"],[544,29,"unknown"],[544,30,"unknown"],[544,31,"unknown"],[544,32,"unknown"],[544,33,"unknown"],[544,34,"unknown"],[544,35,"catchable"],[544,36,"unknown"],[544,37,"unknown"],[544,38,"unknown"],[544,39,"unknown"],[544,47,"unknown"],[544,50,"catchable"],[545,17,"unknown"],[545,18,"unknown"],[545,21,"catchable"],[545,22,"catchable"],[545,23,"unknown"],[545,24,"unknown"],[545,25,"unknown"],[545,26,"unknown"],[545,27,"unknown"],[545,28,"unknown"],[545,29,"unknown"],[545,30,"unknown"],[545,31,"unknown"],[545,32,"unknown"],[545,33,"unknown"],[545,34,"unknown"],[545,35,"catchable"],[545,36,"catchable"],[545,37,"unknown"],[545,38,"unknown"],[545,39,"unknown"],[545,47,"unknown"],[545,49,"unknown"],[545,50,"catchable"],[545,51,"catchable"],[546,17,"catchable"],[546,18,"unknown"],[546,21,"catchable"],[546,22,"catchable"],[546,23,"unknown"],[546,24,"unknown"],[546,25,"unknown"],[546,26,"unknown"],[546,27,"catchable"],[546,28,"unknown"],[546,29,"catchable"],[546,30,"unknown"],[546,31,"unknown"],[546,32,"unknown"],[546,33,"catchable"],[546,34,"catchable"],[546,35,"unknown"],[546,36,"catchable"],[546,37,"unknown"],[546,38,"unknown"],[546,39,"unknown"],[546,40,"unknown"],[546,41,"unknown"],[546,42,"unknown"],[546,43,"unknown"],[546,47,"unknown"],[546,48,"unknown"],[546,51,"catchable"],[546,53,"unknown"],[547,17,"catchable"],[547,18,"unknown"],[547,21,"catchable"],[547,22,"unknown"],[547,23,"unknown"],[547,24,"unknown"],[547,25,"unknown"],[547,26,"unknown"],[547,27,"unknown"],[547,28,"unknown"],[547,29,"unknown"],[547,30,"unknown"],[547,31,"unknown"],[547,32,"unknown"],[547,33,"catchable"],[547,34,"catchable"],[547,35,"unknown"],[547,36,"catchable"],[547,37,"unknown"],[547,38,"unknown"],[547,39,"unknown"],[547,40,"unknown"],[547,41,"unknown"],[547,42,"unknown"],[547,43,"unknown"],[547,47,"unknown"],[547,48,"unknown"],[547,49,"unknown"],[547,51,"catchable"],[547,53,"unknown"],[548,17,"unknown"],[548,18,"catchable"],[548,21,"catchable"],[548,22,"catchable"],[548,23,"catchable"],[548,24,"catchable"],[548,25,"catchable"],[548,26,"catchable"],[548,27,"unknown"],[548,28,"catchable"],[548,29,"unknown"],[548,30,"catchable"],[548,31,"unknown"],[548,32,"unknown"],[548,33,"unknown"],[548,34,"unknown"],[548,35,"catchable"],[548,36,"unknown"],[548,37,"unknown"],[548,38,"unknown"],[548,39,"unknown"],[548,40,"unknown"],[548,41,"unknown"],[548,42,"unknown"],[548,43,"unknown"],[548,47,"unknown"],[548,48,"unknown"],[548,50,"catchable"],[548,52,"unknown"],[549,17,"unknown"],[549,18,"catchable"],[549,21,"unknown"],[549,22,"catchable"],[549,23,"unknown"],[549,24,"unknown"],[549,25,"unknown"],[549,26,"unknown"],[549,27,"unknown"],[549,28,"unknown"],[549,29,"unknown"],[549,30,"unknown"],[549,31,"unknown"],[549,32,"unknown"],[549,33,"unknown"],[549,34,"unknown"],[549,35,"catchable"],[549,36,"catchable"],[549,37,"unknown"],[549,38,"unknown"],[549,39,"unknown"],[549,40,"unknown"],[549,41,"unknown"],[549,42,"unknown"],[549,43,"unknown"],[549,47,"unknown"],[549,48,"unknown"],[549,50,"catchable"],[549,51,"catchable"],[549,52,"unknown"],[550,17,"catchable"],[550,18,"catchable"],[550,21,"catchable"],[550,22,"catchable"],[550,23,"catchable"],[550,24,"catchable"],[550,25,"unknown"],[550,26,"unknown"],[550,27,"unknown"],[550,28,"unknown"],[550,29,"catchable"],[550,30,"catchable"],[550,31,"unknown"],[550,32,"unknown"],[550,33,"catchable"],[550,34,"catchable"],[550,35,"catchable"],[550,36,"catchable"],[550,37,"unknown"],[550,38,"unknown"],[550,39,"unknown"],[550,40,"unknown"],[550,41,"unknown"],[550,42,"unknown"],[550,43,"unknown"],[550,47,"unknown"],[550,48,"unknown"],[550,50,"catchable"],[550,51,"catchable"],[550,52,"unknown"],[551,17,"catchable"],[551,18,"catchable"],[551,21,"catchable"],[551,22,"catchable"],[551,23,"catchable"],[551,24,"catchable"],[551,25,"unknown"],[551,26,"unknown"],[551,27,"catchable"],[551,28,"catchable"],[551,29,"unknown"],[551,30,"unknown"],[551,31,"unknown"],[551,32,"unknown"],[551,33,"unknown"],[551,34,"unknown"],[551,35,"catchable"],[551,36,"unknown"],[551,37,"unknown"],[551,38,"unknown"],[551,39,"unknown"],[551,40,"unknown"],[551,41,"unknown"],[551,42,"unknown"],[551,43,"unknown"],[551,47,"unknown"],[551,48,"unknown"],[551,50,"catchable"],[551,53,"unknown"],[552,17,"catchable"],[552,18,"catchable"],[552,21,"catchable"],[552,22,"catchable"],[552,23,"unknown"],[552,24,"unknown"],[552,25,"unknown"],[552,26,"unknown"],[552,27,"unknown"],[552,28,"unknown"],[552,29,"catchable"],[552,30,"catchable"],[552,31,"unknown"],[552,32,"unknown"],[552,33,"unknown"],[552,34,"unknown"],[552,35,"catchable"],[552,36,"unknown"],[552,37,"unknown"],[552,38,"unknown"],[552,39,"unknown"],[552,40,"unknown"],[552,41,"unknown"],[552,42,"unknown"],[552,43,"unknown"],[552,47,"unknown"],[552,48,"unknown"],[552,50,"catchable"],[552,53,"unknown"],[553,17,"unknown"],[553,18,"unknown"],[553,21,"unknown"],[553,22,"unknown"],[553,23,"unknown"],[553,24,"unknown"],[553,25,"unknown"],[553,26,"unknown"],[553,27,"unknown"],[553,28,"unknown"],[553,29,"unknown"],[553,30,"unknown"],[553,31,"unknown"],[553,32,"unknown"],[553,33,"unknown"],[553,34,"unknown"],[553,35,"catchable"],[553,36,"catchable"],[553,37,"unknown"],[553,38,"unknown"],[553,39,"unknown"],[553,40,"unknown"],[553,41,"unknown"],[553,42,"unknown"],[553,43,"unknown"],[553,47,"unknown"],[553,48,"unknown"],[553,49,"unknown"],[553,50,"catchable"],[553,51,"catchable"],[553,53,"unknown"],[554,17,"catchable"],[554,18,"catchable"],[554,21,"catchable"],[554,22,"catchable"],[554,23,"unknown"],[554,24,"unknown"],[554,25,"unknown"],[554,26,"unknown"],[554,27,"unknown"],[554,28,"unknown"],[554,29,"unknown"],[554,30,"unknown"],[554,31,"unknown"],[554,32,"unknown"],[554,33,"catchable"],[554,34,"unknown"],[554,35,"catchable"],[554,36,"catchable"],[554,37,"unknown"],[554,38,"unknown"],[554,39,"unknown"],[554,51,"unknown"],[555,17,"unknown"],[555,18,"unknown"],[555,21,"unknown"],[555,22,"unknown"],[555,23,"unknown"],[555,24,"unknown"],[555,25,"catchable"],[555,26,"catchable"],[555,27,"unknown"],[555,28,"unknown"],[555,29,"unknown"],[555,30,"unknown"],[555,31,"unknown"],[555,32,"unknown"],[555,33,"catchable"],[555,34,"unknown"],[555,35,"unknown"],[555,36,"catchable"],[555,37,"unknown"],[555,38,"unknown"],[555,39,"unknown"],[555,51,"unknown"],[556,17,"catchable"],[556,18,"catchable"],[556,21,"catchable"],[556,22,"catchable"],[556,23,"catchable"],[556,24,"catchable"],[556,25,"catchable"],[556,26,"catchable"],[556,27,"unknown"],[556,28,"unknown"],[556,29,"unknown"],[556,30,"unknown"],[556,31,"unknown"],[556,32,"unknown"],[556,33,"catchable"],[556,34,"catchable"],[556,35,"catchable"],[556,36,"catchable"],[556,37,"unknown"],[556,38,"unknown"],[556,39,"unknown"],[556,50,"catchable"],[556,51,"catchable"],[557,17,"catchable"],[557,18,"catchable"],[557,21,"catchable"],[557,22,"catchable"],[557,23,"catchable"],[557,24,"catchable"],[557,25,"unknown"],[557,26,"unknown"],[557,27,"unknown"],[557,28,"unknown"],[557,29,"unknown"],[557,30,"unknown"],[557,31,"unknown"],[557,32,"unknown"],[557,33,"catchable"],[557,34,"catchable"],[557,35,"catchable"],[557,36,"unknown"],[557,37,"unknown"],[557,38,"unknown"],[557,39,"unknown"],[557,50,"catchable"],[558,17,"catchable"],[558,18,"catchable"],[558,21,"catchable"],[558,22,"catchable"],[558,23,"unknown"],[558,24,"unknown"],[558,25,"catchable"],[558,26,"catchable"],[558,27,"unknown"],[558,28,"unknown"],[558,29,"catchable"],[558,30,"catchable"],[558,31,"unknown"],[558,32,"unknown"],[558,33,"catchable"],[558,34,"catchable"],[558,35,"catchable"],[558,36,"catchable"],[558,37,"unknown"],[558,38,"unknown"],[558,39,"unknown"],[558,50,"catchable"],[558,51,"catchable"],[559,17,"catchable"],[559,18,"catchable"],[559,21,"catchable"],[559,22,"catchable"],[559,23,"catchable"],[559,24,"catchable"],[559,25,"unknown"],[559,26,"unknown"],[559,27,"unknown"],[559,28,"unknown"],[559,29,"catchable"],[559,30,"catchable"],[559,31,"unknown"],[559,32,"unknown"],[559,33,"catchable"],[559,34,"unknown"],[559,35,"catchable"],[559,36,"unknown"],[559,37,"unknown"],[559,38,"unknown"],[559,39,"unknown"],[559,40,"unknown"],[559,41,"unknown"],[559,42,"unknown"],[559,43,"unknown"],[559,47,"unknown"],[559,48,"unknown"],[559,50,"unknown"],[559,53,"unknown"],[560,17,"unknown"],[560,18,"unknown"],[560,21,"catchable"],[560,22,"catchable"],[560,23,"unknown"],[560,24,"unknown"],[560,25,"unknown"],[560,26,"unknown"],[560,27,"unknown"],[560,28,"unknown"],[560,29,"unknown"],[560,30,"unknown"],[560,31,"unknown"],[560,32,"unknown"],[560,33,"catchable"],[560,34,"unknown"],[560,35,"catchable"],[560,36,"unknown"],[560,37,"unknown"],[560,38,"unknown"],[560,39,"unknown"],[560,40,"unknown"],[560,41,"unknown"],[560,42,"unknown"],[560,43,"unknown"],[560,47,"unknown"],[560,48,"unknown"],[560,49,"unknown"],[560,50,"unknown"],[560,53,"unknown"],[561,17,"catchable"],[561,18,"catchable"],[561,21,"catchable"],[561,22,"catchable"],[561,23,"catchable"],[561,24,"catchable"],[561,25,"unknown"],[561,26,"unknown"],[561,27,"unknown"],[561,28,"unknown"],[561,29,"catchable"],[561,30,"catchable"],[561,31,"unknown"],[561,32,"unknown"],[561,33,"catchable"],[561,34,"catchable"],[561,35,"unknown"],[561,36,"catchable"],[561,37,"unknown"],[561,38,"unknown"],[561,39,"unknown"],[561,51,"catchable"],[562,17,"catchable"],[562,18,"catchable"],[562,21,"catchable"],[562,22,"catchable"],[562,23,"unknown"],[562,24,"unknown"],[562,25,"unknown"],[562,26,"unknown"],[562,27,"unknown"],[562,28,"unknown"],[562,29,"unknown"],[562,30,"unknown"],[562,31,"unknown"],[562,32,"unknown"],[562,33,"catchable"],[562,34,"catchable"],[562,35,"unknown"],[562,36,"unknown"],[562,37,"unknown"],[562,38,"unknown"],[562,39,"unknown"],[562,47,"unknown"],[562,48,"unknown"],[563,17,"catchable"],[563,18,"catchable"],[563,21,"unknown"],[563,22,"unknown"],[563,23,"unknown"],[563,24,"unknown"],[563,25,"catchable"],[563,26,"catchable"],[563,27,"unknown"],[563,28,"unknown"],[563,29,"unknown"],[563,30,"unknown"],[563,31,"unknown"],[563,32,"unknown"],[563,33,"unknown"],[563,34,"unknown"],[563,35,"unknown"],[563,36,"catchable"],[563,37,"unknown"],[563,38,"unknown"],[563,39,"unknown"],[563,47,"unknown"],[563,48,"unknown"],[563,49,"unknown"],[563,51,"catchable"],[564,17,"catchable"],[564,18,"catchable"],[564,21,"catchable"],[564,22,"catchable"],[564,23,"unknown"],[564,24,"unknown"],[564,25,"unknown"],[564,26,"unknown"],[564,27,"catchable"],[564,28,"catchable"],[564,29,"catchable"],[564,30,"catchable"],[564,31,"unknown"],[564,32,"unknown"],[564,33,"unknown"],[564,34,"unknown"],[564,35,"unknown"],[564,36,"catchable"],[564,37,"unknown"],[564,38,"unknown"],[564,39,"unknown"],[564,51,"catchable"],[565,17,"unknown"],[565,18,"unknown"],[565,21,"unknown"],[565,22,"unknown"],[565,23,"unknown"],[565,24,"unknown"],[565,25,"unknown"],[565,26,"unknown"],[565,27,"unknown"],[565,28,"unknown"],[565,29,"unknown"],[565,30,"unknown"],[565,31,"unknown"],[565,32,"unknown"],[565,33,"unknown"],[565,34,"unknown"],[565,35,"unknown"],[565,36,"catchable"],[565,37,"unknown"],[565,38,"unknown"],[565,39,"unknown"],[565,51,"catchable"],[566,17,"catchable"],[566,18,"catchable"],[566,21,"catchable"],[566,22,"catchable"],[566,23,"unknown"],[566,24,"unknown"],[566,25,"unknown"],[566,26,"unknown"],[566,27,"catchable"],[566,28,"catchable"],[566,29,"catchable"],[566,30,"catchable"],[566,31,"unknown"],[566,32,"unknown"],[566,33,"unknown"],[566,34,"unknown"],[566,35,"unknown"],[566,36,"catchable"],[566,37,"unknown"],[566,38,"unknown"],[566,39,"unknown"],[566,51,"catchable"],[567,17,"unknown"],[567,18,"unknown"],[567,21,"unknown"],[567,22,"unknown"],[567,23,"unknown"],[567,24,"unknown"],[567,25,"unknown"],[567,26,"unknown"],[567,27,"unknown"],[567,28,"unknown"],[567,29,"unknown"],[567,30,"unknown"],[567,31,"unknown"],[567,32,"unknown"],[567,33,"unknown"],[567,34,"unknown"],[567,35,"unknown"],[567,36,"unknown"],[567,37,"unknown"],[567,38,"unknown"],[567,39,"unknown"],[567,51,"unknown"],[568,17,"catchable"],[568,18,"catchable"],[568,21,"catchable"],[568,22,"catchable"],[568,23,"catchable"],[568,24,"catchable"],[568,25,"unknown"],[568,26,"unknown"],[568,27,"catchable"],[568,28,"catchable"],[568,29,"catchable"],[568,30,"catchable"],[568,31,"unknown"],[568,32,"unknown"],[568,33,"catchable"],[568,34,"catchable"],[568,35,"unknown"],[568,36,"catchable"],[568,37,"unknown"],[568,38,"unknown"],[568,39,"unknown"],[568,47,"unknown"],[568,51,"catchable"],[569,17,"catchable"],[569,18,"catchable"],[569,21,"catchable"],[569,22,"catchable"],[569,23,"catchable"],[569,24,"catchable"],[569,25,"unknown"],[569,26,"unknown"],[569,27,"catchable"],[569,28,"catchable"],[569,29,"unknown"],[569,30,"unknown"],[569,31,"unknown"],[569,32,"unknown"],[569,33,"catchable"],[569,34,"catchable"],[569,35,"unknown"],[569,36,"catchable"],[569,37,"unknown"],[569,38,"unknown"],[569,39,"unknown"],[569,47,"unknown"],[569,49,"unknown"],[569,51,"catchable"],[570,17,"catchable"],[570,18,"catchable"],[570,21,"catchable"],[570,22,"catchable"],[570,23,"unknown"],[570,24,"unknown"],[570,25,"unknown"],[570,26,"unknown"],[570,27,"unknown"],[570,28,"unknown"],[570,29,"catchable"],[570,30,"catchable"],[570,31,"unknown"],[570,32,"unknown"],[570,33,"unknown"],[570,34,"unknown"],[570,35,"catchable"],[570,36,"unknown"],[570,37,"unknown"],[570,38,"unknown"],[570,39,"unknown"],[570,40,"unknown"],[570,41,"unknown"],[570,42,"unknown"],[570,43,"unknown"],[570,47,"unknown"],[570,48,"unknown"],[570,50,"catchable"],[571,17,"catchable"],[571,18,"catchable"],[571,21,"unknown"],[571,22,"unknown"],[571,23,"catchable"],[571,24,"catchable"],[571,25,"unknown"],[571,26,"unknown"],[571,27,"unknown"],[571,28,"unknown"],[571,29,"catchable"],[571,30,"catchable"],[571,31,"unknown"],[571,32,"unknown"],[571,33,"unknown"],[571,34,"unknown"],[571,35,"catchable"],[571,36,"unknown"],[571,37,"unknown"],[571,38,"unknown"],[571,39,"unknown"],[571,40,"unknown"],[571,41,"unknown"],[571,42,"unknown"],[571,43,"unknown"],[571,47,"unknown"],[571,48,"unknown"],[571,49,"unknown"],[571,50,"catchable"],[572,17,"catchable"],[572,18,"catchable"],[572,21,"catchable"],[572,22,"catchable"],[572,23,"catchable"],[572,24,"catchable"],[572,25,"catchable"],[572,26,"catchable"],[572,27,"unknown"],[572,28,"unknown"],[572,29,"catchable"],[572,30,"catchable"],[572,31,"unknown"],[572,32,"unknown"],[572,33,"catchable"],[572,34,"catchable"],[572,35,"unknown"],[572,36,"unknown"],[572,37,"unknown"],[572,38,"unknown"],[572,39,"unknown"],[572,40,"unknown"],[572,41,"unknown"],[572,42,"unknown"],[572,43,"unknown"],[572,47,"unknown"],[572,48,"unknown"],[572,53,"unknown"],[573,17,"catchable"],[573,18,"catchable"],[573,21,"catchable"],[573,22,"catchable"],[573,23,"unknown"],[573,24,"unknown"],[573,25,"unknown"],[573,26,"unknown"],[573,27,"unknown"],[573,28,"unknown"],[573,29,"unknown"],[573,30,"unknown"],[573,31,"unknown"],[573,32,"unknown"],[573,33,"catchable"],[573,34,"catchable"],[573,35,"catchable"],[573,36,"catchable"],[573,37,"unknown"],[573,38,"unknown"],[573,39,"unknown"],[573,40,"unknown"],[573,41,"unknown"],[573,42,"unknown"],[573,43,"unknown"],[573,47,"unknown"],[573,48,"unknown"],[573,50,"catchable"],[573,51,"catchable"],[573,53,"unknown"],[574,17,"catchable"],[574,18,"unknown"],[574,21,"catchable"],[574,22,"unknown"],[574,23,"unknown"],[574,24,"unknown"],[574,25,"unknown"],[574,26,"unknown"],[574,27,"catchable"],[574,28,"catchable"],[574,29,"unknown"],[574,30,"unknown"],[574,31,"unknown"],[574,32,"unknown"],[574,33,"catchable"],[574,34,"unknown"],[574,35,"unknown"],[574,36,"catchable"],[574,37,"unknown"],[574,38,"unknown"],[574,39,"unknown"],[574,40,"unknown"],[574,41,"unknown"],[574,42,"unknown"],[574,43,"unknown"],[574,47,"unknown"],[574,48,"unknown"],[574,51,"unknown"],[574,53,"unknown"],[575,17,"catchable"],[575,18,"unknown"],[575,21,"catchable"],[575,22,"unknown"],[575,23,"catchable"],[575,24,"catchable"],[575,25,"unknown"],[575,26,"unknown"],[575,27,"unknown"],[575,28,"unknown"],[575,29,"unknown"],[575,30,"unknown"],[575,31,"unknown"],[575,32,"unknown"],[575,33,"catchable"],[575,34,"unknown"],[575,35,"unknown"],[575,36,"catchable"],[575,37,"unknown"],[575,38,"unknown"],[575,39,"unknown"],[575,40,"unknown"],[575,41,"unknown"],[575,42,"unknown"],[575,43,"unknown"],[575,47,"unknown"],[575,48,"unknown"],[575,51,"unknown"],[575,53,"unknown"],[576,17,"catchable"],[576,18,"unknown"],[576,21,"catchable"],[576,22,"unknown"],[576,23,"unknown"],[576,24,"unknown"],[576,25,"unknown"],[576,26,"unknown"],[576,27,"unknown"],[576,28,"unknown"],[576,29,"unknown"],[576,30,"unknown"],[576,31,"unknown"],[576,32,"unknown"],[576,33,"catchable"],[576,34,"unknown"],[576,35,"unknown"],[576,36,"catchable"],[576,37,"unknown"],[576,38,"unknown"],[576,39,"unknown"],[576,40,"unknown"],[576,41,"unknown"],[576,42,"unknown"],[576,43,"unknown"],[576,47,"unknown"],[576,48,"unknown"],[576,51,"unknown"],[576,53,"unknown"],[577,17,"unknown"],[577,18,"catchable"],[577,21,"unknown"],[577,22,"catchable"],[577,23,"catchable"],[577,24,"catchable"],[577,25,"unknown"],[577,26,"unknown"],[577,27,"unknown"],[577,28,"unknown"],[577,29,"unknown"],[577,30,"unknown"],[577,31,"unknown"],[577,32,"unknown"],[577,33,"unknown"],[577,34,"catchable"],[577,35,"unknown"],[577,36,"unknown"],[577,37,"unknown"],[577,38,"unknown"],[577,39,"unknown"],[577,40,"unknown"],[577,41,"unknown"],[577,42,"unknown"],[577,43,"unknown"],[577,47,"unknown"],[577,48,"unknown"],[577,51,"catchable"],[577,53,"unknown"],[578,17,"unknown"],[578,18,"catchable"],[578,21,"unknown"],[578,22,"catchable"],[578,23,"catchable"],[578,24,"catchable"],[578,25,"unknown"],[578,26,"unknown"],[578,27,"catchable"],[578,28,"catchable"],[578,29,"unknown"],[578,30,"unknown"],[578,31,"unknown"],[578,32,"unknown"],[578,33,"unknown"],[578,34,"catchable"],[578,35,"unknown"],[578,36,"unknown"],[578,37,"unknown"],[578,38,"unknown"],[578,39,"unknown"],[578,40,"unknown"],[578,41,"unknown"],[578,42,"unknown"],[578,43,"unknown"],[578,47,"unknown"],[578,48,"unknown"],[578,51,"catchable"],[578,53,"unknown"],[579,17,"unknown"],[579,18,"catchable"],[579,21,"unknown"],[579,22,"catchable"],[579,23,"unknown"],[579,24,"unknown"],[579,25,"unknown"],[579,26,"unknown"],[579,27,"unknown"],[579,28,"unknown"],[579,29,"unknown"],[579,30,"unknown"],[579,31,"unknown"],[579,32,"unknown"],[579,33,"unknown"],[579,34,"catchable"],[579,35,"unknown"],[579,36,"unknown"],[579,37,"unknown"],[579,38,"unknown"],[579,39,"unknown"],[579,40,"unknown"],[579,41,"unknown"],[579,42,"unknown"],[579,43,"unknown"],[579,47,"unknown"],[579,48,"unknown"],[579,49,"unknown"],[579,51,"catchable"],[579,53,"unknown"],[580,17,"catchable"],[580,18,"catchable"],[580,21,"catchable"],[580,22,"catchable"],[580,23,"catchable"],[580,24,"catchable"],[580,25,"unknown"],[580,26,"unknown"],[580,27,"unknown"],[580,28,"unknown"],[580,29,"unknown"],[580,30,"unknown"],[580,31,"unknown"],[580,32,"unknown"],[580,40,"unknown"],[580,41,"unknown"],[580,42,"unknown"],[580,43,"unknown"],[580,47,"unknown"],[580,48,"unknown"],[580,52,"unknown"],[581,17,"catchable"],[581,18,"catchable"],[581,21,"catchable"],[581,22,"catchable"],[581,23,"catchable"],[581,24,"catchable"],[581,25,"unknown"],[581,26,"unknown"],[581,27,"unknown"],[581,28,"unknown"],[581,29,"catchable"],[581,30,"catchable"],[581,31,"unknown"],[581,32,"unknown"],[581,40,"unknown"],[581,41,"unknown"],[581,42,"unknown"],[581,43,"unknown"],[581,47,"unknown"],[581,48,"unknown"],[581,52,"unknown"],[582,17,"catchable"],[582,18,"catchable"],[582,21,"unknown"],[582,22,"unknown"],[582,23,"catchable"],[582,24,"catchable"],[582,25,"unknown"],[582,26,"unknown"],[582,27,"catchable"],[582,28,"catchable"],[582,29,"catchable"],[582,30,"catchable"],[582,31,"unknown"],[582,32,"unknown"],[582,33,"catchable"],[582,34,"catchable"],[582,35,"unknown"],[582,36,"catchable"],[582,37,"unknown"],[582,38,"unknown"],[582,39,"unknown"],[582,47,"unknown"],[582,51,"catchable"],[583,17,"catchable"],[583,18,"catchable"],[583,21,"catchable"],[583,22,"catchable"],[583,23,"unknown"],[583,24,"unknown"],[583,25,"unknown"],[583,26,"unknown"],[583,27,"catchable"],[583,28,"catchable"],[583,29,"catchable"],[583,30,"catchable"],[583,31,"unknown"],[583,32,"unknown"],[583,33,"catchable"],[583,34,"catchable"],[583,35,"unknown"],[583,36,"catchable"],[583,37,"unknown"],[583,38,"unknown"],[583,39,"unknown"],[583,47,"unknown"],[583,51,"catchable"],[584,17,"unknown"],[584,18,"unknown"],[584,21,"catchable"],[584,22,"catchable"],[584,23,"unknown"],[584,24,"unknown"],[584,25,"unknown"],[584,26,"unknown"],[584,27,"unknown"],[584,28,"unknown"],[584,29,"catchable"],[584,30,"catchable"],[584,31,"unknown"],[584,32,"unknown"],[584,33,"catchable"],[584,34,"catchable"],[584,35,"unknown"],[584,36,"catchable"],[584,37,"unknown"],[584,38,"unknown"],[584,39,"unknown"],[584,47,"unknown"],[584,49,"unknown"],[584,51,"catchable"],[585,17,"catchable"],[585,18,"catchable"],[585,21,"catchable"],[585,22,"catchable"],[585,23,"unknown"],[585,24,"unknown"],[585,25,"unknown"],[585,26,"unknown"],[585,27,"unknown"],[585,28,"unknown"],[585,29,"unknown"],[585,30,"unknown"],[585,31,"unknown"],[585,32,"unknown"],[585,40,"unknown"],[585,41,"unknown"],[585,42,"unknown"],[585,43,"unknown"],[585,47,"unknown"],[585,48,"unknown"],[585,53,"unknown"],[586,17,"catchable"],[586,18,"catchable"],[586,21,"catchable"],[586,22,"catchable"],[586,23,"catchable"],[586,24,"catchable"],[586,25,"unknown"],[586,26,"unknown"],[586,27,"unknown"],[586,28,"unknown"],[586,29,"unknown"],[586,30,"unknown"],[586,31,"unknown"],[586,32,"unknown"],[586,40,"unknown"],[586,41,"unknown"],[586,42,"unknown"],[586,43,"unknown"],[586,47,"unknown"],[586,48,"unknown"],[586,53,"unknown"],[587,17,"catchable"],[587,18,"catchable"],[587,21,"catchable"],[587,22,"catchable"],[587,23,"catchable"],[587,24,"catchable"],[587,25,"unknown"],[587,26,"unknown"],[587,27,"catchable"],[587,28,"catchable"],[587,29,"catchable"],[587,30,"catchable"],[587,31,"unknown"],[587,32,"unknown"],[587,33,"unknown"],[587,34,"unknown"],[587,35,"catchable"],[587,36,"catchable"],[587,37,"unknown"],[587,38,"unknown"],[587,39,"unknown"],[587,47,"unknown"],[587,49,"unknown"],[587,50,"catchable"],[587,51,"catchable"],[588,17,"catchable"],[588,18,"catchable"],[588,21,"catchable"],[588,22,"catchable"],[588,23,"catchable"],[588,24,"catchable"],[588,25,"unknown"],[588,26,"unknown"],[588,27,"unknown"],[588,28,"unknown"],[588,29,"unknown"],[588,30,"unknown"],[588,31,"unknown"],[588,32,"unknown"],[588,33,"catchable"],[588,34,"catchable"],[588,35,"catchable"],[588,36,"catchable"],[588,37,"unknown"],[588,38,"unknown"],[588,39,"unknown"],[588,50,"catchable"],[588,51,"catchable"],[589,17,"unknown"],[589,18,"unknown"],[589,21,"unknown"],[589,22,"unknown"],[589,23,"unknown"],[589,24,"unknown"],[589,25,"unknown"],[589,26,"unknown"],[589,27,"unknown"],[589,28,"unknown"],[589,29,"unknown"],[589,30,"unknown"],[589,31,"unknown"],[589,32,"unknown"],[589,33,"catchable"],[589,34,"unknown"],[589,35,"catchable"],[589,36,"catchable"],[589,37,"unknown"],[589,38,"unknown"],[589,39,"unknown"],[589,50,"catchable"],[589,51,"catchable"],[590,17,"catchable"],[590,18,"catchable"],[590,21,"catchable"],[590,22,"catchable"],[590,23,"catchable"],[590,24,"catchable"],[590,25,"unknown"],[590,26,"unknown"],[590,27,"unknown"],[590,28,"unknown"],[590,29,"unknown"],[590,30,"unknown"],[590,31,"unknown"],[590,32,"unknown"],[590,33,"unknown"],[590,34,"unknown"],[590,35,"catchable"],[590,36,"unknown"],[590,37,"unknown"],[590,38,"unknown"],[590,39,"unknown"],[590,40,"unknown"],[590,41,"unknown"],[590,42,"unknown"],[590,43,"unknown"],[590,47,"unknown"],[590,48,"unknown"],[590,50,"catchable"],[591,17,"catchable"],[591,18,"catchable"],[591,21,"catchable"],[591,22,"catchable"],[591,23,"catchable"],[591,24,"catchable"],[591,25,"unknown"],[591,26,"unknown"],[591,27,"unknown"],[591,28,"unknown"],[591,29,"unknown"],[591,30,"unknown"],[591,31,"unknown"],[591,32,"unknown"],[591,33,"unknown"],[591,34,"unknown"],[591,35,"catchable"],[591,36,"catchable"],[591,37,"unknown"],[591,38,"unknown"],[591,39,"unknown"],[591,40,"unknown"],[591,41,"unknown"],[591,42,"unknown"],[591,43,"unknown"],[591,47,"unknown"],[591,48,"unknown"],[591,50,"catchable"],[591,51,"catchable"],[592,17,"catchable"],[592,18,"catchable"],[592,21,"catchable"],[592,22,"catchable"],[592,23,"unknown"],[592,24,"unknown"],[592,25,"unknown"],[592,26,"unknown"],[592,27,"unknown"],[592,28,"unknown"],[592,29,"catchable"],[592,30,"catchable"],[592,31,"unknown"],[592,32,"unknown"],[592,33,"catchable"],[592,34,"catchable"],[592,35,"catchable"],[592,36,"unknown"],[592,37,"unknown"],[592,38,"unknown"],[592,39,"unknown"],[592,50,"catchable"],[593,17,"catchable"],[593,18,"catchable"],[593,21,"catchable"],[593,22,"catchable"],[593,23,"unknown"],[593,24,"unknown"],[593,25,"unknown"],[593,26,"unknown"],[593,27,"unknown"],[593,28,"unknown"],[593,29,"unknown"],[593,30,"unknown"],[593,31,"unknown"],[593,32,"unknown"],[593,33,"catchable"],[593,34,"catchable"],[593,35,"catchable"],[593,36,"catchable"],[593,37,"unknown"],[593,38,"unknown"],[593,39,"unknown"],[593,50,"catchable"],[593,51,"catchable"],[594,17,"catchable"],[594,18,"catchable"],[594,21,"catchable"],[594,22,"catchable"],[594,23,"catchable"],[594,24,"catchable"],[594,25,"unknown"],[594,26,"unknown"],[594,27,"catchable"],[594,28,"catchable"],[594,29,"catchable"],[594,30,"catchable"],[594,31,"unknown"],[594,32,"unknown"],[594,40,"unknown"],[594,41,"unknown"],[594,42,"unknown"],[594,43,"unknown"],[594,47,"unknown"],[594,48,"unknown"],[594,53,"unknown"],[595,17,"catchable"],[595,18,"catchable"],[595,21,"catchable"],[595,22,"catchable"],[595,23,"unknown"],[595,24,"unknown"],[595,25,"unknown"],[595,26,"unknown"],[595,27,"unknown"],[595,28,"unknown"],[595,29,"unknown"],[595,30,"unknown"],[595,31,"unknown"],[595,32,"unknown"],[595,33,"catchable"],[595,34,"catchable"],[595,35,"catchable"],[595,36,"catchable"],[595,37,"unknown"],[595,38,"unknown"],[595,39,"unknown"],[595,40,"unknown"],[595,41,"unknown"],[595,42,"unknown"],[595,43,"unknown"],[595,47,"unknown"],[595,48,"unknown"],[595,50,"catchable"],[595,51,"catchable"],[595,53,"unknown"],[596,17,"unknown"],[596,18,"unknown"],[596,21,"unknown"],[596,22,"unknown"],[596,23,"catchable"],[596,24,"catchable"],[596,25,"unknown"],[596,26,"unknown"],[596,27,"unknown"],[596,28,"unknown"],[596,29,"unknown"],[596,30,"unknown"],[596,31,"unknown"],[596,32,"unknown"],[596,33,"catchable"],[596,34,"catchable"],[596,35,"catchable"],[596,36,"catchable"],[596,37,"unknown"],[596,38,"unknown"],[596,39,"unknown"],[596,40,"unknown"],[596,41,"unknown"],[596,42,"unknown"],[596,43,"unknown"],[596,47,"unknown"],[596,48,"unknown"],[596,50,"catchable"],[596,51,"catchable"],[596,53,"unknown"],[597,17,"catchable"],[597,18,"catchable"],[597,21,"catchable"],[597,22,"catchable"],[597,23,"catchable"],[597,24,"catchable"],[597,25,"unknown"],[597,26,"unknown"],[597,27,"unknown"],[597,28,"unknown"],[597,29,"unknown"],[597,30,"unknown"],[597,31,"unknown"],[597,32,"unknown"],[597,33,"catchable"],[597,34,"catchable"],[597,35,"unknown"],[597,36,"catchable"],[597,37,"unknown"],[597,38,"unknown"],[597,39,"unknown"],[597,51,"catchable"],[598,17,"unknown"],[598,18,"unknown"],[598,21,"unknown"],[598,22,"unknown"],[598,23,"unknown"],[598,24,"unknown"],[598,25,"unknown"],[598,26,"unknown"],[598,27,"unknown"],[598,28,"unknown"],[598,29,"unknown"],[598,30,"unknown"],[598,31,"unknown"],[598,32,"unknown"],[598,33,"catchable"],[598,34,"catchable"],[598,35,"unknown"],[598,36,"catchable"],[598,37,"unknown"],[598,38,"unknown"],[598,39,"unknown"],[598,51,"catchable"],[599,17,"catchable"],[599,18,"catchable"],[599,21,"catchable"],[599,22,"catchable"],[599,23,"unknown"],[599,24,"unknown"],[599,25,"catchable"],[599,26,"catchable"],[599,27,"catchable"],[599,28,"catchable"],[599,29,"unknown"],[599,30,"unknown"],[599,31,"unknown"],[599,32,"unknown"],[599,33,"catchable"],[599,34,"catchable"],[599,35,"unknown"],[599,36,"unknown"],[599,37,"unknown"],[599,38,"unknown"],[599,39,"unknown"],[600,17,"unknown"],[600,18,"unknown"],[600,21,"catchable"],[600,22,"catchable"],[600,23,"catchable"],[600,24,"catchable"],[600,25,"unknown"],[600,26,"unknown"],[600,27,"unknown"],[600,28,"unknown"],[600,29,"unknown"],[600,30,"unknown"],[600,31,"unknown"],[600,32,"unknown"],[600,33,"catchable"],[600,34,"catchable"],[600,35,"unknown"],[600,36,"catchable"],[600,37,"unknown"],[600,38,"unknown"],[600,39,"unknown"],[600,51,"catchable"],[601,17,"unknown"],[601,18,"unknown"],[601,21,"catchable"],[601,22,"catchable"],[601,23,"unknown"],[601,24,"unknown"],[601,25,"unknown"],[601,26,"unknown"],[601,27,"unknown"],[601,28,"unknown"],[601,29,"unknown"],[601,30,"unknown"],[601,31,"unknown"],[601,32,"unknown"],[601,33,"catchable"],[601,34,"catchable"],[601,35,"catchable"],[601,36,"catchable"],[601,37,"unknown"],[601,38,"unknown"],[601,39,"unknown"],[601,50,"catchable"],[601,51,"catchable"],[602,17,"catchable"],[602,18,"catchable"],[602,21,"catchable"],[602,22,"catchable"],[602,23,"unknown"],[602,24,"unknown"],[602,25,"catchable"],[602,26,"catchable"],[602,27,"unknown"],[602,28,"unknown"],[602,29,"unknown"],[602,30,"unknown"],[602,31,"unknown"],[602,32,"unknown"],[602,40,"unknown"],[602,41,"unknown"],[602,42,"unknown"],[602,43,"unknown"],[602,47,"unknown"],[602,48,"unknown"],[602,52,"unknown"],[602,53,"unknown"],[603,17,"unknown"],[603,18,"unknown"],[603,21,"catchable"],[603,22,"catchable"],[603,23,"unknown"],[603,24,"unknown"],[603,25,"unknown"],[603,26,"unknown"],[603,27,"unknown"],[603,28,"unknown"],[603,29,"unknown"],[603,30,"unknown"],[603,31,"unknown"],[603,32,"unknown"],[603,40,"unknown"],[603,41,"unknown"],[603,42,"unknown"],[603,43,"unknown"],[603,47,"unknown"],[603,48,"unknown"],[603,52,"unknown"],[603,53,"unknown"],[604,17,"unknown"],[604,18,"unknown"],[604,21,"unknown"],[604,22,"unknown"],[604,23,"unknown"],[604,24,"unknown"],[604,25,"unknown"],[604,26,"unknown"],[604,27,"catchable"],[604,28,"catchable"],[604,29,"catchable"],[604,30,"catchable"],[604,31,"unknown"],[604,32,"unknown"],[604,40,"unknown"],[604,41,"unknown"],[604,42,"unknown"],[604,43,"unknown"],[604,47,"unknown"],[604,48,"unknown"],[604,49,"unknown"],[604,52,"unknown"],[604,53,"unknown"],[605,17,"catchable"],[605,18,"catchable"],[605,21,"catchable"],[605,22,"catchable"],[605,23,"unknown"],[605,24,"unknown"],[605,25,"unknown"],[605,26,"unknown"],[605,27,"unknown"],[605,28,"unknown"],[605,29,"catchable"],[605,30,"catchable"],[605,31,"unknown"],[605,32,"unknown"],[605,33,"catchable"],[605,34,"catchable"],[605,35,"catchable"],[605,36,"unknown"],[605,37,"unknown"],[605,38,"unknown"],[605,39,"unknown"],[605,50,"catchable"],[606,17,"catchable"],[606,18,"catchable"],[606,21,"unknown"],[606,22,"unknown"],[606,23,"unknown"],[606,24,"unknown"],[606,25,"unknown"],[606,26,"unknown"],[606,27,"unknown"],[606,28,"unknown"],[606,29,"unknown"],[606,30,"unknown"],[606,31,"unknown"],[606,32,"unknown"],[606,33,"catchable"],[606,34,"catchable"],[606,35,"catchable"],[606,36,"catchable"],[606,37,"unknown"],[606,38,"unknown"],[606,39,"unknown"],[606,50,"catchable"],[606,51,"catchable"],[607,17,"catchable"],[607,18,"catchable"],[607,21,"catchable"],[607,22,"catchable"],[607,23,"catchable"],[607,24,"catchable"],[607,25,"unknown"],[607,26,"unknown"],[607,27,"catchable"],[607,28,"catchable"],[607,29,"catchable"],[607,30,"catchable"],[607,31,"unknown"],[607,32,"unknown"],[607,33,"catchable"],[607,34,"catchable"],[607,35,"catchable"],[607,36,"unknown"],[607,37,"unknown"],[607,38,"unknown"],[607,39,"unknown"],[607,40,"unknown"],[607,41,"unknown"],[607,42,"unknown"],[607,43,"unknown"],[607,47,"unknown"],[607,48,"unknown"],[607,50,"catchable"],[607,51,"unknown"],[607,52,"unknown"],[608,17,"unknown"],[608,18,"unknown"],[608,21,"unknown"],[608,22,"unknown"],[608,23,"catchable"],[608,24,"catchable"],[608,25,"unknown"],[608,26,"unknown"],[608,27,"unknown"],[608,28,"unknown"],[608,29,"unknown"],[608,30,"unknown"],[608,31,"unknown"],[608,32,"unknown"],[608,33,"catchable"],[608,34,"catchable"],[608,35,"unknown"],[608,36,"catchable"],[608,37,"unknown"],[608,38,"unknown"],[608,39,"unknown"],[608,40,"unknown"],[608,41,"unknown"],[608,42,"unknown"],[608,43,"unknown"],[608,47,"unknown"],[608,48,"unknown"],[608,51,"catchable"],[608,52,"unknown"],[609,17,"unknown"],[609,18,"unknown"],[609,21,"unknown"],[609,22,"unknown"],[609,23,"unknown"],[609,24,"unknown"],[609,25,"unknown"],[609,26,"unknown"],[609,27,"unknown"],[609,28,"unknown"],[609,29,"unknown"],[609,30,"unknown"],[609,31,"unknown"],[609,32,"unknown"],[609,33,"catchable"],[609,34,"catchable"],[609,35,"catchable"],[609,36,"catchable"],[609,37,"unknown"],[609,38,"unknown"],[609,39,"unknown"],[609,40,"unknown"],[609,41,"unknown"],[609,42,"unknown"],[609,43,"unknown"],[609,47,"unknown"],[609,48,"unknown"],[609,49,"unknown"],[609,50,"catchable"],[609,51,"catchable"],[609,52,"unknown"],[610,17,"catchable"],[610,18,"catchable"],[610,21,"catchable"],[610,22,"catchable"],[610,23,"catchable"],[610,24,"catchable"],[610,25,"unknown"],[610,26,"unknown"],[610,27,"catchable"],[610,28,"catchable"],[610,29,"catchable"],[610,30,"catchable"],[610,31,"unknown"],[610,32,"unknown"],[610,33,"catchable"],[610,34,"catchable"],[610,35,"unknown"],[610,36,"unknown"],[610,37,"unknown"],[610,38,"unknown"],[610,39,"unknown"],[610,40,"unknown"],[610,41,"unknown"],[610,42,"unknown"],[610,43,"unknown"],[610,47,"unknown"],[610,48,"unknown"],[610,53,"unknown"],[611,17,"catchable"],[611,18,"catchable"],[611,21,"catchable"],[611,22,"catchable"],[611,23,"catchable"],[611,24,"catchable"],[611,25,"unknown"],[611,26,"unknown"],[611,27,"unknown"],[611,28,"unknown"],[611,29,"unknown"],[611,30,"unknown"],[611,31,"unknown"],[611,32,"unknown"],[611,33,"catchable"],[611,34,"catchable"],[611,35,"unknown"],[611,36,"catchable"],[611,37,"unknown"],[611,38,"unknown"],[611,39,"unknown"],[611,40,"unknown"],[611,41,"unknown"],[611,42,"unknown"],[611,43,"unknown"],[611,47,"unknown"],[611,48,"unknown"],[611,51,"catchable"],[611,53,"unknown"],[612,17,"unknown"],[612,18,"unknown"],[612,21,"catchable"],[612,22,"catchable"],[612,23,"unknown"],[612,24,"unknown"],[612,25,"unknown"],[612,26,"unknown"],[612,27,"unknown"],[612,28,"unknown"],[612,29,"unknown"],[612,30,"unknown"],[612,31,"unknown"],[612,32,"unknown"],[612,33,"catchable"],[612,34,"catchable"],[612,35,"unknown"],[612,36,"unknown"],[612,37,"unknown"],[612,38,"unknown"],[612,39,"unknown"],[612,40,"unknown"],[612,41,"unknown"],[612,42,"unknown"],[612,43,"unknown"],[612,47,"unknown"],[612,48,"unknown"],[612,53,"unknown"],[613,17,"catchable"],[613,18,"catchable"],[613,21,"catchable"],[613,22,"catchable"],[613,23,"catchable"],[613,24,"catchable"],[613,25,"unknown"],[613,26,"unknown"],[613,27,"unknown"],[613,28,"unknown"],[613,29,"unknown"],[613,30,"unknown"],[613,31,"unknown"],[613,32,"unknown"],[613,33,"catchable"],[613,34,"catchable"],[613,35,"unknown"],[613,36,"catchable"],[613,37,"unknown"],[613,38,"unknown"],[613,39,"unknown"],[613,40,"unknown"],[613,41,"unknown"],[613,42,"unknown"],[613,43,"unknown"],[613,47,"unknown"],[613,48,"unknown"],[613,51,"unknown"],[613,53,"unknown"],[614,17,"catchable"],[614,18,"catchable"],[614,21,"catchable"],[614,22,"catchable"],[614,23,"catchable"],[614,24,"catchable"],[614,25,"unknown"],[614,26,"unknown"],[614,27,"unknown"],[614,28,"unknown"],[614,29,"unknown"],[614,30,"unknown"],[614,31,"unknown"],[614,32,"unknown"],[614,33,"catchable"],[614,34,"catchable"],[614,35,"catchable"],[614,36,"catchable"],[614,37,"unknown"],[614,38,"unknown"],[614,39,"unknown"],[614,40,"unknown"],[614,41,"unknown"],[614,42,"unknown"],[614,43,"unknown"],[614,47,"unknown"],[614,48,"unknown"],[614,49,"unknown"],[614,50,"catchable"],[614,51,"catchable"],[614,53,"unknown"],[615,17,"catchable"],[615,18,"catchable"],[615,21,"catchable"],[615,22,"catchable"],[615,23,"catchable"],[615,24,"catchable"],[615,25,"unknown"],[615,26,"unknown"],[615,27,"unknown"],[615,28,"unknown"],[615,29,"unknown"],[615,30,"unknown"],[615,31,"unknown"],[615,32,"unknown"],[615,33,"unknown"],[615,34,"unknown"],[615,35,"unknown"],[615,36,"catchable"],[615,37,"unknown"],[615,38,"unknown"],[615,39,"unknown"],[615,40,"unknown"],[615,41,"unknown"],[615,42,"unknown"],[615,43,"unknown"],[615,47,"unknown"],[615,48,"unknown"],[615,51,"catchable"],[616,17,"catchable"],[616,18,"catchable"],[616,21,"catchable"],[616,22,"catchable"],[616,23,"catchable"],[616,24,"catchable"],[616,25,"unknown"],[616,26,"unknown"],[616,27,"unknown"],[616,28,"unknown"],[616,29,"unknown"],[616,30,"unknown"],[616,31,"unknown"],[616,32,"unknown"],[616,33,"catchable"],[616,34,"catchable"],[616,35,"catchable"],[616,36,"catchable"],[616,37,"unknown"],[616,38,"unknown"],[616,39,"unknown"],[616,50,"catchable"],[616,51,"catchable"],[617,17,"unknown"],[617,18,"unknown"],[617,21,"unknown"],[617,22,"unknown"],[617,23,"unknown"],[617,24,"unknown"],[617,25,"unknown"],[617,26,"unknown"],[617,27,"unknown"],[617,28,"unknown"],[617,29,"unknown"],[617,30,"unknown"],[617,31,"unknown"],[617,32,"unknown"],[617,33,"unknown"],[617,34,"catchable"],[617,35,"catchable"],[617,36,"catchable"],[617,37,"unknown"],[617,38,"unknown"],[617,39,"unknown"],[617,50,"catchable"],[617,51,"catchable"],[618,17,"catchable"],[618,18,"catchable"],[618,21,"catchable"],[618,22,"catchable"],[618,23,"catchable"],[618,24,"catchable"],[618,25,"unknown"],[618,26,"unknown"],[618,27,"unknown"],[618,28,"unknown"],[618,29,"catchable"],[618,30,"catchable"],[618,31,"unknown"],[618,32,"unknown"],[618,33,"catchable"],[618,34,"catchable"],[618,35,"catchable"],[618,36,"catchable"],[618,37,"unknown"],[618,38,"unknown"],[618,39,"unknown"],[618,47,"unknown"],[618,49,"unknown"],[618,50,"catchable"],[618,51,"catchable"],[619,17,"catchable"],[619,18,"catchable"],[619,21,"catchable"],[619,22,"catchable"],[619,23,"catchable"],[619,24,"catchable"],[619,25,"unknown"],[619,26,"unknown"],[619,27,"unknown"],[619,28,"unknown"],[619,29,"catchable"],[619,30,"catchable"],[619,31,"unknown"],[619,32,"unknown"],[619,33,"unknown"],[619,34,"unknown"],[619,35,"catchable"],[619,36,"unknown"],[619,37,"unknown"],[619,38,"unknown"],[619,39,"unknown"],[619,40,"unknown"],[619,41,"unknown"],[619,42,"unknown"],[619,43,"unknown"],[619,47,"unknown"],[619,48,"unknown"],[619,50,"catchable"],[619,52,"unknown"],[620,17,"catchable"],[620,18,"catchable"],[620,21,"catchable"],[620,22,"catchable"],[620,23,"unknown"],[620,24,"unknown"],[620,25,"unknown"],[620,26,"unknown"],[620,27,"unknown"],[620,28,"unknown"],[620,29,"unknown"],[620,30,"unknown"],[620,31,"unknown"],[620,32,"unknown"],[620,33,"unknown"],[620,34,"unknown"],[620,35,"catchable"],[620,36,"catchable"],[620,37,"unknown"],[620,38,"unknown"],[620,39,"unknown"],[620,40,"unknown"],[620,41,"unknown"],[620,42,"unknown"],[620,43,"unknown"],[620,47,"unknown"],[620,48,"unknown"],[620,50,"catchable"],[620,51,"catchable"],[620,52,"unknown"],[621,17,"catchable"],[621,18,"catchable"],[621,21,"catchable"],[621,22,"catchable"],[621,23,"catchable"],[621,24,"catchable"],[621,25,"unknown"],[621,26,"unknown"],[621,27,"unknown"],[621,28,"unknown"],[621,29,"catchable"],[621,30,"catchable"],[621,31,"unknown"],[621,32,"unknown"],[621,33,"unknown"],[621,34,"unknown"],[621,35,"catchable"],[621,36,"catchable"],[621,37,"unknown"],[621,38,"unknown"],[621,39,"unknown"],[621,50,"catchable"],[621,51,"catchable"],[622,17,"catchable"],[622,18,"catchable"],[622,21,"unknown"],[622,22,"unknown"],[622,23,"catchable"],[622,24,"catchable"],[622,25,"unknown"],[622,26,"unknown"],[622,27,"unknown"],[622,28,"unknown"],[622,29,"catchable"],[622,30,"unknown"],[622,31,"unknown"],[622,32,"unknown"],[622,33,"catchable"],[622,34,"catchable"],[622,35,"unknown"],[622,36,"catchable"],[622,37,"unknown"],[622,38,"unknown"],[622,39,"unknown"],[622,40,"unknown"],[622,41,"unknown"],[622,42,"unknown"],[622,43,"unknown"],[622,47,"unknown"],[622,48,"unknown"],[622,51,"catchable"],[622,53,"unknown"],[623,17,"unknown"],[623,18,"unknown"],[623,21,"catchable"],[623,22,"catchable"],[623,23,"catchable"],[623,24,"catchable"],[623,25,"unknown"],[623,26,"unknown"],[623,27,"unknown"],[623,28,"unknown"],[623,29,"unknown"],[623,30,"unknown"],[623,31,"unknown"],[623,32,"unknown"],[623,33,"catchable"],[623,34,"catchable"],[623,35,"catchable"],[623,36,"catchable"],[623,37,"unknown"],[623,38,"unknown"],[623,39,"unknown"],[623,40,"unknown"],[623,41,"unknown"],[623,42,"unknown"],[623,43,"unknown"],[623,47,"unknown"],[623,48,"unknown"],[623,49,"unknown"],[623,50,"catchable"],[623,51,"catchable"],[623,53,"unknown"],[624,17,"catchable"],[624,18,"catchable"],[624,21,"catchable"],[624,22,"catchable"],[624,23,"catchable"],[624,24,"catchable"],[624,25,"unknown"],[624,26,"unknown"],[624,27,"unknown"],[624,28,"unknown"],[624,29,"catchable"],[624,30,"catchable"],[624,31,"unknown"],[624,32,"unknown"],[624,33,"catchable"],[624,34,"catchable"],[624,35,"catchable"],[624,36,"unknown"],[624,37,"unknown"],[624,38,"unknown"],[624,39,"unknown"],[624,40,"unknown"],[624,41,"unknown"],[624,42,"unknown"],[624,43,"unknown"],[624,47,"unknown"],[624,48,"unknown"],[624,50,"catchable"],[624,52,"unknown"],[625,17,"catchable"],[625,18,"catchable"],[625,21,"unknown"],[625,22,"unknown"],[625,23,"unknown"],[625,24,"unknown"],[625,25,"unknown"],[625,26,"unknown"],[625,27,"unknown"],[625,28,"unknown"],[625,29,"catchable"],[625,30,"catchable"],[625,31,"unknown"],[625,32,"unknown"],[625,33,"catchable"],[625,34,"catchable"],[625,35,"catchable"],[625,36,"catchable"],[625,37,"unknown"],[625,38,"unknown"],[625,39,"unknown"],[625,40,"unknown"],[625,41,"unknown"],[625,42,"unknown"],[625,43,"unknown"],[625,47,"unknown"],[625,48,"unknown"],[625,50,"catchable"],[625,51,"catchable"],[625,52,"unknown"],[626,17,"catchable"],[626,18,"catchable"],[626,21,"catchable"],[626,22,"catchable"],[626,23,"unknown"],[626,24,"unknown"],[626,25,"unknown"],[626,26,"unknown"],[626,27,"unknown"],[626,28,"unknown"],[626,29,"unknown"],[626,30,"unknown"],[626,31,"unknown"],[626,32,"unknown"],[626,33,"unknown"],[626,34,"unknown"],[626,35,"catchable"],[626,36,"catchable"],[626,37,"unknown"],[626,38,"unknown"],[626,39,"unknown"],[626,50,"catchable"],[626,51,"catchable"],[627,17,"unknown"],[627,18,"catchable"],[627,21,"unknown"],[627,22,"catchable"],[627,23,"catchable"],[627,24,"catchable"],[627,25,"catchable"],[627,26,"catchable"],[627,27,"catchable"],[627,28,"unknown"],[627,29,"catchable"],[627,30,"unknown"],[627,31,"unknown"],[627,32,"unknown"],[627,33,"catchable"],[627,34,"unknown"],[627,35,"catchable"],[627,36,"unknown"],[627,37,"unknown"],[627,38,"unknown"],[627,39,"unknown"],[627,40,"unknown"],[627,41,"unknown"],[627,42,"unknown"],[627,43,"unknown"],[627,47,"unknown"],[627,48,"unknown"],[627,50,"unknown"],[627,53,"unknown"],[628,17,"unknown"],[628,18,"catchable"],[628,21,"unknown"],[628,22,"catchable"],[628,23,"unknown"],[628,24,"unknown"],[628,25,"unknown"],[628,26,"unknown"],[628,27,"catchable"],[628,28,"unknown"],[628,29,"catchable"],[628,30,"unknown"],[628,31,"unknown"],[628,32,"unknown"],[628,33,"catchable"],[628,34,"unknown"],[628,35,"catchable"],[628,36,"unknown"],[628,37,"unknown"],[628,38,"unknown"],[628,39,"unknown"],[628,40,"unknown"],[628,41,"unknown"],[628,42,"unknown"],[628,43,"unknown"],[628,47,"unknown"],[628,48,"unknown"],[628,50,"unknown"],[628,53,"unknown"],[629,17,"catchable"],[629,18,"unknown"],[629,21,"catchable"],[629,22,"unknown"],[629,23,"catchable"],[629,24,"catchable"],[629,25,"catchable"],[629,26,"catchable"],[629,27,"unknown"],[629,28,"catchable"],[629,29,"unknown"],[629,30,"catchable"],[629,31,"unknown"],[629,32,"unknown"],[629,33,"unknown"],[629,34,"catchable"],[629,35,"unknown"],[629,36,"unknown"],[629,37,"unknown"],[629,38,"unknown"],[629,39,"unknown"],[629,40,"unknown"],[629,41,"unknown"],[629,42,"unknown"],[629,43,"unknown"],[629,47,"unknown"],[629,48,"unknown"],[629,50,"catchable"],[629,52,"unknown"],[629,53,"unknown"],[630,17,"catchable"],[630,18,"unknown"],[630,21,"catchable"],[630,22,"unknown"],[630,23,"unknown"],[630,24,"unknown"],[630,25,"unknown"],[630,26,"unknown"],[630,27,"unknown"],[630,28,"catchable"],[630,29,"unknown"],[630,30,"catchable"],[630,31,"unknown"],[630,32,"unknown"],[630,33,"unknown"],[630,34,"catchable"],[630,35,"unknown"],[630,36,"unknown"],[630,37,"unknown"],[630,38,"unknown"],[630,39,"unknown"],[630,40,"unknown"],[630,41,"unknown"],[630,42,"unknown"],[630,43,"unknown"],[630,47,"unknown"],[630,48,"unknown"],[630,50,"catchable"],[630,52,"unknown"],[630,53,"unknown"],[631,17,"catchable"],[631,18,"catchable"],[631,21,"catchable"],[631,22,"catchable"],[631,23,"catchable"],[631,24,"catchable"],[631,25,"unknown"],[631,26,"unknown"],[631,27,"unknown"],[631,28,"unknown"],[631,29,"unknown"],[631,30,"unknown"],[631,31,"unknown"],[631,32,"unknown"],[631,33,"catchable"],[631,34,"catchable"],[631,35,"unknown"],[631,36,"catchable"],[631,37,"unknown"],[631,38,"unknown"],[631,39,"unknown"],[631,51,"catchable"],[632,17,"catchable"],[632,18,"catchable"],[632,21,"catchable"],[632,22,"catchable"],[632,23,"catchable"],[632,24,"catchable"],[632,25,"unknown"],[632,26,"unknown"],[632,27,"unknown"],[632,28,"unknown"],[632,29,"unknown"],[632,30,"unknown"],[632,31,"unknown"],[632,32,"unknown"],[632,33,"catchable"],[632,34,"catchable"],[632,35,"unknown"],[632,36,"catchable"],[632,37,"unknown"],[632,38,"unknown"],[632,39,"unknown"],[632,51,"catchable"],[633,17,"catchable"],[633,18,"catchable"],[633,21,"unknown"],[633,22,"unknown"],[633,23,"unknown"],[633,24,"unknown"],[633,25,"unknown"],[633,26,"unknown"],[633,27,"catchable"],[633,28,"catchable"],[633,29,"unknown"],[633,30,"unknown"],[633,31,"unknown"],[633,32,"unknown"],[633,33,"catchable"],[633,34,"unknown"],[633,35,"unknown"],[633,36,"catchable"],[633,37,"unknown"],[633,38,"unknown"],[633,39,"unknown"],[633,40,"unknown"],[633,41,"unknown"],[633,42,"unknown"],[633,43,"unknown"],[633,47,"unknown"],[633,48,"unknown"],[633,51,"unknown"],[634,17,"unknown"],[634,18,"unknown"],[634,21,"catchable"],[634,22,"catchable"],[634,23,"catchable"],[634,24,"catchable"],[634,25,"unknown"],[634,26,"unknown"],[634,27,"unknown"],[634,28,"unknown"],[634,29,"unknown"],[634,30,"unknown"],[634,31,"unknown"],[634,32,"unknown"],[634,33,"catchable"],[634,34,"unknown"],[634,35,"unknown"],[634,36,"unknown"],[634,37,"unknown"],[634,38,"unknown"],[634,39,"unknown"],[634,40,"unknown"],[634,41,"unknown"],[634,42,"unknown"],[634,43,"unknown"],[634,47,"unknown"],[634,48,"unknown"],[634,51,"unknown"],[635,17,"unknown"],[635,18,"unknown"],[635,21,"unknown"],[635,22,"unknown"],[635,23,"catchable"],[635,24,"catchable"],[635,25,"unknown"],[635,26,"unknown"],[635,27,"unknown"],[635,28,"unknown"],[635,29,"unknown"],[635,30,"unknown"],[635,31,"unknown"],[635,32,"unknown"],[635,33,"catchable"],[635,34,"unknown"],[635,35,"unknown"],[635,36,"catchable"],[635,37,"unknown"],[635,38,"unknown"],[635,39,"unknown"],[635,40,"unknown"],[635,41,"unknown"],[635,42,"unknown"],[635,43,"unknown"],[635,47,"unknown"],[635,48,"unknown"],[635,49,"unknown"],[635,51,"unknown"],[636,17,"catchable"],[636,18,"catchable"],[636,21,"unknown"],[636,22,"unknown"],[636,23,"catchable"],[636,24,"catchable"],[636,25,"catchable"],[636,26,"catchable"],[636,27,"unknown"],[636,28,"unknown"],[636,29,"catchable"],[636,30,"catchable"],[636,31,"unknown"],[636,32,"unknown"],[636,33,"unknown"],[636,34,"unknown"],[636,35,"catchable"],[636,36,"unknown"],[636,37,"unknown"],[636,38,"unknown"],[636,39,"unknown"],[636,40,"unknown"],[636,41,"unknown"],[636,42,"unknown"],[636,43,"unknown"],[636,47,"unknown"],[636,48,"unknown"],[636,50,"catchable"],[637,17,"catchable"],[637,18,"catchable"],[637,21,"catchable"],[637,22,"catchable"],[637,23,"unknown"],[637,24,"unknown"],[637,25,"unknown"],[637,26,"unknown"],[637,27,"unknown"],[637,28,"unknown"],[637,29,"catchable"],[637,30,"catchable"],[637,31,"unknown"],[637,32,"unknown"],[637,33,"unknown"],[637,34,"unknown"],[637,35,"catchable"],[637,36,"unknown"],[637,37,"unknown"],[637,38,"unknown"],[637,39,"unknown"],[637,40,"unknown"],[637,41,"unknown"],[637,42,"unknown"],[637,43,"unknown"],[637,47,"unknown"],[637,48,"unknown"],[637,49,"unknown"],[637,50,"catchable"],[638,17,"catchable"],[638,18,"catchable"],[638,21,"catchable"],[638,22,"catchable"],[638,23,"unknown"],[638,24,"unknown"],[638,25,"catchable"],[638,26,"catchable"],[638,27,"unknown"],[638,28,"unknown"],[638,29,"catchable"],[638,30,"catchable"],[638,31,"unknown"],[638,32,"unknown"],[638,33,"unknown"],[638,34,"unknown"],[638,35,"unknown"],[638,36,"catchable"],[638,37,"unknown"],[638,38,"unknown"],[638,39,"unknown"],[638,40,"unknown"],[638,41,"unknown"],[638,42,"unknown"],[638,43,"unknown"],[638,47,"unknown"],[638,48,"unknown"],[638,51,"catchable"],[639,17,"catchable"],[639,18,"catchable"],[639,21,"catchable"],[639,22,"catchable"],[639,23,"unknown"],[639,24,"unknown"],[639,25,"catchable"],[639,26,"catchable"],[639,27,"unknown"],[639,28,"unknown"],[639,29,"catchable"],[639,30,"catchable"],[639,31,"unknown"],[639,32,"unknown"],[639,33,"unknown"],[639,34,"unknown"],[639,35,"unknown"],[639,36,"catchable"],[639,37,"unknown"],[639,38,"unknown"],[639,39,"unknown"],[639,40,"unknown"],[639,41,"unknown"],[639,42,"unknown"],[639,43,"unknown"],[639,47,"unknown"],[639,48,"unknown"],[639,51,"catchable"],[640,17,"catchable"],[640,18,"catchable"],[640,21,"catchable"],[640,22,"catchable"],[640,23,"unknown"],[640,24,"unknown"],[640,25,"catchable"],[640,26,"catchable"],[640,27,"unknown"],[640,28,"unknown"],[640,29,"catchable"],[640,30,"catchable"],[640,31,"unknown"],[640,32,"unknown"],[640,33,"unknown"],[640,34,"unknown"],[640,35,"unknown"],[640,36,"catchable"],[640,37,"unknown"],[640,38,"unknown"],[640,39,"unknown"],[640,40,"unknown"],[640,41,"unknown"],[640,42,"unknown"],[640,43,"unknown"],[640,47,"unknown"],[640,48,"unknown"],[640,51,"catchable"],[641,17,"catchable"],[641,18,"unknown"],[641,21,"unknown"],[641,22,"unknown"],[641,23,"unknown"],[641,24,"unknown"],[641,25,"catchable"],[641,26,"unknown"],[641,27,"unknown"],[641,28,"unknown"],[641,29,"catchable"],[641,30,"unknown"],[641,31,"unknown"],[641,32,"unknown"],[641,33,"unknown"],[641,34,"unknown"],[641,35,"unknown"],[641,36,"catchable"],[641,37,"unknown"],[641,38,"unknown"],[641,39,"unknown"],[641,40,"unknown"],[641,41,"unknown"],[641,42,"unknown"],[641,43,"unknown"],[641,47,"unknown"],[641,48,"unknown"],[642,17,"unknown"],[642,18,"catchable"],[642,21,"unknown"],[642,22,"unknown"],[642,23,"unknown"],[642,24,"unknown"],[642,25,"unknown"],[642,26,"catchable"],[642,27,"unknown"],[642,28,"unknown"],[642,29,"unknown"],[642,30,"catchable"],[642,31,"unknown"],[642,32,"unknown"],[642,33,"unknown"],[642,34,"unknown"],[642,35,"unknown"],[642,36,"unknown"],[642,37,"unknown"],[642,38,"unknown"],[642,39,"unknown"],[642,40,"unknown"],[642,41,"unknown"],[642,42,"unknown"],[642,43,"unknown"],[642,47,"unknown"],[642,48,"unknown"],[642,51,"catchable"],[643,17,"catchable"],[643,18,"unknown"],[643,21,"unknown"],[643,22,"catchable"],[643,23,"unknown"],[643,24,"unknown"],[643,25,"catchable"],[643,26,"unknown"],[643,27,"unknown"],[643,28,"unknown"],[643,29,"catchable"],[643,30,"unknown"],[643,31,"unknown"],[643,32,"unknown"],[643,33,"unknown"],[643,34,"unknown"],[643,35,"unknown"],[643,36,"catchable"],[643,37,"unknown"],[643,38,"unknown"],[643,39,"unknown"],[643,40,"unknown"],[643,41,"unknown"],[643,42,"unknown"],[643,43,"unknown"],[643,47,"unknown"],[643,48,"unknown"],[644,17,"unknown"],[644,18,"catchable"],[644,21,"catchable"],[644,22,"unknown"],[644,23,"unknown"],[644,24,"unknown"],[644,25,"unknown"],[644,26,"catchable"],[644,27,"unknown"],[644,28,"unknown"],[644,29,"unknown"],[644,30,"catchable"],[644,31,"unknown"],[644,32,"unknown"],[644,33,"unknown"],[644,34,"unknown"],[644,35,"unknown"],[644,36,"unknown"],[644,37,"unknown"],[644,38,"unknown"],[644,39,"unknown"],[644,40,"unknown"],[644,41,"unknown"],[644,42,"unknown"],[644,43,"unknown"],[644,47,"unknown"],[644,48,"unknown"],[644,51,"catchable"],[645,17,"catchable"],[645,18,"catchable"],[645,21,"unknown"],[645,22,"unknown"],[645,23,"unknown"],[645,24,"unknown"],[645,25,"catchable"],[645,26,"catchable"],[645,27,"unknown"],[645,28,"unknown"],[645,29,"catchable"],[645,30,"catchable"],[645,31,"unknown"],[645,32,"unknown"],[645,33,"unknown"],[645,34,"unknown"],[645,35,"unknown"],[645,36,"catchable"],[645,37,"unknown"],[645,38,"unknown"],[645,39,"unknown"],[645,40,"unknown"],[645,41,"unknown"],[645,42,"unknown"],[645,43,"unknown"],[645,47,"unknown"],[645,48,"unknown"],[645,51,"catchable"],[646,17,"catchable"],[646,18,"catchable"],[646,21,"catchable"],[646,22,"catchable"],[646,23,"unknown"],[646,24,"unknown"],[646,25,"catchable"],[646,26,"catchable"],[646,27,"unknown"],[646,28,"unknown"],[646,29,"catchable"],[646,30,"catchable"],[646,31,"unknown"],[646,32,"unknown"],[646,33,"unknown"],[646,34,"unknown"],[646,35,"unknown"],[646,36,"catchable"],[646,37,"unknown"],[646,38,"unknown"],[646,39,"unknown"],[646,40,"unknown"],[646,41,"unknown"],[646,42,"unknown"],[646,43,"unknown"],[646,47,"unknown"],[646,48,"unknown"],[646,51,"catchable"],[647,17,"unknown"],[647,18,"unknown"],[647,21,"unknown"],[647,22,"unknown"],[647,23,"unknown"],[647,24,"unknown"],[647,25,"unknown"],[647,26,"unknown"],[647,27,"unknown"],[647,28,"unknown"],[647,29,"unknown"],[647,30,"unknown"],[647,31,"unknown"],[647,32,"unknown"],[647,33,"unknown"],[647,34,"unknown"],[647,35,"unknown"],[647,36,"catchable"],[647,37,"unknown"],[647,38,"unknown"],[647,39,"unknown"],[647,40,"unknown"],[647,41,"unknown"],[647,42,"unknown"],[647,43,"unknown"],[647,47,"unknown"],[647,48,"unknown"],[647,51,"catchable"],[648,17,"unknown"],[648,18,"unknown"],[648,21,"unknown"],[648,22,"unknown"],[648,23,"unknown"],[648,24,"unknown"],[648,25,"unknown"],[648,26,"unknown"],[648,27,"unknown"],[648,28,"unknown"],[648,29,"unknown"],[648,30,"unknown"],[648,31,"unknown"],[648,32,"unknown"],[648,40,"unknown"],[648,41,"unknown"],[648,42,"unknown"],[648,43,"unknown"],[648,47,"unknown"],[648,48,"unknown"],[649,17,"unknown"],[649,18,"unknown"],[649,21,"unknown"],[649,22,"unknown"],[649,23,"unknown"],[649,24,"unknown"],[649,25,"unknown"],[649,26,"unknown"],[649,27,"unknown"],[649,28,"unknown"],[649,29,"unknown"],[649,30,"unknown"],[649,31,"unknown"],[649,32,"unknown"],[649,33,"unknown"],[649,34,"unknown"],[649,35,"unknown"],[649,36,"unknown"],[649,37,"unknown"],[649,38,"unknown"],[649,39,"unknown"],[649,47,"unknown"],[649,48,"unknown"],[650,23,"catchable"],[650,24,"catchable"],[650,25,"unknown"],[650,26,"unknown"],[650,27,"unknown"],[650,28,"unknown"],[650,29,"unknown"],[650,30,"unknown"],[650,31,"unknown"],[650,32,"unknown"],[650,40,"unknown"],[650,41,"unknown"],[650,42,"unknown"],[650,43,"unknown"],[650,47,"unknown"],[650,48,"unknown"],[650,53,"unknown"],[651,23,"catchable"],[651,24,"catchable"],[651,25,"unknown"],[651,26,"unknown"],[651,27,"unknown"],[651,28,"unknown"],[651,29,"unknown"],[651,30,"unknown"],[651,31,"unknown"],[651,32,"unknown"],[651,40,"unknown"],[651,41,"unknown"],[651,42,"unknown"],[651,43,"unknown"],[651,47,"unknown"],[651,48,"unknown"],[651,53,"unknown"],[652,23,"unknown"],[652,24,"unknown"],[652,25,"unknown"],[652,26,"unknown"],[652,27,"unknown"],[652,28,"unknown"],[652,29,"catchable"],[652,30,"catchable"],[652,31,"unknown"],[652,32,"unknown"],[652,40,"unknown"],[652,41,"unknown"],[652,42,"unknown"],[652,43,"unknown"],[652,47,"unknown"],[652,48,"unknown"],[652,49,"unknown"],[652,53,"unknown"],[653,23,"catchable"],[653,24,"catchable"],[653,25,"unknown"],[653,26,"unknown"],[653,27,"unknown"],[653,28,"unknown"],[653,29,"unknown"],[653,30,"unknown"],[653,31,"unknown"],[653,32,"unknown"],[653,40,"unknown"],[653,41,"unknown"],[653,42,"unknown"],[653,43,"unknown"],[653,47,"unknown"],[653,48,"unknown"],[653,53,"unknown"],[654,23,"catchable"],[654,24,"catchable"],[654,25,"unknown"],[654,26,"unknown"],[654,27,"unknown"],[654,28,"unknown"],[654,29,"unknown"],[654,30,"unknown"],[654,31,"unknown"],[654,32,"unknown"],[654,40,"unknown"],[654,41,"unknown"],[654,42,"unknown"],[654,43,"unknown"],[654,47,"unknown"],[654,48,"unknown"],[654,53,"unknown"],[655,23,"unknown"],[655,24,"unknown"],[655,25,"unknown"],[655,26,"unknown"],[655,27,"unknown"],[655,28,"unknown"],[655,29,"catchable"],[655,30,"catchable"],[655,31,"unknown"],[655,32,"unknown"],[655,40,"unknown"],[655,41,"unknown"],[655,42,"unknown"],[655,43,"unknown"],[655,47,"unknown"],[655,48,"unknown"],[655,49,"unknown"],[655,53,"unknown"],[656,23,"catchable"],[656,24,"catchable"],[656,25,"unknown"],[656,26,"unknown"],[656,27,"unknown"],[656,28,"unknown"],[656,29,"unknown"],[656,30,"unknown"],[656,31,"unknown"],[656,32,"unknown"],[656,40,"unknown"],[656,41,"unknown"],[656,42,"unknown"],[656,43,"unknown"],[656,47,"unknown"],[656,48,"unknown"],[656,53,"unknown"],[657,23,"catchable"],[657,24,"catchable"],[657,25,"unknown"],[657,26,"unknown"],[657,27,"unknown"],[657,28,"unknown"],[657,29,"unknown"],[657,30,"unknown"],[657,31,"unknown"],[657,32,"unknown"],[657,40,"unknown"],[657,41,"unknown"],[657,42,"unknown"],[657,43,"unknown"],[657,47,"unknown"],[657,48,"unknown"],[657,53,"unknown"],[658,23,"unknown"],[658,24,"unknown"],[658,25,"unknown"],[658,26,"unknown"],[658,27,"unknown"],[658,28,"unknown"],[658,29,"catchable"],[658,30,"catchable"],[658,31,"unknown"],[658,32,"unknown"],[658,40,"unknown"],[658,41,"unknown"],[658,42,"unknown"],[658,43,"unknown"],[658,47,"unknown"],[658,48,"unknown"],[658,49,"unknown"],[658,53,"unknown"],[659,23,"catchable"],[659,24,"catchable"],[659,25,"unknown"],[659,26,"unknown"],[659,27,"unknown"],[659,28,"unknown"],[659,29,"unknown"],[659,30,"unknown"],[659,31,"unknown"],[659,32,"unknown"],[659,33,"catchable"],[659,34,"catchable"],[659,35,"unknown"],[659,36,"unknown"],[659,37,"unknown"],[659,38,"unknown"],[659,39,"unknown"],[659,47,"unknown"],[660,23,"catchable"],[660,24,"catchable"],[660,25,"unknown"],[660,26,"unknown"],[660,27,"unknown"],[660,28,"unknown"],[660,29,"unknown"],[660,30,"unknown"],[660,31,"unknown"],[660,32,"unknown"],[660,33,"catchable"],[660,34,"catchable"],[660,35,"unknown"],[660,36,"catchable"],[660,37,"unknown"],[660,38,"unknown"],[660,39,"unknown"],[660,47,"unknown"],[660,49,"unknown"],[660,51,"catchable"],[661,23,"catchable"],[661,24,"catchable"],[661,25,"unknown"],[661,26,"unknown"],[661,27,"catchable"],[661,28,"catchable"],[661,29,"catchable"],[661,30,"catchable"],[661,31,"unknown"],[661,32,"unknown"],[661,33,"unknown"],[661,34,"unknown"],[661,35,"catchable"],[661,36,"unknown"],[661,37,"unknown"],[661,38,"unknown"],[661,39,"unknown"],[661,40,"unknown"],[661,41,"unknown"],[661,42,"unknown"],[661,43,"unknown"],[661,47,"unknown"],[661,48,"unknown"],[661,50,"catchable"],[661,53,"unknown"],[662,23,"catchable"],[662,24,"catchable"],[662,25,"unknown"],[662,26,"unknown"],[662,27,"catchable"],[662,28,"catchable"],[662,29,"catchable"],[662,30,"catchable"],[662,31,"unknown"],[662,32,"unknown"],[662,33,"unknown"],[662,34,"unknown"],[662,35,"catchable"],[662,36,"unknown"],[662,37,"unknown"],[662,38,"unknown"],[662,39,"unknown"],[662,40,"unknown"],[662,41,"unknown"],[662,42,"unknown"],[662,43,"unknown"],[662,47,"unknown"],[662,48,"unknown"],[662,50,"catchable"],[662,53,"unknown"],[663,23,"unknown"],[663,24,"unknown"],[663,25,"unknown"],[663,26,"unknown"],[663,27,"catchable"],[663,28,"catchable"],[663,29,"unknown"],[663,30,"unknown"],[663,31,"unknown"],[663,32,"unknown"],[663,33,"unknown"],[663,34,"unknown"],[663,35,"catchable"],[663,36,"catchable"],[663,37,"unknown"],[663,38,"unknown"],[663,39,"unknown"],[663,40,"unknown"],[663,41,"unknown"],[663,42,"unknown"],[663,43,"unknown"],[663,47,"unknown"],[663,48,"unknown"],[663,49,"unknown"],[663,50,"catchable"],[663,51,"catchable"],[663,53,"unknown"],[664,23,"catchable"],[664,24,"catchable"],[664,25,"unknown"],[664,26,"unknown"],[664,27,"unknown"],[664,28,"unknown"],[664,29,"catchable"],[664,30,"catchable"],[664,31,"unknown"],[664,32,"unknown"],[664,40,"unknown"],[664,41,"unknown"],[664,42,"unknown"],[664,43,"unknown"],[664,47,"unknown"],[664,48,"unknown"],[665,23,"catchable"],[665,24,"catchable"],[665,25,"unknown"],[665,26,"unknown"],[665,27,"unknown"],[665,28,"unknown"],[665,29,"unknown"],[665,30,"unknown"],[665,31,"unknown"],[665,32,"unknown"],[665,40,"unknown"],[665,41,"unknown"],[665,42,"unknown"],[665,43,"unknown"],[665,47,"unknown"],[665,48,"unknown"],[666,23,"catchable"],[666,24,"catchable"],[666,25,"unknown"],[666,26,"unknown"],[666,27,"unknown"],[666,28,"unknown"],[666,29,"unknown"],[666,30,"unknown"],[666,31,"unknown"],[666,32,"unknown"],[666,40,"unknown"],[666,41,"unknown"],[666,42,"unknown"],[666,43,"unknown"],[666,47,"unknown"],[666,48,"unknown"],[666,49,"unknown"],[667,23,"catchable"],[667,24,"catchable"],[667,25,"unknown"],[667,26,"unknown"],[667,27,"unknown"],[667,28,"unknown"],[667,29,"catchable"],[667,30,"catchable"],[667,31,"unknown"],[667,32,"unknown"],[667,40,"unknown"],[667,41,"unknown"],[667,42,"unknown"],[667,43,"unknown"],[667,47,"unknown"],[667,48,"unknown"],[667,53,"unknown"],[668,23,"catchable"],[668,24,"catchable"],[668,25,"unknown"],[668,26,"unknown"],[668,27,"unknown"],[668,28,"unknown"],[668,29,"catchable"],[668,30,"catchable"],[668,31,"unknown"],[668,32,"unknown"],[668,40,"unknown"],[668,41,"unknown"],[668,42,"unknown"],[668,43,"unknown"],[668,47,"unknown"],[668,48,"unknown"],[668,49,"unknown"],[668,53,"unknown"],[669,23,"catchable"],[669,24,"catchable"],[669,25,"unknown"],[669,26,"unknown"],[669,27,"unknown"],[669,28,"unknown"],[669,29,"catchable"],[669,30,"catchable"],[669,31,"unknown"],[669,32,"unknown"],[669,40,"unknown"],[669,41,"unknown"],[669,42,"unknown"],[669,43,"unknown"],[669,47,"unknown"],[669,48,"unknown"],[670,23,"catchable"],[670,24,"catchable"],[670,25,"unknown"],[670,26,"unknown"],[670,27,"unknown"],[670,28,"unknown"],[670,29,"catchable"],[670,30,"catchable"],[670,31,"unknown"],[670,32,"unknown"],[670,40,"unknown"],[670,41,"unknown"],[670,42,"unknown"],[670,43,"unknown"],[670,47,"unknown"],[670,48,"unknown"],[670,49,"unknown"],[671,23,"unknown"],[671,24,"unknown"],[671,25,"unknown"],[671,26,"unknown"],[671,27,"unknown"],[671,28,"unknown"],[671,29,"unknown"],[671,30,"unknown"],[671,31,"unknown"],[671,32,"unknown"],[671,40,"unknown"],[671,41,"unknown"],[671,42,"unknown"],[671,43,"unknown"],[671,47,"unknown"],[671,48,"unknown"],[671,49,"unknown"],[672,23,"catchable"],[672,24,"catchable"],[672,25,"unknown"],[672,26,"unknown"],[672,27,"unknown"],[672,28,"unknown"],[672,29,"unknown"],[672,30,"unknown"],[672,31,"unknown"],[672,32,"unknown"],[672,40,"unknown"],[672,41,"unknown"],[672,42,"unknown"],[672,43,"unknown"],[672,47,"unknown"],[672,48,"unknown"],[673,23,"catchable"],[673,24,"catchable"],[673,25,"unknown"],[673,26,"unknown"],[673,27,"unknown"],[673,28,"unknown"],[673,29,"unknown"],[673,30,"unknown"],[673,31,"unknown"],[673,32,"unknown"],[673,40,"unknown"],[673,41,"unknown"],[673,42,"unknown"],[673,43,"unknown"],[673,47,"unknown"],[673,48,"unknown"],[673,49,"unknown"],[674,23,"catchable"],[674,24,"catchable"],[674,25,"unknown"],[674,26,"unknown"],[674,27,"catchable"],[674,28,"catchable"],[674,29,"catchable"],[674,30,"catchable"],[674,31,"unknown"],[674,32,"unknown"],[674,33,"catchable"],[674,34,"catchable"],[674,35,"unknown"],[674,36,"unknown"],[674,37,"unknown"],[674,38,"unknown"],[674,39,"unknown"],[674,47,"unknown"],[675,23,"unknown"],[675,24,"unknown"],[675,25,"unknown"],[675,26,"unknown"],[675,27,"catchable"],[675,28,"catchable"],[675,29,"catchable"],[675,30,"catchable"],[675,31,"unknown"],[675,32,"unknown"],[675,33,"catchable"],[675,34,"catchable"],[675,35,"unknown"],[675,36,"catchable"],[675,37,"unknown"],[675,38,"unknown"],[675,39,"unknown"],[675,47,"unknown"],[675,49,"unknown"],[675,51,"catchable"],[676,23,"catchable"],[676,24,"catchable"],[676,25,"unknown"],[676,26,"unknown"],[676,27,"unknown"],[676,28,"unknown"],[676,29,"catchable"],[676,30,"catchable"],[676,31,"unknown"],[676,32,"unknown"],[676,47,"unknown"],[676,49,"unknown"],[677,23,"catchable"],[677,24,"catchable"],[677,25,"unknown"],[677,26,"unknown"],[677,27,"unknown"],[677,28,"unknown"],[677,29,"unknown"],[677,30,"unknown"],[677,31,"unknown"],[677,32,"unknown"],[677,33,"catchable"],[677,34,"catchable"],[677,35,"unknown"],[677,36,"unknown"],[677,37,"unknown"],[677,38,"unknown"],[677,39,"unknown"],[677,40,"unknown"],[677,41,"unknown"],[677,42,"unknown"],[677,43,"unknown"],[677,47,"unknown"],[677,48,"unknown"],[677,53,"unknown"],[678,23,"unknown"],[678,24,"unknown"],[678,25,"unknown"],[678,26,"unknown"],[678,27,"unknown"],[678,28,"unknown"],[678,29,"unknown"],[678,30,"unknown"],[678,31,"unknown"],[678,32,"unknown"],[678,33,"catchable"],[678,34,"catchable"],[678,35,"catchable"],[678,36,"unknown"],[678,37,"unknown"],[678,38,"unknown"],[678,39,"unknown"],[678,40,"unknown"],[678,41,"unknown"],[678,42,"unknown"],[678,43,"unknown"],[678,47,"unknown"],[678,48,"unknown"],[678,49,"unknown"],[678,50,"catchable"],[678,53,"unknown"],[679,23,"catchable"],[679,24,"catchable"],[679,25,"unknown"],[679,26,"unknown"],[679,27,"catchable"],[679,28,"catchable"],[679,29,"catchable"],[679,30,"catchable"],[679,31,"unknown"],[679,32,"unknown"],[679,33,"catchable"],[679,34,"catchable"],[679,35,"unknown"],[679,36,"unknown"],[679,37,"unknown"],[679,38,"unknown"],[679,39,"unknown"],[679,47,"unknown"],[680,23,"unknown"],[680,24,"unknown"],[680,25,"unknown"],[680,26,"unknown"],[680,27,"unknown"],[680,28,"unknown"],[680,29,"unknown"],[680,30,"unknown"],[680,31,"unknown"],[680,32,"unknown"],[680,33,"catchable"],[680,34,"catchable"],[680,35,"unknown"],[680,36,"catchable"],[680,37,"unknown"],[680,38,"unknown"],[680,39,"unknown"],[680,47,"unknown"],[680,51,"catchable"],[681,23,"unknown"],[681,24,"unknown"],[681,25,"unknown"],[681,26,"unknown"],[681,27,"unknown"],[681,28,"unknown"],[681,29,"unknown"],[681,30,"unknown"],[681,31,"unknown"],[681,32,"unknown"],[681,33,"catchable"],[681,34,"catchable"],[681,35,"unknown"],[681,36,"unknown"],[681,37,"unknown"],[681,38,"unknown"],[681,39,"unknown"],[681,47,"unknown"],[681,49,"unknown"],[682,23,"catchable"],[682,24,"catchable"],[682,25,"unknown"],[682,26,"unknown"],[682,27,"unknown"],[682,28,"unknown"],[682,29,"unknown"],[682,30,"unknown"],[682,31,"unknown"],[682,32,"unknown"],[682,33,"unknown"],[682,34,"catchable"],[682,35,"unknown"],[682,36,"unknown"],[682,37,"unknown"],[682,38,"unknown"],[682,39,"unknown"],[682,47,"unknown"],[683,23,"unknown"],[683,24,"unknown"],[683,25,"unknown"],[683,26,"unknown"],[683,27,"unknown"],[683,28,"unknown"],[683,29,"unknown"],[683,30,"unknown"],[683,31,"unknown"],[683,32,"unknown"],[683,33,"unknown"],[683,34,"catchable"],[683,35,"unknown"],[683,36,"unknown"],[683,37,"unknown"],[683,38,"unknown"],[683,39,"unknown"],[683,47,"unknown"],[683,49,"unknown"],[684,23,"catchable"],[684,24,"catchable"],[684,25,"unknown"],[684,26,"unknown"],[684,27,"unknown"],[684,28,"unknown"],[684,29,"unknown"],[684,30,"unknown"],[684,31,"unknown"],[684,32,"unknown"],[684,33,"catchable"],[684,34,"unknown"],[684,35,"unknown"],[684,36,"unknown"],[684,37,"unknown"],[684,38,"unknown"],[684,39,"unknown"],[684,47,"unknown"],[685,23,"unknown"],[685,24,"unknown"],[685,25,"unknown"],[685,26,"unknown"],[685,27,"unknown"],[685,28,"unknown"],[685,29,"unknown"],[685,30,"unknown"],[685,31,"unknown"],[685,32,"unknown"],[685,33,"catchable"],[685,34,"unknown"],[685,35,"unknown"],[685,36,"unknown"],[685,37,"unknown"],[685,38,"unknown"],[685,39,"unknown"],[685,47,"unknown"],[685,49,"unknown"],[686,23,"catchable"],[686,24,"catchable"],[686,25,"unknown"],[686,26,"unknown"],[686,27,"unknown"],[686,28,"unknown"],[686,29,"catchable"],[686,30,"catchable"],[686,31,"unknown"],[686,32,"unknown"],[686,33,"catchable"],[686,34,"catchable"],[686,35,"catchable"],[686,36,"unknown"],[686,37,"unknown"],[686,38,"unknown"],[686,39,"unknown"],[686,40,"unknown"],[686,41,"unknown"],[686,42,"unknown"],[686,43,"unknown"],[686,47,"unknown"],[686,48,"unknown"],[686,50,"catchable"],[686,53,"unknown"],[687,23,"unknown"],[687,24,"unknown"],[687,25,"unknown"],[687,26,"unknown"],[687,27,"unknown"],[687,28,"unknown"],[687,29,"unknown"],[687,30,"unknown"],[687,31,"unknown"],[687,32,"unknown"],[687,33,"catchable"],[687,34,"catchable"],[687,35,"catchable"],[687,36,"catchable"],[687,37,"unknown"],[687,38,"unknown"],[687,39,"unknown"],[687,40,"unknown"],[687,41,"unknown"],[687,42,"unknown"],[687,43,"unknown"],[687,47,"unknown"],[687,48,"unknown"],[687,49,"unknown"],[687,50,"catchable"],[687,51,"catchable"],[687,53,"unknown"],[688,23,"catchable"],[688,24,"catchable"],[688,25,"catchable"],[688,26,"catchable"],[688,27,"unknown"],[688,28,"unknown"],[688,29,"unknown"],[688,30,"unknown"],[688,31,"unknown"],[688,32,"unknown"],[688,33,"catchable"],[688,34,"catchable"],[688,35,"catchable"],[688,36,"unknown"],[688,37,"unknown"],[688,38,"unknown"],[688,39,"unknown"],[688,47,"unknown"],[688,50,"catchable"],[689,23,"catchable"],[689,24,"catchable"],[689,25,"unknown"],[689,26,"unknown"],[689,27,"unknown"],[689,28,"unknown"],[689,29,"catchable"],[689,30,"catchable"],[689,31,"unknown"],[689,32,"unknown"],[689,33,"catchable"],[689,34,"catchable"],[689,35,"catchable"],[689,36,"catchable"],[689,37,"unknown"],[689,38,"unknown"],[689,39,"unknown"],[689,47,"unknown"],[689,49,"unknown"],[689,50,"catchable"],[689,51,"catchable"],[690,23,"unknown"],[690,24,"catchable"],[690,25,"unknown"],[690,26,"unknown"],[690,27,"unknown"],[690,28,"unknown"],[690,29,"unknown"],[690,30,"unknown"],[690,31,"unknown"],[690,32,"unknown"],[690,33,"unknown"],[690,34,"unknown"],[690,35,"unknown"],[690,36,"unknown"],[690,37,"unknown"],[690,38,"unknown"],[690,39,"unknown"],[690,40,"unknown"],[690,41,"unknown"],[690,42,"unknown"],[690,43,"unknown"],[690,47,"unknown"],[690,48,"unknown"],[690,50,"catchable"],[691,23,"unknown"],[691,24,"catchable"],[691,25,"unknown"],[691,26,"unknown"],[691,27,"unknown"],[691,28,"unknown"],[691,29,"unknown"],[691,30,"catchable"],[691,31,"unknown"],[691,32,"unknown"],[691,33,"unknown"],[691,34,"unknown"],[691,35,"unknown"],[691,36,"unknown"],[691,37,"unknown"],[691,38,"unknown"],[691,39,"unknown"],[691,40,"unknown"],[691,41,"unknown"],[691,42,"unknown"],[691,43,"unknown"],[691,47,"unknown"],[691,48,"unknown"],[691,49,"unknown"],[691,50,"catchable"],[692,23,"catchable"],[692,24,"unknown"],[692,25,"unknown"],[692,26,"unknown"],[692,27,"unknown"],[692,28,"unknown"],[692,29,"unknown"],[692,30,"unknown"],[692,31,"unknown"],[692,32,"unknown"],[692,33,"unknown"],[692,34,"unknown"],[692,35,"catchable"],[692,36,"unknown"],[692,37,"unknown"],[692,38,"unknown"],[692,39,"unknown"],[692,40,"unknown"],[692,41,"unknown"],[692,42,"unknown"],[692,43,"unknown"],[692,47,"unknown"],[692,48,"unknown"],[692,50,"unknown"],[693,23,"catchable"],[693,24,"unknown"],[693,25,"unknown"],[693,26,"unknown"],[693,27,"unknown"],[693,28,"unknown"],[693,29,"catchable"],[693,30,"unknown"],[693,31,"unknown"],[693,32,"unknown"],[693,33,"unknown"],[693,34,"unknown"],[693,35,"catchable"],[693,36,"unknown"],[693,37,"unknown"],[693,38,"unknown"],[693,39,"unknown"],[693,40,"unknown"],[693,41,"unknown"],[693,42,"unknown"],[693,43,"unknown"],[693,47,"unknown"],[693,48,"unknown"],[693,49,"unknown"],[693,50,"unknown"],[694,23,"catchable"],[694,24,"catchable"],[694,25,"unknown"],[694,26,"unknown"],[694,27,"unknown"],[694,28,"unknown"],[694,29,"unknown"],[694,30,"unknown"],[694,31,"unknown"],[694,32,"unknown"],[694,33,"catchable"],[694,34,"catchable"],[694,35,"unknown"],[694,36,"unknown"],[694,37,"unknown"],[694,38,"unknown"],[694,39,"unknown"],[694,47,"unknown"],[695,23,"unknown"],[695,24,"unknown"],[695,25,"unknown"],[695,26,"unknown"],[695,27,"unknown"],[695,28,"unknown"],[695,29,"catchable"],[695,30,"catchable"],[695,31,"unknown"],[695,32,"unknown"],[695,33,"catchable"],[695,34,"catchable"],[695,35,"unknown"],[695,36,"catchable"],[695,37,"unknown"],[695,38,"unknown"],[695,39,"unknown"],[695,47,"unknown"],[695,49,"unknown"],[695,51,"catchable"],[696,23,"catchable"],[696,24,"catchable"],[696,25,"unknown"],[696,26,"unknown"],[696,27,"unknown"],[696,28,"unknown"],[696,29,"catchable"],[696,30,"catchable"],[696,31,"unknown"],[696,32,"unknown"],[696,33,"unknown"],[696,34,"unknown"],[696,35,"unknown"],[696,36,"catchable"],[696,37,"unknown"],[696,38,"unknown"],[696,39,"unknown"],[696,47,"unknown"],[696,51,"catchable"],[697,23,"unknown"],[697,24,"unknown"],[697,25,"unknown"],[697,26,"unknown"],[697,27,"unknown"],[697,28,"unknown"],[697,29,"unknown"],[697,30,"unknown"],[697,31,"unknown"],[697,32,"unknown"],[697,33,"unknown"],[697,34,"unknown"],[697,35,"unknown"],[697,36,"catchable"],[697,37,"unknown"],[697,38,"unknown"],[697,39,"unknown"],[697,47,"unknown"],[697,49,"unknown"],[697,51,"catchable"],[698,23,"catchable"],[698,24,"catchable"],[698,25,"unknown"],[698,26,"unknown"],[698,27,"unknown"],[698,28,"unknown"],[698,29,"catchable"],[698,30,"catchable"],[698,31,"unknown"],[698,32,"unknown"],[698,33,"unknown"],[698,34,"unknown"],[698,35,"unknown"],[698,36,"catchable"],[698,37,"unknown"],[698,38,"unknown"],[698,39,"unknown"],[698,47,"unknown"],[698,51,"catchable"],[699,23,"unknown"],[699,24,"unknown"],[699,25,"unknown"],[699,26,"unknown"],[699,27,"unknown"],[699,28,"unknown"],[699,29,"unknown"],[699,30,"unknown"],[699,31,"unknown"],[699,32,"unknown"],[699,33,"unknown"],[699,34,"unknown"],[699,35,"unknown"],[699,36,"catchable"],[699,37,"unknown"],[699,38,"unknown"],[699,39,"unknown"],[699,47,"unknown"],[699,49,"unknown"],[699,51,"catchable"],[700,23,"unknown"],[700,24,"unknown"],[700,25,"unknown"],[700,26,"unknown"],[700,27,"unknown"],[700,28,"unknown"],[700,29,"unknown"],[700,30,"unknown"],[700,31,"unknown"],[700,32,"unknown"],[700,33,"catchable"],[700,34,"catchable"],[700,35,"unknown"],[700,36,"catchable"],[700,37,"unknown"],[700,38,"unknown"],[700,39,"unknown"],[700,40,"unknown"],[700,41,"unknown"],[700,42,"unknown"],[700,43,"unknown"],[700,47,"unknown"],[700,48,"unknown"],[700,49,"unknown"],[700,51,"catchable"],[701,23,"catchable"],[701,24,"catchable"],[701,25,"unknown"],[701,26,"unknown"],[701,27,"unknown"],[701,28,"unknown"],[701,29,"catchable"],[701,30,"catchable"],[701,31,"unknown"],[701,32,"unknown"],[701,33,"catchable"],[701,34,"catchable"],[701,35,"unknown"],[701,36,"catchable"],[701,37,"unknown"],[701,38,"unknown"],[701,39,"unknown"],[701,40,"unknown"],[701,41,"unknown"],[701,42,"unknown"],[701,43,"unknown"],[701,47,"unknown"],[701,48,"unknown"],[701,49,"unknown"],[701,51,"catchable"],[702,23,"catchable"],[702,24,"catchable"],[702,25,"unknown"],[702,26,"unknown"],[702,27,"unknown"],[702,28,"unknown"],[702,29,"catchable"],[702,30,"catchable"],[702,31,"unknown"],[702,32,"unknown"],[702,33,"unknown"],[702,34,"unknown"],[702,35,"catchable"],[702,36,"catchable"],[702,37,"unknown"],[702,38,"unknown"],[702,39,"unknown"],[702,40,"unknown"],[702,41,"unknown"],[702,42,"unknown"],[702,43,"unknown"],[702,47,"unknown"],[702,48,"unknown"],[702,49,"unknown"],[702,50,"catchable"],[702,51,"catchable"],[703,23,"catchable"],[703,24,"catchable"],[703,25,"unknown"],[703,26,"unknown"],[703,27,"catchable"],[703,28,"catchable"],[703,29,"catchable"],[703,30,"catchable"],[703,31,"unknown"],[703,32,"unknown"],[703,33,"unknown"],[703,34,"unknown"],[703,35,"unknown"],[703,36,"catchable"],[703,37,"unknown"],[703,38,"unknown"],[703,39,"unknown"],[703,40,"unknown"],[703,41,"unknown"],[703,42,"unknown"],[703,43,"unknown"],[703,47,"unknown"],[703,48,"unknown"],[703,51,"catchable"],[703,52,"unknown"],[704,23,"catchable"],[704,24,"catchable"],[704,25,"unknown"],[704,26,"unknown"],[704,27,"catchable"],[704,28,"catchable"],[704,29,"catchable"],[704,30,"catchable"],[704,31,"unknown"],[704,32,"unknown"],[704,33,"unknown"],[704,34,"catchable"],[704,35,"unknown"],[704,36,"unknown"],[704,37,"unknown"],[704,38,"unknown"],[704,39,"unknown"],[704,40,"unknown"],[704,41,"unknown"],[704,42,"unknown"],[704,43,"unknown"],[704,47,"unknown"],[704,48,"unknown"],[704,50,"catchable"],[704,52,"unknown"],[705,23,"catchable"],[705,24,"catchable"],[705,25,"unknown"],[705,26,"unknown"],[705,27,"catchable"],[705,28,"catchable"],[705,29,"catchable"],[705,30,"catchable"],[705,31,"unknown"],[705,32,"unknown"],[705,33,"unknown"],[705,34,"catchable"],[705,35,"unknown"],[705,36,"unknown"],[705,37,"unknown"],[705,38,"unknown"],[705,39,"unknown"],[705,40,"unknown"],[705,41,"unknown"],[705,42,"unknown"],[705,43,"unknown"],[705,47,"unknown"],[705,48,"unknown"],[705,50,"catchable"],[705,52,"unknown"],[706,23,"unknown"],[706,24,"unknown"],[706,25,"unknown"],[706,26,"unknown"],[706,27,"unknown"],[706,28,"unknown"],[706,29,"unknown"],[706,30,"unknown"],[706,31,"unknown"],[706,32,"unknown"],[706,33,"unknown"],[706,34,"catchable"],[706,35,"unknown"],[706,36,"unknown"],[706,37,"unknown"],[706,38,"unknown"],[706,39,"unknown"],[706,40,"unknown"],[706,41,"unknown"],[706,42,"unknown"],[706,43,"unknown"],[706,47,"unknown"],[706,48,"unknown"],[706,49,"unknown"],[706,50,"catchable"],[706,52,"unknown"],[707,23,"catchable"],[707,24,"catchable"],[707,25,"unknown"],[707,26,"unknown"],[707,27,"catchable"],[707,28,"catchable"],[707,29,"catchable"],[707,30,"catchable"],[707,31,"unknown"],[707,32,"unknown"],[707,33,"unknown"],[707,34,"unknown"],[707,35,"catchable"],[707,36,"catchable"],[707,37,"unknown"],[707,38,"unknown"],[707,39,"unknown"],[707,40,"unknown"],[707,41,"unknown"],[707,42,"unknown"],[707,43,"unknown"],[707,47,"unknown"],[707,48,"unknown"],[707,49,"unknown"],[707,50,"catchable"],[707,51,"catchable"],[708,23,"catchable"],[708,24,"catchable"],[708,25,"unknown"],[708,26,"unknown"],[708,27,"catchable"],[708,28,"catchable"],[708,29,"catchable"],[708,30,"catchable"],[708,31,"unknown"],[708,32,"unknown"],[708,33,"catchable"],[708,34,"catchable"],[708,35,"unknown"],[708,36,"catchable"],[708,37,"unknown"],[708,38,"unknown"],[708,39,"unknown"],[708,40,"unknown"],[708,41,"unknown"],[708,42,"unknown"],[708,43,"unknown"],[708,47,"unknown"],[708,48,"unknown"],[708,51,"catchable"],[708,52,"unknown"],[709,23,"catchable"],[709,24,"catchable"],[709,25,"unknown"],[709,26,"unknown"],[709,27,"catchable"],[709,28,"catchable"],[709,29,"unknown"],[709,30,"unknown"],[709,31,"unknown"],[709,32,"unknown"],[709,33,"catchable"],[709,34,"catchable"],[709,35,"unknown"],[709,36,"catchable"],[709,37,"unknown"],[709,38,"unknown"],[709,39,"unknown"],[709,40,"unknown"],[709,41,"unknown"],[709,42,"unknown"],[709,43,"unknown"],[709,47,"unknown"],[709,48,"unknown"],[709,49,"unknown"],[709,51,"catchable"],[709,52,"unknown"],[710,23,"catchable"],[710,24,"catchable"],[710,25,"unknown"],[710,26,"unknown"],[710,27,"unknown"],[710,28,"unknown"],[710,29,"unknown"],[710,30,"unknown"],[710,31,"unknown"],[710,32,"unknown"],[710,33,"catchable"],[710,34,"catchable"],[710,35,"unknown"],[710,36,"unknown"],[710,37,"unknown"],[710,38,"unknown"],[710,39,"unknown"],[710,47,"unknown"],[711,23,"unknown"],[711,24,"unknown"],[711,25,"unknown"],[711,26,"unknown"],[711,27,"unknown"],[711,28,"unknown"],[711,29,"unknown"],[711,30,"unknown"],[711,31,"unknown"],[711,32,"unknown"],[711,33,"catchable"],[711,34,"catchable"],[711,35,"catchable"],[711,36,"catchable"],[711,37,"unknown"],[711,38,"unknown"],[711,39,"unknown"],[711,47,"unknown"],[711,49,"unknown"],[711,50,"catchable"],[711,51,"catchable"],[712,23,"catchable"],[712,24,"catchable"],[712,25,"unknown"],[712,26,"unknown"],[712,27,"unknown"],[712,28,"unknown"],[712,29,"unknown"],[712,30,"unknown"],[712,31,"unknown"],[712,32,"unknown"],[712,33,"catchable"],[712,34,"catchable"],[712,35,"unknown"],[712,36,"catchable"],[712,37,"unknown"],[712,38,"unknown"],[712,39,"unknown"],[712,40,"unknown"],[712,41,"unknown"],[712,42,"unknown"],[712,43,"unknown"],[712,47,"unknown"],[712,48,"unknown"],[712,51,"catchable"],[713,23,"unknown"],[713,24,"unknown"],[713,25,"unknown"],[713,26,"unknown"],[713,27,"unknown"],[713,28,"unknown"],[713,29,"unknown"],[713,30,"unknown"],[713,31,"unknown"],[713,32,"unknown"],[713,33,"catchable"],[713,34,"catchable"],[713,35,"catchable"],[713,36,"catchable"],[713,37,"unknown"],[713,38,"unknown"],[713,39,"unknown"],[713,40,"unknown"],[713,41,"unknown"],[713,42,"unknown"],[713,43,"unknown"],[713,47,"unknown"],[713,48,"unknown"],[713,49,"unknown"],[713,50,"catchable"],[713,51,"catchable"],[714,23,"catchable"],[714,24,"catchable"],[714,25,"unknown"],[714,26,"unknown"],[714,27,"unknown"],[714,28,"unknown"],[714,29,"catchable"],[714,30,"catchable"],[714,31,"unknown"],[714,32,"unknown"],[714,33,"catchable"],[714,34,"catchable"],[714,35,"unknown"],[714,36,"catchable"],[714,37,"unknown"],[714,38,"unknown"],[714,39,"unknown"],[714,40,"unknown"],[714,41,"unknown"],[714,42,"unknown"],[714,43,"unknown"],[714,47,"unknown"],[714,48,"unknown"],[714,51,"catchable"],[714,52,"unknown"],[715,23,"unknown"],[715,24,"unknown"],[715,25,"unknown"],[715,26,"unknown"],[715,27,"unknown"],[715,28,"unknown"],[715,29,"catchable"],[715,30,"catchable"],[715,31,"unknown"],[715,32,"unknown"],[715,33,"catchable"],[715,34,"catchable"],[715,35,"catchable"],[715,36,"catchable"],[715,37,"unknown"],[715,38,"unknown"],[715,39,"unknown"],[715,40,"unknown"],[715,41,"unknown"],[715,42,"unknown"],[715,43,"unknown"],[715,47,"unknown"],[715,48,"unknown"],[715,49,"unknown"],[715,50,"catchable"],[715,51,"catchable"],[715,52,"unknown"],[716,23,"catchable"],[716,24,"unknown"],[716,25,"unknown"],[716,26,"unknown"],[716,27,"unknown"],[716,28,"unknown"],[716,29,"catchable"],[716,30,"unknown"],[716,31,"unknown"],[716,32,"unknown"],[716,33,"unknown"],[716,34,"unknown"],[716,35,"unknown"],[716,36,"catchable"],[716,37,"unknown"],[716,38,"unknown"],[716,39,"unknown"],[716,47,"unknown"],[717,23,"unknown"],[717,24,"catchable"],[717,25,"unknown"],[717,26,"unknown"],[717,27,"unknown"],[717,28,"unknown"],[717,29,"unknown"],[717,30,"catchable"],[717,31,"unknown"],[717,32,"unknown"],[717,33,"unknown"],[717,34,"unknown"],[717,35,"unknown"],[717,36,"unknown"],[717,37,"unknown"],[717,38,"unknown"],[717,39,"unknown"],[717,47,"unknown"],[717,51,"catchable"],[718,23,"catchable"],[718,24,"catchable"],[718,25,"unknown"],[718,26,"unknown"],[718,27,"catchable"],[718,28,"catchable"],[718,29,"catchable"],[718,30,"catchable"],[718,31,"unknown"],[718,32,"unknown"],[718,33,"unknown"],[718,34,"unknown"],[718,35,"unknown"],[718,36,"catchable"],[718,37,"unknown"],[718,38,"unknown"],[718,39,"unknown"],[718,47,"unknown"],[718,51,"catchable"],[719,23,"unknown"],[719,24,"unknown"],[719,25,"unknown"],[719,26,"unknown"],[719,27,"unknown"],[719,28,"unknown"],[719,29,"unknown"],[719,30,"unknown"],[719,31,"unknown"],[719,32,"unknown"],[719,33,"unknown"],[719,34,"unknown"],[719,35,"unknown"],[719,36,"unknown"],[719,37,"unknown"],[719,38,"unknown"],[719,39,"unknown"],[719,40,"unknown"],[719,41,"unknown"],[719,42,"unknown"],[719,43,"unknown"],[719,47,"unknown"],[719,48,"unknown"],[720,23,"unknown"],[720,24,"unknown"],[720,25,"unknown"],[720,26,"unknown"],[720,27,"unknown"],[720,28,"unknown"],[720,29,"unknown"],[720,30,"unknown"],[720,31,"unknown"],[720,32,"unknown"],[720,40,"unknown"],[720,41,"unknown"],[720,42,"unknown"],[720,43,"unknown"],[720,47,"unknown"],[720,48,"unknown"],[721,23,"unknown"],[721,24,"unknown"],[721,25,"unknown"],[721,26,"unknown"],[721,27,"unknown"],[721,28,"unknown"],[721,29,"unknown"],[721,30,"unknown"],[721,31,"unknown"],[721,32,"unknown"],[721,33,"unknown"],[721,34,"unknown"],[721,35,"unknown"],[721,36,"unknown"],[721,37,"unknown"],[721,38,"unknown"],[721,39,"unknown"],[721,40,"unknown"],[721,41,"unknown"],[721,42,"unknown"],[721,43,"unknown"],[721,47,"unknown"],[721,48,"unknown"],[722,27,"catchable"],[722,28,"catchable"],[722,29,"catchable"],[722,30,"catchable"],[722,31,"unknown"],[722,32,"unknown"],[722,33,"unknown"],[722,34,"unknown"],[722,35,"catchable"],[722,36,"unknown"],[722,37,"unknown"],[722,38,"unknown"],[722,39,"unknown"],[722,40,"unknown"],[722,41,"unknown"],[722,42,"unknown"],[722,43,"unknown"],[722,47,"unknown"],[722,48,"unknown"],[722,50,"catchable"],[722,53,"unknown"],[723,27,"unknown"],[723,28,"unknown"],[723,29,"unknown"],[723,30,"unknown"],[723,31,"unknown"],[723,32,"unknown"],[723,33,"unknown"],[723,34,"unknown"],[723,35,"unknown"],[723,36,"unknown"],[723,37,"unknown"],[723,38,"unknown"],[723,39,"unknown"],[723,40,"unknown"],[723,41,"unknown"],[723,42,"unknown"],[723,43,"unknown"],[723,47,"unknown"],[723,48,"unknown"],[723,53,"unknown"],[724,27,"unknown"],[724,28,"unknown"],[724,29,"unknown"],[724,30,"unknown"],[724,31,"unknown"],[724,32,"unknown"],[724,33,"unknown"],[724,34,"unknown"],[724,35,"unknown"],[724,36,"unknown"],[724,37,"unknown"],[724,38,"unknown"],[724,39,"unknown"],[724,40,"unknown"],[724,41,"unknown"],[724,42,"unknown"],[724,43,"unknown"],[724,47,"unknown"],[724,48,"unknown"],[724,49,"unknown"],[724,53,"unknown"],[725,27,"catchable"],[725,28,"catchable"],[725,29,"catchable"],[725,30,"catchable"],[725,31,"unknown"],[725,32,"unknown"],[725,33,"unknown"],[725,34,"unknown"],[725,35,"catchable"],[725,36,"unknown"],[725,37,"unknown"],[725,38,"unknown"],[725,39,"unknown"],[725,40,"unknown"],[725,41,"unknown"],[725,42,"unknown"],[725,43,"unknown"],[725,47,"unknown"],[725,48,"unknown"],[725,50,"catchable"],[725,53,"unknown"],[726,27,"unknown"],[726,28,"unknown"],[726,29,"unknown"],[726,30,"unknown"],[726,31,"unknown"],[726,32,"unknown"],[726,33,"unknown"],[726,34,"unknown"],[726,35,"unknown"],[726,36,"unknown"],[726,37,"unknown"],[726,38,"unknown"],[726,39,"unknown"],[726,40,"unknown"],[726,41,"unknown"],[726,42,"unknown"],[726,43,"unknown"],[726,47,"unknown"],[726,48,"unknown"],[726,53,"unknown"],[727,27,"unknown"],[727,28,"unknown"],[727,29,"unknown"],[727,30,"unknown"],[727,31,"unknown"],[727,32,"unknown"],[727,33,"unknown"],[727,34,"unknown"],[727,35,"unknown"],[727,36,"unknown"],[727,37,"unknown"],[727,38,"unknown"],[727,39,"unknown"],[727,40,"unknown"],[727,41,"unknown"],[727,42,"unknown"],[727,43,"unknown"],[727,47,"unknown"],[727,48,"unknown"],[727,49,"unknown"],[727,53,"unknown"],[728,27,"catchable"],[728,28,"catchable"],[728,29,"catchable"],[728,30,"catchable"],[728,31,"unknown"],[728,32,"unknown"],[728,33,"unknown"],[728,34,"unknown"],[728,35,"catchable"],[728,36,"unknown"],[728,37,"unknown"],[728,38,"unknown"],[728,39,"unknown"],[728,40,"unknown"],[728,41,"unknown"],[728,42,"unknown"],[728,43,"unknown"],[728,47,"unknown"],[728,48,"unknown"],[728,50,"catchable"],[728,53,"unknown"],[729,27,"unknown"],[729,28,"unknown"],[729,29,"unknown"],[729,30,"unknown"],[729,31,"unknown"],[729,32,"unknown"],[729,33,"unknown"],[729,34,"unknown"],[729,35,"unknown"],[729,36,"unknown"],[729,37,"unknown"],[729,38,"unknown"],[729,39,"unknown"],[729,40,"unknown"],[729,41,"unknown"],[729,42,"unknown"],[729,43,"unknown"],[729,47,"unknown"],[729,48,"unknown"],[729,53,"unknown"],[730,27,"unknown"],[730,28,"unknown"],[730,29,"unknown"],[730,30,"unknown"],[730,31,"unknown"],[730,32,"unknown"],[730,33,"unknown"],[730,34,"unknown"],[730,35,"unknown"],[730,36,"unknown"],[730,37,"unknown"],[730,38,"unknown"],[730,39,"unknown"],[730,40,"unknown"],[730,41,"unknown"],[730,42,"unknown"],[730,43,"unknown"],[730,47,"unknown"],[730,48,"unknown"],[730,49,"unknown"],[730,53,"unknown"],[731,27,"catchable"],[731,28,"catchable"],[731,29,"catchable"],[731,30,"catchable"],[731,31,"unknown"],[731,32,"unknown"],[731,40,"unknown"],[731,41,"unknown"],[731,42,"unknown"],[731,43,"unknown"],[731,47,"unknown"],[731,48,"unknown"],[731,53,"unknown"],[732,27,"catchable"],[732,28,"catchable"],[732,29,"catchable"],[732,30,"catchable"],[732,31,"unknown"],[732,32,"unknown"],[732,40,"unknown"],[732,41,"unknown"],[732,42,"unknown"],[732,43,"unknown"],[732,47,"unknown"],[732,48,"unknown"],[732,53,"unknown"],[733,27,"unknown"],[733,28,"unknown"],[733,29,"catchable"],[733,30,"catchable"],[733,31,"unknown"],[733,32,"unknown"],[733,40,"unknown"],[733,41,"unknown"],[733,42,"unknown"],[733,43,"unknown"],[733,47,"unknown"],[733,48,"unknown"],[733,49,"unknown"],[733,53,"unknown"],[734,27,"catchable"],[734,28,"catchable"],[734,29,"catchable"],[734,30,"catchable"],[734,31,"unknown"],[734,32,"unknown"],[734,40,"unknown"],[734,41,"unknown"],[734,42,"unknown"],[734,43,"unknown"],[734,47,"unknown"],[734,48,"unknown"],[735,27,"catchable"],[735,28,"catchable"],[735,29,"catchable"],[735,30,"catchable"],[735,31,"unknown"],[735,32,"unknown"],[735,40,"unknown"],[735,41,"unknown"],[735,42,"unknown"],[735,43,"unknown"],[735,47,"unknown"],[735,48,"unknown"],[736,27,"catchable"],[736,28,"catchable"],[736,29,"catchable"],[736,30,"catchable"],[736,31,"unknown"],[736,32,"unknown"],[736,33,"catchable"],[736,34,"catchable"],[736,35,"unknown"],[736,36,"unknown"],[736,37,"unknown"],[736,38,"unknown"],[736,39,"unknown"],[736,40,"unknown"],[736,41,"unknown"],[736,42,"unknown"],[736,43,"unknown"],[736,47,"unknown"],[736,48,"unknown"],[736,52,"unknown"],[737,27,"catchable"],[737,28,"catchable"],[737,29,"catchable"],[737,30,"catchable"],[737,31,"unknown"],[737,32,"unknown"],[737,33,"catchable"],[737,34,"catchable"],[737,35,"unknown"],[737,36,"catchable"],[737,37,"unknown"],[737,38,"unknown"],[737,39,"unknown"],[737,40,"unknown"],[737,41,"unknown"],[737,42,"unknown"],[737,43,"unknown"],[737,47,"unknown"],[737,48,"unknown"],[737,51,"catchable"],[737,52,"unknown"],[738,27,"unknown"],[738,28,"unknown"],[738,29,"catchable"],[738,30,"catchable"],[738,31,"unknown"],[738,32,"unknown"],[738,33,"catchable"],[738,34,"catchable"],[738,35,"unknown"],[738,36,"catchable"],[738,37,"unknown"],[738,38,"unknown"],[738,39,"unknown"],[738,40,"unknown"],[738,41,"unknown"],[738,42,"unknown"],[738,43,"unknown"],[738,47,"unknown"],[738,48,"unknown"],[738,51,"catchable"],[738,52,"unknown"],[739,27,"catchable"],[739,28,"catchable"],[739,29,"catchable"],[739,30,"catchable"],[739,31,"unknown"],[739,32,"unknown"],[739,40,"unknown"],[739,41,"unknown"],[739,42,"unknown"],[739,43,"unknown"],[739,47,"unknown"],[739,48,"unknown"],[739,53,"unknown"],[740,27,"unknown"],[740,28,"unknown"],[740,29,"unknown"],[740,30,"unknown"],[740,31,"unknown"],[740,32,"unknown"],[740,40,"unknown"],[740,41,"unknown"],[740,42,"unknown"],[740,43,"unknown"],[740,47,"unknown"],[740,48,"unknown"],[740,49,"unknown"],[740,53,"unknown"],[741,27,"catchable"],[741,28,"catchable"],[741,29,"catchable"],[741,30,"catchable"],[741,31,"unknown"],[741,32,"unknown"],[741,40,"unknown"],[741,41,"unknown"],[741,42,"unknown"],[741,43,"unknown"],[741,47,"unknown"],[741,48,"unknown"],[741,52,"unknown"],[741,53,"unknown"],[742,27,"catchable"],[742,28,"catchable"],[742,29,"catchable"],[742,30,"catchable"],[742,31,"unknown"],[742,32,"unknown"],[742,33,"catchable"],[742,34,"catchable"],[742,35,"catchable"],[742,36,"unknown"],[742,37,"unknown"],[742,38,"unknown"],[742,39,"unknown"],[742,40,"unknown"],[742,41,"unknown"],[742,42,"unknown"],[742,43,"unknown"],[742,47,"unknown"],[742,48,"unknown"],[742,50,"catchable"],[742,52,"unknown"],[743,27,"catchable"],[743,28,"catchable"],[743,29,"catchable"],[743,30,"catchable"],[743,31,"unknown"],[743,32,"unknown"],[743,33,"catchable"],[743,34,"catchable"],[743,35,"catchable"],[743,36,"catchable"],[743,37,"unknown"],[743,38,"unknown"],[743,39,"unknown"],[743,40,"unknown"],[743,41,"unknown"],[743,42,"unknown"],[743,43,"unknown"],[743,47,"unknown"],[743,48,"unknown"],[743,50,"catchable"],[743,51,"catchable"],[743,52,"unknown"],[744,27,"catchable"],[744,28,"catchable"],[744,29,"catchable"],[744,30,"catchable"],[744,31,"unknown"],[744,32,"unknown"],[744,33,"unknown"],[744,34,"unknown"],[744,35,"catchable"],[744,36,"unknown"],[744,37,"unknown"],[744,38,"unknown"],[744,39,"unknown"],[744,40,"unknown"],[744,41,"unknown"],[744,42,"unknown"],[744,43,"unknown"],[744,47,"unknown"],[744,48,"unknown"],[744,50,"catchable"],[744,52,"unknown"],[745,27,"catchable"],[745,28,"catchable"],[745,29,"catchable"],[745,30,"catchable"],[745,31,"unknown"],[745,32,"unknown"],[745,33,"unknown"],[745,34,"unknown"],[745,35,"catchable"],[745,36,"catchable"],[745,37,"unknown"],[745,38,"unknown"],[745,39,"unknown"],[745,40,"unknown"],[745,41,"unknown"],[745,42,"unknown"],[745,43,"unknown"],[745,47,"unknown"],[745,48,"unknown"],[745,49,"unknown"],[745,50,"catchable"],[745,51,"catchable"],[745,52,"unknown"],[746,27,"catchable"],[746,28,"catchable"],[746,29,"catchable"],[746,30,"catchable"],[746,31,"unknown"],[746,32,"unknown"],[746,33,"catchable"],[746,34,"catchable"],[746,35,"catchable"],[746,36,"unknown"],[746,37,"unknown"],[746,38,"unknown"],[746,39,"unknown"],[746,50,"catchable"],[747,27,"catchable"],[747,28,"catchable"],[747,29,"catchable"],[747,30,"catchable"],[747,31,"unknown"],[747,32,"unknown"],[747,33,"catchable"],[747,34,"catchable"],[747,35,"catchable"],[747,36,"unknown"],[747,37,"unknown"],[747,38,"unknown"],[747,39,"unknown"],[747,40,"unknown"],[747,41,"unknown"],[747,42,"unknown"],[747,43,"unknown"],[747,47,"unknown"],[747,48,"unknown"],[747,50,"catchable"],[748,27,"unknown"],[748,28,"unknown"],[748,29,"unknown"],[748,30,"unknown"],[748,31,"unknown"],[748,32,"unknown"],[748,33,"catchable"],[748,34,"catchable"],[748,35,"catchable"],[748,36,"unknown"],[748,37,"unknown"],[748,38,"unknown"],[748,39,"unknown"],[748,40,"unknown"],[748,41,"unknown"],[748,42,"unknown"],[748,43,"unknown"],[748,47,"unknown"],[748,48,"unknown"],[748,49,"unknown"],[748,50,"catchable"],[749,27,"catchable"],[749,28,"catchable"],[749,29,"catchable"],[749,30,"catchable"],[749,31,"unknown"],[749,32,"unknown"],[749,33,"catchable"],[749,34,"catchable"],[749,35,"unknown"],[749,36,"unknown"],[749,37,"unknown"],[749,38,"unknown"],[749,39,"unknown"],[749,40,"unknown"],[749,41,"unknown"],[749,42,"unknown"],[749,43,"unknown"],[749,47,"unknown"],[749,48,"unknown"],[749,52,"unknown"],[750,27,"catchable"],[750,28,"catchable"],[750,29,"catchable"],[750,30,"catchable"],[750,31,"unknown"],[750,32,"unknown"],[750,33,"catchable"],[750,34,"catchable"],[750,35,"unknown"],[750,36,"catchable"],[750,37,"unknown"],[750,38,"unknown"],[750,39,"unknown"],[750,40,"unknown"],[750,41,"unknown"],[750,42,"unknown"],[750,43,"unknown"],[750,47,"unknown"],[750,48,"unknown"],[750,49,"unknown"],[750,51,"catchable"],[750,52,"unknown"],[751,27,"catchable"],[751,28,"catchable"],[751,29,"catchable"],[751,30,"catchable"],[751,31,"unknown"],[751,32,"unknown"],[751,33,"catchable"],[751,34,"catchable"],[751,35,"catchable"],[751,36,"catchable"],[751,37,"unknown"],[751,38,"unknown"],[751,39,"unknown"],[751,40,"unknown"],[751,41,"unknown"],[751,42,"unknown"],[751,43,"unknown"],[751,47,"unknown"],[751,48,"unknown"],[751,50,"catchable"],[751,51,"catchable"],[751,53,"unknown"],[752,27,"catchable"],[752,28,"catchable"],[752,29,"catchable"],[752,30,"catchable"],[752,31,"unknown"],[752,32,"unknown"],[752,33,"catchable"],[752,34,"catchable"],[752,35,"catchable"],[752,36,"catchable"],[752,37,"unknown"],[752,38,"unknown"],[752,39,"unknown"],[752,40,"unknown"],[752,41,"unknown"],[752,42,"unknown"],[752,43,"unknown"],[752,47,"unknown"],[752,48,"unknown"],[752,49,"unknown"],[752,50,"catchable"],[752,51,"catchable"],[752,53,"unknown"],[753,27,"catchable"],[753,28,"catchable"],[753,29,"catchable"],[753,30,"catchable"],[753,31,"unknown"],[753,32,"unknown"],[753,33,"unknown"],[753,34,"unknown"],[753,35,"catchable"],[753,36,"unknown"],[753,37,"unknown"],[753,38,"unknown"],[753,39,"unknown"],[753,40,"unknown"],[753,41,"unknown"],[753,42,"unknown"],[753,43,"unknown"],[753,47,"unknown"],[753,48,"unknown"],[753,50,"catchable"],[753,52,"unknown"],[754,27,"unknown"],[754,28,"unknown"],[754,29,"catchable"],[754,30,"unknown"],[754,31,"unknown"],[754,32,"unknown"],[754,33,"unknown"],[754,34,"unknown"],[754,35,"catchable"],[754,36,"catchable"],[754,37,"unknown"],[754,38,"unknown"],[754,39,"unknown"],[754,40,"unknown"],[754,41,"unknown"],[754,42,"unknown"],[754,43,"unknown"],[754,47,"unknown"],[754,48,"unknown"],[754,50,"catchable"],[754,51,"catchable"],[754,52,"unknown"],[755,27,"catchable"],[755,28,"catchable"],[755,29,"catchable"],[755,30,"catchable"],[755,31,"unknown"],[755,32,"unknown"],[755,33,"catchable"],[755,34,"catchable"],[755,35,"catchable"],[755,36,"unknown"],[755,37,"unknown"],[755,38,"unknown"],[755,39,"unknown"],[755,50,"catchable"],[756,27,"unknown"],[756,28,"unknown"],[756,29,"catchable"],[756,30,"catchable"],[756,31,"unknown"],[756,32,"unknown"],[756,33,"catchable"],[756,34,"catchable"],[756,35,"catchable"],[756,36,"catchable"],[756,37,"unknown"],[756,38,"unknown"],[756,39,"unknown"],[756,50,"catchable"],[756,51,"catchable"],[757,27,"catchable"],[757,28,"catchable"],[757,29,"catchable"],[757,30,"catchable"],[757,31,"unknown"],[757,32,"unknown"],[757,33,"catchable"],[757,34,"catchable"],[757,35,"catchable"],[757,36,"unknown"],[757,37,"unknown"],[757,38,"unknown"],[757,39,"unknown"],[757,40,"unknown"],[757,41,"unknown"],[757,42,"unknown"],[757,43,"unknown"],[757,47,"unknown"],[757,48,"unknown"],[757,50,"catchable"],[757,52,"unknown"],[758,27,"unknown"],[758,28,"unknown"],[758,29,"catchable"],[758,30,"catchable"],[758,31,"unknown"],[758,32,"unknown"],[758,33,"catchable"],[758,34,"catchable"],[758,35,"catchable"],[758,36,"catchable"],[758,37,"unknown"],[758,38,"unknown"],[758,39,"unknown"],[758,40,"unknown"],[758,41,"unknown"],[758,42,"unknown"],[758,43,"unknown"],[758,47,"unknown"],[758,48,"unknown"],[758,49,"unknown"],[758,50,"catchable"],[758,51,"catchable"],[758,52,"unknown"],[759,27,"catchable"],[759,28,"catchable"],[759,29,"catchable"],[759,30,"catchable"],[759,31,"unknown"],[759,32,"unknown"],[759,33,"catchable"],[759,34,"catchable"],[759,35,"catchable"],[759,36,"unknown"],[759,37,"unknown"],[759,38,"unknown"],[759,39,"unknown"],[759,50,"catchable"],[760,27,"catchable"],[760,28,"catchable"],[760,29,"catchable"],[760,30,"catchable"],[760,31,"unknown"],[760,32,"unknown"],[760,33,"catchable"],[760,34,"catchable"],[760,35,"catchable"],[760,36,"catchable"],[760,37,"unknown"],[760,38,"unknown"],[760,39,"unknown"],[760,50,"catchable"],[760,51,"catchable"],[761,27,"catchable"],[761,28,"catchable"],[761,29,"unknown"],[761,30,"unknown"],[761,31,"unknown"],[761,32,"unknown"],[761,33,"catchable"],[761,34,"catchable"],[761,35,"unknown"],[761,36,"unknown"],[761,37,"unknown"],[761,38,"unknown"],[761,39,"unknown"],[761,40,"unknown"],[761,41,"unknown"],[761,42,"unknown"],[761,43,"unknown"],[761,47,"unknown"],[761,48,"unknown"],[762,27,"catchable"],[762,28,"catchable"],[762,29,"catchable"],[762,30,"catchable"],[762,31,"unknown"],[762,32,"unknown"],[762,33,"catchable"],[762,34,"catchable"],[762,35,"catchable"],[762,36,"unknown"],[762,37,"unknown"],[762,38,"unknown"],[762,39,"unknown"],[762,40,"unknown"],[762,41,"unknown"],[762,42,"unknown"],[762,43,"unknown"],[762,47,"unknown"],[762,48,"unknown"],[762,50,"catchable"],[763,27,"unknown"],[763,28,"unknown"],[763,29,"unknown"],[763,30,"unknown"],[763,31,"unknown"],[763,32,"unknown"],[763,33,"catchable"],[763,34,"catchable"],[763,35,"catchable"],[763,36,"catchable"],[763,37,"unknown"],[763,38,"unknown"],[763,39,"unknown"],[763,40,"unknown"],[763,41,"unknown"],[763,42,"unknown"],[763,43,"unknown"],[763,47,"unknown"],[763,48,"unknown"],[763,49,"unknown"],[763,50,"catchable"],[763,51,"catchable"],[764,27,"catchable"],[764,28,"catchable"],[764,29,"catchable"],[764,30,"catchable"],[764,31,"unknown"],[764,32,"unknown"],[764,33,"unknown"],[764,34,"unknown"],[764,35,"catchable"],[764,36,"catchable"],[764,37,"unknown"],[764,38,"unknown"],[764,39,"unknown"],[764,40,"unknown"],[764,41,"unknown"],[764,42,"unknown"],[764,43,"unknown"],[764,47,"unknown"],[764,48,"unknown"],[764,50,"catchable"],[764,51,"catchable"],[764,53,"unknown"],[765,27,"unknown"],[765,28,"catchable"],[765,29,"unknown"],[765,30,"catchable"],[765,31,"unknown"],[765,32,"unknown"],[765,33,"unknown"],[765,34,"catchable"],[765,35,"catchable"],[765,36,"catchable"],[765,37,"unknown"],[765,38,"unknown"],[765,39,"unknown"],[765,40,"unknown"],[765,41,"unknown"],[765,42,"unknown"],[765,43,"unknown"],[765,47,"unknown"],[765,48,"unknown"],[765,49,"unknown"],[765,50,"catchable"],[765,51,"catchable"],[766,27,"catchable"],[766,28,"unknown"],[766,29,"catchable"],[766,30,"unknown"],[766,31,"unknown"],[766,32,"unknown"],[766,33,"catchable"],[766,34,"unknown"],[766,35,"catchable"],[766,36,"catchable"],[766,37,"unknown"],[766,38,"unknown"],[766,39,"unknown"],[766,40,"unknown"],[766,41,"unknown"],[766,42,"unknown"],[766,43,"unknown"],[766,47,"unknown"],[766,48,"unknown"],[766,49,"unknown"],[766,50,"catchable"],[766,51,"catchable"],[767,27,"catchable"],[767,28,"catchable"],[767,29,"catchable"],[767,30,"catchable"],[767,31,"unknown"],[767,32,"unknown"],[767,33,"catchable"],[767,34,"catchable"],[767,35,"catchable"],[767,36,"unknown"],[767,37,"unknown"],[767,38,"unknown"],[767,39,"unknown"],[767,47,"unknown"],[767,48,"unknown"],[767,50,"catchable"],[768,27,"unknown"],[768,28,"unknown"],[768,29,"unknown"],[768,30,"unknown"],[768,31,"unknown"],[768,32,"unknown"],[768,33,"catchable"],[768,34,"catchable"],[768,35,"catchable"],[768,36,"unknown"],[768,37,"unknown"],[768,38,"unknown"],[768,39,"unknown"],[768,47,"unknown"],[768,48,"unknown"],[768,49,"unknown"],[768,50,"catchable"],[769,27,"catchable"],[769,28,"catchable"],[769,29,"catchable"],[769,30,"catchable"],[769,31,"unknown"],[769,32,"unknown"],[769,33,"unknown"],[769,34,"unknown"],[769,35,"catchable"],[769,36,"unknown"],[769,37,"unknown"],[769,38,"unknown"],[769,39,"unknown"],[769,40,"unknown"],[769,41,"unknown"],[769,42,"unknown"],[769,43,"unknown"],[769,47,"unknown"],[769,48,"unknown"],[769,50,"catchable"],[770,27,"unknown"],[770,28,"unknown"],[770,29,"unknown"],[770,30,"unknown"],[770,31,"unknown"],[770,32,"unknown"],[770,33,"unknown"],[770,34,"unknown"],[770,35,"catchable"],[770,36,"catchable"],[770,37,"unknown"],[770,38,"unknown"],[770,39,"unknown"],[770,40,"unknown"],[770,41,"unknown"],[770,42,"unknown"],[770,43,"unknown"],[770,47,"unknown"],[770,48,"unknown"],[770,50,"catchable"],[770,51,"catchable"],[771,27,"catchable"],[771,28,"catchable"],[771,29,"catchable"],[771,30,"catchable"],[771,31,"unknown"],[771,32,"unknown"],[771,33,"catchable"],[771,34,"catchable"],[771,35,"catchable"],[771,36,"catchable"],[771,37,"unknown"],[771,38,"unknown"],[771,39,"unknown"],[771,50,"catchable"],[771,51,"catchable"],[772,27,"catchable"],[772,28,"catchable"],[772,29,"catchable"],[772,30,"catchable"],[772,31,"unknown"],[772,32,"unknown"],[772,33,"catchable"],[772,34,"catchable"],[772,35,"unknown"],[772,36,"unknown"],[772,37,"unknown"],[772,38,"unknown"],[772,39,"unknown"],[773,27,"unknown"],[773,28,"unknown"],[773,29,"unknown"],[773,30,"unknown"],[773,31,"unknown"],[773,32,"unknown"],[773,33,"unknown"],[773,34,"unknown"],[773,35,"unknown"],[773,36,"unknown"],[773,37,"unknown"],[773,38,"unknown"],[773,39,"unknown"],[774,27,"catchable"],[774,28,"catchable"],[774,29,"catchable"],[774,30,"catchable"],[774,31,"unknown"],[774,32,"unknown"],[774,40,"unknown"],[774,41,"unknown"],[774,42,"unknown"],[774,43,"unknown"],[774,47,"unknown"],[774,48,"unknown"],[774,53,"unknown"],[775,27,"catchable"],[775,28,"catchable"],[775,29,"catchable"],[775,30,"catchable"],[775,31,"unknown"],[775,32,"unknown"],[775,40,"unknown"],[775,41,"unknown"],[775,42,"unknown"],[775,43,"unknown"],[775,47,"unknown"],[775,48,"unknown"],[776,27,"catchable"],[776,28,"unknown"],[776,29,"catchable"],[776,30,"unknown"],[776,31,"unknown"],[776,32,"unknown"],[776,33,"catchable"],[776,34,"unknown"],[776,35,"catchable"],[776,36,"catchable"],[776,37,"unknown"],[776,38,"unknown"],[776,39,"unknown"],[777,27,"catchable"],[777,28,"catchable"],[777,29,"catchable"],[777,30,"catchable"],[777,31,"unknown"],[777,32,"unknown"],[777,33,"catchable"],[777,34,"catchable"],[777,35,"unknown"],[777,36,"catchable"],[777,37,"unknown"],[777,38,"unknown"],[777,39,"unknown"],[777,51,"catchable"],[778,27,"catchable"],[778,28,"catchable"],[778,29,"catchable"],[778,30,"catchable"],[778,31,"unknown"],[778,32,"unknown"],[778,33,"catchable"],[778,34,"catchable"],[778,35,"unknown"],[778,36,"catchable"],[778,37,"unknown"],[778,38,"unknown"],[778,39,"unknown"],[778,40,"unknown"],[778,41,"unknown"],[778,42,"unknown"],[778,43,"unknown"],[778,47,"unknown"],[778,48,"unknown"],[778,49,"unknown"],[778,51,"catchable"],[778,52,"unknown"],[779,27,"catchable"],[779,28,"catchable"],[779,29,"catchable"],[779,30,"catchable"],[779,31,"unknown"],[779,32,"unknown"],[779,40,"unknown"],[779,41,"unknown"],[779,42,"unknown"],[779,43,"unknown"],[779,47,"unknown"],[779,48,"unknown"],[779,53,"unknown"],[780,27,"unknown"],[780,28,"catchable"],[780,29,"unknown"],[780,30,"catchable"],[780,31,"unknown"],[780,32,"unknown"],[780,33,"unknown"],[780,34,"catchable"],[780,35,"unknown"],[780,36,"unknown"],[780,37,"unknown"],[780,38,"unknown"],[780,39,"unknown"],[780,47,"unknown"],[780,49,"unknown"],[780,50,"catchable"],[780,51,"catchable"],[781,27,"catchable"],[781,28,"catchable"],[781,29,"catchable"],[781,30,"catchable"],[781,31,"unknown"],[781,32,"unknown"],[781,33,"catchable"],[781,34,"catchable"],[781,35,"catchable"],[781,36,"catchable"],[781,37,"unknown"],[781,38,"unknown"],[781,39,"unknown"],[781,50,"catchable"],[781,51,"catchable"],[782,27,"catchable"],[782,28,"catchable"],[782,29,"catchable"],[782,30,"catchable"],[782,31,"unknown"],[782,32,"unknown"],[782,33,"catchable"],[782,34,"unknown"],[782,35,"catchable"],[782,36,"unknown"],[782,37,"unknown"],[782,38,"unknown"],[782,39,"unknown"],[782,40,"unknown"],[782,41,"unknown"],[782,42,"unknown"],[782,43,"unknown"],[782,47,"unknown"],[782,48,"unknown"],[782,50,"unknown"],[782,52,"unknown"],[783,27,"catchable"],[783,28,"catchable"],[783,29,"catchable"],[783,30,"catchable"],[783,31,"unknown"],[783,32,"unknown"],[783,33,"catchable"],[783,34,"unknown"],[783,35,"catchable"],[783,36,"unknown"],[783,37,"unknown"],[783,38,"unknown"],[783,39,"unknown"],[783,40,"unknown"],[783,41,"unknown"],[783,42,"unknown"],[783,43,"unknown"],[783,47,"unknown"],[783,48,"unknown"],[783,50,"unknown"],[783,52,"unknown"],[784,27,"catchable"],[784,28,"catchable"],[784,29,"catchable"],[784,30,"catchable"],[784,31,"unknown"],[784,32,"unknown"],[784,33,"catchable"],[784,34,"unknown"],[784,35,"catchable"],[784,36,"unknown"],[784,37,"unknown"],[784,38,"unknown"],[784,39,"unknown"],[784,40,"unknown"],[784,41,"unknown"],[784,42,"unknown"],[784,43,"unknown"],[784,47,"unknown"],[784,48,"unknown"],[784,49,"unknown"],[784,50,"unknown"],[784,52,"unknown"],[785,27,"catchable"],[785,28,"catchable"],[785,29,"catchable"],[785,30,"catchable"],[785,31,"unknown"],[785,32,"unknown"],[785,33,"unknown"],[785,34,"unknown"],[785,35,"unknown"],[785,36,"catchable"],[785,37,"unknown"],[785,38,"unknown"],[785,39,"unknown"],[785,51,"catchable"],[786,27,"catchable"],[786,28,"catchable"],[786,29,"catchable"],[786,30,"catchable"],[786,31,"unknown"],[786,32,"unknown"],[786,33,"unknown"],[786,34,"unknown"],[786,35,"unknown"],[786,36,"catchable"],[786,37,"unknown"],[786,38,"unknown"],[786,39,"unknown"],[786,51,"catchable"],[787,27,"catchable"],[787,28,"catchable"],[787,29,"catchable"],[787,30,"catchable"],[787,31,"unknown"],[787,32,"unknown"],[787,33,"unknown"],[787,34,"unknown"],[787,35,"unknown"],[787,36,"catchable"],[787,37,"unknown"],[787,38,"unknown"],[787,39,"unknown"],[787,51,"catchable"],[788,27,"catchable"],[788,28,"catchable"],[788,29,"catchable"],[788,30,"catchable"],[788,31,"unknown"],[788,32,"unknown"],[788,33,"unknown"],[788,34,"unknown"],[788,35,"unknown"],[788,36,"catchable"],[788,37,"unknown"],[788,38,"unknown"],[788,39,"unknown"],[788,51,"catchable"],[789,27,"catchable"],[789,28,"catchable"],[789,29,"catchable"],[789,30,"catchable"],[789,31,"unknown"],[789,32,"unknown"],[789,33,"unknown"],[789,34,"unknown"],[789,35,"unknown"],[789,36,"catchable"],[789,37,"unknown"],[789,38,"unknown"],[789,39,"unknown"],[789,40,"unknown"],[789,41,"unknown"],[789,42,"unknown"],[789,43,"unknown"],[789,47,"unknown"],[789,48,"unknown"],[789,51,"catchable"],[790,27,"unknown"],[790,28,"unknown"],[790,29,"unknown"],[790,30,"unknown"],[790,31,"unknown"],[790,32,"unknown"],[790,33,"unknown"],[790,34,"unknown"],[790,35,"unknown"],[790,36,"unknown"],[790,37,"unknown"],[790,38,"unknown"],[790,39,"unknown"],[790,40,"unknown"],[790,41,"unknown"],[790,42,"unknown"],[790,43,"unknown"],[790,47,"unknown"],[790,48,"unknown"],[791,27,"catchable"],[791,28,"unknown"],[791,29,"catchable"],[791,30,"unknown"],[791,31,"unknown"],[791,32,"unknown"],[791,33,"unknown"],[791,34,"unknown"],[791,35,"unknown"],[791,36,"catchable"],[791,37,"unknown"],[791,38,"unknown"],[791,39,"unknown"],[791,40,"unknown"],[791,41,"unknown"],[791,42,"unknown"],[791,43,"unknown"],[791,47,"unknown"],[791,48,"unknown"],[792,27,"unknown"],[792,28,"catchable"],[792,29,"unknown"],[792,30,"catchable"],[792,31,"unknown"],[792,32,"unknown"],[792,33,"unknown"],[792,34,"unknown"],[792,35,"unknown"],[792,36,"unknown"],[792,37,"unknown"],[792,38,"unknown"],[792,39,"unknown"],[792,40,"unknown"],[792,41,"unknown"],[792,42,"unknown"],[792,43,"unknown"],[792,47,"unknown"],[792,48,"unknown"],[792,51,"catchable"],[793,27,"catchable"],[793,28,"catchable"],[793,29,"catchable"],[793,30,"catchable"],[793,31,"unknown"],[793,32,"unknown"],[793,33,"unknown"],[793,34,"unknown"],[793,35,"unknown"],[793,36,"catchable"],[793,37,"unknown"],[793,38,"unknown"],[793,39,"unknown"],[793,51,"catchable"],[794,27,"catchable"],[794,28,"unknown"],[794,29,"catchable"],[794,30,"unknown"],[794,31,"unknown"],[794,32,"unknown"],[794,33,"unknown"],[794,34,"unknown"],[794,35,"unknown"],[794,36,"catchable"],[794,37,"unknown"],[794,38,"unknown"],[794,39,"unknown"],[794,51,"catchable"],[795,27,"unknown"],[795,28,"catchable"],[795,29,"unknown"],[795,30,"catchable"],[795,31,"unknown"],[795,32,"unknown"],[795,33,"unknown"],[795,34,"unknown"],[795,35,"unknown"],[795,36,"catchable"],[795,37,"unknown"],[795,38,"unknown"],[795,39,"unknown"],[795,51,"catchable"],[796,27,"catchable"],[796,28,"catchable"],[796,29,"catchable"],[796,30,"catchable"],[796,31,"unknown"],[796,32,"unknown"],[796,33,"unknown"],[796,34,"unknown"],[796,35,"unknown"],[796,36,"catchable"],[796,37,"unknown"],[796,38,"unknown"],[796,39,"unknown"],[796,51,"catchable"],[797,27,"unknown"],[797,28,"catchable"],[797,29,"unknown"],[797,30,"catchable"],[797,31,"unknown"],[797,32,"unknown"],[797,33,"unknown"],[797,34,"unknown"],[797,35,"unknown"],[797,36,"catchable"],[797,37,"unknown"],[797,38,"unknown"],[797,39,"unknown"],[797,51,"catchable"],[798,27,"catchable"],[798,28,"unknown"],[798,29,"catchable"],[798,30,"unknown"],[798,31,"unknown"],[798,32,"unknown"],[798,33,"unknown"],[798,34,"unknown"],[798,35,"unknown"],[798,36,"catchable"],[798,37,"unknown"],[798,38,"unknown"],[798,39,"unknown"],[798,51,"catchable"],[799,27,"catchable"],[799,28,"catchable"],[799,29,"catchable"],[799,30,"catchable"],[799,31,"unknown"],[799,32,"unknown"],[799,33,"unknown"],[799,34,"unknown"],[799,35,"unknown"],[799,36,"catchable"],[799,37,"unknown"],[799,38,"unknown"],[799,39,"unknown"],[799,51,"catchable"],[800,27,"catchable"],[800,28,"catchable"],[800,29,"catchable"],[800,30,"catchable"],[800,31,"unknown"],[800,32,"unknown"],[800,33,"unknown"],[800,34,"unknown"],[800,35,"unknown"],[800,36,"catchable"],[800,37,"unknown"],[800,38,"unknown"],[800,39,"unknown"],[800,40,"unknown"],[800,41,"unknown"],[800,42,"unknown"],[800,43,"unknown"],[800,47,"unknown"],[800,48,"unknown"],[800,51,"catchable"],[801,27,"unknown"],[801,28,"unknown"],[801,29,"catchable"],[801,30,"catchable"],[801,31,"unknown"],[801,32,"unknown"],[801,33,"unknown"],[801,34,"unknown"],[801,35,"unknown"],[801,36,"unknown"],[801,37,"unknown"],[801,38,"unknown"],[801,39,"unknown"],[801,40,"unknown"],[801,41,"unknown"],[801,42,"unknown"],[801,43,"unknown"],[801,47,"unknown"],[801,48,"unknown"],[802,27,"unknown"],[802,28,"unknown"],[802,29,"unknown"],[802,30,"unknown"],[802,31,"unknown"],[802,32,"unknown"],[802,33,"unknown"],[802,34,"unknown"],[802,35,"unknown"],[802,36,"unknown"],[802,37,"unknown"],[802,38,"unknown"],[802,39,"unknown"],[802,47,"unknown"],[802,48,"unknown"],[803,29,"catchable"],[803,30,"catchable"],[803,33,"unknown"],[803,34,"unknown"],[803,35,"unknown"],[803,36,"catchable"],[803,37,"unknown"],[803,38,"unknown"],[803,39,"unknown"],[803,51,"catchable"],[804,29,"unknown"],[804,30,"unknown"],[804,33,"unknown"],[804,34,"unknown"],[804,35,"unknown"],[804,36,"unknown"],[804,37,"unknown"],[804,38,"unknown"],[804,39,"unknown"],[805,29,"unknown"],[805,30,"catchable"],[805,33,"unknown"],[805,34,"unknown"],[805,35,"unknown"],[805,36,"catchable"],[805,37,"unknown"],[805,38,"unknown"],[805,39,"unknown"],[805,51,"catchable"],[806,29,"catchable"],[806,30,"unknown"],[806,33,"unknown"],[806,34,"unknown"],[806,35,"unknown"],[806,36,"catchable"],[806,37,"unknown"],[806,38,"unknown"],[806,39,"unknown"],[806,51,"catchable"],[807,29,"unknown"],[807,30,"unknown"],[807,33,"unknown"],[807,34,"unknown"],[807,35,"unknown"],[807,36,"unknown"],[807,37,"unknown"],[807,38,"unknown"],[807,39,"unknown"],[807,47,"unknown"],[807,48,"unknown"],[808,31,"unknown"],[808,32,"unknown"],[808,33,"unknown"],[808,34,"unknown"],[808,35,"unknown"],[808,36,"unknown"],[808,37,"unknown"],[808,38,"unknown"],[808,39,"unknown"],[808,47,"unknown"],[808,48,"unknown"],[809,31,"unknown"],[809,32,"unknown"],[809,33,"unknown"],[809,34,"unknown"],[809,35,"unknown"],[809,36,"unknown"],[809,37,"unknown"],[809,38,"unknown"],[809,39,"unknown"],[809,47,"unknown"],[809,48,"unknown"],[810,33,"catchable"],[810,34,"catchable"],[810,35,"unknown"],[810,36,"unknown"],[810,37,"unknown"],[810,38,"unknown"],[810,39,"unknown"],[810,40,"unknown"],[810,41,"unknown"],[810,42,"unknown"],[810,43,"unknown"],[810,47,"unknown"],[810,48,"unknown"],[810,53,"unknown"],[811,33,"unknown"],[811,34,"unknown"],[811,35,"unknown"],[811,36,"unknown"],[811,37,"unknown"],[811,38,"unknown"],[811,39,"unknown"],[811,40,"unknown"],[811,41,"unknown"],[811,42,"unknown"],[811,43,"unknown"],[811,47,"unknown"],[811,48,"unknown"],[811,53,"unknown"],[812,33,"unknown"],[812,34,"unknown"],[812,35,"unknown"],[812,36,"unknown"],[812,37,"unknown"],[812,38,"unknown"],[812,39,"unknown"],[812,40,"unknown"],[812,41,"unknown"],[812,42,"unknown"],[812,43,"unknown"],[812,47,"unknown"],[812,48,"unknown"],[812,49,"unknown"],[812,53,"unknown"],[813,33,"catchable"],[813,34,"catchable"],[813,35,"unknown"],[813,36,"unknown"],[813,37,"unknown"],[813,38,"unknown"],[813,39,"unknown"],[813,40,"unknown"],[813,41,"unknown"],[813,42,"unknown"],[813,43,"unknown"],[813,47,"unknown"],[813,48,"unknown"],[813,53,"unknown"],[814,33,"unknown"],[814,34,"unknown"],[814,35,"unknown"],[814,36,"unknown"],[814,37,"unknown"],[814,38,"unknown"],[814,39,"unknown"],[814,40,"unknown"],[814,41,"unknown"],[814,42,"unknown"],[814,43,"unknown"],[814,47,"unknown"],[814,48,"unknown"],[814,53,"unknown"],[815,33,"unknown"],[815,34,"unknown"],[815,35,"unknown"],[815,36,"unknown"],[815,37,"unknown"],[815,38,"unknown"],[815,39,"unknown"],[815,40,"unknown"],[815,41,"unknown"],[815,42,"unknown"],[815,43,"unknown"],[815,47,"unknown"],[815,48,"unknown"],[815,49,"unknown"],[815,53,"unknown"],[816,33,"catchable"],[816,34,"catchable"],[816,35,"unknown"],[816,36,"unknown"],[816,37,"unknown"],[816,38,"unknown"],[816,39,"unknown"],[816,40,"unknown"],[816,41,"unknown"],[816,42,"unknown"],[816,43,"unknown"],[816,47,"unknown"],[816,48,"unknown"],[816,53,"unknown"],[817,33,"unknown"],[817,34,"unknown"],[817,35,"unknown"],[817,36,"unknown"],[817,37,"unknown"],[817,38,"unknown"],[817,39,"unknown"],[817,40,"unknown"],[817,41,"unknown"],[817,42,"unknown"],[817,43,"unknown"],[817,47,"unknown"],[817,48,"unknown"],[817,53,"unknown"],[818,33,"unknown"],[818,34,"unknown"],[818,35,"unknown"],[818,36,"unknown"],[818,37,"unknown"],[818,38,"unknown"],[818,39,"unknown"],[818,40,"unknown"],[818,41,"unknown"],[818,42,"unknown"],[818,43,"unknown"],[818,47,"unknown"],[818,48,"unknown"],[818,49,"unknown"],[818,53,"unknown"],[819,33,"catchable"],[819,34,"catchable"],[819,35,"catchable"],[819,36,"catchable"],[819,37,"unknown"],[819,38,"unknown"],[819,39,"unknown"],[819,40,"unknown"],[819,41,"unknown"],[819,42,"unknown"],[819,43,"unknown"],[819,47,"unknown"],[819,48,"unknown"],[819,50,"catchable"],[819,51,"catchable"],[819,52,"unknown"],[820,33,"catchable"],[820,34,"catchable"],[820,35,"catchable"],[820,36,"catchable"],[820,37,"unknown"],[820,38,"unknown"],[820,39,"unknown"],[820,40,"unknown"],[820,41,"unknown"],[820,42,"unknown"],[820,43,"unknown"],[820,47,"unknown"],[820,48,"unknown"],[820,50,"catchable"],[820,51,"catchable"],[820,52,"unknown"],[821,33,"catchable"],[821,34,"catchable"],[821,35,"unknown"],[821,36,"unknown"],[821,37,"unknown"],[821,38,"unknown"],[821,39,"unknown"],[821,40,"unknown"],[821,41,"unknown"],[821,42,"unknown"],[821,43,"unknown"],[821,47,"unknown"],[821,48,"unknown"],[821,51,"unknown"],[822,33,"catchable"],[822,34,"catchable"],[822,35,"unknown"],[822,36,"catchable"],[822,37,"unknown"],[822,38,"unknown"],[822,39,"unknown"],[822,40,"unknown"],[822,41,"unknown"],[822,42,"unknown"],[822,43,"unknown"],[822,47,"unknown"],[822,48,"unknown"],[822,51,"catchable"],[823,33,"catchable"],[823,34,"catchable"],[823,35,"unknown"],[823,36,"catchable"],[823,37,"unknown"],[823,38,"unknown"],[823,39,"unknown"],[823,40,"unknown"],[823,41,"unknown"],[823,42,"unknown"],[823,43,"unknown"],[823,47,"unknown"],[823,48,"unknown"],[823,49,"unknown"],[823,51,"catchable"],[824,33,"catchable"],[824,34,"catchable"],[824,35,"catchable"],[824,36,"unknown"],[824,37,"unknown"],[824,38,"unknown"],[824,39,"unknown"],[824,50,"catchable"],[825,33,"catchable"],[825,34,"catchable"],[825,35,"catchable"],[825,36,"unknown"],[825,37,"unknown"],[825,38,"unknown"],[825,39,"unknown"],[825,50,"catchable"],[826,33,"catchable"],[826,34,"catchable"],[826,35,"catchable"],[826,36,"catchable"],[826,37,"unknown"],[826,38,"unknown"],[826,39,"unknown"],[826,50,"catchable"],[826,51,"catchable"],[827,33,"catchable"],[827,34,"catchable"],[827,35,"unknown"],[827,36,"unknown"],[827,37,"unknown"],[827,38,"unknown"],[827,39,"unknown"],[827,47,"unknown"],[827,48,"unknown"],[828,33,"catchable"],[828,34,"catchable"],[828,35,"catchable"],[828,36,"catchable"],[828,37,"unknown"],[828,38,"unknown"],[828,39,"unknown"],[828,47,"unknown"],[828,48,"unknown"],[828,49,"unknown"],[828,50,"catchable"],[828,51,"catchable"],[829,33,"catchable"],[829,34,"catchable"],[829,35,"unknown"],[829,36,"catchable"],[829,37,"unknown"],[829,38,"unknown"],[829,39,"unknown"],[829,51,"catchable"],[830,33,"catchable"],[830,34,"catchable"],[830,35,"unknown"],[830,36,"catchable"],[830,37,"unknown"],[830,38,"unknown"],[830,39,"unknown"],[830,51,"catchable"],[831,33,"catchable"],[831,34,"catchable"],[831,35,"unknown"],[831,36,"catchable"],[831,37,"unknown"],[831,38,"unknown"],[831,39,"unknown"],[831,51,"catchable"],[832,33,"catchable"],[832,34,"catchable"],[832,35,"catchable"],[832,36,"catchable"],[832,37,"unknown"],[832,38,"unknown"],[832,39,"unknown"],[832,50,"catchable"],[832,51,"catchable"],[833,33,"catchable"],[833,34,"catchable"],[833,35,"catchable"],[833,36,"unknown"],[833,37,"unknown"],[833,38,"unknown"],[833,39,"unknown"],[833,40,"unknown"],[833,41,"unknown"],[833,42,"unknown"],[833,43,"unknown"],[833,47,"unknown"],[833,48,"unknown"],[833,50,"catchable"],[833,52,"unknown"],[834,33,"catchable"],[834,34,"catchable"],[834,35,"catchable"],[834,36,"catchable"],[834,37,"unknown"],[834,38,"unknown"],[834,39,"unknown"],[834,40,"unknown"],[834,41,"unknown"],[834,42,"unknown"],[834,43,"unknown"],[834,47,"unknown"],[834,48,"unknown"],[834,50,"catchable"],[834,51,"catchable"],[834,52,"unknown"],[835,33,"catchable"],[835,34,"catchable"],[835,35,"unknown"],[835,36,"catchable"],[835,37,"unknown"],[835,38,"unknown"],[835,39,"unknown"],[835,51,"catchable"],[836,33,"catchable"],[836,34,"catchable"],[836,35,"catchable"],[836,36,"catchable"],[836,37,"unknown"],[836,38,"unknown"],[836,39,"unknown"],[836,50,"catchable"],[836,51,"catchable"],[837,33,"catchable"],[837,34,"catchable"],[837,35,"unknown"],[837,36,"unknown"],[837,37,"unknown"],[837,38,"unknown"],[837,39,"unknown"],[837,40,"unknown"],[837,41,"unknown"],[837,42,"unknown"],[837,43,"unknown"],[837,47,"unknown"],[837,48,"unknown"],[837,51,"catchable"],[838,33,"catchable"],[838,34,"catchable"],[838,35,"unknown"],[838,36,"catchable"],[838,37,"unknown"],[838,38,"unknown"],[838,39,"unknown"],[838,40,"unknown"],[838,41,"unknown"],[838,42,"unknown"],[838,43,"unknown"],[838,47,"unknown"],[838,48,"unknown"],[838,51,"catchable"],[839,33,"catchable"],[839,34,"catchable"],[839,35,"unknown"],[839,36,"catchable"],[839,37,"unknown"],[839,38,"unknown"],[839,39,"unknown"],[839,40,"unknown"],[839,41,"unknown"],[839,42,"unknown"],[839,43,"unknown"],[839,47,"unknown"],[839,48,"unknown"],[839,51,"catchable"],[840,33,"catchable"],[840,34,"catchable"],[840,35,"catchable"],[840,36,"unknown"],[840,37,"unknown"],[840,38,"unknown"],[840,39,"unknown"],[840,40,"unknown"],[840,41,"unknown"],[840,42,"unknown"],[840,43,"unknown"],[840,47,"unknown"],[840,48,"unknown"],[840,50,"catchable"],[840,52,"unknown"],[841,33,"catchable"],[841,34,"catchable"],[841,35,"catchable"],[841,36,"unknown"],[841,37,"unknown"],[841,38,"unknown"],[841,39,"unknown"],[841,40,"unknown"],[841,41,"unknown"],[841,42,"unknown"],[841,43,"unknown"],[841,47,"unknown"],[841,48,"unknown"],[841,49,"unknown"],[841,50,"unknown"],[841,52,"unknown"],[842,33,"catchable"],[842,34,"catchable"],[842,35,"unknown"],[842,36,"unknown"],[842,37,"unknown"],[842,38,"unknown"],[842,39,"unknown"],[842,40,"unknown"],[842,41,"unknown"],[842,42,"unknown"],[842,43,"unknown"],[842,47,"unknown"],[842,48,"unknown"],[842,49,"unknown"],[842,50,"catchable"],[842,52,"unknown"],[843,33,"catchable"],[843,34,"catchable"],[843,35,"catchable"],[843,36,"unknown"],[843,37,"unknown"],[843,38,"unknown"],[843,39,"unknown"],[843,40,"unknown"],[843,41,"unknown"],[843,42,"unknown"],[843,43,"unknown"],[843,47,"unknown"],[843,48,"unknown"],[843,50,"catchable"],[844,33,"catchable"],[844,34,"catchable"],[844,35,"catchable"],[844,36,"catchable"],[844,37,"unknown"],[844,38,"unknown"],[844,39,"unknown"],[844,40,"unknown"],[844,41,"unknown"],[844,42,"unknown"],[844,43,"unknown"],[844,47,"unknown"],[844,48,"unknown"],[844,49,"unknown"],[844,50,"catchable"],[844,51,"catchable"],[845,33,"catchable"],[845,34,"catchable"],[845,35,"catchable"],[845,36,"catchable"],[845,37,"unknown"],[845,38,"unknown"],[845,39,"unknown"],[845,40,"unknown"],[845,41,"unknown"],[845,42,"unknown"],[845,43,"unknown"],[845,47,"unknown"],[845,48,"unknown"],[845,50,"catchable"],[845,51,"catchable"],[845,52,"unknown"],[846,33,"catchable"],[846,34,"catchable"],[846,35,"catchable"],[846,36,"unknown"],[846,37,"unknown"],[846,38,"unknown"],[846,39,"unknown"],[846,40,"unknown"],[846,41,"unknown"],[846,42,"unknown"],[846,43,"unknown"],[846,47,"unknown"],[846,48,"unknown"],[846,50,"catchable"],[846,52,"unknown"],[847,33,"catchable"],[847,34,"catchable"],[847,35,"catchable"],[847,36,"catchable"],[847,37,"unknown"],[847,38,"unknown"],[847,39,"unknown"],[847,40,"unknown"],[847,41,"unknown"],[847,42,"unknown"],[847,43,"unknown"],[847,47,"unknown"],[847,48,"unknown"],[847,50,"catchable"],[847,51,"catchable"],[847,52,"unknown"],[848,33,"catchable"],[848,34,"catchable"],[848,35,"unknown"],[848,36,"unknown"],[848,37,"unknown"],[848,38,"unknown"],[848,39,"unknown"],[848,40,"unknown"],[848,41,"unknown"],[848,42,"unknown"],[848,43,"unknown"],[848,47,"unknown"],[848,48,"unknown"],[849,33,"catchable"],[849,34,"catchable"],[849,35,"unknown"],[849,36,"catchable"],[849,37,"unknown"],[849,38,"unknown"],[849,39,"unknown"],[849,40,"unknown"],[849,41,"unknown"],[849,42,"unknown"],[849,43,"unknown"],[849,47,"unknown"],[849,48,"unknown"],[849,49,"unknown"],[849,51,"catchable"],[850,33,"catchable"],[850,34,"catchable"],[850,35,"unknown"],[850,36,"catchable"],[850,37,"unknown"],[850,38,"unknown"],[850,39,"unknown"],[850,51,"catchable"],[851,33,"catchable"],[851,34,"catchable"],[851,35,"unknown"],[851,36,"catchable"],[851,37,"unknown"],[851,38,"unknown"],[851,39,"unknown"],[851,51,"catchable"],[852,33,"catchable"],[852,34,"catchable"],[852,35,"catchable"],[852,36,"unknown"],[852,37,"unknown"],[852,38,"unknown"],[852,39,"unknown"],[852,47,"unknown"],[852,48,"unknown"],[852,50,"catchable"],[853,33,"catchable"],[853,34,"catchable"],[853,35,"catchable"],[853,36,"catchable"],[853,37,"unknown"],[853,38,"unknown"],[853,39,"unknown"],[853,47,"unknown"],[853,48,"unknown"],[853,49,"unknown"],[853,50,"catchable"],[853,51,"catchable"],[854,33,"catchable"],[854,34,"catchable"],[854,35,"unknown"],[854,36,"catchable"],[854,37,"unknown"],[854,38,"unknown"],[854,39,"unknown"],[854,40,"unknown"],[854,41,"unknown"],[854,42,"unknown"],[854,43,"unknown"],[854,47,"unknown"],[854,48,"unknown"],[854,51,"catchable"],[854,53,"unknown"],[855,33,"catchable"],[855,34,"catchable"],[855,35,"unknown"],[855,36,"catchable"],[855,37,"unknown"],[855,38,"unknown"],[855,39,"unknown"],[855,40,"unknown"],[855,41,"unknown"],[855,42,"unknown"],[855,43,"unknown"],[855,47,"unknown"],[855,48,"unknown"],[855,49,"unknown"],[855,51,"catchable"],[855,53,"unknown"],[856,33,"catchable"],[856,34,"catchable"],[856,35,"unknown"],[856,36,"catchable"],[856,37,"unknown"],[856,38,"unknown"],[856,39,"unknown"],[856,40,"unknown"],[856,41,"unknown"],[856,42,"unknown"],[856,43,"unknown"],[856,47,"unknown"],[856,48,"unknown"],[856,51,"catchable"],[856,52,"unknown"],[857,33,"catchable"],[857,34,"catchable"],[857,35,"unknown"],[857,36,"catchable"],[857,37,"unknown"],[857,38,"unknown"],[857,39,"unknown"],[857,40,"unknown"],[857,41,"unknown"],[857,42,"unknown"],[857,43,"unknown"],[857,47,"unknown"],[857,48,"unknown"],[857,51,"catchable"],[857,52,"unknown"],[858,33,"catchable"],[858,34,"catchable"],[858,35,"unknown"],[858,36,"catchable"],[858,37,"unknown"],[858,38,"unknown"],[858,39,"unknown"],[858,40,"unknown"],[858,41,"unknown"],[858,42,"unknown"],[858,43,"unknown"],[858,47,"unknown"],[858,48,"unknown"],[858,49,"unknown"],[858,51,"catchable"],[858,52,"unknown"],[859,33,"catchable"],[859,34,"catchable"],[859,35,"unknown"],[859,36,"catchable"],[859,37,"unknown"],[859,38,"unknown"],[859,39,"unknown"],[859,40,"unknown"],[859,41,"unknown"],[859,42,"unknown"],[859,43,"unknown"],[859,47,"unknown"],[859,48,"unknown"],[859,51,"catchable"],[859,52,"unknown"],[860,33,"catchable"],[860,34,"catchable"],[860,35,"unknown"],[860,36,"catchable"],[860,37,"unknown"],[860,38,"unknown"],[860,39,"unknown"],[860,40,"unknown"],[860,41,"unknown"],[860,42,"unknown"],[860,43,"unknown"],[860,47,"unknown"],[860,48,"unknown"],[860,51,"catchable"],[860,52,"unknown"],[861,33,"catchable"],[861,34,"catchable"],[861,35,"unknown"],[861,36,"catchable"],[861,37,"unknown"],[861,38,"unknown"],[861,39,"unknown"],[861,40,"unknown"],[861,41,"unknown"],[861,42,"unknown"],[861,43,"unknown"],[861,47,"unknown"],[861,48,"unknown"],[861,49,"unknown"],[861,51,"catchable"],[861,52,"unknown"],[862,33,"catchable"],[862,34,"catchable"],[862,35,"unknown"],[862,36,"catchable"],[862,37,"unknown"],[862,38,"unknown"],[862,39,"unknown"],[862,51,"catchable"],[863,33,"catchable"],[863,34,"catchable"],[863,35,"catchable"],[863,36,"catchable"],[863,37,"unknown"],[863,38,"unknown"],[863,39,"unknown"],[863,40,"unknown"],[863,41,"unknown"],[863,42,"unknown"],[863,43,"unknown"],[863,47,"unknown"],[863,48,"unknown"],[863,49,"unknown"],[863,50,"catchable"],[863,51,"catchable"],[864,33,"unknown"],[864,34,"catchable"],[864,35,"unknown"],[864,36,"unknown"],[864,37,"unknown"],[864,38,"unknown"],[864,39,"unknown"],[864,50,"catchable"],[864,51,"catchable"],[865,33,"catchable"],[865,34,"unknown"],[865,35,"catchable"],[865,36,"catchable"],[865,37,"unknown"],[865,38,"unknown"],[865,39,"unknown"],[865,47,"unknown"],[865,48,"unknown"],[865,49,"unknown"],[866,33,"catchable"],[866,34,"catchable"],[866,35,"unknown"],[866,36,"catchable"],[866,37,"unknown"],[866,38,"unknown"],[866,39,"unknown"],[866,47,"unknown"],[866,48,"unknown"],[866,49,"unknown"],[866,51,"catchable"],[867,33,"catchable"],[867,34,"catchable"],[867,35,"unknown"],[867,36,"unknown"],[867,37,"unknown"],[867,38,"unknown"],[867,39,"unknown"],[867,47,"unknown"],[867,48,"unknown"],[867,49,"unknown"],[868,33,"catchable"],[868,34,"catchable"],[868,35,"unknown"],[868,36,"unknown"],[868,37,"unknown"],[868,38,"unknown"],[868,39,"unknown"],[868,40,"unknown"],[868,41,"unknown"],[868,42,"unknown"],[868,43,"unknown"],[868,47,"unknown"],[868,48,"unknown"],[868,53,"unknown"],[869,33,"catchable"],[869,34,"catchable"],[869,35,"unknown"],[869,36,"catchable"],[869,37,"unknown"],[869,38,"unknown"],[869,39,"unknown"],[869,40,"unknown"],[869,41,"unknown"],[869,42,"unknown"],[869,43,"unknown"],[869,47,"unknown"],[869,48,"unknown"],[869,49,"unknown"],[869,51,"catchable"],[869,53,"unknown"],[870,33,"catchable"],[870,34,"catchable"],[870,35,"catchable"],[870,36,"catchable"],[870,37,"unknown"],[870,38,"unknown"],[870,39,"unknown"],[870,40,"unknown"],[870,41,"unknown"],[870,42,"unknown"],[870,43,"unknown"],[870,47,"unknown"],[870,48,"unknown"],[870,49,"unknown"],[870,50,"catchable"],[870,51,"catchable"],[871,33,"catchable"],[871,34,"catchable"],[871,35,"catchable"],[871,36,"catchable"],[871,37,"unknown"],[871,38,"unknown"],[871,39,"unknown"],[871,40,"unknown"],[871,41,"unknown"],[871,42,"unknown"],[871,43,"unknown"],[871,47,"unknown"],[871,48,"unknown"],[871,49,"unknown"],[871,50,"catchable"],[871,51,"catchable"],[872,33,"catchable"],[872,34,"catchable"],[872,35,"unknown"],[872,36,"catchable"],[872,37,"unknown"],[872,38,"unknown"],[872,39,"unknown"],[872,40,"unknown"],[872,41,"unknown"],[872,42,"unknown"],[872,43,"unknown"],[872,47,"unknown"],[872,48,"unknown"],[872,51,"catchable"],[873,33,"catchable"],[873,34,"catchable"],[873,35,"unknown"],[873,36,"catchable"],[873,37,"unknown"],[873,38,"unknown"],[873,39,"unknown"],[873,40,"unknown"],[873,41,"unknown"],[873,42,"unknown"],[873,43,"unknown"],[873,47,"unknown"],[873,48,"unknown"],[873,51,"catchable"],[874,33,"catchable"],[874,34,"unknown"],[874,35,"unknown"],[874,36,"catchable"],[874,37,"unknown"],[874,38,"unknown"],[874,39,"unknown"],[874,40,"unknown"],[874,41,"unknown"],[874,42,"unknown"],[874,43,"unknown"],[874,47,"unknown"],[874,48,"unknown"],[874,51,"unknown"],[875,33,"unknown"],[875,34,"catchable"],[875,35,"unknown"],[875,36,"unknown"],[875,37,"unknown"],[875,38,"unknown"],[875,39,"unknown"],[875,40,"unknown"],[875,41,"unknown"],[875,42,"unknown"],[875,43,"unknown"],[875,47,"unknown"],[875,48,"unknown"],[875,51,"catchable"],[876,33,"catchable"],[876,34,"catchable"],[876,35,"catchable"],[876,36,"catchable"],[876,37,"unknown"],[876,38,"unknown"],[876,39,"unknown"],[876,40,"unknown"],[876,41,"unknown"],[876,42,"unknown"],[876,43,"unknown"],[876,47,"unknown"],[876,48,"unknown"],[876,49,"unknown"],[876,50,"catchable"],[876,51,"catchable"],[876,52,"unknown"],[877,33,"catchable"],[877,34,"catchable"],[877,35,"catchable"],[877,36,"catchable"],[877,37,"unknown"],[877,38,"unknown"],[877,39,"unknown"],[877,40,"unknown"],[877,41,"unknown"],[877,42,"unknown"],[877,43,"unknown"],[877,47,"unknown"],[877,48,"unknown"],[877,49,"unknown"],[877,50,"catchable"],[877,51,"catchable"],[877,52,"unknown"],[878,33,"catchable"],[878,34,"catchable"],[878,35,"unknown"],[878,36,"catchable"],[878,37,"unknown"],[878,38,"unknown"],[878,39,"unknown"],[878,40,"unknown"],[878,41,"unknown"],[878,42,"unknown"],[878,43,"unknown"],[878,47,"unknown"],[878,48,"unknown"],[878,51,"catchable"],[879,33,"catchable"],[879,34,"catchable"],[879,35,"unknown"],[879,36,"catchable"],[879,37,"unknown"],[879,38,"unknown"],[879,39,"unknown"],[879,40,"unknown"],[879,41,"unknown"],[879,42,"unknown"],[879,43,"unknown"],[879,47,"unknown"],[879,48,"unknown"],[879,51,"catchable"],[880,33,"catchable"],[880,34,"catchable"],[880,35,"unknown"],[880,36,"catchable"],[880,37,"unknown"],[880,38,"unknown"],[880,39,"unknown"],[880,51,"catchable"],[881,33,"catchable"],[881,34,"catchable"],[881,35,"unknown"],[881,36,"catchable"],[881,37,"unknown"],[881,38,"unknown"],[881,39,"unknown"],[881,51,"catchable"],[882,33,"catchable"],[882,34,"catchable"],[882,35,"unknown"],[882,36,"catchable"],[882,37,"unknown"],[882,38,"unknown"],[882,39,"unknown"],[882,51,"catchable"],[883,33,"catchable"],[883,34,"catchable"],[883,35,"unknown"],[883,36,"catchable"],[883,37,"unknown"],[883,38,"unknown"],[883,39,"unknown"],[883,51,"catchable"],[884,33,"catchable"],[884,34,"catchable"],[884,35,"unknown"],[884,36,"catchable"],[884,37,"unknown"],[884,38,"unknown"],[884,39,"unknown"],[884,40,"unknown"],[884,41,"unknown"],[884,42,"unknown"],[884,43,"unknown"],[884,47,"unknown"],[884,48,"unknown"],[884,51,"catchable"],[884,53,"unknown"],[885,33,"catchable"],[885,34,"catchable"],[885,35,"unknown"],[885,36,"catchable"],[885,37,"unknown"],[885,38,"unknown"],[885,39,"unknown"],[885,40,"unknown"],[885,41,"unknown"],[885,42,"unknown"],[885,43,"unknown"],[885,47,"unknown"],[885,48,"unknown"],[885,51,"catchable"],[886,33,"catchable"],[886,34,"catchable"],[886,35,"unknown"],[886,36,"catchable"],[886,37,"unknown"],[886,38,"unknown"],[886,39,"unknown"],[886,40,"unknown"],[886,41,"unknown"],[886,42,"unknown"],[886,43,"unknown"],[886,47,"unknown"],[886,48,"unknown"],[886,51,"catchable"],[887,33,"catchable"],[887,34,"catchable"],[887,35,"unknown"],[887,36,"catchable"],[887,37,"unknown"],[887,38,"unknown"],[887,39,"unknown"],[887,40,"unknown"],[887,41,"unknown"],[887,42,"unknown"],[887,43,"unknown"],[887,47,"unknown"],[887,48,"unknown"],[887,49,"unknown"],[887,51,"catchable"],[888,33,"catchable"],[888,34,"unknown"],[888,35,"unknown"],[888,36,"unknown"],[888,37,"unknown"],[888,38,"unknown"],[888,39,"unknown"],[888,40,"unknown"],[888,41,"unknown"],[888,42,"unknown"],[888,43,"unknown"],[888,47,"unknown"],[888,48,"unknown"],[889,33,"unknown"],[889,34,"catchable"],[889,35,"unknown"],[889,36,"unknown"],[889,37,"unknown"],[889,38,"unknown"],[889,39,"unknown"],[889,40,"unknown"],[889,41,"unknown"],[889,42,"unknown"],[889,43,"unknown"],[889,47,"unknown"],[889,48,"unknown"],[890,33,"catchable"],[890,34,"catchable"],[890,35,"unknown"],[890,36,"unknown"],[890,37,"unknown"],[890,38,"unknown"],[890,39,"unknown"],[890,40,"unknown"],[890,41,"unknown"],[890,42,"unknown"],[890,43,"unknown"],[890,47,"unknown"],[890,48,"unknown"],[891,33,"unknown"],[891,34,"unknown"],[891,35,"catchable"],[891,36,"unknown"],[891,37,"unknown"],[891,38,"unknown"],[891,39,"unknown"],[891,40,"unknown"],[891,41,"unknown"],[891,42,"unknown"],[891,43,"unknown"],[891,47,"unknown"],[891,48,"unknown"],[891,50,"catchable"],[892,33,"unknown"],[892,34,"unknown"],[892,35,"unknown"],[892,36,"unknown"],[892,37,"unknown"],[892,38,"unknown"],[892,39,"unknown"],[892,40,"unknown"],[892,41,"unknown"],[892,42,"unknown"],[892,43,"unknown"],[892,47,"unknown"],[892,48,"unknown"],[892,50,"unknown"],[893,33,"unknown"],[893,34,"unknown"],[893,35,"unknown"],[893,36,"unknown"],[893,37,"unknown"],[893,38,"unknown"],[893,39,"unknown"],[893,40,"unknown"],[893,41,"unknown"],[893,42,"unknown"],[893,43,"unknown"],[893,47,"unknown"],[893,48,"unknown"],[893,50,"unknown"],[894,33,"unknown"],[894,34,"unknown"],[894,35,"unknown"],[894,36,"catchable"],[894,37,"unknown"],[894,38,"unknown"],[894,39,"unknown"],[894,40,"unknown"],[894,41,"unknown"],[894,42,"unknown"],[894,43,"unknown"],[894,47,"unknown"],[894,48,"unknown"],[894,51,"catchable"],[895,33,"unknown"],[895,34,"unknown"],[895,35,"unknown"],[895,36,"catchable"],[895,37,"unknown"],[895,38,"unknown"],[895,39,"unknown"],[895,40,"unknown"],[895,41,"unknown"],[895,42,"unknown"],[895,43,"unknown"],[895,47,"unknown"],[895,48,"unknown"],[895,51,"catchable"],[896,33,"unknown"],[896,34,"unknown"],[896,35,"unknown"],[896,36,"catchable"],[896,37,"unknown"],[896,38,"unknown"],[896,39,"unknown"],[896,40,"unknown"],[896,41,"unknown"],[896,42,"unknown"],[896,43,"unknown"],[896,47,"unknown"],[896,48,"unknown"],[896,51,"catchable"],[897,33,"unknown"],[897,34,"unknown"],[897,35,"unknown"],[897,36,"catchable"],[897,37,"unknown"],[897,38,"unknown"],[897,39,"unknown"],[897,40,"unknown"],[897,41,"unknown"],[897,42,"unknown"],[897,43,"unknown"],[897,47,"unknown"],[897,48,"unknown"],[897,51,"catchable"],[898,33,"unknown"],[898,34,"unknown"],[898,35,"unknown"],[898,36,"catchable"],[898,37,"unknown"],[898,38,"unknown"],[898,39,"unknown"],[898,40,"unknown"],[898,41,"unknown"],[898,42,"unknown"],[898,43,"unknown"],[898,47,"unknown"],[898,48,"unknown"],[898,51,"catchable"],[899,39,"unknown"],[899,40,"unknown"],[899,41,"unknown"],[899,42,"unknown"],[899,43,"unknown"],[899,47,"unknown"],[899,48,"unknown"],[899,49,"unknown"],[900,39,"unknown"],[900,40,"unknown"],[900,41,"unknown"],[900,42,"unknown"],[900,43,"unknown"],[900,47,"unknown"],[900,48,"unknown"],[900,49,"unknown"],[900,53,"unknown"],[901,39,"unknown"],[901,40,"unknown"],[901,41,"unknown"],[901,42,"unknown"],[901,43,"unknown"],[901,47,"unknown"],[901,48,"unknown"],[901,52,"unknown"],[902,39,"unknown"],[902,40,"unknown"],[902,41,"unknown"],[902,42,"unknown"],[902,43,"unknown"],[902,47,"unknown"],[902,48,"unknown"],[902,49,"unknown"],[902,52,"unknown"],[903,39,"unknown"],[903,40,"unknown"],[903,41,"unknown"],[903,42,"unknown"],[903,43,"unknown"],[903,47,"unknown"],[903,48,"unknown"],[903,49,"unknown"],[904,39,"unknown"],[904,40,"unknown"],[904,41,"unknown"],[904,42,"unknown"],[904,43,"unknown"],[904,47,"unknown"],[904,48,"unknown"],[904,49,"unknown"],[904,53,"unknown"],[905,39,"unknown"],[905,40,"unknown"],[905,41,"unknown"],[905,42,"unknown"],[905,43,"unknown"],[905,47,"unknown"],[905,48,"unknown"],[906,40,"unknown"],[906,41,"unknown"],[906,42,"unknown"],[906,43,"unknown"],[906,47,"unknown"],[906,48,"unknown"],[907,40,"unknown"],[907,41,"unknown"],[907,42,"unknown"],[907,43,"unknown"],[907,47,"unknown"],[907,48,"unknown"],[908,40,"unknown"],[908,41,"unknown"],[908,42,"unknown"],[908,43,"unknown"],[908,47,"unknown"],[908,48,"unknown"],[908,49,"unknown"],[909,40,"unknown"],[909,41,"unknown"],[909,42,"unknown"],[909,43,"unknown"],[909,47,"unknown"],[909,48,"unknown"],[910,40,"unknown"],[910,41,"unknown"],[910,42,"unknown"],[910,43,"unknown"],[910,47,"unknown"],[910,48,"unknown"],[911,40,"unknown"],[911,41,"unknown"],[911,42,"unknown"],[911,43,"unknown"],[911,47,"unknown"],[911,48,"unknown"],[911,49,"unknown"],[912,40,"unknown"],[912,41,"unknown"],[912,42,"unknown"],[912,43,"unknown"],[912,47,"unknown"],[912,48,"unknown"],[913,40,"unknown"],[913,41,"unknown"],[913,42,"unknown"],[913,43,"unknown"],[913,47,"unknown"],[913,48,"unknown"],[914,40,"unknown"],[914,41,"unknown"],[914,42,"unknown"],[914,43,"unknown"],[914,47,"unknown"],[914,48,"unknown"],[914,49,"unknown"],[915,40,"unknown"],[915,41,"unknown"],[915,42,"unknown"],[915,43,"unknown"],[915,47,"unknown"],[915,48,"unknown"],[916,40,"unknown"],[916,41,"unknown"],[916,42,"unknown"],[916,43,"unknown"],[916,47,"unknown"],[916,48,"unknown"],[917,40,"unknown"],[917,41,"unknown"],[917,42,"unknown"],[917,43,"unknown"],[917,47,"unknown"],[917,48,"unknown"],[918,40,"unknown"],[918,41,"unknown"],[918,42,"unknown"],[918,43,"unknown"],[918,47,"unknown"],[918,48,"unknown"],[919,40,"unknown"],[919,41,"unknown"],[919,42,"unknown"],[919,43,"unknown"],[919,47,"unknown"],[919,48,"unknown"],[920,40,"unknown"],[920,41,"unknown"],[920,42,"unknown"],[920,43,"unknown"],[920,47,"unknown"],[920,48,"unknown"],[921,40,"unknown"],[921,41,"unknown"],[921,42,"unknown"],[921,43,"unknown"],[921,47,"unknown"],[921,48,"unknown"],[922,40,"unknown"],[922,41,"unknown"],[922,42,"unknown"],[922,43,"unknown"],[922,47,"unknown"],[922,48,"unknown"],[923,40,"unknown"],[923,41,"unknown"],[923,42,"unknown"],[923,43,"unknown"],[923,47,"unknown"],[923,48,"unknown"],[923,49,"unknown"],[924,40,"unknown"],[924,41,"unknown"],[924,42,"unknown"],[924,43,"unknown"],[924,47,"unknown"],[924,48,"unknown"],[924,52,"unknown"],[925,40,"unknown"],[925,41,"unknown"],[925,42,"unknown"],[925,43,"unknown"],[925,47,"unknown"],[925,48,"unknown"],[925,49,"unknown"],[925,52,"unknown"],[926,40,"unknown"],[926,41,"unknown"],[926,42,"unknown"],[926,43,"unknown"],[926,47,"unknown"],[926,48,"unknown"],[927,40,"unknown"],[927,41,"unknown"],[927,42,"unknown"],[927,43,"unknown"],[927,47,"unknown"],[927,48,"unknown"],[928,40,"unknown"],[928,41,"unknown"],[928,42,"unknown"],[928,43,"unknown"],[928,47,"unknown"],[928,48,"unknown"],[929,40,"unknown"],[929,41,"unknown"],[929,42,"unknown"],[929,43,"unknown"],[929,47,"unknown"],[929,48,"unknown"],[930,40,"unknown"],[930,41,"unknown"],[930,42,"unknown"],[930,43,"unknown"],[930,47,"unknown"],[930,48,"unknown"],[930,49,"unknown"],[931,40,"unknown"],[931,41,"unknown"],[931,42,"unknown"],[931,43,"unknown"],[931,47,"unknown"],[931,48,"unknown"],[931,49,"unknown"],[932,40,"unknown"],[932,41,"unknown"],[932,42,"unknown"],[932,43,"unknown"],[932,47,"unknown"],[932,48,"unknown"],[933,40,"unknown"],[933,41,"unknown"],[933,42,"unknown"],[933,43,"unknown"],[933,47,"unknown"],[933,48,"unknown"],[934,40,"unknown"],[934,41,"unknown"],[934,42,"unknown"],[934,43,"unknown"],[934,47,"unknown"],[934,48,"unknown"],[934,49,"unknown"],[935,40,"unknown"],[935,41,"unknown"],[935,42,"unknown"],[935,43,"unknown"],[935,47,"unknown"],[935,48,"unknown"],[936,40,"unknown"],[936,41,"unknown"],[936,42,"unknown"],[936,43,"unknown"],[936,47,"unknown"],[936,48,"unknown"],[936,49,"unknown"],[937,40,"unknown"],[937,41,"unknown"],[937,42,"unknown"],[937,43,"unknown"],[937,47,"unknown"],[937,48,"unknown"],[937,49,"unknown"],[938,40,"unknown"],[938,41,"unknown"],[938,42,"unknown"],[938,43,"unknown"],[938,47,"unknown"],[938,48,"unknown"],[939,40,"unknown"],[939,41,"unknown"],[939,42,"unknown"],[939,43,"unknown"],[939,47,"unknown"],[939,48,"unknown"],[939,49,"unknown"],[940,40,"unknown"],[940,41,"unknown"],[940,42,"unknown"],[940,43,"unknown"],[940,47,"unknown"],[940,48,"unknown"],[941,40,"unknown"],[941,41,"unknown"],[941,42,"unknown"],[941,43,"unknown"],[941,47,"unknown"],[941,48,"unknown"],[942,40,"unknown"],[942,41,"unknown"],[942,42,"unknown"],[942,43,"unknown"],[942,47,"unknown"],[942,48,"unknown"],[943,40,"unknown"],[943,41,"unknown"],[943,42,"unknown"],[943,43,"unknown"],[943,47,"unknown"],[943,48,"unknown"],[943,49,"unknown"],[944,40,"unknown"],[944,41,"unknown"],[944,42,"unknown"],[944,43,"unknown"],[944,47,"unknown"],[944,48,"unknown"],[945,40,"unknown"],[945,41,"unknown"],[945,42,"unknown"],[945,43,"unknown"],[945,47,"unknown"],[945,48,"unknown"],[946,40,"unknown"],[946,41,"unknown"],[946,42,"unknown"],[946,43,"unknown"],[946,47,"unknown"],[946,48,"unknown"],[947,40,"unknown"],[947,41,"unknown"],[947,42,"unknown"],[947,43,"unknown"],[947,47,"unknown"],[947,48,"unknown"],[948,40,"unknown"],[948,41,"unknown"],[948,42,"unknown"],[948,43,"unknown"],[948,47,"unknown"],[948,48,"unknown"],[948,52,"unknown"],[949,40,"unknown"],[949,41,"unknown"],[949,42,"unknown"],[949,43,"unknown"],[949,47,"unknown"],[949,48,"unknown"],[949,52,"unknown"],[950,40,"unknown"],[950,41,"unknown"],[950,42,"unknown"],[950,43,"unknown"],[950,47,"unknown"],[950,48,"unknown"],[951,40,"unknown"],[951,41,"unknown"],[951,42,"unknown"],[951,43,"unknown"],[951,47,"unknown"],[951,48,"unknown"],[952,40,"unknown"],[952,41,"unknown"],[952,42,"unknown"],[952,43,"unknown"],[952,47,"unknown"],[952,48,"unknown"],[952,49,"unknown"],[953,40,"unknown"],[953,41,"unknown"],[953,42,"unknown"],[953,43,"unknown"],[953,47,"unknown"],[953,48,"unknown"],[953,53,"unknown"],[954,40,"unknown"],[954,41,"unknown"],[954,42,"unknown"],[954,43,"unknown"],[954,47,"unknown"],[954,48,"unknown"],[954,53,"unknown"],[955,40,"unknown"],[955,41,"unknown"],[955,42,"unknown"],[955,43,"unknown"],[955,47,"unknown"],[955,48,"unknown"],[956,40,"unknown"],[956,41,"unknown"],[956,42,"unknown"],[956,43,"unknown"],[956,47,"unknown"],[956,48,"unknown"],[956,49,"unknown"],[957,40,"unknown"],[957,41,"unknown"],[957,42,"unknown"],[957,43,"unknown"],[957,47,"unknown"],[957,48,"unknown"],[958,40,"unknown"],[958,41,"unknown"],[958,42,"unknown"],[958,43,"unknown"],[958,47,"unknown"],[958,48,"unknown"],[959,40,"unknown"],[959,41,"unknown"],[959,42,"unknown"],[959,43,"unknown"],[959,47,"unknown"],[959,48,"unknown"],[959,49,"unknown"],[960,40,"unknown"],[960,41,"unknown"],[960,42,"unknown"],[960,43,"unknown"],[960,47,"unknown"],[960,48,"unknown"],[961,40,"unknown"],[961,41,"unknown"],[961,42,"unknown"],[961,43,"unknown"],[961,47,"unknown"],[961,48,"unknown"],[962,40,"unknown"],[962,41,"unknown"],[962,42,"unknown"],[962,43,"unknown"],[962,47,"unknown"],[962,48,"unknown"],[962,52,"unknown"],[963,40,"unknown"],[963,41,"unknown"],[963,42,"unknown"],[963,43,"unknown"],[963,47,"unknown"],[963,48,"unknown"],[964,40,"unknown"],[964,41,"unknown"],[964,42,"unknown"],[964,43,"unknown"],[964,47,"unknown"],[964,48,"unknown"],[964,49,"unknown"],[965,40,"unknown"],[965,41,"unknown"],[965,42,"unknown"],[965,43,"unknown"],[965,47,"unknown"],[965,48,"unknown"],[966,40,"unknown"],[966,41,"unknown"],[966,42,"unknown"],[966,43,"unknown"],[966,47,"unknown"],[966,48,"unknown"],[967,40,"unknown"],[967,41,"unknown"],[967,42,"unknown"],[967,43,"unknown"],[967,47,"unknown"],[967,48,"unknown"],[968,40,"unknown"],[968,41,"unknown"],[968,42,"unknown"],[968,43,"unknown"],[968,47,"unknown"],[968,48,"unknown"],[968,49,"unknown"],[968,52,"unknown"],[969,40,"unknown"],[969,41,"unknown"],[969,42,"unknown"],[969,43,"unknown"],[969,47,"unknown"],[969,48,"unknown"],[969,52,"unknown"],[970,40,"unknown"],[970,41,"unknown"],[970,42,"unknown"],[970,43,"unknown"],[970,47,"unknown"],[970,48,"unknown"],[970,49,"unknown"],[970,52,"unknown"],[971,40,"unknown"],[971,41,"unknown"],[971,42,"unknown"],[971,43,"unknown"],[971,47,"unknown"],[971,48,"unknown"],[972,40,"unknown"],[972,41,"unknown"],[972,42,"unknown"],[972,43,"unknown"],[972,47,"unknown"],[972,48,"unknown"],[972,49,"unknown"],[973,40,"unknown"],[973,41,"unknown"],[973,42,"unknown"],[973,43,"unknown"],[973,47,"unknown"],[973,48,"unknown"],[974,40,"unknown"],[974,41,"unknown"],[974,42,"unknown"],[974,43,"unknown"],[974,47,"unknown"],[974,48,"unknown"],[975,40,"unknown"],[975,41,"unknown"],[975,42,"unknown"],[975,43,"unknown"],[975,47,"unknown"],[975,48,"unknown"],[976,40,"unknown"],[976,41,"unknown"],[976,42,"unknown"],[976,43,"unknown"],[976,47,"unknown"],[976,48,"unknown"],[977,40,"unknown"],[977,41,"unknown"],[977,42,"unknown"],[977,43,"unknown"],[977,47,"unknown"],[977,48,"unknown"],[978,40,"unknown"],[978,41,"unknown"],[978,42,"unknown"],[978,43,"unknown"],[978,47,"unknown"],[978,48,"unknown"],[979,40,"unknown"],[979,41,"unknown"],[979,42,"unknown"],[979,43,"unknown"],[979,47,"unknown"],[979,48,"unknown"],[979,49,"unknown"],[979,52,"unknown"],[980,40,"unknown"],[980,41,"unknown"],[980,42,"unknown"],[980,43,"unknown"],[980,47,"unknown"],[980,48,"unknown"],[981,40,"unknown"],[981,41,"unknown"],[981,42,"unknown"],[981,43,"unknown"],[981,47,"unknown"],[981,48,"unknown"],[981,49,"unknown"],[981,53,"unknown"],[982,40,"unknown"],[982,41,"unknown"],[982,42,"unknown"],[982,43,"unknown"],[982,47,"unknown"],[982,48,"unknown"],[982,52,"unknown"],[983,40,"unknown"],[983,41,"unknown"],[983,42,"unknown"],[983,43,"unknown"],[983,47,"unknown"],[983,48,"unknown"],[983,49,"unknown"],[983,52,"unknown"],[984,40,"unknown"],[984,41,"unknown"],[984,42,"unknown"],[984,43,"unknown"],[984,47,"unknown"],[984,48,"unknown"],[985,40,"unknown"],[985,41,"unknown"],[985,42,"unknown"],[985,43,"unknown"],[985,47,"unknown"],[985,48,"unknown"],[986,40,"unknown"],[986,41,"unknown"],[986,42,"unknown"],[986,43,"unknown"],[986,47,"unknown"],[986,48,"unknown"],[987,40,"unknown"],[987,41,"unknown"],[987,42,"unknown"],[987,43,"unknown"],[987,47,"unknown"],[987,48,"unknown"],[988,40,"unknown"],[988,41,"unknown"],[988,42,"unknown"],[988,43,"unknown"],[988,47,"unknown"],[988,48,"unknown"],[989,40,"unknown"],[989,41,"unknown"],[989,42,"unknown"],[989,43,"unknown"],[989,47,"unknown"],[989,48,"unknown"],[990,40,"unknown"],[990,41,"unknown"],[990,42,"unknown"],[990,43,"unknown"],[990,47,"unknown"],[990,48,"unknown"],[991,40,"unknown"],[991,41,"unknown"],[991,42,"unknown"],[991,43,"unknown"],[991,47,"unknown"],[991,48,"unknown"],[992,40,"unknown"],[992,41,"unknown"],[992,42,"unknown"],[992,43,"unknown"],[992,47,"unknown"],[992,48,"unknown"],[993,40,"unknown"],[993,41,"unknown"],[993,42,"unknown"],[993,43,"unknown"],[993,47,"unknown"],[993,48,"unknown"],[994,40,"unknown"],[994,41,"unknown"],[994,42,"unknown"],[994,43,"unknown"],[994,47,"unknown"],[994,48,"unknown"],[995,40,"unknown"],[995,41,"unknown"],[995,42,"unknown"],[995,43,"unknown"],[995,47,"unknown"],[995,48,"unknown"],[996,40,"unknown"],[996,41,"unknown"],[996,42,"unknown"],[996,43,"unknown"],[996,47,"unknown"],[996,48,"unknown"],[997,40,"unknown"],[997,41,"unknown"],[997,42,"unknown"],[997,43,"unknown"],[997,47,"unknown"],[997,48,"unknown"],[998,40,"unknown"],[998,41,"unknown"],[998,42,"unknown"],[998,43,"unknown"],[998,47,"unknown"],[998,48,"unknown"],[998,49,"unknown"],[999,40,"unknown"],[999,41,"unknown"],[999,42,"unknown"],[999,43,"unknown"],[999,47,"unknown"],[999,48,"unknown"],[1000,40,"unknown"],[1000,41,"unknown"],[1000,42,"unknown"],[1000,43,"unknown"],[1000,47,"unknown"],[1000,48,"unknown"],[1000,49,"unknown"],[1001,40,"unknown"],[1001,41,"unknown"],[1001,42,"unknown"],[1001,43,"unknown"],[1001,47,"unknown"],[1001,48,"unknown"],[1002,40,"unknown"],[1002,41,"unknown"],[1002,42,"unknown"],[1002,43,"unknown"],[1002,47,"unknown"],[1002,48,"unknown"],[1003,40,"unknown"],[1003,41,"unknown"],[1003,42,"unknown"],[1003,43,"unknown"],[1003,47,"unknown"],[1003,48,"unknown"],[1004,40,"unknown"],[1004,41,"unknown"],[1004,42,"unknown"],[1004,43,"unknown"],[1004,47,"unknown"],[1004,48,"unknown"],[1005,40,"unknown"],[1005,41,"unknown"],[1005,42,"unknown"],[1005,43,"unknown"],[1005,47,"unknown"],[1005,48,"unknown"],[1006,40,"unknown"],[1006,41,"unknown"],[1006,42,"unknown"],[1006,43,"unknown"],[1006,47,"unknown"],[1006,48,"unknown"],[1007,40,"unknown"],[1007,41,"unknown"],[1007,42,"unknown"],[1007,43,"unknown"],[1007,47,"unknown"],[1007,48,"unknown"],[1008,40,"unknown"],[1008,41,"unknown"],[1008,42,"unknown"],[1008,43,"unknown"],[1008,47,"unknown"],[1008,48,"unknown"],[1009,40,"unknown"],[1009,41,"unknown"],[1009,42,"unknown"],[1009,43,"unknown"],[1009,47,"unknown"],[1009,48,"unknown"],[1009,53,"unknown"],[1010,40,"unknown"],[1010,41,"unknown"],[1010,42,"unknown"],[1010,43,"unknown"],[1010,47,"unknown"],[1010,48,"unknown"],[1010,53,"unknown"],[1011,40,"unknown"],[1011,41,"unknown"],[1011,42,"unknown"],[1011,43,"unknown"],[1011,47,"unknown"],[1011,48,"unknown"],[1011,52,"unknown"],[1012,40,"unknown"],[1012,41,"unknown"],[1012,42,"unknown"],[1012,43,"unknown"],[1012,47,"unknown"],[1012,48,"unknown"],[1012,52,"unknown"],[1013,40,"unknown"],[1013,41,"unknown"],[1013,42,"unknown"],[1013,43,"unknown"],[1013,47,"unknown"],[1013,48,"unknown"],[1013,49,"unknown"],[1013,52,"unknown"],[1014,40,"unknown"],[1014,41,"unknown"],[1014,42,"unknown"],[1014,43,"unknown"],[1014,47,"unknown"],[1014,48,"unknown"],[1014,52,"unknown"],[1015,40,"unknown"],[1015,41,"unknown"],[1015,42,"unknown"],[1015,43,"unknown"],[1015,47,"unknown"],[1015,48,"unknown"],[1015,52,"unknown"],[1016,40,"unknown"],[1016,41,"unknown"],[1016,42,"unknown"],[1016,43,"unknown"],[1016,47,"unknown"],[1016,48,"unknown"],[1016,52,"unknown"],[1017,40,"unknown"],[1017,41,"unknown"],[1017,42,"unknown"],[1017,43,"unknown"],[1017,47,"unknown"],[1017,48,"unknown"],[1017,52,"unknown"],[1018,40,"unknown"],[1018,41,"unknown"],[1018,42,"unknown"],[1018,43,"unknown"],[1018,47,"unknown"],[1018,48,"unknown"],[1018,49,"unknown"],[1018,53,"unknown"],[1019,40,"unknown"],[1019,41,"unknown"],[1019,42,"unknown"],[1019,43,"unknown"],[1019,47,"unknown"],[1019,48,"unknown"],[1019,49,"unknown"],[1019,53,"unknown"],[1020,40,"unknown"],[1020,41,"unknown"],[1020,42,"unknown"],[1020,43,"unknown"],[1020,47,"unknown"],[1020,48,"unknown"],[1020,53,"unknown"],[1021,40,"unknown"],[1021,41,"unknown"],[1021,42,"unknown"],[1021,43,"unknown"],[1021,47,"unknown"],[1021,48,"unknown"],[1021,53,"unknown"],[1022,40,"unknown"],[1022,41,"unknown"],[1022,42,"unknown"],[1022,43,"unknown"],[1022,47,"unknown"],[1022,48,"unknown"],[1022,53,"unknown"],[1023,40,"unknown"],[1023,41,"unknown"],[1023,42,"unknown"],[1023,43,"unknown"],[1023,47,"unknown"],[1023,48,"unknown"],[1023,53,"unknown"],[1024,40,"unknown"],[1024,41,"unknown"],[1024,42,"unknown"],[1024,43,"unknown"],[1024,47,"unknown"],[1024,48,"unknown"],[1024,53,"unknown"],[1025,40,"unknown"],[1025,41,"unknown"],[1025,42,"unknown"],[1025,43,"unknown"],[1025,47,"unknown"],[1025,48,"unknown"],[1025,53,"unknown"]]} diff --git a/drizzle.config.ts b/drizzle.config.ts index fc368b0..3b1bd5b 100755 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from 'drizzle-kit'; export default defineConfig({ dialect: 'postgresql', - schema: './src/lib/server/db/schema.ts', + schema: './src/lib/server/db/schema/index.ts', out: './drizzle', verbose: true, strict: true, diff --git a/package.json b/package.json index f0938a0..447f455 100755 --- a/package.json +++ b/package.json @@ -17,9 +17,12 @@ "db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate", "db:studio": "drizzle-kit studio", - "db:seed": "bun scripts/seed.ts", - "db:reset": "bun scripts/reset.ts && drizzle-kit push --force && bun scripts/seed.ts", - "auth:schema": "bunx @better-auth/cli generate --config src/lib/server/auth.ts --output src/lib/server/db/auth.schema.ts --yes" + "db:seed": "bun scripts/seed-catalog.ts", + "db:migrate:auth": "bun scripts/migrate-auth-catalog.ts", + "db:migrate:foundation": "bun scripts/migrate-foundation.ts", + "auth:role": "bun scripts/set-admin.ts", + "catalog:build": "python3 scripts/build-pokemon-catalog.py", + "test:auth": "node --env-file=.env node_modules/@playwright/test/cli.js test --config playwright.auth.config.ts" }, "devDependencies": { "@eslint/js": "^10.0.1", diff --git a/playwright.auth.config.ts b/playwright.auth.config.ts new file mode 100644 index 0000000..957ed10 --- /dev/null +++ b/playwright.auth.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from '@playwright/test'; +process.env.AUTH_E2E = '1'; +export default defineConfig({ + testDir: 'tests', + testMatch: 'auth.test.ts', + workers: 1, + use: { baseURL: 'http://127.0.0.1:4174' }, + webServer: { + command: 'npm run dev -- --host 127.0.0.1 --port 4174 --strictPort', + url: 'http://127.0.0.1:4174/login', + env: { ORIGIN: 'http://127.0.0.1:4174', BETTER_AUTH_URL: 'http://127.0.0.1:4174' }, + timeout: 60000 + } +}); diff --git a/scripts/animaldex-uuid-to-serial.sql b/scripts/animaldex-uuid-to-serial.sql new file mode 100644 index 0000000..e17d6b3 --- /dev/null +++ b/scripts/animaldex-uuid-to-serial.sql @@ -0,0 +1,84 @@ +-- One-off: convert animaldex ids from uuid to serial, keeping existing rows. +-- Postgres can't cast uuid -> integer, so db:push can't do this itself. +-- +-- Run BEFORE re-running db:push, once per database: +-- psql "$DB_URL" -v ON_ERROR_STOP=1 -f scripts/animaldex-uuid-to-serial.sql +-- +-- Safe to run on an empty database too. Everything is in one transaction, so a +-- failure leaves the database untouched. + +BEGIN; + +-- the failed push created this before erroring out +DROP SEQUENCE IF EXISTS animals_id_seq; + +-- 1. new integer ids alongside the uuid ones +ALTER TABLE animals ADD COLUMN new_id serial; +ALTER TABLE sightings ADD COLUMN new_id serial; +ALTER TABLE photos ADD COLUMN new_id serial; + +-- 2. translate the foreign keys through the uuid -> integer mapping +ALTER TABLE sightings ADD COLUMN new_animal_id integer; +UPDATE sightings s SET new_animal_id = a.new_id FROM animals a WHERE a.id = s.animal_id; + +ALTER TABLE photos ADD COLUMN new_sighting_id integer; +UPDATE photos p SET new_sighting_id = s.new_id FROM sightings s WHERE s.id = p.sighting_id; + +-- 3. drop the old foreign keys (names vary by how they were created) +DO $$ +DECLARE r record; +BEGIN + FOR r IN + SELECT conrelid::regclass AS tbl, conname + FROM pg_constraint + WHERE contype = 'f' AND conrelid IN ('sightings'::regclass, 'photos'::regclass) + LOOP + EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %I', r.tbl, r.conname); + END LOOP; +END $$; + +-- 4. swap the foreign key columns +ALTER TABLE photos DROP COLUMN sighting_id; +ALTER TABLE photos RENAME COLUMN new_sighting_id TO sighting_id; +ALTER TABLE photos ALTER COLUMN sighting_id SET NOT NULL; + +ALTER TABLE sightings DROP COLUMN animal_id; +ALTER TABLE sightings RENAME COLUMN new_animal_id TO animal_id; +ALTER TABLE sightings ALTER COLUMN animal_id SET NOT NULL; + +-- 5. swap the primary keys +DO $$ +DECLARE r record; +BEGIN + FOR r IN + SELECT conrelid::regclass AS tbl, conname + FROM pg_constraint + WHERE contype = 'p' + AND conrelid IN ('animals'::regclass, 'sightings'::regclass, 'photos'::regclass) + LOOP + EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %I', r.tbl, r.conname); + END LOOP; +END $$; + +ALTER TABLE animals DROP COLUMN id; +ALTER TABLE animals RENAME COLUMN new_id TO id; +ALTER TABLE animals ADD PRIMARY KEY (id); +ALTER SEQUENCE animals_new_id_seq RENAME TO animals_id_seq; + +ALTER TABLE sightings DROP COLUMN id; +ALTER TABLE sightings RENAME COLUMN new_id TO id; +ALTER TABLE sightings ADD PRIMARY KEY (id); +ALTER SEQUENCE sightings_new_id_seq RENAME TO sightings_id_seq; + +ALTER TABLE photos DROP COLUMN id; +ALTER TABLE photos RENAME COLUMN new_id TO id; +ALTER TABLE photos ADD PRIMARY KEY (id); +ALTER SEQUENCE photos_new_id_seq RENAME TO photos_id_seq; + +-- 6. restore the foreign keys under the names drizzle expects +ALTER TABLE sightings ADD CONSTRAINT sightings_animal_id_animals_id_fkey + FOREIGN KEY (animal_id) REFERENCES animals(id) ON DELETE CASCADE; +ALTER TABLE photos ADD CONSTRAINT photos_sighting_id_sightings_id_fkey + FOREIGN KEY (sighting_id) REFERENCES sightings(id) ON DELETE CASCADE; + +COMMIT; diff --git a/scripts/auth-catalog-migration.sql b/scripts/auth-catalog-migration.sql new file mode 100644 index 0000000..555d67a --- /dev/null +++ b/scripts/auth-catalog-migration.sql @@ -0,0 +1,18 @@ +-- Additive migration for the existing domain schema. No users or progress are removed. +ALTER TABLE "user" ADD COLUMN IF NOT EXISTS role text NOT NULL DEFAULT 'user'; +ALTER TABLE account ADD COLUMN IF NOT EXISTS issuer text; +-- Existing credentials use Better Auth's local namespace. Fail on unknown legacy +-- OAuth providers rather than silently changing which remote identity they trust. +UPDATE account SET issuer = 'local:credential' WHERE issuer IS NULL AND provider_id = 'credential'; +UPDATE account SET issuer = 'https://accounts.google.com' WHERE issuer IS NULL AND provider_id = 'google'; +UPDATE account SET issuer = 'local:oauth:github' WHERE issuer IS NULL AND provider_id = 'github'; +UPDATE account SET issuer = 'local:oauth:osu' WHERE issuer IS NULL AND provider_id = 'osu'; +ALTER TABLE account ALTER COLUMN issuer SET NOT NULL; +CREATE UNIQUE INDEX IF NOT EXISTS account_issuer_account_id_unique ON account (issuer, account_id); +ALTER TABLE games ADD COLUMN IF NOT EXISTS source_id integer; +CREATE UNIQUE INDEX IF NOT EXISTS games_source_id_unique ON games (source_id); +CREATE UNIQUE INDEX IF NOT EXISTS pokemon_number_unique ON pokemon (number); +ALTER TYPE availability ADD VALUE IF NOT EXISTS 'unknown'; +CREATE TABLE IF NOT EXISTS catch_em_all_settings ( + user_id text PRIMARY KEY REFERENCES "user"(id) ON DELETE CASCADE +); diff --git a/scripts/build-pokemon-catalog.py b/scripts/build-pokemon-catalog.py new file mode 100644 index 0000000..512800f --- /dev/null +++ b/scripts/build-pokemon-catalog.py @@ -0,0 +1,96 @@ +"""Build the species-level catalog from a pinned PokéAPI CSV snapshot. + +Run with --source-dir to reuse downloaded CSVs. Default downloads into a temporary +folder. Encounter absence is not evidence of trade/transfer/event exclusivity. +""" +import argparse +import concurrent.futures +import csv +import json +from pathlib import Path +import tempfile +import urllib.request + +REVISION = '575291cdb197a7e3a320297be276c9de4ef8401a' +TABLES = ['pokemon', 'pokemon_species', 'pokemon_species_names', 'pokemon_types', + 'pokemon_stats', 'type_names', 'versions', 'version_names', 'version_groups', + 'pokemon_dex_numbers', 'pokedex_version_groups', 'pokemon_game_indices', 'encounters'] + + +def build(directory): + def rows(name): + with (directory / f'{name}.csv').open() as f: + return list(csv.DictReader(f)) + + species = rows('pokemon_species') + pokemon = rows('pokemon') + species_for = {int(p['id']): int(p['species_id']) for p in pokemon} + defaults = {int(p['species_id']): int(p['id']) for p in pokemon if p['is_default'] == '1'} + names = {int(p['pokemon_species_id']): p['name'] for p in rows('pokemon_species_names') if p['local_language_id'] == '9'} + type_names = {int(t['type_id']): t['name'] for t in rows('type_names') if t['local_language_id'] == '9'} + types = {} + for p in rows('pokemon_types'): + types.setdefault(int(p['pokemon_id']), {})[int(p['slot'])] = type_names[int(p['type_id'])] + stats = {} + for p in rows('pokemon_stats'): + stats.setdefault(int(p['pokemon_id']), {})[int(p['stat_id'])] = int(p['base_stat']) + stat_fields = ['hp', 'attack', 'defense', 'specialAttack', 'specialDefense', 'speed'] + mons = [] + for s in species: + number = int(s['id']) + default = defaults[number] + mons.append(dict(number=number, name=names[number], generation=int(s['generation_id']), + type1=types[default][1], type2=types[default].get(2), + **{name: stats[default][i + 1] for i, name in enumerate(stat_fields)})) + + groups = {int(g['id']): g for g in rows('version_groups')} + versions = rows('versions') + game_names = {int(v['version_id']): v['name'] for v in rows('version_names') if v['local_language_id'] == '9'} + games = [dict(sourceId=int(v['id']), name=game_names.get(int(v['id']), v['identifier'].replace('-', ' ').title()), + generation=int(groups[int(v['version_group_id'])]['generation_id'])) for v in versions] + for game, version in zip(games, versions): + if version['identifier'].endswith('-japan'): + game['name'] += ' (Japan)' + versions_for_group = {} + for v in versions: + versions_for_group.setdefault(int(v['version_group_id']), []).append(int(v['id'])) + groups_for_dex = {} + for d in rows('pokedex_version_groups'): + groups_for_dex.setdefault(int(d['pokedex_id']), []).append(int(d['version_group_id'])) + entries = {} + # Membership and internal game indices establish presence, not how it is obtained. + for p in rows('pokemon_dex_numbers'): + for group in groups_for_dex.get(int(p['pokedex_id']), []): + for version in versions_for_group.get(group, []): + entries[(int(p['species_id']), version)] = 'unknown' + for p in rows('pokemon_game_indices'): + if int(p['game_index']) > 0: + entries[(species_for[int(p['pokemon_id'])], int(p['version_id']))] = 'unknown' + for p in rows('encounters'): + entries[(species_for[int(p['pokemon_id'])], int(p['version_id']))] = 'catchable' + return dict(source={'repository': 'https://github.com/PokeAPI/pokeapi', 'revision': REVISION, + 'scope': 'All species and game versions in this snapshot; default-form types/stats. Unknown means presence without confirmed encounter data. Missing pairs have no source record, not proven absence.'}, + pokemon=mons, games=games, entries=[[p, g, availability] for (p, g), availability in sorted(entries.items())]) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--source-dir', type=Path) + args = parser.parse_args() + with tempfile.TemporaryDirectory() as temporary: + directory = args.source_dir or Path(temporary) + if not args.source_dir: + def download(table): + url = f'https://raw.githubusercontent.com/PokeAPI/pokeapi/{REVISION}/data/v2/csv/{table}.csv' + with urllib.request.urlopen(url, timeout=60) as response: + (directory / f'{table}.csv').write_bytes(response.read()) + with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: + list(executor.map(download, TABLES)) + catalog = build(directory) + target = Path(__file__).resolve().parent.parent / 'data/pokemon-catalog.json' + target.write_text(json.dumps(catalog, ensure_ascii=False, separators=(',', ':')) + '\n') + print(f"Built {len(catalog['pokemon'])} species, {len(catalog['games'])} versions, {len(catalog['entries'])} entries") + + +if __name__ == '__main__': + main() diff --git a/scripts/deploy-preflight.ts b/scripts/deploy-preflight.ts new file mode 100644 index 0000000..b729eaf --- /dev/null +++ b/scripts/deploy-preflight.ts @@ -0,0 +1,70 @@ +import postgres from 'postgres'; + +const expectedOrigin = process.argv[2]; +if ( + !expectedOrigin || + !['https://stanrunge.dev', 'https://staging.stanrunge.dev'].includes(expectedOrigin) +) { + throw new Error('Expected a known production or staging origin'); +} +if (!process.env.DB_URL) throw new Error('DB_URL is missing'); +if (!process.env.BETTER_AUTH_SECRET || process.env.BETTER_AUTH_SECRET.length < 32) { + throw new Error('BETTER_AUTH_SECRET must be at least 32 characters'); +} +if (process.env.ORIGIN !== expectedOrigin || process.env.BETTER_AUTH_URL !== expectedOrigin) { + throw new Error('ORIGIN and BETTER_AUTH_URL must both match the public site origin'); +} +const client = postgres(process.env.DB_URL, { max: 1, connect_timeout: 10 }); +try { + await client`select 1`; + const [schema] = await client` + select + (select count(*) from information_schema.columns + where table_name = 'user' and column_name = 'role') as user_role, + (select count(*) from information_schema.columns + where table_name = 'account' and column_name = 'issuer') as account_issuer, + (select count(*) from information_schema.columns + where table_name = 'blog_articles' and column_name = 'tags') as blog_tags, + to_regclass('public.catch_em_all_settings') is not null as settings_ready, + (select count(*) from information_schema.columns where table_name = 'lists' and column_name = 'slug') as list_slug, + to_regclass('public.list_item_completions') is not null as list_completions, + (select count(*) from information_schema.columns where table_name = 'tasks_to_topics' and column_name = 'id') as topic_link_id, + (select count(*) from information_schema.columns + where table_name in ('animals', 'sightings', 'photos') + and column_name = 'id' and data_type = 'integer') as animal_serial_ids + `; + if ( + !Number(schema.user_role) || + !Number(schema.account_issuer) || + !Number(schema.blog_tags) || + !schema.settings_ready || + !Number(schema.list_slug) || + !schema.list_completions || + !Number(schema.topic_link_id) || + Number(schema.animal_serial_ids) !== 3 + ) { + throw new Error( + 'Required migrations or Animaldex ID conversion have not been applied to this database' + ); + } + const [catalog] = await client` + select + (select count(*) from pokemon) as pokemon, + (select count(*) from games where source_id is not null) as games, + (select count(*) from pokemon_game_entries) as entries + `; + if ( + Number(catalog.pokemon) < 1025 || + Number(catalog.games) < 53 || + Number(catalog.entries) < 27267 + ) { + throw new Error('Pokémon catalog has not been seeded in this database'); + } +} finally { + await client.end(); +} +const google = !!(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET); +const osu = !!(process.env.OSU_CLIENT_ID && process.env.OSU_CLIENT_SECRET); +console.log( + `Preflight passed for ${expectedOrigin}; Google ${google ? 'configured' : 'disabled'}, osu! ${osu ? 'configured' : 'disabled'}` +); diff --git a/scripts/deploy-remote.sh b/scripts/deploy-remote.sh new file mode 100644 index 0000000..5057e52 --- /dev/null +++ b/scripts/deploy-remote.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +set -euo pipefail + +sha=${1:?commit SHA required} +directory=${2:?deployment directory required} +origin=${3:?public origin required} +case "$sha" in + *[!0-9a-f]*|'') echo 'Invalid image tag' >&2; exit 2 ;; +esac +case "$directory:$origin" in + /opt/personal-website:https://stanrunge.dev) + environment=/etc/personal-website/prod.env ;; + /opt/personal-website-staging:https://staging.stanrunge.dev) + environment=/etc/personal-website-staging/staging.env ;; + *) echo 'Unrecognized deployment target' >&2; exit 2 ;; +esac + +image="git.stanrunge.dev/stan/personal-website:$sha" +compose="$directory/compose.prod.yml" +previous_tag=$(sed -n 's/^IMAGE_TAG=//p' "$directory/.env" | head -n 1) +switched=0 +rollback() { + if [ "$switched" -eq 1 ] && [ -n "$previous_tag" ]; then + echo "Health check failed; restoring prior image tag $previous_tag" >&2 + printf 'IMAGE_TAG=%s\n' "$previous_tag" | sudo tee "$directory/.env" >/dev/null + sudo docker compose --env-file "$directory/.env" -f "$compose" up -d + fi +} +trap rollback ERR + +sudo docker run --rm --network backend --env-file "$environment" "$image" \ + bun scripts/deploy-preflight.ts "$origin" + +printf 'IMAGE_TAG=%s\n' "$sha" | sudo tee "$directory/.env" >/dev/null +switched=1 +sudo docker compose --env-file "$directory/.env" -f "$compose" up -d + +container=$(sudo docker compose --env-file "$directory/.env" -f "$compose" ps -q app) +expected_image=$(sudo docker image inspect -f '{{.Id}}' "$image") +actual_image=$(sudo docker inspect -f '{{.Image}}' "$container") +if [ "$actual_image" != "$expected_image" ]; then + echo 'Compose did not start the intended image' >&2 + false +fi +curl --retry 12 --retry-delay 2 --retry-all-errors --fail --silent --show-error \ + "$origin/login" >/dev/null +curl --retry 6 --retry-delay 2 --retry-all-errors --fail --silent --show-error \ + "$origin/projects/catch-em-all" >/dev/null +trap - ERR +echo "Deployed $sha to $origin" diff --git a/scripts/foundation-migration.sql b/scripts/foundation-migration.sql new file mode 100644 index 0000000..7dafbe6 --- /dev/null +++ b/scripts/foundation-migration.sql @@ -0,0 +1,93 @@ +-- Apply after auth-catalog-migration.sql and before deploying the foundation release. +-- Additive domain-schema changes; existing records and numeric IDs are retained. + +ALTER TABLE blog_articles ADD COLUMN IF NOT EXISTS tags text[] NOT NULL DEFAULT '{}'::text[]; + +ALTER TABLE lists ADD COLUMN IF NOT EXISTS slug text; +UPDATE lists SET slug = COALESCE(NULLIF(trim(both '-' from regexp_replace(lower(name), '[^a-z0-9]+', '-', 'g')), ''), 'list') || '-' || id +WHERE slug IS NULL; +ALTER TABLE lists ALTER COLUMN slug SET NOT NULL; +CREATE UNIQUE INDEX IF NOT EXISTS lists_slug_unique ON lists (slug); +ALTER TABLE lists ADD COLUMN IF NOT EXISTS is_progress boolean NOT NULL DEFAULT false; +ALTER TABLE list_items ADD COLUMN IF NOT EXISTS picture_url text; +ALTER TABLE list_items ADD COLUMN IF NOT EXISTS description text; + +CREATE TABLE IF NOT EXISTS list_item_completions ( + id serial PRIMARY KEY, + item_id integer NOT NULL REFERENCES list_items(id) ON DELETE CASCADE, + user_id text NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + CONSTRAINT list_item_completions_item_id_user_id_unique UNIQUE (item_id, user_id) +); +CREATE INDEX IF NOT EXISTS list_item_completions_user_id_idx ON list_item_completions(user_id); + +-- Join/setting records gain the same numeric identity as other site-owned rows. +ALTER TABLE tasks_to_topics ADD COLUMN IF NOT EXISTS id serial; +DO $$ BEGIN + IF EXISTS (SELECT 1 FROM pg_constraint WHERE conrelid = 'tasks_to_topics'::regclass AND conname = 'tasks_to_topics_pkey' + AND pg_get_constraintdef(oid) NOT LIKE 'PRIMARY KEY (id)') THEN + ALTER TABLE tasks_to_topics DROP CONSTRAINT tasks_to_topics_pkey; + END IF; +END $$; +DO $$ BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conrelid = 'tasks_to_topics'::regclass AND contype = 'p') THEN + ALTER TABLE tasks_to_topics ADD CONSTRAINT tasks_to_topics_pkey PRIMARY KEY (id); + END IF; +END $$; +CREATE UNIQUE INDEX IF NOT EXISTS tasks_to_topics_task_id_topic_id_unique ON tasks_to_topics(task_id, topic_id); + +ALTER TABLE catch_em_all_settings ADD COLUMN IF NOT EXISTS id serial; +DO $$ BEGIN + IF EXISTS (SELECT 1 FROM pg_constraint WHERE conrelid = 'catch_em_all_settings'::regclass AND conname = 'catch_em_all_settings_pkey' + AND pg_get_constraintdef(oid) NOT LIKE 'PRIMARY KEY (id)') THEN + ALTER TABLE catch_em_all_settings DROP CONSTRAINT catch_em_all_settings_pkey; + END IF; +END $$; +DO $$ BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conrelid = 'catch_em_all_settings'::regclass AND contype = 'p') THEN + ALTER TABLE catch_em_all_settings ADD CONSTRAINT catch_em_all_settings_pkey PRIMARY KEY (id); + END IF; +END $$; +CREATE UNIQUE INDEX IF NOT EXISTS catch_em_all_settings_user_id_unique ON catch_em_all_settings(user_id); + +-- Every site-owned table records creation and latest update. Domain-specific +-- event times (submitted_at, seen_at, uploaded_at) remain untouched. +DO $$ +DECLARE table_name text; +BEGIN + FOREACH table_name IN ARRAY ARRAY[ + 'blog_articles', 'lists', 'list_items', 'list_item_completions', + 'animals', 'sightings', 'photos', 'tasks', 'topics', 'tasks_to_topics', + 'pokemon', 'games', 'pokemon_game_entries', 'user_entries', 'user_games', + 'catch_em_all_settings' + ] LOOP + EXECUTE format('ALTER TABLE %I ADD COLUMN IF NOT EXISTS created_at timestamptz NOT NULL DEFAULT now()', table_name); + EXECUTE format('ALTER TABLE %I ADD COLUMN IF NOT EXISTS updated_at timestamptz NOT NULL DEFAULT now()', table_name); + END LOOP; +END $$; + +-- Preserve the best available creation time for older Animaldex rows. +UPDATE animals SET created_at = submitted_at WHERE created_at > submitted_at; +UPDATE sightings SET created_at = submitted_at WHERE created_at > submitted_at; +UPDATE photos SET created_at = uploaded_at WHERE created_at > uploaded_at; + +CREATE OR REPLACE FUNCTION site_touch_updated_at() RETURNS trigger LANGUAGE plpgsql AS $$ +BEGIN + NEW.updated_at = now(); + RETURN NEW; +END $$; + +DO $$ +DECLARE table_name text; +BEGIN + FOREACH table_name IN ARRAY ARRAY[ + 'blog_articles', 'lists', 'list_items', 'list_item_completions', + 'animals', 'sightings', 'photos', 'tasks', 'topics', 'tasks_to_topics', + 'pokemon', 'games', 'pokemon_game_entries', 'user_entries', 'user_games', + 'catch_em_all_settings' + ] LOOP + EXECUTE format('DROP TRIGGER IF EXISTS site_touch_updated_at ON %I', table_name); + EXECUTE format('CREATE TRIGGER site_touch_updated_at BEFORE UPDATE ON %I FOR EACH ROW EXECUTE FUNCTION site_touch_updated_at()', table_name); + END LOOP; +END $$; diff --git a/scripts/migrate-auth-catalog.ts b/scripts/migrate-auth-catalog.ts new file mode 100644 index 0000000..f491003 --- /dev/null +++ b/scripts/migrate-auth-catalog.ts @@ -0,0 +1,14 @@ +import { readFile } from 'node:fs/promises'; +import postgres from 'postgres'; +if (!process.env.DB_URL) throw new Error('DB_URL is required'); +const sql = postgres(process.env.DB_URL, { max: 1 }); +try { + await sql.begin(async (tx) => { + await tx.unsafe( + await readFile(new URL('./auth-catalog-migration.sql', import.meta.url), 'utf8') + ); + }); + console.log('Authentication and catalog migration applied'); +} finally { + await sql.end(); +} diff --git a/scripts/migrate-foundation.ts b/scripts/migrate-foundation.ts new file mode 100644 index 0000000..d44e642 --- /dev/null +++ b/scripts/migrate-foundation.ts @@ -0,0 +1,13 @@ +import { readFile } from 'node:fs/promises'; +import postgres from 'postgres'; + +if (!process.env.DB_URL) throw new Error('DB_URL is required'); +const client = postgres(process.env.DB_URL, { max: 1 }); +try { + await client.begin(async (tx) => { + await tx.unsafe(await readFile(new URL('./foundation-migration.sql', import.meta.url), 'utf8')); + }); + console.log('Foundation migration applied'); +} finally { + await client.end(); +} diff --git a/scripts/seed-catalog.ts b/scripts/seed-catalog.ts new file mode 100644 index 0000000..2730297 --- /dev/null +++ b/scripts/seed-catalog.ts @@ -0,0 +1,84 @@ +import { readFile } from 'node:fs/promises'; +import { drizzle } from 'drizzle-orm/postgres-js'; +import { and, eq, isNull, sql } from 'drizzle-orm'; +import postgres from 'postgres'; +import { pokemon, games, pokemonGameEntries } from '../src/lib/server/db/schema/catch-em-all'; + +type Catalog = { + source: { revision: string }; + pokemon: (typeof pokemon.$inferInsert)[]; + games: { sourceId: number; name: string; generation: number }[]; + entries: [number, number, 'catchable' | 'unknown'][]; +}; +if (!process.env.DB_URL) throw new Error('DB_URL is required'); +const catalog: Catalog = JSON.parse( + await readFile(new URL('../data/pokemon-catalog.json', import.meta.url), 'utf8') +); +const client = postgres(process.env.DB_URL, { max: 1 }); +const db = drizzle({ client }); +try { + await db.transaction(async (tx) => { + const pokemonIds = new Map(); + const gameIds = new Map(); + for (const row of catalog.pokemon) { + const [saved] = await tx + .insert(pokemon) + .values(row) + .onConflictDoUpdate({ target: pokemon.number, set: row }) + .returning(); + pokemonIds.set(saved.number, saved.id); + } + for (const row of catalog.games) { + // Adopt older rows by exact name to preserve existing progress and game IDs. + const [imported] = await tx.select().from(games).where(eq(games.sourceId, row.sourceId)); + if (!imported) { + const legacy = await tx + .select() + .from(games) + .where(and(eq(games.name, row.name), isNull(games.sourceId))); + if (legacy.length > 1) throw new Error(`Ambiguous legacy game: ${row.name}`); + if (legacy[0]) + await tx.update(games).set({ sourceId: row.sourceId }).where(eq(games.id, legacy[0].id)); + } + const [saved] = await tx + .insert(games) + .values(row) + .onConflictDoUpdate({ target: games.sourceId, set: row }) + .returning(); + gameIds.set(row.sourceId, saved.id); + } + for (let offset = 0; offset < catalog.entries.length; offset += 1000) { + const rows = catalog.entries + .slice(offset, offset + 1000) + .map(([number, version, availability]) => { + const pokemonId = pokemonIds.get(number), + gameId = gameIds.get(version); + if (!pokemonId || !gameId) + throw new Error(`Unknown catalog reference ${number}/${version}`); + return { + pokemonId, + gameId, + availability, + note: + availability === 'catchable' + ? 'PokéAPI: documented encounter; conditions, location, or a specific form may be required.' + : 'PokéAPI: Pokédex or game-index record only; catch, evolution, gift, trade, transfer, and event availability is not confirmed.' + }; + }); + await tx + .insert(pokemonGameEntries) + .values(rows) + .onConflictDoUpdate({ + target: [pokemonGameEntries.pokemonId, pokemonGameEntries.gameId], + set: { availability: sql`excluded.availability`, note: sql`excluded.note` }, + // Preserve hand-maintained availability and notes. + setWhere: sql`${pokemonGameEntries.note} like 'PokéAPI:%'` + }); + } + }); + console.log( + `Seeded ${catalog.pokemon.length} species, ${catalog.games.length} versions, ${catalog.entries.length} entries from ${catalog.source.revision}` + ); +} finally { + await client.end(); +} diff --git a/scripts/set-admin.ts b/scripts/set-admin.ts new file mode 100644 index 0000000..c123da5 --- /dev/null +++ b/scripts/set-admin.ts @@ -0,0 +1,15 @@ +import postgres from 'postgres'; +const [userId, role = 'admin'] = process.argv.slice(2); +if (!userId || !['admin', 'user'].includes(role)) + throw new Error('Usage: bun scripts/set-admin.ts [admin|user]'); +if (!process.env.DB_URL) throw new Error('DB_URL is required'); +const sql = postgres(process.env.DB_URL, { max: 1 }); +try { + const users = + await sql`update "user" set role = ${role}, updated_at = now() where id = ${userId} returning id, role`; + if (!users.length) + throw new Error('User ID not found. Register first and copy the ID from your account page.'); + console.log(users[0]); +} finally { + await sql.end(); +} diff --git a/scripts/verify-staging-image.sh b/scripts/verify-staging-image.sh new file mode 100644 index 0000000..b7c8df0 --- /dev/null +++ b/scripts/verify-staging-image.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail + +sha=${1:?staging commit required} +case "$sha" in + *[!0-9a-f]*|'') echo 'Invalid image tag' >&2; exit 2 ;; +esac +directory=/opt/personal-website-staging +tag=$(sed -n 's/^IMAGE_TAG=//p' "$directory/.env" | head -n 1) +if [ "$tag" != "$sha" ]; then + echo "Staging runs $tag, not $sha" >&2 + exit 1 +fi +image="git.stanrunge.dev/stan/personal-website:$sha" +container=$(sudo docker compose --env-file "$directory/.env" -f "$directory/compose.prod.yml" ps -q app) +expected=$(sudo docker image inspect -f '{{.Id}}' "$image") +actual=$(sudo docker inspect -f '{{.Image}}' "$container") +if [ "$actual" != "$expected" ]; then + echo 'Staging container differs from the tested image' >&2 + exit 1 +fi +curl --fail --silent --show-error https://staging.stanrunge.dev/login >/dev/null +echo "Verified staging image $sha" diff --git a/src/app.css b/src/app.css index ec5a3d6..d75ac61 100755 --- a/src/app.css +++ b/src/app.css @@ -2,22 +2,113 @@ @plugin '@tailwindcss/typography'; @theme { - --color-bg: #f6f4f0; - --color-surface: #edeae4; - --color-surface-hover: #e4e0d8; - --color-border: #d6d2ca; - --color-border-light: #e8e5de; - --color-text: #2c2c2c; - --color-text-muted: #6b6b6b; - --color-text-dim: #999999; - --color-text-ghost: #c5c0b8; - --color-accent: #3d6b8e; - --color-accent-hover: #4d7fa6; + --color-bg: #000; + --color-surface: #0a0a0a; + --color-surface-hover: #171717; + --color-border: #262626; + --color-border-light: #1a1a1a; + --color-text: #ededed; + --color-text-muted: #a1a1a1; + --color-text-dim: #888; + --color-text-ghost: #666; + --color-accent: #ededed; + --color-accent-hover: #fff; --color-danger: #b44; - --font-heading: 'DM Serif Display', Georgia, serif; + --font-heading: Montserrat, Arial, Helvetica, sans-serif; --font-mono: 'IBM Plex Mono', 'Courier New', monospace; - --font-body: 'Source Sans 3', 'Helvetica Neue', sans-serif; + --font-body: Montserrat, Arial, Helvetica, sans-serif; +} + +:root { + color-scheme: dark; + --site-bg: #000; + --site-surface: #0a0a0a; + --site-hover: #171717; + --site-text: #ededed; + --site-muted: #a1a1a1; + --site-border: #292929; +} + +:root[data-theme='light'] { + color-scheme: light; + --site-bg: #fff; + --site-surface: #fafafa; + --site-hover: #f4f4f5; + --site-text: #171717; + --site-muted: #646464; + --site-border: #e5e5e5; + --color-bg: #fff; + --color-surface: #fafafa; + --color-surface-hover: #f4f4f5; + --color-border: #e5e5e5; + --color-border-light: #eee; + --color-text: #171717; + --color-text-muted: #646464; + --color-text-dim: #777; + --color-text-ghost: #999; + --color-accent: #171717; + --color-accent-hover: #000; +} + +.article-content { + --tw-prose-body: var(--site-text); + --tw-prose-headings: var(--site-text); + --tw-prose-lead: var(--site-text); + --tw-prose-links: var(--site-text); + --tw-prose-bold: var(--site-text); + --tw-prose-counters: var(--site-muted); + --tw-prose-bullets: var(--site-muted); + --tw-prose-hr: var(--site-border); + --tw-prose-quotes: var(--site-text); + --tw-prose-quote-borders: var(--site-border); + --tw-prose-captions: var(--site-muted); + --tw-prose-code: var(--site-text); + --tw-prose-th-borders: var(--site-border); + --tw-prose-td-borders: var(--site-border); +} + +/* Keep older project pages readable while their individual styles use light utility colors. */ +:root:not([data-theme='light']) .bg-white, +:root:not([data-theme='light']) .bg-gray-50, +:root:not([data-theme='light']) .bg-neutral-50 { + background-color: #0a0a0a; +} + +:root:not([data-theme='light']) .bg-gray-100, +:root:not([data-theme='light']) .bg-neutral-100 { + background-color: #171717; +} + +:root:not([data-theme='light']) .bg-gray-200, +:root:not([data-theme='light']) .bg-neutral-200 { + background-color: #262626; +} + +:root:not([data-theme='light']) .text-black, +:root:not([data-theme='light']) .text-gray-900, +:root:not([data-theme='light']) .text-gray-800 { + color: #ededed; +} + +:root:not([data-theme='light']) .text-gray-700 { + color: #d4d4d4; +} + +:root:not([data-theme='light']) .text-gray-600, +:root:not([data-theme='light']) .text-gray-500 { + color: #a1a1a1; +} + +:root:not([data-theme='light']) .border-gray-100, +:root:not([data-theme='light']) .border-gray-200, +:root:not([data-theme='light']) .border-gray-300 { + border-color: #292929; +} + +:root:not([data-theme='light']) .hover\:bg-gray-50:hover, +:root:not([data-theme='light']) .hover\:bg-gray-100:hover { + background-color: #171717; } @layer base { @@ -36,15 +127,27 @@ } body { - background: var(--color-bg); - color: var(--color-text); + background: var(--site-bg); + color: var(--site-text); font-family: var(--font-body); - font-size: 15px; - line-height: 1.65; + font-size: 16px; + line-height: 1.6; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + button, + input, + textarea, + select { + font: inherit; + } + + :focus-visible { + outline: 2px solid var(--site-text); + outline-offset: 3px; + } + ::selection { background: color-mix(in srgb, var(--color-accent) 20%, transparent); } diff --git a/src/app.d.ts b/src/app.d.ts index 585bebc..039bbe1 100755 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -5,7 +5,10 @@ declare global { namespace App { // interface Error {} - // interface Locals {} + interface Locals { + user: typeof import('$lib/server/auth').auth.$Infer.Session.user | null; + session: typeof import('$lib/server/auth').auth.$Infer.Session.session | null; + } // interface PageData {} // interface PageState {} // interface Platform {} diff --git a/src/app.html b/src/app.html index 4e11c43..3eff41c 100755 --- a/src/app.html +++ b/src/app.html @@ -1,6 +1,25 @@ + + + +
+

+ {mode === 'register' ? 'create account' : 'sign in'} +

+ {#if message || oauthError} + + {/if} +
+ {#if mode === 'register'} + + {/if} + + + {#if mode === 'register'}

Use at least 12 characters.

{/if} + +
+ {#if providers.google || providers.osu} +
+ {#if providers.google}{/if} + {#if providers.osu}{/if} +
+ {/if} +

+ {mode === 'register' ? 'sign in' : 'Create account'} +

+ +
diff --git a/src/lib/components/CopyButton.svelte b/src/lib/components/CopyButton.svelte index 638e31a..755058e 100644 --- a/src/lib/components/CopyButton.svelte +++ b/src/lib/components/CopyButton.svelte @@ -33,7 +33,7 @@ diff --git a/src/lib/components/ListPictureDropzone.svelte b/src/lib/components/ListPictureDropzone.svelte new file mode 100644 index 0000000..fe84443 --- /dev/null +++ b/src/lib/components/ListPictureDropzone.svelte @@ -0,0 +1,64 @@ + + +
+ {label} + + +

JPEG, PNG, or WebP · up to 5 MB

+ {#if fileName}{/if} +
diff --git a/src/lib/components/ProgressBar.svelte b/src/lib/components/ProgressBar.svelte new file mode 100644 index 0000000..2924a67 --- /dev/null +++ b/src/lib/components/ProgressBar.svelte @@ -0,0 +1,43 @@ + + + + + diff --git a/src/lib/derby/generic.test.ts b/src/lib/derby/generic.test.ts new file mode 100644 index 0000000..57bb698 --- /dev/null +++ b/src/lib/derby/generic.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from 'vitest'; +import { defaultsFor, gPredict } from './generic'; +import { placings } from './model'; +import { races } from './races'; + +describe('generic race model', () => { + for (const race of races) { + it(`${race.slug}: probabilities sum to one and placings are consistent`, () => { + const preds = gPredict(race.runners, defaultsFor(race)); + expect(preds.reduce((a, r) => a + r.p, 0)).toBeCloseTo(1, 9); + expect(preds.length).toBe(race.runners.length); + const { top, trio } = placings(preds, 0.8); + expect(top.reduce((a, t) => a + t.win, 0)).toBeCloseTo(1, 9); + expect(trio.reduce((a, t) => a + t.p, 0)).toBeCloseTo(1, 9); + for (const r of preds) expect(Number.isFinite(r.logit)).toBe(true); + }); + } + + it('debutants get the field average and a higher fail risk', () => { + const race = races.find((r) => r.slug === 'south-holland')!; + const preds = gPredict(race.runners, defaultsFor(race)); + const deb = preds.find((r) => r.horse.n === 1)!; + expect(deb.features.estimated).toEqual(['form', 'speed', 'level']); + expect(deb.features.pFail).toBeCloseTo(0.12); + }); +}); diff --git a/src/lib/derby/generic.ts b/src/lib/derby/generic.ts new file mode 100644 index 0000000..09fd7f6 --- /dev/null +++ b/src/lib/derby/generic.ts @@ -0,0 +1,132 @@ +// Algemeen kansmodel voor de overige koersen: zelfde opzet als het Derby-model +// (z-scores × gewichten → softmax), maar zonder proef- en marktsignaal. +// Signalen: uitslagen, snelheid (beste recente km-tijd), niveau (prijzengeld +// van de laatste starts), startpositie en uitvalrisico. + +import type { Result } from './data'; +import type { Race, Runner } from './races'; + +export type GWeights = { + form: number; + speed: number; + level: number; + draw: number; + risk: number; + halfLife: number; + temperature: number; + lambda: number; +}; + +export const gFeatureKeys = ['form', 'speed', 'level', 'draw'] as const; +export type GFeatureKey = (typeof gFeatureKeys)[number]; + +export const gDefaults: GWeights = { + form: 1, + speed: 1, + level: 0.6, + draw: 0.4, + risk: 1, + halfLife: 2, + temperature: 1, + lambda: 0.8 +}; + +/** rensport: geen tijden, startbox minder belangrijk over 1900 m */ +export const defaultsFor = (race: Race): GWeights => + race.discipline === 'ren' ? { ...gDefaults, speed: 0, draw: 0.2, level: 0.8 } : { ...gDefaults }; + +export const gPresets: Record> = { + Standaard: {}, + Vorm: { form: 1.6, speed: 0.5, level: 0.4 }, + Snelheid: { form: 0.5, speed: 1.6, level: 0.4 }, + Niveau: { form: 0.6, speed: 0.6, level: 1.5 } +}; + +const SCALE = 0.55; +const POSITION_POINTS: Record = { 1: 1, 2: 0.75, 3: 0.6, 4: 0.45, 5: 0.35, 6: 0.25 }; +const positionPoints = (r: Result) => (r === 'D' ? 0 : (POSITION_POINTS[r] ?? 0.1)); +const DRAW_SCORE = [0, 0.6, 0.7, 0.6, 0.45, 0.4, 0.25, 0.1, 0, -0.2, -0.3]; + +export type GFeatures = { + form: number; + speed: number; + level: number; + draw: number; + pFail: number; + /** welke signalen ontbraken en het veldgemiddelde kregen */ + estimated: GFeatureKey[]; +}; + +const mean = (xs: number[]) => xs.reduce((a, b) => a + b, 0) / xs.length; + +function rawForm(h: Runner, w: GWeights): number | null { + if (h.form.length === 0) return null; + const decay = h.form.map((_, i) => Math.pow(0.5, i / w.halfLife)); + return h.form.reduce((s: number, r, i) => s + decay[i] * positionPoints(r), 0) / decay.reduce((a, b) => a + b, 0); +} + +export function gFeatures(runners: Runner[], w: GWeights): GFeatures[] { + const raw = runners.map((h) => ({ + form: rawForm(h, w), + speed: h.times.length ? -Math.min(...h.times) : null, + level: h.purses.length ? mean(h.purses.map((p) => Math.log(p))) : null + })); + const fill = (k: 'form' | 'speed' | 'level') => { + const known = raw.map((r) => r[k]).filter((v): v is number => v !== null); + return known.length ? mean(known) : 0; + }; + const avg = { form: fill('form'), speed: fill('speed'), level: fill('level') }; + + return runners.map((h, i) => { + const estimated: GFeatureKey[] = []; + const pick = (k: 'form' | 'speed' | 'level') => { + const v = raw[i][k]; + if (v === null) estimated.push(k); + return v ?? avg[k]; + }; + const disq = h.form.filter((r) => r === 'D').length; + const poor = h.form.filter((r) => r !== 'D' && r >= 7).length; + // debutanten: geen bewijs dat ze in de draf blijven + const base = h.form.length === 0 ? 0.12 : 0.03; + const pFail = Math.min(0.5, base + 0.1 * disq + 0.03 * poor); + return { form: pick('form'), speed: pick('speed'), level: pick('level'), draw: DRAW_SCORE[h.n] ?? 0, pFail, estimated }; + }); +} + +/** + * ondergrens voor de spreiding per signaal, anders wordt 0,2 s verschil in een + * veld met drie bijna gelijke tijden een enorme z-score + */ +const SD_FLOOR: Record = { form: 0.08, speed: 1, level: 0.3, draw: 0.15 }; + +function zscores(values: number[], floor: number): number[] { + const m = mean(values); + const sd = Math.max(floor, Math.sqrt(mean(values.map((v) => (v - m) ** 2)))); + return values.map((v) => (v - m) / sd); +} + +export type GPrediction = { + horse: Runner; + features: GFeatures; + contributions: Record; + riskPenalty: number; + logit: number; + p: number; +}; + +export function gPredict(runners: Runner[], w: GWeights): GPrediction[] { + if (runners.length === 0) return []; + const feats = gFeatures(runners, w); + const z = Object.fromEntries(gFeatureKeys.map((k) => [k, zscores(feats.map((f) => f[k]), SD_FLOOR[k])])) as Record; + const rows = runners.map((horse, i) => { + const contributions = Object.fromEntries(gFeatureKeys.map((k) => [k, w[k] * z[k][i] * SCALE])) as Record; + const riskPenalty = w.risk * Math.log(1 - feats[i].pFail); + const logit = Object.values(contributions).reduce((a, b) => a + b, 0) + riskPenalty; + return { horse, features: feats[i], contributions, riskPenalty, logit, p: 0 }; + }); + const max = Math.max(...rows.map((r) => r.logit)); + const exp = rows.map((r) => Math.exp((r.logit - max) / w.temperature)); + const total = exp.reduce((a, b) => a + b, 0); + rows.forEach((r, i) => (r.p = exp[i] / total)); + return rows.sort((a, b) => b.p - a.p); +} diff --git a/src/lib/derby/model.ts b/src/lib/derby/model.ts index b3ba615..668d37c 100644 --- a/src/lib/derby/model.ts +++ b/src/lib/derby/model.ts @@ -129,7 +129,7 @@ export type Placings = { * Stern-demping: voor de 2e en 3e plaats wordt p^lambda gebruikt, wat de * neiging van pure PL corrigeert om de favoriet te vaak tweede te laten worden. */ -export function placings(preds: Prediction[], lambda: number): Placings { +export function placings(preds: { p: number }[], lambda: number): Placings { const n = preds.length; const p1 = preds.map((r) => r.p); const p2 = p1.map((p) => Math.pow(p, lambda)); diff --git a/src/lib/derby/races.ts b/src/lib/derby/races.ts new file mode 100644 index 0000000..8530dea --- /dev/null +++ b/src/lib/derby/races.ts @@ -0,0 +1,128 @@ +// Duindigt · zondag 20 september 2026 · koersen 3, 4 en 5 +// Bron: ZEturf koerskaarten en paardenfiches (laatste starts, kilometertijden, prijzengeld). + +import type { Result } from './data'; + +export type Runner = { + n: number; + name: string; + driver: string; + trainer: string; + sex: 'M' | 'H' | 'R'; + age: number; + /** laatste vijf uitslagen, nieuwste eerst; D = gediskwalificeerd/gevallen; leeg = debutant */ + form: Result[]; + /** kilometertijden (s) van de laatste starts, nieuwste eerst; alleen bekende */ + times: number[]; + /** prijzengeld (€) van de laatste starts, nieuwste eerst: niveau waarop het paard uitkomt */ + purses: number[]; + /** beste kilometertijd ooit, null = onbekend */ + record: number | null; + /** gedragen gewicht (alleen rensport) */ + kg?: number; + note?: string; +}; + +export type Race = { + slug: string; + number: number; + name: string; + short: string; + time: string; + distance: number; + start: string; + purse: number; + surface: string; + discipline: 'draf' | 'ren'; + conditions: string; + /** voorbeschouwing ZEturf (Kees Nakoersen) */ + preview: string; + tips: number[]; + runners: Runner[]; + sources: { label: string; href: string }[]; +}; + +const t = (m: number, s: number) => m * 60 + s; +const ze = (c: number, slug: string) => `https://www.zeturf.be/nl/course-du-jour/2026-09-20/R14C${c}-duindigt-${slug}`; + +export const races: Race[] = [ + { + slug: 'sheikh-mansour', + number: 3, + name: 'HH Sheikh Mansour bin Zayed Al Nahyan Prijs', + short: 'Sheikh Mansour Prijs', + time: '16:10', + distance: 1900, + start: 'Startboxen', + purse: 10000, + surface: 'Grasbaan · standaard', + discipline: 'ren', + conditions: 'Ren voor Arabische volbloeds, 4 jaar en ouder', + preview: + 'Tex D.A. (3) kan mogelijk op herhaling op deze baan waar hij op 26 juli sterk won voor tweede Ektor D.A. (6) en met als vierde Orszana JR (5). Maar de ruin treft in El Zarka D.A. (1) en Farida P (2) twee sterke tegenstanders. Beide bleven weliswaar op iets meer dan 8 lengte op deze baan ongeplaatst, maar dat was tegen de top van Europa. Princess T (4) versloeg Tex D.A. met een neusje verschil op de grasbaan van Joure, dus ook deze merrie moeten we serieus nemen. Een koers waarin veel mogelijk is.', + tips: [3, 1, 2, 6], + sources: [{ label: 'ZEturf koerskaart', href: ze(3, 'hh-sheikh-mansour-bin-zayed-al-nahyan-prijs') }], + runners: [ + { n: 1, name: 'El Zarka D.A.', driver: 'Jurico Bogaerts', trainer: 'Johan Verstrepen', sex: 'R', age: 12, form: [7, 9, 5, 5, 3], times: [], purses: [250000, 100000, 26400, 92764, 6000], record: null, kg: 64, note: 'loopt tegen de Europese top' }, + { n: 2, name: 'Farida P', driver: 'Anne Engels', trainer: 'Peter Deckers', sex: 'M', age: 7, form: ['D', 10, 3, 3, 1], times: [], purses: [250000, 100000, 26400, 92764, 6000], record: null, kg: 62, note: 'D = gevallen in Waregem' }, + { n: 3, name: 'Tex D.A.', driver: 'Luca van Toor', trainer: 'Bianca Dunk', sex: 'R', age: 9, form: [10, 1, 2, 2, 2], times: [], purses: [250000, 5000, 4000, 6000, 6000], record: null, kg: 61, note: 'won 26 juli op Duindigt' }, + { n: 4, name: 'Princess T', driver: 'Mirko Sanna', trainer: 'Gerard Zoetelief', sex: 'M', age: 6, form: [1, 4, 3, 5, 4], times: [], purses: [4000, 6000, 4000, 6000, 6000], record: null, kg: 57, note: 'versloeg Tex D.A. in Joure' }, + { n: 5, name: 'Orszana JR', driver: 'Josephine Bruning', trainer: "Manouk van 't Slot", sex: 'M', age: 8, form: [4, 4, 4, 7], times: [], purses: [5000, 4000, 4200, 5100], record: null, kg: 56 }, + { n: 6, name: 'Ektor D.A.', driver: 'Siem Bos', trainer: 'Johan Verstrepen', sex: 'H', age: 4, form: [3, 2, 5, 3, 7], times: [], purses: [6000, 5000, 6000, 6000, 7000], record: null, kg: 55 } + ] + }, + { + slug: 'schieweg', + number: 4, + name: 'Handelsonderneming Schieweg B.V. Prijs', + short: 'Schieweg Prijs', + time: '16:40', + distance: 2000, + start: 'Autostart', + purse: 4750, + surface: 'Sintelbaan · goed', + discipline: 'draf', + conditions: 'Draverij voor 4 jaar en ouder, winsom lager dan € 18.000', + preview: + 'Paradepaard van Duindigt 2025 Louis Vuiton (7) wordt na deze koers gehuldigd, maar of dat als winnaar is staat niet vast. Pasion d’Oro (4) is waarschijnlijk het te kloppen paard: de hengst van Jacky Mollema verkeert in topvorm. Michel D (6) is eveneens in grote vorm, won tweemaal in Duitsland maar nog niet op Duindigt, al zat hij daar steeds dichtbij. Nobell Starro (5) werd in zijn laatste koers vierde op één lijn met tweede aankomende Louis Vuiton. Nolana Boko (8) won dit jaar al driemaal, laatst in Alkmaar. Otini Bianco (2) is hoogstwaarschijnlijk het Paradepaard van Duindigt 2026; met een juiste koers is de ruin er vandaag ook bij.', + tips: [4, 7, 6, 5], + sources: [{ label: 'ZEturf koerskaart', href: ze(4, 'handelsonderneming-schieweg-b-v-prijs') }], + runners: [ + { n: 1, name: 'Puck Ballaco', driver: 'Micha Brouwer', trainer: 'Rob de Vlieger', sex: 'M', age: 4, form: [4, 4, 1, 4, 3], times: [t(1, 17.9), t(1, 16.3), t(1, 16.6), t(1, 16.5), t(1, 17.8)], purses: [2750, 4000, 4000, 4400, 1100], record: t(1, 13.0) }, + { n: 2, name: 'Otini Bianco', driver: 'Rob de Vlieger', trainer: 'Rob de Vlieger', sex: 'R', age: 5, form: ['D', 6, 1, 2, 'D'], times: [t(1, 15.5), t(1, 15.9), t(1, 16.4)], purses: [2750, 4400, 2750, 2750, 2750], record: t(1, 14.7), note: 'won 31 juli op Duindigt' }, + { n: 3, name: 'Memory de Legume', driver: 'Patrick de Haan', trainer: 'Patrick de Haan', sex: 'M', age: 7, form: [6, 7, 8, 4, 4], times: [t(1, 19.7), t(1, 16.9), t(1, 15.6), t(1, 18.2), t(1, 14.1)], purses: [1600, 4400, 4400, 1500, 2200], record: t(1, 14.1) }, + { n: 4, name: "Pasion d'Oro", driver: 'Jaap van Rijn', trainer: 'Jack Mollema', sex: 'H', age: 4, form: [1, 5, 1, 1, 5], times: [t(1, 16.6), t(1, 11.6), t(1, 12.2), t(1, 21.1), t(1, 14.0)], purses: [2750, 19567, 2200, 1650, 13806], record: t(1, 11.6), note: 'liep in Zweden tegen sterkere' }, + { n: 5, name: 'Nobell Starro', driver: 'Robin Bakker', trainer: 'Fons Bakker', sex: 'R', age: 6, form: [4, 2, 1, 2, 'D'], times: [t(1, 14.0), t(1, 16.2), t(1, 11.1)], purses: [2750, 5000, 2000, 2200, 4400], record: t(1, 11.1) }, + { n: 6, name: 'Michel D', driver: 'Jim Veldman', trainer: 'Huug van Dijk', sex: 'H', age: 7, form: [3, 2, 1, 2, 1], times: [t(1, 20.2), t(1, 15.6), t(1, 14.1), t(1, 16.9), t(1, 14.9)], purses: [5000, 2750, 2000, 5500, 1500], record: t(1, 13.8), note: 'laatste tijd over 3375 m' }, + { n: 7, name: 'Louis Vuiton', driver: 'Hugo Langeweg', trainer: 'Hugo Langeweg', sex: 'R', age: 8, form: [2, 5, 4, 'D', 1], times: [t(1, 17.8), t(1, 12.1), t(1, 16.9)], purses: [2750, 11000, 2200, 1650, 2750], record: t(1, 12.1), note: 'Paradepaard 2025' }, + { n: 8, name: 'Nolana Boko', driver: 'John Dekker', trainer: 'Carel Roodenrijs', sex: 'R', age: 6, form: [1, 'D', 5, 4, 4], times: [t(1, 19.1), t(1, 20.9), t(1, 13.9), t(1, 23.0)], purses: [1600, 2750, 1100, 2000, 1210], record: t(1, 13.4), note: 'vaak op tragere banen (Alkmaar)' } + ] + }, + { + slug: 'south-holland', + number: 5, + name: 'South Holland Prijs · TCT Tweejarigen Satellietkoers', + short: 'South Holland Prijs', + time: '17:10', + distance: 1609, + start: 'Autostart', + purse: 4000, + surface: 'Sintelbaan · goed', + discipline: 'draf', + conditions: 'Draverij voor tweejarigen (sprint, 1609 m)', + preview: + 'Sisi Hazelaar (5) is op basis van haar laatste tweede plaats in Wolvega, waar ze een puike indruk maakte, kansrijk. Zo ook Seabiscuit Lobell (4), die vorige week bij haar debuut tweede werd achter Salina Meerswal; met een fijn stuk speed kan ze binnendoor plek twee veroveren. Spirit Meerswal (2) debuteerde met een derde plaats in Wolvega in 15,2 en is kanshebber nummer drie. Sophie Starlake (1) debuteert voor de stal van Dion Tesselaar, en dan zijn we sowieso gewaarschuwd.', + tips: [5, 4, 2, 1], + sources: [{ label: 'ZEturf koerskaart', href: ze(5, 'south-holland-prijs-tct-tweejarigen-satellietkoers') }], + runners: [ + { n: 1, name: 'Sophie Starlake', driver: 'Dion Tesselaar', trainer: 'Dion Tesselaar', sex: 'M', age: 2, form: [], times: [], purses: [], record: null, note: 'debutant · stal Tesselaar' }, + { n: 2, name: 'Spirit Meerswal', driver: 'Jaap van Rijn', trainer: 'Jack Mollema', sex: 'H', age: 2, form: [3], times: [t(1, 15.2)], purses: [5500], record: t(1, 15.2) }, + { n: 3, name: 'Shiva Jabi', driver: 'Jan Baas', trainer: 'Jan Baas', sex: 'H', age: 2, form: ['D', 'D'], times: [], purses: [3300, 5500], record: null, note: 'twee keer uit de draf' }, + { n: 4, name: 'Seabiscuit Lobell', driver: 'Hugo Langeweg', trainer: 'Hugo Langeweg', sex: 'M', age: 2, form: [2], times: [t(1, 15.2)], purses: [3300], record: t(1, 15.2), note: '2e bij debuut, 10 september' }, + { n: 5, name: 'Sisi Hazelaar', driver: 'Jeffrey Mieras', trainer: 'Dion Tesselaar', sex: 'M', age: 2, form: [2, 'D'], times: [t(1, 15.0)], purses: [5500, 5500], record: t(1, 15.0) }, + { n: 6, name: 'Sir Bianco', driver: 'Frans van der Blonk', trainer: 'Frans van der Blonk', sex: 'R', age: 2, form: [], times: [], purses: [], record: null, note: 'debutant' } + ] + } +]; + +export const raceBySlug = (slug: string) => races.find((r) => r.slug === slug); diff --git a/src/lib/geo.test.ts b/src/lib/geo.test.ts new file mode 100644 index 0000000..1d801e0 --- /dev/null +++ b/src/lib/geo.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from 'vitest'; +import { distanceMeters } from './geo'; + +describe('distanceMeters', () => { + it('keeps nearby sightings within the 30 km limit and rejects distant ones', () => { + expect(distanceMeters(52.009, 4.708, 52.009, 4.708)).toBe(0); + expect(distanceMeters(52.009, 4.708, 52.01, 4.71)).toBeLessThan(30_000); + expect(distanceMeters(52.009, 4.708, 52.37, 4.9)).toBeGreaterThan(30_000); + }); +}); diff --git a/src/lib/geo.ts b/src/lib/geo.ts new file mode 100644 index 0000000..fa3acf1 --- /dev/null +++ b/src/lib/geo.ts @@ -0,0 +1,11 @@ +const EARTH_RADIUS_METERS = 6_371_000; + +export function distanceMeters(lat1: number, lng1: number, lat2: number, lng2: number): number { + const toRad = (degrees: number) => (degrees * Math.PI) / 180; + const deltaLat = toRad(lat2 - lat1); + const deltaLng = toRad(lng2 - lng1); + const a = + Math.sin(deltaLat / 2) ** 2 + + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(deltaLng / 2) ** 2; + return 2 * EARTH_RADIUS_METERS * Math.asin(Math.sqrt(a)); +} diff --git a/src/lib/map-finder/Artwork.svelte b/src/lib/map-finder/Artwork.svelte new file mode 100644 index 0000000..797e528 --- /dev/null +++ b/src/lib/map-finder/Artwork.svelte @@ -0,0 +1,23 @@ + + +
+ {#if src?.startsWith('https://') && !failed} (failed = true)} + />{:else}{/if} +
diff --git a/src/lib/map-finder/MapCard.svelte b/src/lib/map-finder/MapCard.svelte new file mode 100644 index 0000000..169866b --- /dev/null +++ b/src/lib/map-finder/MapCard.svelte @@ -0,0 +1,26 @@ + + + + +
+

+ {map.artist_unicode || map.artist} – {map.title_unicode || map.title} +

+

{map.score}/100 · {map.confidence} confidence

+

{map.reasons.join(' · ')}

+ {#if map.status || map.beatmaps}

+ {map.status ?? ''}{map.status && map.beatmaps ? ' · ' : ''}{map.beatmaps + ? `${map.beatmaps.length} difficulties` + : ''} +

{/if} +
+
diff --git a/src/lib/map-finder/finder.test.ts b/src/lib/map-finder/finder.test.ts new file mode 100644 index 0000000..7a4bfae --- /dev/null +++ b/src/lib/map-finder/finder.test.ts @@ -0,0 +1,90 @@ +import { describe, expect, it } from 'vitest'; +import { parseSpotifyInput } from './input'; +import { normalize, cleanTitle, scoreBeatmapset, rankCandidates, MAX_CANDIDATES } from './matching'; +import type { SpotifyTrack } from './types'; +const id = '6PUzxtIHkv346yP89NzP9X'; +const track: SpotifyTrack = { + id, + name: 'Song Title', + artists: [{ name: 'Beyoncé & Friends' }], + album: { name: 'Album', images: [] } +}; +const map = { id: 1, title: 'Song Title', artist: 'Beyonce and Friends' }; +describe('Spotify input', () => { + it.each([ + `https://open.spotify.com/track/${id}`, + ` https://open.spotify.com/track/${id}?si=abc `, + `http://www.open.spotify.com/track/${id}/`, + `https://open.spotify.com/intl-nl/track/${id}/?si=abc`, + `spotify:track:${id}` + ])('parses %s', (value) => expect(parseSpotifyInput(value)).toEqual({ kind: 'track', id })); + it.each([`spotify:playlist:${id}`, `https://open.spotify.com/playlist/${id}?si=abc`])( + 'parses playlist %s', + (value) => expect(parseSpotifyInput(value)).toEqual({ kind: 'playlist', id }) + ); + it.each(['artist', 'episode', 'show'])('rejects unsupported %s', (resource) => + expect(parseSpotifyInput(`https://open.spotify.com/${resource}/${id}`).kind).toBe('unsupported') + ); + it.each([ + '', + ' ', + 'spotify:track:bad', + 'https://open.spotify.com/track/', + 'https://open.spotify.com/track/bad', + 'x'.repeat(501) + ])('validates %s', (value) => expect(() => parseSpotifyInput(value)).toThrow()); + it('preserves plain search and rejects lookalike host recognition', () => { + expect(parseSpotifyInput(' Deftones Change ')).toEqual({ + kind: 'search', + query: 'Deftones Change' + }); + expect(parseSpotifyInput(`https://open.spotify.com.evil.test/track/${id}`).kind).toBe('search'); + }); +}); +describe('matching', () => { + it.each([ + 'Song Title', + 'Song Title (Remastered 2011)', + 'Song Title - Remaster', + 'Song Title (feat. Someone)', + 'Song Title [Radio Edit]', + 'Song Title - Album Version' + ])('cleans %s', (value) => expect(cleanTitle(value)).toBe('song title')); + it('normalizes punctuation, diacritics, ampersands and whitespace', () => + expect(normalize(' Beyoncé & Friends! ')).toBe('beyonce and friends')); + it('keeps non-Latin text', () => expect(normalize('世界の歌')).toBe('世界の歌')); + it('scores exact and unicode aliases highly', () => { + expect(scoreBeatmapset(track, map).score).toBe(100); + expect( + scoreBeatmapset( + { ...track, name: '世界の歌' }, + { ...map, title: 'Sekai no uta', title_unicode: '世界の歌' } + ).confidence + ).toBe('high'); + }); + it('does not confidently match the wrong artist', () => + expect(scoreBeatmapset(track, { ...map, artist: 'Unrelated Singer' }).confidence).toBe('low')); + it('penalizes remix mismatch', () => + expect(scoreBeatmapset(track, { ...map, title: 'Song Title (Club Remix)' }).confidence).toBe( + 'low' + )); + it('sorts, merges duplicate IDs and limits results', () => { + const candidates = rankCandidates(track, [ + { ...map, title: 'Song Title remix' }, + ...Array.from({ length: 10 }, (_, id) => ({ ...map, id })) + ]); + expect(candidates).toHaveLength(MAX_CANDIDATES); + expect(new Set(candidates.map((m) => m.id)).size).toBe(MAX_CANDIDATES); + expect(candidates[0].score).toBe(100); + expect(candidates.every((m, i) => !i || candidates[i - 1].score >= m.score)).toBe(true); + }); + it('discards unrelated candidates', () => + expect( + rankCandidates(track, [{ ...map, title: 'Nothing Alike', artist: 'Different' }]) + ).toEqual([])); +}); + +it.each([`spotify:album:${id}`, `https://www.open.spotify.com/intl-nl/album/${id}/?si=abc`])( + 'parses album %s', + (value) => expect(parseSpotifyInput(value)).toEqual({ kind: 'album', id }) +); diff --git a/src/lib/map-finder/input.ts b/src/lib/map-finder/input.ts new file mode 100644 index 0000000..7beef9b --- /dev/null +++ b/src/lib/map-finder/input.ts @@ -0,0 +1,44 @@ +export type SpotifyInput = + | { kind: 'track'; id: string } + | { kind: 'playlist'; id: string } + | { kind: 'album'; id: string } + | { kind: 'search'; query: string } + | { kind: 'unsupported'; resource: string }; +export function parseSpotifyInput(value: string): SpotifyInput { + const query = value.trim(); + if (!query || query.length > 500) + throw new Error('Enter a Spotify URL, URI, or song search (up to 500 characters).'); + let resource: string | undefined; + let id: string | undefined; + if (/^spotify:/i.test(query)) { + const match = /^spotify:([^:]+):([^:]+)$/i.exec(query); + if (!match) + throw new Error( + 'Invalid Spotify URI. Use spotify:track:ID or spotify:playlist:ID or spotify:album:ID.' + ); + [, resource, id] = match; + } else { + let url: URL; + try { + url = new URL(query); + } catch { + if (/^(?:https?:\/\/)?(?:www\.)?open\.spotify\.com\b/i.test(query)) + throw new Error('Invalid Spotify URL. Include https://open.spotify.com/.'); + return { kind: 'search', query }; + } + if (!/^(www\.)?open\.spotify\.com$/i.test(url.hostname)) return { kind: 'search', query }; + if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.port) + throw new Error('Invalid Spotify URL.'); + const match = /^\/(?:intl-[a-z-]+\/)?([^/]+)(?:\/([^/]+))?\/?$/i.exec(url.pathname); + if (!match) throw new Error('Invalid Spotify URL path.'); + [, resource, id] = match; + } + resource = resource.toLowerCase(); + if (resource !== 'track' && resource !== 'playlist' && resource !== 'album') + return { kind: 'unsupported', resource }; + if (!id || !/^[a-zA-Z0-9]{22}$/.test(id)) + throw new Error( + 'Invalid Spotify ID. Track, playlist, and album IDs must contain 22 letters or digits.' + ); + return { kind: resource, id }; +} diff --git a/src/lib/map-finder/matching.ts b/src/lib/map-finder/matching.ts new file mode 100644 index 0000000..2d2d924 --- /dev/null +++ b/src/lib/map-finder/matching.ts @@ -0,0 +1,87 @@ +import type { OsuBeatmapset, ScoredBeatmapset, SpotifyTrack } from './types'; +// Medium requires a strong title plus artist evidence. High is reserved for near-exact pairs. +export const HIGH_CONFIDENCE = 88; +export const MEDIUM_CONFIDENCE = 72; +export const MIN_CANDIDATE_SCORE = 40; +export const MAX_CANDIDATES = 6; +export function normalize(value: string): string { + return value + .normalize('NFKD') + .replace(/\p{M}/gu, '') + .toLowerCase() + .replace(/&/g, ' and ') + .replace(/[^\p{L}\p{N}\s]/gu, ' ') + .replace(/\s+/g, ' ') + .trim(); +} +export function cleanTitle(value: string): string { + return normalize( + value + .replace( + /\s*[([](?:feat\.?|ft\.?|featuring|[^)\]]*(?:remaster|radio edit|album version|soundtrack|from the))[^)\]]*[)\]]/gi, + '' + ) + .replace(/\s+(?:feat\.?|ft\.?|featuring)\s+.*$/i, '') + .replace(/\s*[-–—]\s*(?:\d{4}\s*)?(?:remaster\w*|radio edit|album version|from\s+).*$/i, '') + ); +} +function similarity(a: string, b: string): number { + if (!a || !b) return 0; + if (a === b) return 1; + const left = new Set(a.split(' ')), + right = new Set(b.split(' ')); + const overlap = [...left].filter((token) => right.has(token)).length; + return Math.max( + (2 * overlap) / (left.size + right.size), + a.length >= 5 && b.length >= 5 && (a.includes(b) || b.includes(a)) ? 0.8 : 0 + ); +} +function versions(value: string): string { + const normalized = normalize(value); + return ['remix', 'live', 'acoustic', 'instrumental', 'sped up', 'nightcore'] + .filter((word) => normalized.includes(word)) + .join(' '); +} +export function scoreBeatmapset(track: SpotifyTrack, map: OsuBeatmapset): ScoredBeatmapset { + const title = Math.max( + ...[map.title, map.title_unicode ?? ''].map((v) => + similarity(cleanTitle(track.name), cleanTitle(v)) + ) + ); + const artistNames = [ + ...track.artists.map((a) => a.name), + track.artists.map((a) => a.name).join(' and ') + ]; + const artist = Math.max( + 0, + ...artistNames.flatMap((a) => + [map.artist, map.artist_unicode ?? ''].map((b) => similarity(normalize(a), normalize(b))) + ) + ); + const mismatch = versions(track.name) !== versions(map.title + ' ' + (map.title_unicode ?? '')); + let score = Math.round(title * 65 + artist * 35 - (mismatch ? 24 : 0)); + if (artist < 0.3) score = Math.min(score, MEDIUM_CONFIDENCE - 1); + score = Math.max(0, score); + const reasons = [ + title === 1 ? 'title exact' : 'title similar', + artist === 1 ? 'artist exact' : artist >= 0.3 ? 'artist similar' : 'artist differs' + ]; + if (mismatch) reasons.push('version differs'); + return { + ...map, + score, + confidence: score >= HIGH_CONFIDENCE ? 'high' : score >= MEDIUM_CONFIDENCE ? 'medium' : 'low', + reasons + }; +} +export function rankCandidates(track: SpotifyTrack, maps: OsuBeatmapset[]): ScoredBeatmapset[] { + const merged = new Map(); + for (const map of maps) { + const scored = scoreBeatmapset(track, map); + if (scored.score > (merged.get(map.id)?.score ?? -1)) merged.set(map.id, scored); + } + return [...merged.values()] + .filter((m) => m.score >= MIN_CANDIDATE_SCORE) + .sort((a, b) => b.score - a.score || a.id - b.id) + .slice(0, MAX_CANDIDATES); +} diff --git a/src/lib/map-finder/types.ts b/src/lib/map-finder/types.ts new file mode 100644 index 0000000..7299190 --- /dev/null +++ b/src/lib/map-finder/types.ts @@ -0,0 +1,34 @@ +export type SpotifyTrack = { + id: string; + name: string; + artists: { name: string }[]; + album: { name: string; images: { url: string }[] }; +}; +export type SpotifyCollection = { + kind: 'playlist' | 'album'; + id: string; + name: string; + owner: string; + image?: string; +}; +export type OsuBeatmapset = { + id: number; + artist: string; + title: string; + artist_unicode?: string; + title_unicode?: string; + covers?: { card?: string; 'card@2x'?: string }; + status?: string; + beatmaps?: { id: number }[]; +}; +export type ScoredBeatmapset = OsuBeatmapset & { + score: number; + confidence: 'high' | 'medium' | 'low'; + reasons: string[]; +}; +export type TrackMatchResult = { + track: SpotifyTrack; + matches: ScoredBeatmapset[]; + status: 'matched' | 'no_match' | 'error'; + error?: string; +}; diff --git a/src/lib/relative-time.test.ts b/src/lib/relative-time.test.ts new file mode 100644 index 0000000..2a18e99 --- /dev/null +++ b/src/lib/relative-time.test.ts @@ -0,0 +1,12 @@ +import { describe, expect, it } from 'vitest'; +import { relativeTime } from './relative-time'; + +describe('relativeTime', () => { + it('uses readable singular and plural dates', () => { + const now = Date.UTC(2026, 8, 23); + expect(relativeTime(new Date(now - 1000), now)).toBe('just now'); + expect(relativeTime(new Date(now - 1000 * 30), now)).toBe('30 seconds ago'); + expect(relativeTime(new Date(now - 1000 * 60 * 60), now)).toBe('an hour ago'); + expect(relativeTime(new Date(now - 1000 * 60 * 60 * 24 * 365), now)).toBe('a year ago'); + }); +}); diff --git a/src/lib/relative-time.ts b/src/lib/relative-time.ts new file mode 100644 index 0000000..caa368e --- /dev/null +++ b/src/lib/relative-time.ts @@ -0,0 +1,26 @@ +export function relativeTime(date: Date | string, now: number) { + const elapsed = Math.max(0, Math.floor((now - new Date(date).getTime()) / 1000)); + if (elapsed < 5) return 'just now'; + const units: [number, string][] = [ + [31_536_000, 'year'], + [2_592_000, 'month'], + [604_800, 'week'], + [86_400, 'day'], + [3_600, 'hour'], + [60, 'minute'], + [1, 'second'] + ]; + for (const [seconds, unit] of units) { + if (elapsed >= seconds) { + const count = Math.floor(elapsed / seconds); + return `${count === 1 ? (unit === 'hour' ? 'an' : 'a') : count} ${unit}${count === 1 ? '' : 's'} ago`; + } + } + return 'just now'; +} + +const dateFormatter = new Intl.DateTimeFormat('en', { dateStyle: 'long', timeZone: 'UTC' }); + +export function calendarDate(date: Date | string) { + return dateFormatter.format(new Date(date)); +} diff --git a/src/lib/seo.test.ts b/src/lib/seo.test.ts new file mode 100644 index 0000000..2c16790 --- /dev/null +++ b/src/lib/seo.test.ts @@ -0,0 +1,54 @@ +import { describe, expect, it } from 'vitest'; +import { getSeo } from './seo'; + +describe('public page metadata', () => { + it('gives the homepage a descriptive title and production canonical URL', () => { + const seo = getSeo('/'); + expect(seo.title).toBe('Projects, lists and writing | Stan Runge'); + expect(seo.url).toBe('https://stanrunge.dev/'); + expect(seo.indexable).toBe(true); + expect(seo.image).toBe('https://stanrunge.dev/moon.jpg'); + }); + + it('uses article content and its latest edit time', () => { + const article = getSeo('/blog/my-post', { + blogArticle: { + title: 'My post', + content: 'A **specific** article about lists.', + updatedAt: '2026-09-02T00:00:00.000Z' + } + }); + expect(article.title).toBe('My post | Stan Runge'); + expect(article.description).toBe('A specific article about lists.'); + expect(article.type).toBe('article'); + expect(article.modifiedAt).toBe('2026-09-02T00:00:00.000Z'); + }); + + it('describes a list using its contents', () => { + const seo = getSeo('/lists/vinyls-to-collect', { + list: { + name: 'Vinyls to collect', + isProgress: true, + items: [{ name: 'Album one' }, { name: 'Album two' }] + } + }); + expect(seo.title).toBe('Vinyls to collect | Stan Runge'); + expect(seo.description).toContain('Album one, Album two'); + expect(seo.indexable).toBe(true); + }); + + it('keeps private and staging pages out of search results', () => { + expect(getSeo('/login').indexable).toBe(false); + expect(getSeo('/projects/animaldex/register').indexable).toBe(false); + expect( + getSeo('/blog/my-post/edit', { + blogArticle: { + title: 'My post', + content: '', + updatedAt: '' + } + }).indexable + ).toBe(false); + expect(getSeo('/projects/catch-em-all', {}, 'STAGING').indexable).toBe(false); + }); +}); diff --git a/src/lib/seo.ts b/src/lib/seo.ts new file mode 100644 index 0000000..fcb9ec5 --- /dev/null +++ b/src/lib/seo.ts @@ -0,0 +1,118 @@ +import { formatTitle, getTitle, type SiteEnvironment } from './title'; + +export const SITE_ORIGIN = 'https://stanrunge.dev'; + +type Article = { + title: string; + content: string; + updatedAt: Date | string; +}; +type List = { name: string; isProgress: boolean; items: { name: string }[] }; +type Race = { short: string; distance: number; discipline: string }; +type PageContent = { blogArticle?: Article; list?: List; race?: Race }; + +type Seo = { + title: string; + description: string; + url: string; + indexable: boolean; + type: 'website' | 'article'; + image: string; + imageAlt: string; + modifiedAt?: string; +}; + +const publicPages: Record = { + '/': { + title: 'Projects, lists and writing', + description: 'Stan Runge’s projects, lists, writing and experience.' + }, + '/projects': { + title: 'Projects', + description: 'Software projects by Stan Runge, including Catchemall, Animaldex and Derby Lens.' + }, + '/blog': { title: 'Blog', description: 'Articles and notes by Stan Runge.' }, + '/lists': { title: 'Lists', description: 'Lists collected and maintained by Stan Runge.' }, + '/projects/catch-em-all': { + title: 'Catchemall', + description: 'Track which Pokémon you have caught across 53 games and 1,025 Pokémon.' + }, + '/projects/animaldex': { + title: 'Animaldex', + description: 'Find and add neighborhood animals on a map.' + }, + '/projects/derby': { + title: 'Derby Lens', + description: 'Estimate horse racing odds and compare them with market prices.' + }, + '/projects/spotify-beatmap-finder': { + title: 'osu! map finder', + description: 'Find osu! beatmaps for Spotify songs, albums and playlists.' + } +}; + +function excerpt(markdown: string): string { + return markdown + .replace(/!\[[^\]]*\]\([^)]*\)/g, '') + .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1') + .replace(/<[^>]*>/g, ' ') + .replace(/[`*_>#~|]/g, ' ') + .replace(/\s+/g, ' ') + .trim() + .slice(0, 160); +} + +function date(value: Date | string): string | undefined { + const parsed = new Date(value); + return Number.isNaN(parsed.getTime()) ? undefined : parsed.toISOString(); +} + +export function getSeo( + pathname: string, + content: PageContent = {}, + environment: SiteEnvironment = null +): Seo { + const path = pathname.replace(/\/$/, '') || '/'; + const url = new URL(path, SITE_ORIGIN).href; + let page = publicPages[path]; + let type: Seo['type'] = 'website'; + let modifiedAt: string | undefined; + + if (/^\/blog\/[^/]+$/.test(path) && content.blogArticle) { + const article = content.blogArticle; + page = { + title: article.title, + description: excerpt(article.content) || `Read ${article.title} by Stan Runge.` + }; + type = 'article'; + modifiedAt = date(article.updatedAt); + } else if (/^\/blog\/[^/]+\/edit$/.test(path) && content.blogArticle) { + page = { title: `Editing ${content.blogArticle.title}`, description: 'Edit a blog article.' }; + } else if (/^\/lists\/[^/]+$/.test(path) && content.list) { + const list = content.list; + const names = list.items.slice(0, 3).map((item) => item.name); + page = { + title: list.name, + description: names.length + ? `${list.name}: ${names.join(', ')}${list.items.length > names.length ? ', and more' : ''}.` + : `${list.name}, a ${list.isProgress ? 'progress ' : ''}list by Stan Runge.` + }; + } else if (/^\/projects\/derby\/[^/]+$/.test(path) && content.race) { + const race = content.race; + page = { + title: `${race.short} · Derby Lens`, + description: `Estimate odds for the ${race.short}, a ${race.distance} m ${race.discipline} race.` + }; + } + + return { + title: page ? formatTitle(page.title, environment) : getTitle(path, environment), + description: page?.description ?? 'Stan Runge’s personal website.', + url, + indexable: !!page && !environment && !/^\/blog\/[^/]+\/edit$/.test(path), + type, + image: `${SITE_ORIGIN}/moon.jpg`, + imageAlt: 'Moon icon for Stan Runge’s website', + modifiedAt + }; +} diff --git a/src/lib/server/auth.ts b/src/lib/server/auth.ts index bb3fec3..d9723f0 100644 --- a/src/lib/server/auth.ts +++ b/src/lib/server/auth.ts @@ -1,35 +1,88 @@ import { env } from '$env/dynamic/private'; +import { building, dev } from '$app/environment'; import { betterAuth } from 'better-auth/minimal'; import { drizzleAdapter } from 'better-auth/adapters/drizzle'; +import { genericOAuth } from 'better-auth/plugins'; +import { APIError, createAuthMiddleware } from 'better-auth/api'; import { sveltekitCookies } from 'better-auth/svelte-kit'; import { getRequestEvent } from '$app/server'; import { db } from '$lib/server/db'; import * as schema from '$lib/server/db/schema'; -import { error, type RequestEvent } from '@sveltejs/kit'; +import { osuProfile } from './osu-profile'; +export { isAdmin, requireAdmin, requireUser } from './authorization'; +if (!building && (!env.BETTER_AUTH_SECRET || env.BETTER_AUTH_SECRET.length < 32)) { + throw new Error('Set BETTER_AUTH_SECRET to a random secret of at least 32 characters'); +} +if (!building && !dev && !env.BETTER_AUTH_URL && !env.ORIGIN) { + throw new Error('Set BETTER_AUTH_URL to the public site origin'); +} +export const authProviders = { + google: !!(env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET), + osu: !!(env.OSU_CLIENT_ID && env.OSU_CLIENT_SECRET) +}; export const auth = betterAuth({ - baseURL: env.ORIGIN ?? 'http://localhost:3000', - secret: env.BETTER_AUTH_SECRET ?? 'build-time-placeholder', + baseURL: env.BETTER_AUTH_URL || env.ORIGIN || 'http://localhost:5173', + secret: env.BETTER_AUTH_SECRET || 'build-only-placeholder-not-a-runtime-secret', database: drizzleAdapter(db, { provider: 'pg', schema }), - emailAndPassword: { enabled: true }, - socialProviders: { - github: { - clientId: env.GITHUB_CLIENT_ID, - clientSecret: env.GITHUB_CLIENT_SECRET + emailAndPassword: { enabled: true, minPasswordLength: 12, maxPasswordLength: 128 }, + user: { + additionalFields: { + role: { type: 'string', required: false, defaultValue: 'user', input: false } } }, + account: { + accountLinking: { + enabled: true, + disableImplicitLinking: true, + allowDifferentEmails: true, + trustedProviders: ['osu'] + } + }, + rateLimit: { enabled: true }, + socialProviders: authProviders.google + ? { + google: { clientId: env.GOOGLE_CLIENT_ID!, clientSecret: env.GOOGLE_CLIENT_SECRET! } + } + : {}, + hooks: { + before: createAuthMiddleware(async (ctx) => { + // osu! has no email scope. Reserve its internal identifiers against credential signup. + if ( + ctx.path === '/sign-up/email' && + typeof ctx.body?.email === 'string' && + ctx.body.email.toLowerCase().endsWith('.invalid') + ) { + throw new APIError('BAD_REQUEST', { message: 'Please use a deliverable email address' }); + } + }) + }, plugins: [ - sveltekitCookies(getRequestEvent) // make sure this is the last plugin in the array + genericOAuth({ + config: authProviders.osu + ? [ + { + providerId: 'osu', + clientId: env.OSU_CLIENT_ID!, + clientSecret: env.OSU_CLIENT_SECRET!, + authorizationUrl: 'https://osu.ppy.sh/oauth/authorize', + tokenUrl: 'https://osu.ppy.sh/oauth/token', + scopes: ['identify'], + getUserInfo: async (tokens) => { + const response = await fetch('https://osu.ppy.sh/api/v2/me', { + headers: { + Authorization: `Bearer ${tokens.accessToken}`, + Accept: 'application/json' + }, + signal: AbortSignal.timeout(10000) + }); + if (!response.ok) throw new Error('Could not load osu! profile'); + return osuProfile(await response.json()); + } + } + ] + : [] + }), + sveltekitCookies(getRequestEvent) ] }); - -export function isAdmin(event: RequestEvent): boolean { - const token = event.cookies.get('admin_token'); - return !!token && token === env.ADMIN_SECRET; -} - -export function requireAdmin(event: RequestEvent): void { - if (!isAdmin(event)) { - error(401, { message: 'Unauthorized' }); - } -} diff --git a/src/lib/server/authorization.test.ts b/src/lib/server/authorization.test.ts new file mode 100644 index 0000000..3b0017f --- /dev/null +++ b/src/lib/server/authorization.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, it } from 'vitest'; +import { isAdmin, requireAdmin, requireUser } from './authorization'; +function event(role?: string) { + return { locals: { user: role ? { id: 'alice', role } : null, session: null } } as { + locals: App.Locals; + }; +} +describe('central authorization', () => { + it('rejects anonymous requests even with a legacy admin cookie', () => { + const anonymous = { ...event(), cookies: { get: () => 'old-admin-secret' } }; + expect(isAdmin(anonymous)).toBe(false); + expect(() => requireAdmin(anonymous)).toThrow(expect.objectContaining({ status: 401 })); + }); + it('allows normal users to own data but not administer the site', () => { + expect(requireUser(event('user')).id).toBe('alice'); + expect(() => requireAdmin(event('user'))).toThrow(expect.objectContaining({ status: 403 })); + }); + it('allows only the explicit admin role', () => { + expect(requireAdmin(event('admin')).id).toBe('alice'); + expect(isAdmin(event('superadmin'))).toBe(false); + }); +}); diff --git a/src/lib/server/authorization.ts b/src/lib/server/authorization.ts new file mode 100644 index 0000000..ab3c11b --- /dev/null +++ b/src/lib/server/authorization.ts @@ -0,0 +1,18 @@ +import { error } from '@sveltejs/kit'; + +type AuthEvent = { locals: App.Locals }; + +export function requireUser(event: AuthEvent) { + if (!event.locals.user) error(401, 'Log in to continue'); + return event.locals.user; +} + +export function isAdmin(event: AuthEvent): boolean { + return event.locals.user?.role === 'admin'; +} + +export function requireAdmin(event: AuthEvent) { + const user = requireUser(event); + if (!isAdmin(event)) error(403, 'Administrator access required'); + return user; +} diff --git a/src/lib/server/catalog.test.ts b/src/lib/server/catalog.test.ts new file mode 100644 index 0000000..9cd209b --- /dev/null +++ b/src/lib/server/catalog.test.ts @@ -0,0 +1,35 @@ +import { readFileSync } from 'node:fs'; +import { describe, expect, it } from 'vitest'; +const catalog = JSON.parse(readFileSync('data/pokemon-catalog.json', 'utf8')) as { + pokemon: { number: number; name: string; hp: number; type1: string }[]; + games: { sourceId: number; name: string }[]; + entries: [number, number, string][]; +}; +describe('Pokémon catalog snapshot', () => { + it('contains the national species catalog and the latest source versions', () => { + expect(catalog.pokemon).toHaveLength(1025); + expect(catalog.games.length).toBeGreaterThanOrEqual(53); + expect(catalog.pokemon.find((p) => p.number === 25)).toMatchObject({ + name: 'Pikachu', + type1: 'Electric', + hp: 35 + }); + expect(catalog.games.some((g) => g.name.includes('Z-A'))).toBe(true); + }); + it('has unique species, games, and valid entry references', () => { + const pokemon = new Set(catalog.pokemon.map((p) => p.number)); + const games = new Set(catalog.games.map((g) => g.sourceId)); + expect(pokemon.size).toBe(catalog.pokemon.length); + expect(games.size).toBe(catalog.games.length); + expect(new Set(catalog.entries.map(([p, g]) => `${p}/${g}`)).size).toBe(catalog.entries.length); + expect( + catalog.entries.every( + ([p, g, a]) => pokemon.has(p) && games.has(g) && ['catchable', 'unknown'].includes(a) + ) + ).toBe(true); + }); + it('does not invent exclusive availability from missing encounters', () => { + expect(catalog.entries.some(([, , a]) => a === 'catchable')).toBe(true); + expect(catalog.entries.some(([, , a]) => a === 'unknown')).toBe(true); + }); +}); diff --git a/src/lib/server/db/relations.ts b/src/lib/server/db/relations.ts index b40ea02..a891522 100644 --- a/src/lib/server/db/relations.ts +++ b/src/lib/server/db/relations.ts @@ -2,6 +2,27 @@ import { defineRelations } from 'drizzle-orm'; import * as schema from './schema'; export const relations = defineRelations(schema, (r) => ({ + // ── Auth ────────────────────────────────────── + user: { + sessions: r.many.session(), + accounts: r.many.account(), + entries: r.many.userEntries(), + games: r.many.userGames(), + listCompletions: r.many.listItemCompletions() + }, + session: { + user: r.one.user({ + from: r.session.userId, + to: r.user.id + }) + }, + account: { + user: r.one.user({ + from: r.account.userId, + to: r.user.id + }) + }, + // ── Progress ────────────────────────────────── tasks: { tasksToTopics: r.many.tasksToTopics() @@ -21,61 +42,41 @@ export const relations = defineRelations(schema, (r) => ({ }, // ── CatchEmAll ──────────────────────────────── - game: { - entries: r.many.pokemonGameEntry() + games: { + entries: r.many.pokemonGameEntries() }, pokemon: { - entry: r.many.pokemonGameEntry() + entry: r.many.pokemonGameEntries() }, - pokemonGameEntry: { - game: r.one.game({ - from: r.pokemonGameEntry.gameId, - to: r.game.id + pokemonGameEntries: { + game: r.one.games({ + from: r.pokemonGameEntries.gameId, + to: r.games.id }), pokemon: r.one.pokemon({ - from: r.pokemonGameEntry.pokemonId, + from: r.pokemonGameEntries.pokemonId, to: r.pokemon.id }), - userEntries: r.many.userEntry() + userEntries: r.many.userEntries() }, - userEntry: { - pokemonGameEntry: r.one.pokemonGameEntry({ - from: r.userEntry.pokemonGameEntryId, - to: r.pokemonGameEntry.id + userEntries: { + pokemonGameEntry: r.one.pokemonGameEntries({ + from: r.userEntries.pokemonGameEntryId, + to: r.pokemonGameEntries.id }), user: r.one.user({ - from: r.userEntry.userId, + from: r.userEntries.userId, to: r.user.id }) }, - userGame: { + userGames: { user: r.one.user({ - from: r.userGame.userId, + from: r.userGames.userId, to: r.user.id }), - game: r.one.game({ - from: r.userGame.gameId, - to: r.game.id - }) - }, - - // ── Auth ────────────────────────────────────── - user: { - sessions: r.many.session(), - accounts: r.many.account(), - entries: r.many.userEntry(), - games: r.many.userGame() - }, - session: { - user: r.one.user({ - from: r.session.userId, - to: r.user.id - }) - }, - account: { - user: r.one.user({ - from: r.account.userId, - to: r.user.id + game: r.one.games({ + from: r.userGames.gameId, + to: r.games.id }) }, @@ -95,5 +96,27 @@ export const relations = defineRelations(schema, (r) => ({ from: r.photos.sightingId, to: r.sightings.id }) + }, + + // ── Lists ───────────────────────────────────── + lists: { + items: r.many.listItems() + }, + listItems: { + list: r.one.lists({ + from: r.listItems.listId, + to: r.lists.id + }), + completions: r.many.listItemCompletions() + }, + listItemCompletions: { + item: r.one.listItems({ + from: r.listItemCompletions.itemId, + to: r.listItems.id + }), + user: r.one.user({ + from: r.listItemCompletions.userId, + to: r.user.id + }) } })); diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts deleted file mode 100755 index 5dcc73a..0000000 --- a/src/lib/server/db/schema.ts +++ /dev/null @@ -1,234 +0,0 @@ -import { - doublePrecision, - index, - integer, - pgEnum, - pgTable, - real, - serial, - text, - timestamp, - unique, - uuid, - varchar -} from 'drizzle-orm/pg-core'; - -import { user } from './auth.schema'; -import { availabilityValues } from '../../availability'; - -export const tasks = pgTable('tasks', { - id: serial('id').primaryKey(), - name: varchar('name', { length: 256 }), - currentPoints: integer('current_points').default(0), - totalPoints: integer('total_points').default(1), - notes: varchar('notes', { length: 8192 }), - createdAt: timestamp('created_at').defaultNow(), - updatedAt: timestamp('updated_at').defaultNow() -}); - -export const topics = pgTable('topics', { - id: serial('id').primaryKey(), - name: varchar('name', { length: 256 }), - emoji: varchar('emoji', { length: 256 }), - createdAt: timestamp('created_at').defaultNow(), - updatedAt: timestamp('updated_at').defaultNow() -}); - -export const tasksToTopics = pgTable('tasks_to_topics', { - taskId: integer('task_id') - .notNull() - .references(() => tasks.id), - topicId: integer('topic_id') - .notNull() - .references(() => topics.id) -}); - -export const universities = pgTable('universities', { - id: serial('id').primaryKey(), - name: varchar('name', { length: 256 }), - progress: integer('progress').default(0), - createdAt: timestamp('created_at').defaultNow(), - updatedAt: timestamp('updated_at').defaultNow() -}); - -export const certificates = pgTable('certificates', { - id: serial('id').primaryKey(), - name: varchar('name', { length: 256 }), - progress: integer('progress').default(0), - createdAt: timestamp('created_at').defaultNow(), - updatedAt: timestamp('updated_at').defaultNow() -}); - -export const publications = pgTable('publications', { - id: serial('id').primaryKey(), - name: varchar('name', { length: 256 }), - createdAt: timestamp('created_at').defaultNow(), - updatedAt: timestamp('updated_at').defaultNow() -}); - -// Legacy ^ -// New - -export const blogArticleStatus = pgEnum('blog_article_status', ['draft', 'published']); - -export const blogArticles = pgTable( - 'blog_articles', - { - id: serial('id').primaryKey(), - title: varchar('title', { length: 256 }).notNull(), - slug: varchar('slug', { length: 256 }).notNull(), - content: text('content').default(''), - status: blogArticleStatus('status').notNull().default('draft'), - createdAt: timestamp('created_at').defaultNow(), - updatedAt: timestamp('updated_at').defaultNow() - }, - (table) => [unique().on(table.slug)] -); - -// CatchEmAll - -export const availability = pgEnum('availability', availabilityValues); - -export const pokemon = pgTable('pokemon', { - id: serial('id').primaryKey(), - number: integer('number').notNull(), - generation: integer('generation').notNull().default(1), - name: varchar('name', { length: 256 }).notNull(), - type1: varchar('type1', { length: 256 }).notNull(), - type2: varchar('type2', { length: 256 }), - hp: integer('hp').notNull().default(0), - attack: integer('attack').notNull().default(0), - defense: integer('defense').notNull().default(0), - specialAttack: integer('special_attack').notNull().default(0), - specialDefense: integer('special_defense').notNull().default(0), - speed: integer('speed').notNull().default(0) -}); - -export const game = pgTable('game', { - id: serial('id').primaryKey(), - name: varchar('name', { length: 256 }).notNull(), - generation: integer('generation').notNull().default(1) -}); - -export const pokemonGameEntry = pgTable( - 'pokemon_game_entry', - { - id: serial('id').primaryKey(), - pokemonId: integer('pokemon_id') - .notNull() - .references(() => pokemon.id, { onDelete: 'cascade' }), - gameId: integer('game_id') - .notNull() - .references(() => game.id, { onDelete: 'cascade' }), - availability: availability('availability').notNull().default('catchable'), - // optional extra detail for the tooltip, e.g. "trade with a Blue version owner" - note: varchar('note', { length: 256 }) - }, - (table) => [unique().on(table.pokemonId, table.gameId), index().on(table.gameId)] -); - -export const userEntry = pgTable( - 'user_entry', - { - id: serial('id').primaryKey(), - pokemonGameEntryId: integer('pokemon_game_entry_id') - .notNull() - .references(() => pokemonGameEntry.id, { onDelete: 'cascade' }), - userId: text('user_id') - .notNull() - .references(() => user.id, { onDelete: 'cascade' }) - }, - (table) => [unique().on(table.pokemonGameEntryId, table.userId), index().on(table.userId)] -); - -// which games a user has chosen to track ("rules") -export const userGame = pgTable( - 'user_game', - { - id: serial('id').primaryKey(), - userId: text('user_id') - .notNull() - .references(() => user.id, { onDelete: 'cascade' }), - gameId: integer('game_id') - .notNull() - .references(() => game.id, { onDelete: 'cascade' }) - }, - (table) => [unique().on(table.userId, table.gameId), index().on(table.userId)] -); - -// Animaldex - -export const animals = pgTable('animals', { - id: uuid('id').primaryKey().defaultRandom(), - - species: text('species').notNull(), - breed: text('breed'), - animalName: text('animal_name'), - description: text('description'), - - // AI detection stored on the animal (from the first/primary photo) - aiBreedSuggestion: text('ai_breed_suggestion'), - aiBreedConfidence: real('ai_breed_confidence'), - - // Moderation — the animal entity is moderated once. - // Accepted = visible on map (as long as it has accepted sightings too). - // Denied animals are hidden but not deleted. - submittedAt: timestamp('submitted_at', { withTimezone: true }).notNull().defaultNow(), - acceptedAt: timestamp('accepted_at', { withTimezone: true }), - deniedAt: timestamp('denied_at', { withTimezone: true }) -}); - -export const sightings = pgTable('sightings', { - id: uuid('id').primaryKey().defaultRandom(), - animalId: uuid('animal_id') - .notNull() - .references(() => animals.id, { onDelete: 'cascade' }), - - reporterName: text('reporter_name'), - - seenAt: timestamp('seen_at', { withTimezone: true }).notNull(), - lat: doublePrecision('lat').notNull(), - lng: doublePrecision('lng').notNull(), - - submittedAt: timestamp('submitted_at', { withTimezone: true }).notNull().defaultNow(), - acceptedAt: timestamp('accepted_at', { withTimezone: true }), - deniedAt: timestamp('denied_at', { withTimezone: true }) -}); - -export const photos = pgTable('photos', { - id: uuid('id').primaryKey().defaultRandom(), - sightingId: uuid('sighting_id') - .notNull() - .references(() => sightings.id, { onDelete: 'cascade' }), - r2Key: text('r2_key').notNull(), - url: text('url').notNull(), - sortOrder: integer('sort_order').notNull().default(0), - uploadedAt: timestamp('uploaded_at', { withTimezone: true }).notNull().defaultNow() -}); - -export type Pokemon = typeof pokemon.$inferSelect; -export type Game = typeof game.$inferSelect; -export type PokemonGameEntry = typeof pokemonGameEntry.$inferSelect; -export type UserEntry = typeof userEntry.$inferSelect; -export type UserGame = typeof userGame.$inferSelect; -export type Availability = (typeof availability.enumValues)[number]; - -export type Animal = typeof animals.$inferSelect; -export type NewAnimal = typeof animals.$inferInsert; -export type Sighting = typeof sightings.$inferSelect; -export type NewSighting = typeof sightings.$inferInsert; -export type Photo = typeof photos.$inferSelect; - -// ── Helpers ─────────────────────────────────────────────────────────────────── - -export type ModerationStatus = 'pending' | 'accepted' | 'denied'; - -export function getModerationStatus( - row: Pick -): ModerationStatus { - if (row.deniedAt) return 'denied'; - if (row.acceptedAt) return 'accepted'; - return 'pending'; -} - -export * from './auth.schema'; diff --git a/src/lib/server/db/schema/animaldex.ts b/src/lib/server/db/schema/animaldex.ts new file mode 100644 index 0000000..fd27f70 --- /dev/null +++ b/src/lib/server/db/schema/animaldex.ts @@ -0,0 +1,69 @@ +import { doublePrecision, integer, pgTable, text } from 'drizzle-orm/pg-core'; +import { id, timestamps, timestamptz } from './helpers'; + +export const animals = pgTable('animals', { + id: id(), + + species: text('species').notNull(), + breed: text('breed'), + animalName: text('animal_name'), + description: text('description'), + + // AI detection stored on the animal (from the first/primary photo) + aiBreedSuggestion: text('ai_breed_suggestion'), + aiBreedConfidence: doublePrecision('ai_breed_confidence'), + + // Moderation — the animal entity is moderated once. + // Accepted = visible on map (as long as it has accepted sightings too). + // Denied animals are hidden but not deleted. + submittedAt: timestamptz('submitted_at').notNull().defaultNow(), + acceptedAt: timestamptz('accepted_at'), + deniedAt: timestamptz('denied_at'), + ...timestamps +}); + +export const sightings = pgTable('sightings', { + id: id(), + animalId: integer('animal_id') + .notNull() + .references(() => animals.id, { onDelete: 'cascade' }), + + reporterName: text('reporter_name'), + + seenAt: timestamptz('seen_at').notNull(), + lat: doublePrecision('lat').notNull(), + lng: doublePrecision('lng').notNull(), + + submittedAt: timestamptz('submitted_at').notNull().defaultNow(), + acceptedAt: timestamptz('accepted_at'), + deniedAt: timestamptz('denied_at'), + ...timestamps +}); + +export const photos = pgTable('photos', { + id: id(), + sightingId: integer('sighting_id') + .notNull() + .references(() => sightings.id, { onDelete: 'cascade' }), + r2Key: text('r2_key').notNull(), + url: text('url').notNull(), + sortOrder: integer('sort_order').notNull().default(0), + uploadedAt: timestamptz('uploaded_at').notNull().defaultNow(), + ...timestamps +}); + +export type Animal = typeof animals.$inferSelect; +export type NewAnimal = typeof animals.$inferInsert; +export type Sighting = typeof sightings.$inferSelect; +export type NewSighting = typeof sightings.$inferInsert; +export type Photo = typeof photos.$inferSelect; + +export type ModerationStatus = 'pending' | 'accepted' | 'denied'; + +export function getModerationStatus( + row: Pick +): ModerationStatus { + if (row.deniedAt) return 'denied'; + if (row.acceptedAt) return 'accepted'; + return 'pending'; +} diff --git a/src/lib/server/db/auth.schema.ts b/src/lib/server/db/schema/auth.ts similarity index 55% rename from src/lib/server/db/auth.schema.ts rename to src/lib/server/db/schema/auth.ts index 6827070..9438bd4 100644 --- a/src/lib/server/db/auth.schema.ts +++ b/src/lib/server/db/schema/auth.ts @@ -1,13 +1,14 @@ -import { pgTable, text, timestamp, boolean, index } from 'drizzle-orm/pg-core'; +import { pgTable, text, timestamp, boolean, index, uniqueIndex } from 'drizzle-orm/pg-core'; export const user = pgTable('user', { id: text('id').primaryKey(), name: text('name').notNull(), + role: text('role').notNull().default('user'), email: text('email').notNull().unique(), emailVerified: boolean('email_verified').default(false).notNull(), image: text('image'), - createdAt: timestamp('created_at').defaultNow().notNull(), - updatedAt: timestamp('updated_at') + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { withTimezone: true }) .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull() @@ -17,10 +18,10 @@ export const session = pgTable( 'session', { id: text('id').primaryKey(), - expiresAt: timestamp('expires_at').notNull(), + expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(), token: text('token').notNull().unique(), - createdAt: timestamp('created_at').defaultNow().notNull(), - updatedAt: timestamp('updated_at') + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { withTimezone: true }) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), ipAddress: text('ip_address'), @@ -37,6 +38,7 @@ export const account = pgTable( { id: text('id').primaryKey(), accountId: text('account_id').notNull(), + issuer: text('issuer').notNull(), providerId: text('provider_id').notNull(), userId: text('user_id') .notNull() @@ -44,16 +46,19 @@ export const account = pgTable( accessToken: text('access_token'), refreshToken: text('refresh_token'), idToken: text('id_token'), - accessTokenExpiresAt: timestamp('access_token_expires_at'), - refreshTokenExpiresAt: timestamp('refresh_token_expires_at'), + accessTokenExpiresAt: timestamp('access_token_expires_at', { withTimezone: true }), + refreshTokenExpiresAt: timestamp('refresh_token_expires_at', { withTimezone: true }), scope: text('scope'), password: text('password'), - createdAt: timestamp('created_at').defaultNow().notNull(), - updatedAt: timestamp('updated_at') + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { withTimezone: true }) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull() }, - (table) => [index('account_userId_idx').on(table.userId)] + (table) => [ + index('account_userId_idx').on(table.userId), + uniqueIndex('account_issuer_account_id_unique').on(table.issuer, table.accountId) + ] ); export const verification = pgTable( @@ -62,9 +67,9 @@ export const verification = pgTable( id: text('id').primaryKey(), identifier: text('identifier').notNull(), value: text('value').notNull(), - expiresAt: timestamp('expires_at').notNull(), - createdAt: timestamp('created_at').defaultNow().notNull(), - updatedAt: timestamp('updated_at') + expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { withTimezone: true }) .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull() diff --git a/src/lib/server/db/schema/blog.ts b/src/lib/server/db/schema/blog.ts new file mode 100644 index 0000000..a3479d3 --- /dev/null +++ b/src/lib/server/db/schema/blog.ts @@ -0,0 +1,22 @@ +import { pgEnum, pgTable, text, unique } from 'drizzle-orm/pg-core'; +import { id, timestamps } from './helpers'; + +export const blogArticleStatus = pgEnum('blog_article_status', ['draft', 'published']); + +export const blogArticles = pgTable( + 'blog_articles', + { + id: id(), + title: text('title').notNull(), + slug: text('slug').notNull(), + content: text('content').notNull().default(''), + tags: text('tags').array().notNull().default([]), + status: blogArticleStatus('status').notNull().default('draft'), + ...timestamps + }, + (table) => [unique().on(table.slug)] +); + +export type BlogArticle = typeof blogArticles.$inferSelect; +export type NewBlogArticle = typeof blogArticles.$inferInsert; +export type BlogArticleStatus = (typeof blogArticleStatus.enumValues)[number]; diff --git a/src/lib/server/db/schema/catch-em-all.ts b/src/lib/server/db/schema/catch-em-all.ts new file mode 100644 index 0000000..30d15fd --- /dev/null +++ b/src/lib/server/db/schema/catch-em-all.ts @@ -0,0 +1,96 @@ +import { index, integer, pgEnum, pgTable, text, unique } from 'drizzle-orm/pg-core'; +import { availabilityValues } from '../../../availability'; +import { user } from './auth'; +import { id, timestamps } from './helpers'; + +export const availability = pgEnum('availability', availabilityValues); + +export const pokemon = pgTable('pokemon', { + id: id(), + number: integer('number').notNull().unique(), + generation: integer('generation').notNull().default(1), + name: text('name').notNull(), + type1: text('type1').notNull(), + type2: text('type2'), + hp: integer('hp').notNull().default(0), + attack: integer('attack').notNull().default(0), + defense: integer('defense').notNull().default(0), + specialAttack: integer('special_attack').notNull().default(0), + specialDefense: integer('special_defense').notNull().default(0), + speed: integer('speed').notNull().default(0), + ...timestamps +}); + +export const games = pgTable('games', { + id: id(), + sourceId: integer('source_id').unique(), + name: text('name').notNull(), + generation: integer('generation').notNull().default(1), + ...timestamps +}); + +export const pokemonGameEntries = pgTable( + 'pokemon_game_entries', + { + id: id(), + pokemonId: integer('pokemon_id') + .notNull() + .references(() => pokemon.id, { onDelete: 'cascade' }), + gameId: integer('game_id') + .notNull() + .references(() => games.id, { onDelete: 'cascade' }), + availability: availability('availability').notNull().default('catchable'), + // optional extra detail for the tooltip, e.g. "trade with a Blue version owner" + note: text('note'), + ...timestamps + }, + (table) => [unique().on(table.pokemonId, table.gameId), index().on(table.gameId)] +); + +export const userEntries = pgTable( + 'user_entries', + { + id: id(), + pokemonGameEntryId: integer('pokemon_game_entry_id') + .notNull() + .references(() => pokemonGameEntries.id, { onDelete: 'cascade' }), + userId: text('user_id') + .notNull() + .references(() => user.id, { onDelete: 'cascade' }), + ...timestamps + }, + (table) => [unique().on(table.pokemonGameEntryId, table.userId), index().on(table.userId)] +); + +// which games a user has chosen to track ("rules") +export const userGames = pgTable( + 'user_games', + { + id: id(), + userId: text('user_id') + .notNull() + .references(() => user.id, { onDelete: 'cascade' }), + gameId: integer('game_id') + .notNull() + .references(() => games.id, { onDelete: 'cascade' }), + ...timestamps + }, + (table) => [unique().on(table.userId, table.gameId), index().on(table.userId)] +); + +// A row distinguishes an explicit empty game selection from a new account. +export const catchEmAllSettings = pgTable('catch_em_all_settings', { + id: id(), + userId: text('user_id') + .notNull() + .unique() + .references(() => user.id, { onDelete: 'cascade' }), + ...timestamps +}); + +export type Pokemon = typeof pokemon.$inferSelect; +export type Game = typeof games.$inferSelect; +export type PokemonGameEntry = typeof pokemonGameEntries.$inferSelect; +export type UserEntry = typeof userEntries.$inferSelect; +export type UserGame = typeof userGames.$inferSelect; +export type Availability = (typeof availability.enumValues)[number]; diff --git a/src/lib/server/db/schema/helpers.ts b/src/lib/server/db/schema/helpers.ts new file mode 100644 index 0000000..142f802 --- /dev/null +++ b/src/lib/server/db/schema/helpers.ts @@ -0,0 +1,17 @@ +import { serial, timestamp } from 'drizzle-orm/pg-core'; + +// Shared column patterns so every table is built the same way. +// Timestamps are always `timestamptz` — they represent a moment in time, not a +// wall-clock reading. + +export const id = () => serial('id').primaryKey(); + +export const timestamptz = (name: string) => timestamp(name, { withTimezone: true }); + +export const timestamps = { + createdAt: timestamptz('created_at').notNull().defaultNow(), + updatedAt: timestamptz('updated_at') + .notNull() + .defaultNow() + .$onUpdate(() => new Date()) +}; diff --git a/src/lib/server/db/schema/index.ts b/src/lib/server/db/schema/index.ts new file mode 100644 index 0000000..b7e6e07 --- /dev/null +++ b/src/lib/server/db/schema/index.ts @@ -0,0 +1,8 @@ +// One file per domain. Everything is re-exported here so the rest of the app +// (and drizzle-kit / relations) only ever imports `$lib/server/db/schema`. +export * from './auth'; +export * from './blog'; +export * from './progress'; +export * from './catch-em-all'; +export * from './animaldex'; +export * from './lists'; diff --git a/src/lib/server/db/schema/lists.ts b/src/lib/server/db/schema/lists.ts new file mode 100644 index 0000000..a3c76b3 --- /dev/null +++ b/src/lib/server/db/schema/lists.ts @@ -0,0 +1,46 @@ +import { boolean, index, integer, pgTable, text, unique } from 'drizzle-orm/pg-core'; +import { id, timestamps } from './helpers'; +import { user } from './auth'; + +export const lists = pgTable('lists', { + id: id(), + name: text('name').notNull(), + slug: text('slug').notNull().unique(), + isProgress: boolean('is_progress').notNull().default(false), + ...timestamps +}); + +export const listItems = pgTable( + 'list_items', + { + id: id(), + listId: integer('list_id') + .notNull() + .references(() => lists.id, { onDelete: 'cascade' }), + name: text('name').notNull(), + pictureUrl: text('picture_url'), + description: text('description'), + ...timestamps + }, + (table) => [index().on(table.listId)] +); + +export const listItemCompletions = pgTable( + 'list_item_completions', + { + id: id(), + itemId: integer('item_id') + .notNull() + .references(() => listItems.id, { onDelete: 'cascade' }), + userId: text('user_id') + .notNull() + .references(() => user.id, { onDelete: 'cascade' }), + ...timestamps + }, + (table) => [unique().on(table.itemId, table.userId), index().on(table.userId)] +); + +export type List = typeof lists.$inferSelect; +export type NewList = typeof lists.$inferInsert; +export type ListItem = typeof listItems.$inferSelect; +export type NewListItem = typeof listItems.$inferInsert; diff --git a/src/lib/server/db/schema/progress.ts b/src/lib/server/db/schema/progress.ts new file mode 100644 index 0000000..1f57ca9 --- /dev/null +++ b/src/lib/server/db/schema/progress.ts @@ -0,0 +1,38 @@ +import { integer, pgTable, text, unique } from 'drizzle-orm/pg-core'; +import { id, timestamps } from './helpers'; + +export const tasks = pgTable('tasks', { + id: id(), + name: text('name').notNull(), + currentPoints: integer('current_points').notNull().default(0), + totalPoints: integer('total_points').notNull().default(1), + notes: text('notes'), + ...timestamps +}); + +export const topics = pgTable('topics', { + id: id(), + name: text('name').notNull(), + emoji: text('emoji'), + ...timestamps +}); + +export const tasksToTopics = pgTable( + 'tasks_to_topics', + { + id: id(), + taskId: integer('task_id') + .notNull() + .references(() => tasks.id, { onDelete: 'cascade' }), + topicId: integer('topic_id') + .notNull() + .references(() => topics.id, { onDelete: 'cascade' }), + ...timestamps + }, + (table) => [unique().on(table.taskId, table.topicId)] +); + +export type Task = typeof tasks.$inferSelect; +export type NewTask = typeof tasks.$inferInsert; +export type Topic = typeof topics.$inferSelect; +export type NewTopic = typeof topics.$inferInsert; diff --git a/src/lib/server/finder-http.ts b/src/lib/server/finder-http.ts new file mode 100644 index 0000000..b04ae4d --- /dev/null +++ b/src/lib/server/finder-http.ts @@ -0,0 +1,119 @@ +export class ApiError extends Error { + constructor( + public provider: string, + public status: number, + message: string + ) { + super(message); + } +} +export function publicError(error: unknown): string { + return error instanceof ApiError + ? error.message + : 'Search could not be completed. Please try again.'; +} +export function logApiError(error: unknown) { + console.error( + 'Map finder request failed', + error instanceof ApiError + ? { provider: error.provider, status: error.status } + : { type: 'unexpected' } + ); +} +const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); +const cooldowns = new Map(); +export async function requestJson( + fetchFn: typeof fetch, + provider: string, + url: string, + init: RequestInit = {}, + wait = sleep +): Promise { + for (let attempt = 0; attempt < 3; attempt++) { + if ((cooldowns.get(provider) ?? 0) > Date.now()) + throw new ApiError(provider, 429, `${provider} is rate-limited. Please try again later.`); + let response: Response; + try { + response = await fetchFn(url, { ...init, signal: AbortSignal.timeout(12000) }); + } catch { + if (attempt < 2) { + await wait(300 * 2 ** attempt + Math.random() * 150); + continue; + } + throw new ApiError(provider, 503, `${provider} is unavailable. Please try again later.`); + } + if (response.ok) { + try { + return await response.json(); + } catch { + throw new ApiError( + provider, + 502, + `${provider} returned an invalid response. Please try again.` + ); + } + } + if (response.status === 429 || response.status >= 500) { + const retry = response.headers.get('Retry-After'); + const delay = retry + ? /^\d+(\.\d+)?$/.test(retry) + ? Number(retry) * 1000 + : Math.max(0, Date.parse(retry) - Date.now()) + : 300 * 2 ** attempt; + const boundedDelay = Number.isFinite(delay) ? delay : 1000; + if (response.status === 429) cooldowns.set(provider, Date.now() + boundedDelay); + if (attempt < 2 && boundedDelay <= 4000) { + await wait(boundedDelay + Math.random() * 150); + continue; + } + } + throw new ApiError( + provider, + response.status, + response.status === 429 + ? `${provider} is rate-limited. Please try again later.` + : `${provider} request failed. Please try again later.` + ); + } + throw new ApiError(provider, 503, `${provider} is unavailable.`); +} +export function createTokenCache() { + let token: { value: string; expires: number } | undefined; + let pending: Promise | undefined; + return async (refresh: () => Promise): Promise => { + if (token && token.expires > Date.now() + 30000) return token.value; + if (!pending) + pending = (async () => { + const result = (await refresh()) as { access_token?: unknown; expires_in?: unknown }; + if ( + typeof result?.access_token !== 'string' || + typeof result.expires_in !== 'number' || + result.expires_in <= 0 + ) + throw new ApiError('OAuth', 502, 'API authentication is temporarily unavailable.'); + token = { value: result.access_token, expires: Date.now() + result.expires_in * 1000 }; + return token.value; + })().finally(() => { + pending = undefined; + }); + return pending; + }; +} +export async function mapConcurrent( + items: T[], + limit: number, + work: (item: T) => Promise +): Promise { + if (!Number.isInteger(limit) || limit < 1) throw new Error('Concurrency must be positive.'); + const results: R[] = new Array(items.length); + let cursor = 0; + await Promise.all( + Array.from({ length: Math.min(limit, items.length) }, async () => { + while (cursor < items.length) { + const index = cursor++; + results[index] = await work(items[index]); + } + }) + ); + return results; +} diff --git a/src/lib/server/finder-limit.ts b/src/lib/server/finder-limit.ts new file mode 100644 index 0000000..0c7056f --- /dev/null +++ b/src/lib/server/finder-limit.ts @@ -0,0 +1,28 @@ +export const RATE_WINDOW_MS = 10 * 60_000; +export const RATE_BUDGET = 12; +export function createRateLimiter() { + let activeSearches = 0; + const records = new Map(); + return (key: string, cost: number, now = Date.now()) => { + // Opportunistic cleanup on every action; no timers keep the server alive. + for (const [id, entry] of records) + if (entry.expires <= now && !entry.active) records.delete(id); + let entry = records.get(key); + if (!entry) { + if (records.size >= 10000) return null; + entry = { expires: now + RATE_WINDOW_MS, used: 0, active: false }; + records.set(key, entry); + } + if (activeSearches >= 6 || entry.active || entry.used + cost > RATE_BUDGET) return null; + entry.used += cost; + entry.active = true; + activeSearches++; + return () => { + if (entry.active) { + entry.active = false; + activeSearches--; + } + }; + }; +} +export const acquireSearch = createRateLimiter(); diff --git a/src/lib/server/finder.test.ts b/src/lib/server/finder.test.ts new file mode 100644 index 0000000..7ff4eef --- /dev/null +++ b/src/lib/server/finder.test.ts @@ -0,0 +1,167 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +vi.mock('$env/dynamic/private', () => ({ + env: { SPOTIFY_CLIENT_ID: 'test', SPOTIFY_CLIENT_SECRET: 'test' } +})); +import { createTokenCache, mapConcurrent, requestJson } from './finder-http'; +import { createRateLimiter, RATE_WINDOW_MS } from './finder-limit'; +import { getSpotifyMetadata, playlistTracks, MAX_PLAYLIST_TRACKS } from './spotify'; +const id = (n: number) => String(n).padStart(22, '0'); +const track = (n: number) => ({ + type: 'track', + id: id(n), + name: `Song ${n}`, + artists: [{ name: 'Artist' }], + album: { name: 'Album', images: [] } +}); +afterEach(() => vi.useRealTimers()); +describe('request controls', () => { + it('reuses tokens, coalesces refreshes and refreshes near expiry', async () => { + vi.useFakeTimers(); + const cache = createTokenCache(); + const refresh = vi.fn(async () => ({ access_token: 'token', expires_in: 60 })); + expect(await Promise.all([cache(refresh), cache(refresh)])).toEqual(['token', 'token']); + await cache(refresh); + expect(refresh).toHaveBeenCalledTimes(1); + vi.advanceTimersByTime(31000); + await cache(refresh); + expect(refresh).toHaveBeenCalledTimes(2); + }); + it('bounds concurrency and preserves order', async () => { + let active = 0, + peak = 0; + const result = await mapConcurrent([3, 2, 1, 0], 2, async (n) => { + active++; + peak = Math.max(peak, active); + await new Promise((r) => setTimeout(r, n)); + active--; + return n * 2; + }); + expect(peak).toBe(2); + expect(result).toEqual([6, 4, 2, 0]); + }); + it('retries 429 after Retry-After', async () => { + vi.useFakeTimers(); + const fetchFn = vi + .fn() + .mockResolvedValueOnce(new Response('', { status: 429, headers: { 'Retry-After': '1' } })) + .mockResolvedValueOnce(Response.json({ ok: true })); + const wait = vi.fn(async (ms: number) => { + vi.advanceTimersByTime(ms); + }); + expect(await requestJson(fetchFn, 'retry-test', 'https://example.test', {}, wait)).toEqual({ + ok: true + }); + expect(wait.mock.calls[0][0]).toBeGreaterThanOrEqual(1000); + expect(fetchFn).toHaveBeenCalledTimes(2); + }); + it('does not retry 404 or malformed JSON', async () => { + const fetchFn = vi.fn().mockResolvedValue(new Response('', { status: 404 })); + await expect(requestJson(fetchFn, 'test', 'https://example.test')).rejects.toMatchObject({ + status: 404 + }); + expect(fetchFn).toHaveBeenCalledTimes(1); + await expect( + requestJson( + vi.fn().mockResolvedValue(new Response('invalid')), + 'test', + 'https://example.test' + ) + ).rejects.toMatchObject({ status: 502 }); + }); + it('limits server retries and respects long cooldowns without sleeping', async () => { + const fetchFn = vi.fn().mockImplementation(async () => new Response('', { status: 503 })); + await expect( + requestJson(fetchFn, 'server-test', 'https://example.test', {}, async () => {}) + ).rejects.toMatchObject({ status: 503 }); + expect(fetchFn).toHaveBeenCalledTimes(3); + const throttled = vi + .fn() + .mockResolvedValue(new Response('', { status: 429, headers: { 'Retry-After': '60' } })); + await expect( + requestJson(throttled, 'long-retry', 'https://example.test') + ).rejects.toMatchObject({ status: 429 }); + expect(throttled).toHaveBeenCalledTimes(1); + }); + it('limits weighted searches, concurrent requests and expires records', () => { + const acquire = createRateLimiter(); + const release = acquire('ip', 6, 0)!; + expect(acquire('ip', 1, 1)).toBeNull(); + release(); + acquire('ip', 6, 2)!(); + expect(acquire('ip', 1, 3)).toBeNull(); + expect(acquire('ip', 6, RATE_WINDOW_MS + 1)).toBeTypeOf('function'); + }); +}); +describe('playlists', () => { + it('skips unusable entries and deduplicates in order', () => + expect( + playlistTracks([ + { track: track(2) }, + { track: null }, + { track: { ...track(3), is_local: true } }, + { track: { ...track(4), type: 'episode' } }, + { track: { ...track(5), is_playable: false } }, + { track: track(2) }, + { item: track(1) }, + { track: { id: id(7) } } + ]).map((t) => t.id) + ).toEqual([id(2), id(1)])); + it('paginates, deduplicates across pages and truncates', async () => { + const fetchFn = vi.fn(async (url: string | URL | Request) => { + const value = String(url); + if (value.includes('/api/token')) + return Response.json({ access_token: 'token', expires_in: 3600 }); + if (value.includes('offset=2')) + return Response.json({ + items: Array.from({ length: 55 }, (_, n) => ({ track: track(n + 1) })), + next: null, + total: 57 + }); + return Response.json({ + name: 'Playlist', + owner: { display_name: 'Owner' }, + tracks: { + items: [{ track: track(1) }, { track: null }], + next: 'https://evil.test', + total: 57 + } + }); + }); + const result = await getSpotifyMetadata(fetchFn as typeof fetch, { + kind: 'playlist', + id: id(1) + }); + expect(result.tracks).toHaveLength(MAX_PLAYLIST_TRACKS); + expect(result.tracks[0].id).toBe(id(1)); + expect(result.tracks[1].id).toBe(id(2)); + expect(result.truncated).toBe(true); + expect(fetchFn.mock.calls.every(([url]) => !String(url).includes('evil.test'))).toBe(true); + }); + it('supports the newer items/item response', async () => { + const fetchFn = vi.fn(async () => + Response.json({ name: 'New playlist', items: { items: [{ item: track(1) }], next: null } }) + ); + const result = await getSpotifyMetadata(fetchFn, { kind: 'playlist', id: id(1) }); + expect(result.tracks).toHaveLength(1); + expect(result.truncated).toBe(false); + }); +}); + +it('paginates album tracks and attaches shared album metadata', async () => { + const fetchFn = vi.fn(async (url: string | URL | Request) => + String(url).includes('offset=1') + ? Response.json({ items: [track(2)], next: null, total: 2 }) + : Response.json({ + name: 'Album name', + artists: [{ name: 'Artist' }], + images: [{ url: 'https://example.test/cover.jpg' }], + tracks: { items: [track(1)], next: 'next', total: 2 } + }) + ); + const result = await getSpotifyMetadata(fetchFn as typeof fetch, { kind: 'album', id: id(1) }); + expect(result.collection).toMatchObject({ kind: 'album', name: 'Album name', owner: 'Artist' }); + expect(result.tracks.map((t) => t.id)).toEqual([id(1), id(2)]); + expect(result.tracks[1].album.name).toBe('Album name'); + expect(result.truncated).toBe(false); + expect(String(fetchFn.mock.calls[1][0])).toContain('/albums/'); +}); diff --git a/src/lib/server/osu-profile.test.ts b/src/lib/server/osu-profile.test.ts new file mode 100644 index 0000000..d7a88fc --- /dev/null +++ b/src/lib/server/osu-profile.test.ts @@ -0,0 +1,20 @@ +import { expect, it } from 'vitest'; +import { osuProfile } from './osu-profile'; +it('binds osu accounts to numeric provider IDs, never a claimed email or username', () => { + const profile = osuProfile({ + id: 123, + username: 'Alice', + avatar_url: 'https://a.ppy.sh/123', + email: 'admin@example.com', + email_verified: true + }); + expect(profile).toMatchObject({ id: '123', email: '123@osu.invalid', emailVerified: false }); + expect( + osuProfile({ id: 123, username: 'Renamed', avatar_url: 'https://a.ppy.sh/123' }).email + ).toBe(profile.email); +}); +it('rejects malformed provider identities', () => { + expect(() => + osuProfile({ id: 'admin', username: 'Alice', avatar_url: 'https://a.ppy.sh/123' }) + ).toThrow(); +}); diff --git a/src/lib/server/osu-profile.ts b/src/lib/server/osu-profile.ts new file mode 100644 index 0000000..4d0d189 --- /dev/null +++ b/src/lib/server/osu-profile.ts @@ -0,0 +1,16 @@ +import { z } from 'zod'; +const profileSchema = z.object({ + id: z.number().int().positive(), + username: z.string().min(1), + avatar_url: z.string().url() +}); +export function osuProfile(value: unknown) { + const profile = profileSchema.parse(value); + return { + id: String(profile.id), + name: profile.username, + image: profile.avatar_url, + email: `${profile.id}@osu.invalid`, + emailVerified: false + }; +} diff --git a/src/lib/server/osu.test.ts b/src/lib/server/osu.test.ts new file mode 100644 index 0000000..2e9c518 --- /dev/null +++ b/src/lib/server/osu.test.ts @@ -0,0 +1,37 @@ +import { expect, it, vi } from 'vitest'; +vi.mock('$env/dynamic/private', () => ({ env: { OSU_CLIENT_ID: '1', OSU_CLIENT_SECRET: 'test' } })); +import { getOsuMaps } from './osu'; +it('falls back deliberately, merges IDs, reuses OAuth and caches matching results', async () => { + const fetchFn = vi.fn(async (url: string | URL | Request) => { + if (String(url).includes('/oauth/token')) + return Response.json({ access_token: 'token', expires_in: 3600 }); + const query = new URL(String(url)).searchParams.get('q'); + return Response.json({ + beatmapsets: [ + { + id: 1, + title: 'Unique Song', + artist: query === 'unique song' ? 'Artist' : 'Wrong Performer' + } + ] + }); + }); + const track = { + id: '6PUzxtIHkv346yP89NzP9X', + name: 'Unique Song', + artists: [{ name: 'Artist' }], + album: { name: '', images: [] } + }; + const results = await Promise.all([ + getOsuMaps(fetchFn as typeof fetch, track), + getOsuMaps(fetchFn as typeof fetch, track) + ]); + expect(results[0]).toHaveLength(1); + expect(results[0][0].score).toBe(100); + expect(results[1]).toEqual(results[0]); + await getOsuMaps(fetchFn as typeof fetch, track); + expect(fetchFn).toHaveBeenCalledTimes(3); + expect(fetchFn.mock.calls.filter(([url]) => String(url).includes('/oauth/token'))).toHaveLength( + 1 + ); +}); diff --git a/src/lib/server/osu.ts b/src/lib/server/osu.ts new file mode 100644 index 0000000..c0b8865 --- /dev/null +++ b/src/lib/server/osu.ts @@ -0,0 +1,90 @@ +import { env } from '$env/dynamic/private'; +import type { OsuBeatmapset, ScoredBeatmapset, SpotifyTrack } from '$lib/map-finder/types'; +import { cleanTitle, normalize, rankCandidates, MEDIUM_CONFIDENCE } from '$lib/map-finder/matching'; +import { ApiError, createTokenCache, requestJson } from './finder-http'; +const token = createTokenCache(); +const cache = new Map(); +const pending = new Map>(); +export const MATCH_CONCURRENCY = 3; +// Global permits also bound outbound work across simultaneous visitors. +let active = 0; +const queue: (() => void)[] = []; +async function limited(work: () => Promise): Promise { + if (active >= MATCH_CONCURRENCY) await new Promise((resolve) => queue.push(resolve)); + else active++; + try { + return await work(); + } finally { + const next = queue.shift(); + if (next) next(); + else active--; + } +} +async function search(fetchFn: typeof fetch, query: string): Promise { + const access = await token(() => { + if (!env.OSU_CLIENT_ID || !env.OSU_CLIENT_SECRET) + throw new ApiError('osu!', 503, 'osu! is not configured on this server.'); + return requestJson(fetchFn, 'osu!', 'https://osu.ppy.sh/oauth/token', { + method: 'POST', + headers: { 'Content-Type': 'application/json', Accept: 'application/json' }, + body: JSON.stringify({ + client_id: Number(env.OSU_CLIENT_ID), + client_secret: env.OSU_CLIENT_SECRET, + grant_type: 'client_credentials', + scope: 'public' + }) + }); + }); + const response = (await requestJson( + fetchFn, + 'osu!', + `https://osu.ppy.sh/api/v2/beatmapsets/search?${new URLSearchParams({ q: query, s: 'any' })}`, + { headers: { Authorization: `Bearer ${access}`, Accept: 'application/json' } } + )) as { beatmapsets?: unknown[] }; + if (!Array.isArray(response?.beatmapsets)) + throw new ApiError('osu!', 502, 'osu! returned an invalid search response.'); + return response.beatmapsets + .filter( + (item): item is OsuBeatmapset => + !!item && + typeof item === 'object' && + Number.isInteger((item as OsuBeatmapset).id) && + typeof (item as OsuBeatmapset).title === 'string' && + typeof (item as OsuBeatmapset).artist === 'string' + ) + .map((item) => ({ + id: item.id, + title: item.title, + artist: item.artist, + title_unicode: typeof item.title_unicode === 'string' ? item.title_unicode : undefined, + artist_unicode: typeof item.artist_unicode === 'string' ? item.artist_unicode : undefined, + status: typeof item.status === 'string' ? item.status : undefined, + covers: { card: typeof item.covers?.card === 'string' ? item.covers.card : undefined }, + beatmaps: Array.isArray(item.beatmaps) ? item.beatmaps.map(() => ({ id: 0 })) : undefined + })); +} +export async function getOsuMaps( + fetchFn: typeof fetch, + track: SpotifyTrack +): Promise { + const key = JSON.stringify([normalize(track.name), track.artists.map((a) => normalize(a.name))]); + for (const [key, entry] of cache) if (entry.expires <= Date.now()) cache.delete(key); + const hit = cache.get(key); + if (hit) return hit.result; + const existing = pending.get(key); + if (existing) return existing; + const work = limited(async () => { + const maps = await search(fetchFn, `${track.artists[0].name} ${track.name}`); + let ranked = rankCandidates(track, maps); + if (!ranked.some((m) => m.score >= MEDIUM_CONFIDENCE)) + ranked = rankCandidates(track, [ + ...maps, + ...(await search(fetchFn, cleanTitle(track.name) || track.name)) + ]); + if (cache.size >= 500) cache.delete(cache.keys().next().value!); + cache.set(key, { expires: Date.now() + 5 * 60_000, result: ranked }); + return ranked; + }).finally(() => pending.delete(key)); + pending.set(key, work); + return work; +} diff --git a/src/lib/server/r2.ts b/src/lib/server/r2.ts index e057e6b..2d7c09c 100644 --- a/src/lib/server/r2.ts +++ b/src/lib/server/r2.ts @@ -1,5 +1,4 @@ import { S3Client, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3'; -import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; import { env } from '$env/dynamic/private'; import { randomUUID } from 'crypto'; @@ -44,38 +43,41 @@ const EXT: Record = { 'image/heic': 'heic' }; -export interface PresignedUpload { - /** R2 object key — store this in the DB */ - key: string; - /** One-time presigned PUT URL — browser PUTs file directly here */ - uploadUrl: string; - /** Permanent public URL to store in photos table */ - publicUrl: string; -} - -/** - * Generate a presigned PUT URL for a single photo. - * - * Flow: - * 1. Client POSTs to /api/upload/presign → gets { key, uploadUrl, publicUrl } - * 2. Client PUTs file to uploadUrl (direct to R2, server never sees the bytes) - * 3. Client submits sighting with photo keys included - * 4. Server stores key + publicUrl in photos table - */ -export async function createPresignedUpload(mimeType: AllowedMimeType): Promise { - const key = `sightings/${randomUUID()}.${EXT[mimeType]}`; - - const uploadUrl = await getSignedUrl( - getClient(), +/** Upload through the site server so browsers do not need R2 CORS access. */ +export async function uploadImage( + file: File, + prefix: 'sightings' | 'lists' = 'sightings' +): Promise<{ key: string; publicUrl: string }> { + if (!isAllowedMimeType(file.type)) throw new Error('Unsupported image type'); + const mimeType = file.type; + const key = `${prefix}/${randomUUID()}.${EXT[mimeType]}`; + await getClient().send( new PutObjectCommand({ Bucket: env.R2_BUCKET, Key: key, - ContentType: mimeType - }), - { expiresIn: 3600 } + ContentType: mimeType, + Body: new Uint8Array(await file.arrayBuffer()) + }) ); + return { key, publicUrl: `${env.R2_PUBLIC_URL!.replace(/\/$/, '')}/${key}` }; +} - return { key, uploadUrl, publicUrl: `${env.R2_PUBLIC_URL}/${key}` }; +export function listImageUrl(key: string): string | null { + if ( + !/^lists\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.(jpg|png|webp)$/.test( + key + ) + ) + return null; + if (!env.R2_PUBLIC_URL) return null; + return `${env.R2_PUBLIC_URL.replace(/\/$/, '')}/${key}`; +} + +export function listImageKey(url: string): string | null { + const base = env.R2_PUBLIC_URL?.replace(/\/$/, ''); + if (!base || !url.startsWith(`${base}/`)) return null; + const key = url.slice(base.length + 1); + return listImageUrl(key) === url ? key : null; } /** diff --git a/src/lib/server/slugify.test.ts b/src/lib/server/slugify.test.ts new file mode 100644 index 0000000..d9c610f --- /dev/null +++ b/src/lib/server/slugify.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from 'vitest'; +import { slugify, validSlug } from './slugify'; + +describe('content slugs', () => { + it('turns titles into readable URL segments', () => { + expect(slugify('Hello, World!')).toBe('hello-world'); + expect(slugify(' A / B ')).toBe('a-b'); + expect(slugify('!!!', 'list')).toBe('list'); + }); + + it('accepts only canonical editable slugs', () => { + expect(validSlug('my-list-2026')).toBe(true); + for (const value of ['My-List', 'two words', '-leading', 'trailing-', 'double--dash', '']) { + expect(validSlug(value)).toBe(false); + } + }); +}); diff --git a/src/lib/server/slugify.ts b/src/lib/server/slugify.ts index 237be2f..2a6bfa0 100644 --- a/src/lib/server/slugify.ts +++ b/src/lib/server/slugify.ts @@ -1,14 +1,14 @@ import { db } from '$lib/server/db'; -import { blogArticles } from '$lib/server/db/schema'; +import { blogArticles, lists } from '$lib/server/db/schema'; import { eq } from 'drizzle-orm'; -export function slugify(title: string): string { +export function slugify(title: string, fallback = 'article'): string { return ( title .toLowerCase() .trim() .replace(/[^a-z0-9]+/g, '-') - .replace(/^-+|-+$/g, '') || 'article' + .replace(/^-+|-+$/g, '') || fallback ); } @@ -27,3 +27,17 @@ export async function uniqueSlug(title: string): Promise { return slug; } + +export async function uniqueListSlug(name: string): Promise { + const base = slugify(name, 'list'); + let slug = base; + let suffix = 2; + while ((await db.select({ id: lists.id }).from(lists).where(eq(lists.slug, slug))).length > 0) { + slug = `${base}-${suffix++}`; + } + return slug; +} + +export function validSlug(slug: string): boolean { + return slug.length <= 120 && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug); +} diff --git a/src/lib/server/spotify.ts b/src/lib/server/spotify.ts new file mode 100644 index 0000000..60962f4 --- /dev/null +++ b/src/lib/server/spotify.ts @@ -0,0 +1,188 @@ +import { env } from '$env/dynamic/private'; +import type { SpotifyInput } from '$lib/map-finder/input'; +import type { SpotifyTrack, SpotifyCollection } from '$lib/map-finder/types'; +import { ApiError, createTokenCache, requestJson } from './finder-http'; +export const MAX_PLAYLIST_TRACKS = 50; +export const MAX_PLAYLIST_PAGES = 10; +const token = createTokenCache(); +type RecordValue = Record; +function record(value: unknown): RecordValue { + return value && typeof value === 'object' ? (value as RecordValue) : {}; +} +export function usableTrack(value: unknown): SpotifyTrack | null { + const track = record(value), + album = record(track.album); + if ( + track.type !== 'track' || + track.is_local || + track.is_playable === false || + typeof track.id !== 'string' || + !/^[a-zA-Z0-9]{22}$/.test(track.id) || + typeof track.name !== 'string' || + !track.name.trim() + ) + return null; + const artists = Array.isArray(track.artists) + ? track.artists + .map(record) + .filter((a) => typeof a.name === 'string' && a.name.trim()) + .map((a) => ({ name: a.name as string })) + : []; + if (!artists.length) return null; + const images = Array.isArray(album.images) + ? album.images + .map(record) + .filter((i) => typeof i.url === 'string' && i.url.startsWith('https://')) + .map((i) => ({ url: i.url as string })) + : []; + return { + id: track.id, + name: track.name, + artists, + album: { name: typeof album.name === 'string' ? album.name : '', images } + }; +} +export function playlistTracks(items: unknown[], seen = new Set()): SpotifyTrack[] { + const result: SpotifyTrack[] = []; + for (const entry of items) { + const item = record(entry); + if (item.is_local) continue; + const track = usableTrack(item.track ?? item.item); + if (track && !seen.has(track.id)) { + seen.add(track.id); + result.push(track); + } + } + return result; +} +async function spotify(fetchFn: typeof fetch, path: string) { + const access = await token(() => { + if (!env.SPOTIFY_CLIENT_ID || !env.SPOTIFY_CLIENT_SECRET) + throw new ApiError('Spotify', 503, 'Spotify is not configured on this server.'); + return requestJson(fetchFn, 'Spotify', 'https://accounts.spotify.com/api/token', { + method: 'POST', + headers: { + Authorization: `Basic ${btoa(`${env.SPOTIFY_CLIENT_ID}:${env.SPOTIFY_CLIENT_SECRET}`)}`, + 'Content-Type': 'application/x-www-form-urlencoded' + }, + body: new URLSearchParams({ grant_type: 'client_credentials' }) + }); + }); + return record( + await requestJson(fetchFn, 'Spotify', `https://api.spotify.com/v1/${path}`, { + headers: { Authorization: `Bearer ${access}` } + }) + ); +} +export async function getSpotifyMetadata( + fetchFn: typeof fetch, + input: + | Extract + | Extract +): Promise<{ tracks: SpotifyTrack[]; collection?: SpotifyCollection; truncated: boolean }> { + if (input.kind === 'track' || input.kind === 'search') { + let response: RecordValue; + try { + response = await spotify( + fetchFn, + input.kind === 'track' + ? `tracks/${input.id}` + : `search?${new URLSearchParams({ q: input.query, type: 'track', limit: '1' })}` + ); + } catch (error) { + if (error instanceof ApiError && error.status === 404) + throw new ApiError('Spotify', 404, 'Spotify track not found.'); + throw error; + } + const track = usableTrack( + input.kind === 'track' + ? response + : (record(response.tracks).items as unknown[] | undefined)?.[0] + ); + if (!track) + throw new ApiError( + 'Spotify', + 404, + input.kind === 'track' + ? 'Spotify track is unavailable.' + : 'No Spotify text-search result. Try an artist and song title.' + ); + return { tracks: [track], truncated: false }; + } + try { + const isAlbum = input.kind === 'album'; + const resource = isAlbum ? 'albums' : 'playlists'; + const metadata = await spotify(fetchFn, `${resource}/${input.id}`); + if (typeof metadata.name !== 'string') + throw new ApiError('Spotify', 502, 'Spotify returned incomplete playlist metadata.'); + const owner = record(metadata.owner), + images = metadata.images; + const collection: SpotifyCollection = { + id: input.id, + kind: input.kind, + name: metadata.name, + owner: + isAlbum && Array.isArray(metadata.artists) + ? metadata.artists + .map(record) + .map((a) => (typeof a.name === 'string' ? a.name : '')) + .filter(Boolean) + .join(', ') + : typeof owner.display_name === 'string' + ? owner.display_name + : '', + image: + Array.isArray(images) && typeof record(images[0]).url === 'string' + ? (record(images[0]).url as string) + : undefined + }; + // Extended-quota responses use tracks/track; newer development-mode responses use items/item. + const modern = metadata.items !== undefined; + let page = record(modern ? metadata.items : metadata.tracks); + let offset = 0; + const tracks: SpotifyTrack[] = []; + const seen = new Set(); + for (let pages = 0; pages < MAX_PLAYLIST_PAGES; pages++) { + if (!Array.isArray(page.items)) + page = await spotify( + fetchFn, + `${resource}/${input.id}/${modern ? 'items' : 'tracks'}?limit=50&offset=${offset}` + ); + if (!Array.isArray(page.items)) + throw new ApiError( + 'Spotify', + 502, + 'Spotify playlist tracks are unavailable for this application.' + ); + const usable = playlistTracks( + isAlbum + ? page.items.map((item) => ({ + track: { ...record(item), album: { name: metadata.name, images: metadata.images } } + })) + : page.items, + seen + ); + const room = MAX_PLAYLIST_TRACKS - tracks.length; + tracks.push(...usable.slice(0, room)); + offset += page.items.length; + const more = Boolean(page.next) || (typeof page.total === 'number' && offset < page.total); + if (tracks.length >= MAX_PLAYLIST_TRACKS || !more || pages === MAX_PLAYLIST_PAGES - 1) + return { tracks, collection, truncated: usable.length > room || more }; + if (!page.items.length) + throw new ApiError('Spotify', 502, 'Spotify returned incomplete playlist tracks.'); + // Construct pagination locally: never forward credentials to an upstream-supplied URL. + page = {}; + } + return { tracks, collection, truncated: true }; + } catch (error) { + if (error instanceof ApiError && [401, 403, 404].includes(error.status)) + throw new ApiError( + 'Spotify', + error.status, + input.kind === 'album' + ? 'Spotify album unavailable or not found. Try an individual track.' + : 'Spotify playlist unavailable or private, or this application does not have playlist access. Try a public playlist or an individual track.' + ); + throw error; + } +} diff --git a/src/lib/title.test.ts b/src/lib/title.test.ts new file mode 100644 index 0000000..86c238a --- /dev/null +++ b/src/lib/title.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from 'vitest'; +import { formatTitle, getTitle, siteEnvironment } from './title'; + +describe('site titles', () => { + it('uses one suffix and an environment prefix', () => { + expect(getTitle('/', 'DEV')).toBe('(DEV) Home | Stan Runge'); + expect(getTitle('/projects/catch-em-all', 'STAGING')).toBe('(STAGING) Catchemall | Stan Runge'); + expect(formatTitle('A blog post')).toBe('A blog post | Stan Runge'); + }); + + it('gives unlisted routes a readable title', () => { + expect(getTitle('/projects/typing-practice')).toBe('typing practice | Stan Runge'); + }); + + it('labels development and staging without labelling production', () => { + expect(siteEnvironment(true, 'https://staging.stanrunge.dev')).toBe('DEV'); + expect(siteEnvironment(false, 'https://staging.stanrunge.dev')).toBe('STAGING'); + expect(siteEnvironment(false, 'https://stanrunge.dev')).toBeNull(); + }); +}); diff --git a/src/lib/title.ts b/src/lib/title.ts index d7d23b8..48f4b39 100644 --- a/src/lib/title.ts +++ b/src/lib/title.ts @@ -1,9 +1,40 @@ -import { dev } from "$app/env"; +export type SiteEnvironment = 'DEV' | 'STAGING' | null; -export function getTitle(path: string): string { - let builtTitle = "Stan Runge"; - - if (dev) builtTitle = "(DEV) " + builtTitle; - - return builtTitle; +export function siteEnvironment(isDev: boolean, origin?: string): SiteEnvironment { + if (isDev) return 'DEV'; + try { + return new URL(origin ?? '').hostname === 'staging.stanrunge.dev' ? 'STAGING' : null; + } catch { + return null; + } +} + +export function formatTitle(title: string, environment: SiteEnvironment = null): string { + return `${environment ? `(${environment}) ` : ''}${title} | Stan Runge`; +} + +export function getTitle(path: string, environment: SiteEnvironment = null): string { + const titles: Record = { + '/': 'Home', + '/projects': 'Projects', + '/blog': 'Blog', + '/lists': 'Lists', + '/login': 'Sign in', + '/register': 'Register', + '/account': 'Account', + '/projects/catch-em-all': 'Catchemall', + '/projects/animaldex': 'Animaldex', + '/projects/animaldex/register': 'Log a sighting', + '/projects/animaldex/admin': 'Animaldex admin', + '/projects/derby': 'Derby Lens', + '/projects/cs-prices': 'CS Prices', + '/projects/game-tracker': 'Game Tracker', + '/projects/money-tracker': 'Money Tracker', + '/projects/spotify-beatmap-finder': 'osu! map finder', + '/projects/progress': 'Progress' + }; + const cleaned = path.replace(/\/$/, '') || '/'; + const title = + titles[cleaned] ?? cleaned.split('/').filter(Boolean).at(-1)?.replace(/-/g, ' ') ?? 'Home'; + return formatTitle(title, environment); } diff --git a/src/lib/validation/blog.ts b/src/lib/validation/blog.ts index 694e9e8..283e948 100644 --- a/src/lib/validation/blog.ts +++ b/src/lib/validation/blog.ts @@ -6,5 +6,18 @@ export const createArticleSchema = z.object({ export const updateArticleSchema = z.object({ title: z.string().min(1).max(256), - content: z.string().max(50000) + slug: z.string().min(1).max(120), + content: z.string().max(50000), + tags: z.array(z.string().min(1).max(32)).max(8) }); + +export function parseArticleTags(value: string) { + return [ + ...new Set( + value + .split(',') + .map((tag) => tag.trim().toLowerCase()) + .filter(Boolean) + ) + ]; +} diff --git a/src/lib/validation/sighting.ts b/src/lib/validation/sighting.ts index 85470a4..f883ea9 100644 --- a/src/lib/validation/sighting.ts +++ b/src/lib/validation/sighting.ts @@ -1,11 +1,5 @@ import { z } from 'zod'; -// ── Presigned upload ────────────────────────────────────────────────────────── - -export const presignedUploadSchema = z.object({ - mimeType: z.enum(['image/jpeg', 'image/png', 'image/webp', 'image/heic']) -}); - // ── Register new animal (+ first sighting) ──────────────────────────────────── export const registerAnimalSchema = z.object({ @@ -29,7 +23,7 @@ export const registerAnimalSchema = z.object({ deviceLat: z.number().min(-90).max(90), deviceLng: z.number().min(-180).max(180), - // Already-uploaded R2 keys (1–10 photos, browser uploaded directly) + // Already-uploaded R2 keys (1–10 photos) photoKeys: z.array(z.string().min(1)).min(1).max(10) }); @@ -38,7 +32,7 @@ export type RegisterAnimalInput = z.infer; // ── Add sighting to existing animal ────────────────────────────────────────── export const addSightingSchema = z.object({ - animalId: z.string().uuid(), + animalId: z.coerce.number().int().positive(), reporterName: z.string().max(100).optional(), seenAt: z.iso.datetime(), lat: z.number().min(-90).max(90), diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index 49993ed..e98693c 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1,5 +1,14 @@ -export const load = async ({ cookies }) => { - return { - editable: cookies.get('token') - }; -}; +import { isAdmin } from '$lib/server/authorization'; +import { dev } from '$app/environment'; +import { siteEnvironment } from '$lib/title'; +import type { LayoutServerLoad } from './$types'; +const environment = siteEnvironment(dev, process.env.ORIGIN); +export const load: LayoutServerLoad = (event) => ({ + user: event.locals.user + ? { id: event.locals.user.id, name: event.locals.user.name, image: event.locals.user.image } + : null, + isAdmin: isAdmin(event), + editable: isAdmin(event), + version: process.env.APP_VERSION || 'dev', + environment +}); diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index b704e30..42401cd 100755 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,6 +1,11 @@ +{#snippet themeIcon()} + +{/snippet} + {#if !dev} {/if} - - {getTitle(page.url.pathname)} + {seo.title} + + + + + + + + + + + + + {#if seo.modifiedAt}{/if} + + + + + + -
-
- Stan Runge -
-
- Blog -
- - -
- - -
- -
- {@render children()} -
- -
diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts index d0df6ef..2f922ff 100755 --- a/src/routes/+page.server.ts +++ b/src/routes/+page.server.ts @@ -1,31 +1,36 @@ -import { env } from '$env/dynamic/private'; +import { fail } from '@sveltejs/kit'; +import { db } from '$lib/server/db'; +import { listItemCompletions } from '$lib/server/db/schema'; +import { eq } from 'drizzle-orm'; +import type { PageServerLoad } from './$types'; -export const actions = { - authenticate: async ({ request, cookies }) => { - const data = await request.formData(); +export const load: PageServerLoad = async ({ locals }) => { + const lists = await db.query.lists.findMany({ + columns: { id: true, name: true, slug: true, isProgress: true }, + with: { items: { columns: { id: true } } }, + orderBy: { id: 'desc' } + }); - const token = data.get('token'); - if (!token) { - return { - status: 400, - body: { error: 'Missing token' } - }; - } - - if (token !== env.AUTH_TOKEN) { - return { - status: 401, - body: { error: 'Invalid token' } - }; - } - - cookies.set('token', token, { - path: '/', - maxAge: 60 * 60 * 24 * 7 - }); - - return { - success: true - }; - } + const completed = new Set( + locals.user + ? ( + await db + .select({ itemId: listItemCompletions.itemId }) + .from(listItemCompletions) + .where(eq(listItemCompletions.userId, locals.user.id)) + ).map((row) => row.itemId) + : [] + ); + return { + lists: lists.map(({ items, ...list }) => ({ + ...list, + total: items.length, + checked: list.isProgress ? items.filter((item) => completed.has(item.id)).length : 0 + })) + }; +}; + +// Retire the old shared-token login; legacy cookies grant no permissions. +export const actions = { + authenticate: () => fail(410, { message: 'Use the central account login at /login' }) }; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 1b8a44f..b7a76b8 100755 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,107 +1,181 @@ + + + -
-
-

experience

-
-

2026 - current

-
-

Associate Software Engineer

- -

Cargill

-
-
-
-

2021 - 2026

-
-

BSc. Computer Science (Software Engineering)

-

The Hague University of Applied Sciences

-
-
-
-

2026

-

internship at 3webapps

-
-
-

2023

-

internship at h5mag

-
-
-

2021 - 2023

-

junior IT specialist at Finance Plus

-
-
-

2020 - current

-

300+ IT problems solved in Netherlands

-
-
- -
-

Stan Runge

- -

- me preparing for my presentation about quantum vision transformers +

+
+

stan runge

+
- -
- + Stan at his desk +
-
- -

vash esports

-

automated osu! matchmaking/tournament platform

-
-
-

eudi-auth for 3webapps

-

- plugin for WooCommerce/Magento2 that adds authentication with the European Digital - Identity (EUDI) wallet -

-
-
-

realtime collaboration for h5mag

-

- socket.io server for h5mag (magazine web editor) that broadcasts user actions to other - editors, similar to writing a Google Doc together -

-
-
-

infra

-

server, project deployments and dev config as code with setup script

-
- -

animaldex

-

world map with pets & other animals around the neighborhood 😼

-
- -

catch em all

-

table of all 1025 pokemon across 38 games with checkboxes for catching them all

-
- -

spotify osu! map finder

-

small tool for finding osu! maps using a spotify url of a song or playlist

-
- -

beerio kart

-
Go
-

webserver in go with a double-elim bracket for a one-time mario kart tournament

-
+
+

+ projects ↗ +

+ +
-

+ a lot more planned (soon™)

-
-
+
+

+ lists ↗ +

+ +
+ +
+

experience

+
    + {#each experience as item (item.when + item.place)} +
  1. +
    +

    {item.role}

    +

    {item.place}

    +
    + {item.when} +
  2. + {/each} +
+
diff --git a/src/routes/account/+page.server.ts b/src/routes/account/+page.server.ts new file mode 100644 index 0000000..fd0a862 --- /dev/null +++ b/src/routes/account/+page.server.ts @@ -0,0 +1,13 @@ +import { auth, authProviders } from '$lib/server/auth'; +import { redirect } from '@sveltejs/kit'; +import type { PageServerLoad } from './$types'; +export const load: PageServerLoad = async ({ locals, request, url }) => { + if (!locals.user) redirect(303, '/login?returnTo=/account'); + const accounts = await auth.api.listUserAccounts({ headers: request.headers }); + return { + email: locals.user.email.endsWith('@osu.invalid') ? null : locals.user.email, + providers: authProviders, + linkedProviders: accounts.map((account) => account.providerId), + oauthError: url.searchParams.has('error') + }; +}; diff --git a/src/routes/account/+page.svelte b/src/routes/account/+page.svelte new file mode 100644 index 0000000..a195e5e --- /dev/null +++ b/src/routes/account/+page.svelte @@ -0,0 +1,72 @@ + + +
+
+

Your account

+

Signed in as {data.user?.name}{data.email ? ` (${data.email})` : ''}.

+
+

Account ID: {data.user?.id}

+ +
+

Sign-in methods

+

+ Link a provider here to use it with this account and keep your saved progress together. +

+ {#if message || data.oauthError}{/if} + {#if data.linkedProviders.includes('credential')}

Email and password connected

{/if} + {#each ['google', 'osu'] as provider (provider)} + {@const label = provider === 'google' ? 'Google' : 'osu!'} + {#if data.linkedProviders.includes(provider)}

{label} connected

+ {:else if data.providers[provider as 'google' | 'osu']}{/if} + {/each} +
+ {#if data.isAdmin} + + {/if} +
+ +
+
diff --git a/src/routes/admin/login/+server.ts b/src/routes/admin/login/+server.ts index e2cd02c..b063e69 100644 --- a/src/routes/admin/login/+server.ts +++ b/src/routes/admin/login/+server.ts @@ -1,25 +1,3 @@ -import { json, error } from '@sveltejs/kit'; -import type { RequestHandler } from './$types'; -import { env } from '$env/dynamic/private'; -import { z } from 'zod'; - -const loginSchema = z.object({ password: z.string().min(1) }); - -export const POST: RequestHandler = async ({ request, cookies }) => { - const body = await request.json().catch(() => null); - const parsed = loginSchema.safeParse(body); - - if (!parsed.success || parsed.data.password !== env.ADMIN_SECRET) { - throw error(401, { message: 'Invalid password' }); - } - - cookies.set('admin_token', env.ADMIN_SECRET, { - path: '/', - httpOnly: true, - sameSite: 'strict', - secure: process.env.NODE_ENV === 'production', - maxAge: 60 * 60 * 24 * 7 - }); - - return json({ ok: true }); -}; +import { error, redirect } from '@sveltejs/kit'; +export const GET = () => redirect(303, '/login'); +export const POST = () => error(410, 'Use the central account login at /login'); diff --git a/src/routes/blog/+page.server.ts b/src/routes/blog/+page.server.ts index 52ba94b..36e50ab 100644 --- a/src/routes/blog/+page.server.ts +++ b/src/routes/blog/+page.server.ts @@ -20,7 +20,8 @@ export const load: PageServerLoad = async (event) => { return { blogArticles: articles, - isAdmin: admin + isAdmin: admin, + now: Date.now() }; }; diff --git a/src/routes/blog/+page.svelte b/src/routes/blog/+page.svelte index bea4401..b721e25 100644 --- a/src/routes/blog/+page.svelte +++ b/src/routes/blog/+page.svelte @@ -1,125 +1,111 @@ -
-

Blog (Stan's yapping corner)

- {#if data.isAdmin} - - {:else} - - {/if} -
- -
- {#each data.blogArticles as article (article.slug)} - -
-

{article.title}

- {#if data.isAdmin && article.status === 'draft'} - draft -
edit +
+

blog

+ {#if data.isAdmin}
+ new article +
+ - {/if} -

{article.createdAt?.toDateString()}

+ +
+
{/if} +
+ {#if form?.message}{/if} +
+ + {#if tags.length} +
+ + {#each tags as tag (tag)} + + {/each}
- - {/each} + {/if} +
+
    + {#each visibleArticles as article (article.id)} +
  • +
    + {article.title} +
    + {#if data.isAdmin && article.status === 'draft'}draft{/if} + {#each article.tags as tag (tag)}{tag}{/each} + + {#if data.isAdmin}edit{/if} +
    +
    +
  • + {:else} +
  • + {data.blogArticles.length ? 'no matching articles' : 'no articles yet'} +
  • + {/each} +
- -{#if createNewArticlePopup} -
-
-

Create New Article

- -
- - -
-
-
-{/if} - -{#if loginPopup} -
-
-

Admin login

- e.key === 'Enter' && login()} - class="mb-3 w-full rounded border border-gray-300 px-3 py-2 text-sm outline-none" - /> - {#if loginError} -

{loginError}

- {/if} -
- - -
-
-
-{/if} diff --git a/src/routes/blog/[slug]/+page.svelte b/src/routes/blog/[slug]/+page.svelte index 539bbf4..2aaa4bd 100644 --- a/src/routes/blog/[slug]/+page.svelte +++ b/src/routes/blog/[slug]/+page.svelte @@ -1,24 +1,30 @@ -{data.blogArticle.title} - Blog -
-
-

{data.blogArticle.title}

+
+

{data.blogArticle.title}

{#if data.isAdmin} Editedit {/if}
-

{data.blogArticle.createdAt?.toDateString()}

-
+
+ + {#each data.blogArticle.tags as tag (tag)}{tag}{/each} +
+
+ + {@html data.contentHtml}
diff --git a/src/routes/blog/[slug]/edit/+page.server.ts b/src/routes/blog/[slug]/edit/+page.server.ts index dd67d63..3e9592d 100644 --- a/src/routes/blog/[slug]/edit/+page.server.ts +++ b/src/routes/blog/[slug]/edit/+page.server.ts @@ -1,9 +1,10 @@ import { db } from '$lib/server/db'; import { blogArticles } from '$lib/server/db/schema'; import { isAdmin, requireAdmin } from '$lib/server/auth'; -import { updateArticleSchema } from '$lib/validation/blog'; -import { eq } from 'drizzle-orm'; -import { error, fail, redirect } from '@sveltejs/kit'; +import { parseArticleTags, updateArticleSchema } from '$lib/validation/blog'; +import { validSlug } from '$lib/server/slugify'; +import { and, eq, ne } from 'drizzle-orm'; +import { error, fail, redirect, type RequestEvent } from '@sveltejs/kit'; import type { PageServerLoad } from './$types.js'; @@ -26,59 +27,81 @@ export const load: PageServerLoad = async (event) => { }; }; +async function readArticleForm(event: RequestEvent) { + const formData = await event.request.formData(); + const parsed = updateArticleSchema.safeParse({ + title: formData.get('title')?.toString().trim(), + slug: formData.get('slug')?.toString().trim().toLowerCase(), + content: formData.get('content')?.toString(), + tags: parseArticleTags(formData.get('tags')?.toString() ?? '') + }); + if (!parsed.success || !validSlug(parsed.data.slug)) return null; + return parsed.data; +} + export const actions = { save: async (event) => { requireAdmin(event); - - const formData = await event.request.formData(); - const parsed = updateArticleSchema.safeParse({ - title: formData.get('title')?.toString(), - content: formData.get('content')?.toString() - }); - - if (!parsed.success) { - return fail(400, { message: 'Title and content are required' }); - } + const values = await readArticleForm(event); + if (!values) + return fail(400, { + message: 'Enter a title, a lowercase slug, and up to 8 tags of 32 characters each.' + }); + const current = await db.query.blogArticles.findFirst({ where: { slug: event.params.slug } }); + if (!current) error(404, 'Article not found'); + const duplicate = await db + .select({ id: blogArticles.id }) + .from(blogArticles) + .where(and(eq(blogArticles.slug, values.slug), ne(blogArticles.id, current.id))); + if (duplicate.length) return fail(409, { message: 'That article slug is already in use.' }); const [updated] = await db .update(blogArticles) .set({ - title: parsed.data.title, - content: parsed.data.content, + title: values.title, + slug: values.slug, + content: values.content, + tags: values.tags, updatedAt: new Date() }) - .where(eq(blogArticles.slug, event.params.slug)) + .where(eq(blogArticles.id, current.id)) .returning(); if (!updated) { return error(404, { message: 'Article not found' }); } + if (values.slug !== event.params.slug) redirect(303, `/blog/${values.slug}/edit`); return { saved: true }; }, publish: async (event) => { requireAdmin(event); - const formData = await event.request.formData(); - const parsed = updateArticleSchema.safeParse({ - title: formData.get('title')?.toString(), - content: formData.get('content')?.toString() - }); - - if (!parsed.success) { - return fail(400, { message: 'Title and content are required' }); - } + const values = await readArticleForm(event); + if (!values) + return fail(400, { + message: 'Enter a title, a lowercase slug, and up to 8 tags of 32 characters each.' + }); + const current = await db.query.blogArticles.findFirst({ where: { slug: event.params.slug } }); + if (!current) error(404, 'Article not found'); + const duplicate = await db + .select({ id: blogArticles.id }) + .from(blogArticles) + .where(and(eq(blogArticles.slug, values.slug), ne(blogArticles.id, current.id))); + if (duplicate.length) return fail(409, { message: 'That article slug is already in use.' }); const [updated] = await db .update(blogArticles) .set({ - title: parsed.data.title, - content: parsed.data.content, + title: values.title, + slug: values.slug, + content: values.content, + tags: values.tags, status: 'published', updatedAt: new Date() }) - .where(eq(blogArticles.slug, event.params.slug)) + .where(eq(blogArticles.id, current.id)) .returning(); if (!updated) { @@ -86,5 +109,15 @@ export const actions = { } return redirect(303, `/blog/${updated.slug}`); + }, + delete: async (event) => { + requireAdmin(event); + const current = await db.query.blogArticles.findFirst({ where: { slug: event.params.slug } }); + if (!current) error(404, 'Article not found'); + const confirmation = String((await event.request.formData()).get('confirmTitle') ?? ''); + if (confirmation !== current.title) + return fail(400, { message: 'Type the exact article title to confirm deletion.' }); + await db.delete(blogArticles).where(eq(blogArticles.id, current.id)); + redirect(303, '/blog'); } }; diff --git a/src/routes/blog/[slug]/edit/+page.svelte b/src/routes/blog/[slug]/edit/+page.svelte index d13ac96..7a7d3de 100644 --- a/src/routes/blog/[slug]/edit/+page.svelte +++ b/src/routes/blog/[slug]/edit/+page.svelte @@ -4,30 +4,43 @@ let { data, form } = $props(); - let title = $state(data.blogArticle.title); - let content = $state(data.blogArticle.content ?? ''); + let title = $state(''); + let slug = $state(''); + let tags = $state(''); + let content = $state(''); let saving = $state(false); + let loadedSlug = ''; + $effect(() => { + const article = data.blogArticle; + if (article.slug === loadedSlug) return; + loadedSlug = article.slug; + title = article.title; + slug = article.slug; + tags = article.tags.join(', '); + content = article.content ?? ''; + }); -Editing {data.blogArticle.title} - -
-
-

- Editing article - {data.blogArticle.status} + ← blog +
+
+

edit article

+

{data.blogArticle.status}

+
+ {#if data.blogArticle.status === 'published'} + view article ↗ -

- View + {/if}
{#if form?.message} -

{form.message}

+ {/if}
- - -

Supports Markdown formatting.

+ +
+ + +
+ -
+
save {data.blogArticle.status === 'published' ? 'update published article' : 'publish'}
+
+ delete article +
+

+ This permanently deletes the article. Type {data.blogArticle.title} to confirm. +

+ + +
+
diff --git a/src/routes/lists/+page.server.ts b/src/routes/lists/+page.server.ts new file mode 100644 index 0000000..2cd15c5 --- /dev/null +++ b/src/routes/lists/+page.server.ts @@ -0,0 +1,47 @@ +import { db } from '$lib/server/db'; +import { listItemCompletions, lists } from '$lib/server/db/schema'; +import { requireAdmin } from '$lib/server/authorization'; +import { uniqueListSlug } from '$lib/server/slugify'; +import { eq } from 'drizzle-orm'; +import { fail, redirect } from '@sveltejs/kit'; +import type { Actions, PageServerLoad } from './$types'; + +export const load: PageServerLoad = async ({ locals }) => { + const rows = await db.query.lists.findMany({ + with: { items: { columns: { id: true } } }, + orderBy: { id: 'desc' } + }); + const completed = new Set( + locals.user + ? ( + await db + .select({ itemId: listItemCompletions.itemId }) + .from(listItemCompletions) + .where(eq(listItemCompletions.userId, locals.user.id)) + ).map((row) => row.itemId) + : [] + ); + return { + lists: rows.map(({ items, ...list }) => ({ + ...list, + total: items.length, + checked: list.isProgress ? items.filter((item) => completed.has(item.id)).length : 0 + })) + }; +}; + +export const actions: Actions = { + newList: async (event) => { + requireAdmin(event); + const form = await event.request.formData(); + const name = String(form.get('name') ?? '').trim(); + const type = String(form.get('type') ?? ''); + if (!name || name.length > 200) + return fail(400, { message: 'Enter a list name of 1–200 characters.' }); + if (type !== 'normal' && type !== 'progress') + return fail(400, { message: 'Choose a list type.' }); + const slug = await uniqueListSlug(name); + await db.insert(lists).values({ name, slug, isProgress: type === 'progress' }); + redirect(303, `/lists/${slug}`); + } +}; diff --git a/src/routes/lists/+page.svelte b/src/routes/lists/+page.svelte new file mode 100644 index 0000000..1276b7f --- /dev/null +++ b/src/routes/lists/+page.svelte @@ -0,0 +1,78 @@ + + +
+
+

lists

+ {#if data.isAdmin}
+ new list +
+ + + +
+
{/if} +
+ {#if form?.message}{/if} + +
diff --git a/src/routes/lists/[slug]/+page.server.ts b/src/routes/lists/[slug]/+page.server.ts new file mode 100644 index 0000000..f0d4893 --- /dev/null +++ b/src/routes/lists/[slug]/+page.server.ts @@ -0,0 +1,178 @@ +import { db } from '$lib/server/db'; +import { lists, listItems, listItemCompletions } from '$lib/server/db/schema'; +import { requireAdmin, requireUser } from '$lib/server/authorization'; +import { deleteObject, listImageKey, listImageUrl } from '$lib/server/r2'; +import { validSlug } from '$lib/server/slugify'; +import { and, eq, ne } from 'drizzle-orm'; +import { error, fail, redirect } from '@sveltejs/kit'; +import type { Actions, PageServerLoad } from './$types'; + +async function currentList(slug: string) { + const list = await db.query.lists.findFirst({ where: { slug } }); + if (!list) error(404, 'List not found'); + return list; +} +async function removeStoredPicture(url: string | null) { + const key = url ? listImageKey(url) : null; + if (!key) return; + try { + await deleteObject(key); + } catch (cause) { + console.error('Could not remove list picture from R2', cause); + } +} +function itemFields(form: FormData) { + const name = String(form.get('name') ?? '').trim(); + const description = String(form.get('description') ?? '').trim(); + const pictureKey = String(form.get('pictureKey') ?? '').trim(); + const removePicture = form.get('removePicture') === 'on'; + const file = form.get('picture'); + if (!name || name.length > 500) return { error: 'Enter an item name of 1–500 characters.' }; + if (description.length > 5000) return { error: 'Description must be 5,000 characters or less.' }; + if (file instanceof File && file.size > 0) + return { error: 'Enable JavaScript to upload an image.' }; + if (pictureKey && removePicture) return { error: 'Choose a new picture or remove the old one.' }; + const pictureUrl = pictureKey ? listImageUrl(pictureKey) : null; + if (pictureKey && !pictureUrl) return { error: 'Invalid uploaded picture.' }; + return { + values: { + name, + description: description || null, + ...(pictureKey ? { pictureUrl } : removePicture ? { pictureUrl: null } : {}) + } + }; +} +export const load: PageServerLoad = async ({ params, locals }) => { + if (/^[1-9]\d*$/.test(params.slug)) { + const oldId = Number(params.slug); + if (Number.isSafeInteger(oldId)) { + const oldList = await db.query.lists.findFirst({ where: { id: oldId } }); + if (oldList) redirect(308, `/lists/${oldList.slug}`); + } + } + const list = await db.query.lists.findFirst({ + where: { slug: params.slug }, + with: { items: { orderBy: { id: 'asc' } } } + }); + if (!list) error(404, 'List not found'); + const completedIds = + locals.user && list.isProgress + ? ( + await db + .select({ itemId: listItemCompletions.itemId }) + .from(listItemCompletions) + .where(eq(listItemCompletions.userId, locals.user.id)) + ).map((row) => row.itemId) + : []; + const inList = completedIds.filter((id) => list.items.some((item) => item.id === id)); + return { list, completedIds: inList, checked: inList.length, total: list.items.length }; +}; +export const actions: Actions = { + deleteList: async (event) => { + requireAdmin(event); + const list = await currentList(event.params.slug); + const confirmation = String((await event.request.formData()).get('confirmName') ?? ''); + if (confirmation !== list.name) + return fail(400, { message: 'Type the exact list name to confirm deletion.' }); + const pictures = await db + .select({ pictureUrl: listItems.pictureUrl }) + .from(listItems) + .where(eq(listItems.listId, list.id)); + await db.delete(lists).where(eq(lists.id, list.id)); + await Promise.all(pictures.map((item) => removeStoredPicture(item.pictureUrl))); + redirect(303, '/lists'); + }, + updateList: async (event) => { + requireAdmin(event); + const form = await event.request.formData(); + const name = String(form.get('name') ?? '').trim(); + const slug = String(form.get('slug') ?? '') + .trim() + .toLowerCase(); + const type = String(form.get('type') ?? ''); + if (!name || name.length > 200) + return fail(400, { message: 'Enter a name of 1–200 characters' }); + if (type !== 'normal' && type !== 'progress') + return fail(400, { message: 'Choose a list type.' }); + if (!validSlug(slug)) + return fail(400, { message: 'Use a lowercase slug with letters, numbers, and hyphens.' }); + const current = await currentList(event.params.slug); + const duplicate = await db + .select({ id: lists.id }) + .from(lists) + .where(and(eq(lists.slug, slug), ne(lists.id, current.id))); + if (duplicate.length) return fail(409, { message: 'That list slug is already in use.' }); + const [list] = await db + .update(lists) + .set({ name, slug, isProgress: type === 'progress' }) + .where(eq(lists.id, current.id)) + .returning(); + if (!list) error(404, 'List not found'); + if (slug !== event.params.slug) redirect(303, `/lists/${slug}`); + return { saved: true }; + }, + addItem: async (event) => { + requireAdmin(event); + const fields = itemFields(await event.request.formData()); + if (fields.error) return fail(400, { message: fields.error }); + const list = await currentList(event.params.slug); + await db.insert(listItems).values({ ...fields.values!, listId: list.id }); + return { saved: true }; + }, + updateItem: async (event) => { + requireAdmin(event); + const form = await event.request.formData(); + const id = Number(form.get('itemId')); + if (!Number.isSafeInteger(id) || id <= 0) return fail(400, { message: 'Invalid item.' }); + const fields = itemFields(form); + if (fields.error) return fail(400, { message: fields.error }); + const list = await currentList(event.params.slug); + const existing = await db.query.listItems.findFirst({ where: { id, listId: list.id } }); + if (!existing) error(404, 'Item not found'); + const [item] = await db + .update(listItems) + .set(fields.values!) + .where(and(eq(listItems.id, id), eq(listItems.listId, list.id))) + .returning({ id: listItems.id }); + if (!item) error(404, 'Item not found'); + if ('pictureUrl' in fields.values! && fields.values!.pictureUrl !== existing.pictureUrl) + await removeStoredPicture(existing.pictureUrl); + return { saved: true }; + }, + removeItem: async (event) => { + requireAdmin(event); + const id = Number((await event.request.formData()).get('itemId')); + if (!Number.isSafeInteger(id) || id <= 0) return fail(400, { message: 'Invalid item' }); + const list = await currentList(event.params.slug); + const [item] = await db + .delete(listItems) + .where(and(eq(listItems.id, id), eq(listItems.listId, list.id))) + .returning({ pictureUrl: listItems.pictureUrl }); + if (!item) error(404, 'Item not found'); + await removeStoredPicture(item.pictureUrl); + return { saved: true }; + }, + setCompletion: async (event) => { + const user = requireUser(event); + const list = await currentList(event.params.slug); + if (!list.isProgress) return fail(400, { message: 'This is not a progress list.' }); + const form = await event.request.formData(); + const id = Number(form.get('itemId')); + const completed = form.get('completed'); + if (!Number.isSafeInteger(id) || id <= 0 || (completed !== 'yes' && completed !== 'no')) + return fail(400, { message: 'Invalid progress change.' }); + const item = await db.query.listItems.findFirst({ where: { id, listId: list.id } }); + if (!item) error(404, 'Item not found'); + if (completed === 'yes') { + await db + .insert(listItemCompletions) + .values({ itemId: id, userId: user.id }) + .onConflictDoNothing(); + } else { + await db + .delete(listItemCompletions) + .where(and(eq(listItemCompletions.itemId, id), eq(listItemCompletions.userId, user.id))); + } + return { saved: true }; + } +}; diff --git a/src/routes/lists/[slug]/+page.svelte b/src/routes/lists/[slug]/+page.svelte new file mode 100644 index 0000000..181973d --- /dev/null +++ b/src/routes/lists/[slug]/+page.svelte @@ -0,0 +1,265 @@ + + +
+ ← lists +
+
+

{data.list.name}

+

+ {data.total} + {data.total === 1 ? 'item' : 'items'} +

+
+ {#if data.isAdmin}{/if} +
+ {#if form?.message}{/if} + {#if uploadError}{/if} + {#if data.list.isProgress} + {#if data.user} +
+

+ {data.checked} of {data.total} checked · {data.total + ? Math.round((data.checked / data.total) * 100) + : 0}% +

+
+ +
+
+ {:else} +

+ Log in to + save your progress. +

+ {/if} + {/if} + {#if data.isAdmin && managing} +
+ list settings +
+
+ + + + +
+
+ Delete this list +
+

+ This deletes the list, its items, and everyone’s saved progress. Type {data.list.name} to confirm. +

+ + +
+
+
+
+ {/if} +
    + {#each data.list.items as item (item.id)} +
  • +
    + {#if item.pictureUrl}{item.name}{/if} +
    +

    {item.name}

    + {#if item.description}

    + {item.description} +

    {/if} +
    + {#if data.list.isProgress && data.user} +
    + + + +
    + {/if} +
    + {#if data.isAdmin && managing} +
    + edit item +
    + + + + {#if item.pictureUrl}{/if} + + + +
    + + +
    +
    + {/if} +
  • + {:else}
  • no items yet
  • {/each} +
+ {#if data.isAdmin && managing} +
+ add item +
+ + + + + +
+ + {/if} +
diff --git a/src/routes/lists/api/upload/+server.ts b/src/routes/lists/api/upload/+server.ts new file mode 100644 index 0000000..da51893 --- /dev/null +++ b/src/routes/lists/api/upload/+server.ts @@ -0,0 +1,24 @@ +import { json, error } from '@sveltejs/kit'; +import { requireAdmin } from '$lib/server/authorization'; +import { uploadImage } from '$lib/server/r2'; +import type { RequestHandler } from './$types'; + +export const POST: RequestHandler = async (event) => { + requireAdmin(event); + const form = await event.request.formData().catch(() => null); + const picture = form?.get('picture'); + if ( + !(picture instanceof File) || + !['image/jpeg', 'image/png', 'image/webp'].includes(picture.type) + ) { + error(400, 'Choose a JPEG, PNG, or WebP image.'); + } + if (!picture.size || picture.size > 5 * 1024 * 1024) + error(400, 'Images must be 5 MB or smaller.'); + try { + return json(await uploadImage(picture, 'lists')); + } catch (cause) { + console.error('List image upload failed', cause); + error(503, 'Image storage is unavailable.'); + } +}; diff --git a/src/routes/login/+page.server.ts b/src/routes/login/+page.server.ts new file mode 100644 index 0000000..7971d70 --- /dev/null +++ b/src/routes/login/+page.server.ts @@ -0,0 +1,9 @@ +import { authProviders } from '$lib/server/auth'; +import { safeReturnTo } from '$lib/auth-redirect'; +import { redirect } from '@sveltejs/kit'; +import type { PageServerLoad } from './$types'; +export const load: PageServerLoad = ({ url, locals }) => { + const returnTo = safeReturnTo(url.searchParams.get('returnTo')); + if (locals.user) redirect(303, returnTo); + return { providers: authProviders, returnTo, oauthError: url.searchParams.has('error') }; +}; diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte new file mode 100644 index 0000000..2ac5213 --- /dev/null +++ b/src/routes/login/+page.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/routes/logout/+server.ts b/src/routes/logout/+server.ts new file mode 100644 index 0000000..da36ea6 --- /dev/null +++ b/src/routes/logout/+server.ts @@ -0,0 +1,15 @@ +import { auth } from '$lib/server/auth'; +import { error, redirect } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; +export const POST: RequestHandler = async ({ request, url, cookies }) => { + if ( + ![url.origin, new URL(String(auth.options.baseURL)).origin].includes( + request.headers.get('origin') ?? '' + ) + ) + error(403, 'Invalid origin'); + await auth.api.signOut({ headers: request.headers }); + cookies.delete('admin_token', { path: '/' }); + cookies.delete('token', { path: '/' }); + redirect(303, '/login'); +}; diff --git a/src/routes/projects/+page.svelte b/src/routes/projects/+page.svelte index 0fca7d0..9a5bdda 100644 --- a/src/routes/projects/+page.svelte +++ b/src/routes/projects/+page.svelte @@ -2,45 +2,57 @@ import { resolve } from '$app/paths'; const projects = [ - { - name: 'Animaldex', - href: '/projects/animaldex', - description: 'World map with pets & other animals around the neighborhood' - }, - { - name: 'CatchEmAll', - href: '/projects/catch-em-all', - description: 'Table of all 1025 pokemon across 38 games with checkboxes for catching them all' - }, - { - name: 'Derby Lens', - href: '/projects/derby', - description: 'Experimental win-probability model for the Duindigt Derby R 2026 with scenario sliders' - }, - { - name: 'CS Prices', - href: '/projects/cs-prices', - description: 'Dashboard for CS2 skin price histories, trends and predictions' - }, - { - name: 'Spotify Beatmap Finder', - href: '/projects/spotify-beatmap-finder', - description: 'Search for osu! beatmaps with Spotify songs/albums/playlists' - } + { name: 'catchemall', href: '/projects/catch-em-all', external: false }, + { name: 'animaldex', href: '/projects/animaldex', external: false }, + { name: 'derby lens', href: '/projects/derby', external: false }, + { name: 'cs prices', href: '/projects/cs-prices', external: false }, + { name: 'osu! map finder', href: '/projects/spotify-beatmap-finder', external: false }, + { name: 'game tracker', href: '/projects/game-tracker', external: false }, + { name: 'money tracker', href: '/projects/money-tracker', external: false }, + { name: 'vash esports', href: 'https://esports.vash.software', external: true }, + { name: 'beerio kart', href: 'https://beeriokart.stanrunge.dev', external: true } + ] as const; + const earlier = [ + 'distributor', + 'realtime editing', + 'eIDAS auth module for WooCommerce + Magento 2' ]; -
-

Projects ({projects.length})

- -
    +
    +

    projects

    + +

    other

    +
      + {#each earlier as name (name)} +
    • + {name} +
    • {/each}
    diff --git a/src/routes/projects/animaldex/+layout.svelte b/src/routes/projects/animaldex/+layout.svelte index 1e47fdb..a54cfdc 100644 --- a/src/routes/projects/animaldex/+layout.svelte +++ b/src/routes/projects/animaldex/+layout.svelte @@ -1,15 +1,5 @@ - - - - - - - - {@render children()} diff --git a/src/routes/projects/animaldex/+page.svelte b/src/routes/projects/animaldex/+page.svelte index d8f9677..1892ce7 100644 --- a/src/routes/projects/animaldex/+page.svelte +++ b/src/routes/projects/animaldex/+page.svelte @@ -1,10 +1,11 @@ - Animaldex -
    -
    - -
    +
    +
    +
    +

    animaldex

    +

    neighborhood animals on the map

    +
    - + Log a sighting + add an animal -
    + {#if submitted}

    + sighting submitted. it will appear after review. +

    {/if} +
    + {animalCount === null + ? mapError + ? 'map unavailable' + : 'loading animals…' + : `${animalCount} ${animalCount === 1 ? 'animal' : 'animals'} in this area`} - Filters - {#if activeFilterCount > 0} - {activeFilterCount} - {/if} - +
    + + +
    {#if showFilters} -
    -
    -

    Filter sightings

    - -
    -
    +
    +

    filter sightings

    +
    -
    +
    - +
    - +
    -
    +
    - apply +
    {/if} +
    + {#if mapError}{/if} + {#if animalCount === 0}

    + no animals here yet. try another area. +

    {/if} {#if selected} -
    - {#if selected.trail[0]?.photoUrl} -
    - +
    + {#if [...selected.trail].reverse().find((point) => point.photoUrl)?.photoUrl} +
    + point.photoUrl)?.photoUrl} + alt={selected.animalName || selected.species} + class="h-full w-full object-cover" + /> ✕
    {/if} -
    -
    +
    +
    -

    +

    {selected.animalName ?? selected.species} -

    -

    +

    +

    {selected.species}{selected.breed ? ` · ${selected.breed}` : ''}

    - {selected.sightingCount} {selected.sightingCount === 1 ? 'sighting' : 'sightings'}
    -
    + +
    {#each [...selected.trail].sort((a, b) => new Date(b.seenAt).getTime() - new Date(a.seenAt).getTime()) as s (s.id)} -
    - + {new Date(s.seenAt).toLocaleDateString('nl-NL', { day: 'numeric', month: 'short', year: 'numeric' })} - {#if s.reporterName}by {s.reporterName}{/if} + {#if s.reporterName}by {s.reporterName}{/if}
    {/each}
    - I saw this animal too! + i saw this animal too ↗
    {/if} -
    + {#if visibleAnimals.length} +
    +

    animals in this area

    +
      + {#each visibleAnimals.slice(0, 24) as feature (feature.properties.animalId)} + {@const animal = feature.properties} + {@const photo = [...parseTrail(animal.trail)] + .reverse() + .find((point) => point.photoUrl)?.photoUrl} +
    • + +
    • + {/each} +
    + {#if visibleAnimals.length > 24}

    + showing 24 animals. zoom in to see the others. +

    {/if} +
    + {/if} +
    diff --git a/src/routes/projects/animaldex/+page.ts b/src/routes/projects/animaldex/+page.ts deleted file mode 100644 index a3d1578..0000000 --- a/src/routes/projects/animaldex/+page.ts +++ /dev/null @@ -1 +0,0 @@ -export const ssr = false; diff --git a/src/routes/projects/animaldex/admin/+page.svelte b/src/routes/projects/animaldex/admin/+page.svelte index ca73304..3ee1304 100644 --- a/src/routes/projects/animaldex/admin/+page.svelte +++ b/src/routes/projects/animaldex/admin/+page.svelte @@ -5,97 +5,63 @@ let { data }: { data: PageData } = $props(); - let password = $state(''); - let loginError = $state(''); - let loginLoading = $state(false); - - async function login() { - loginLoading = true; - loginError = ''; - const res = await fetch('/admin/login', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ password }) - }); - if (res.ok) { - await invalidateAll(); - } else { - loginError = 'Wrong password'; - } - loginLoading = false; - } - let actionLoading = $state(null); + let actionError = $state(''); - async function moderate(type: 'animals' | 'sightings', id: string, action: 'accept' | 'deny') { - actionLoading = `${type}-${id}-${action}`; - await fetch(`/api/${type}/${id}/moderate`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ action }) - }); - actionLoading = null; - await invalidateAll(); + async function moderate(id: number, action: 'accept' | 'deny') { + actionLoading = `animals-${id}-${action}`; + actionError = ''; + try { + const response = await fetch(resolve(`/projects/animaldex/api/animals/${id}/moderate`), { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action }) + }); + if (!response.ok) throw new Error(); + await invalidateAll(); + } catch { + actionError = 'Could not update this animal. Please try again.'; + } finally { + actionLoading = null; + } } const queue = $derived(data.queue ?? []); -Animaldex - Admin - {#if !data.admin} -
    -
    -

    Admin login

    - e.key === 'Enter' && login()} - class="mb-3 w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-orange-400" - /> - {#if loginError} -

    {loginError}

    - {/if} - -
    + {:else}

    Your account does not have administrator access.

    {/if}
    {:else} -
    -
    + ← animaldex -
    - ← -

    Animaldex admin

    -
    - +
    +

    animaldex admin

    + {queue.filter((r) => !r.acceptedAt && !r.deniedAt).length} pending
    - -
    + {#if actionError}{/if} +
    {#if queue.length === 0} -
    - No submissions yet -
    +

    + no submissions yet +

    {/if} {#each queue as item (item.animalId)} {@const status = item.acceptedAt ? 'accepted' : item.deniedAt ? 'denied' : 'pending'} -
    +
    -
    +
    {#if item.photoUrl} {:else} @@ -105,30 +71,23 @@
    -

    {item.animalName ?? item.species}

    -

    +

    {item.animalName ?? item.species}

    +

    {item.species}{item.breed ? ` · ${item.breed}` : ''}

    - + {status}
    {#if item.aiBreedSuggestion} -

    +

    🤖 AI: {item.aiBreedSuggestion} ({Math.round( (item.aiBreedConfidence ?? 0) * 100 )}%)

    {/if} -

    +

    {new Date(item.submittedAt).toLocaleDateString('nl-NL', { day: 'numeric', month: 'short', @@ -138,27 +97,23 @@ })} {#if item.reporterName}· by {item.reporterName}{/if}

    -

    +

    📍 {item.sightingLat.toFixed(5)}, {item.sightingLng.toFixed(5)}

    -
    +
    @@ -166,5 +121,5 @@
    {/each}
    -
    + {/if} diff --git a/src/routes/projects/animaldex/admin/login/+server.ts b/src/routes/projects/animaldex/admin/login/+server.ts index e2cd02c..b063e69 100644 --- a/src/routes/projects/animaldex/admin/login/+server.ts +++ b/src/routes/projects/animaldex/admin/login/+server.ts @@ -1,25 +1,3 @@ -import { json, error } from '@sveltejs/kit'; -import type { RequestHandler } from './$types'; -import { env } from '$env/dynamic/private'; -import { z } from 'zod'; - -const loginSchema = z.object({ password: z.string().min(1) }); - -export const POST: RequestHandler = async ({ request, cookies }) => { - const body = await request.json().catch(() => null); - const parsed = loginSchema.safeParse(body); - - if (!parsed.success || parsed.data.password !== env.ADMIN_SECRET) { - throw error(401, { message: 'Invalid password' }); - } - - cookies.set('admin_token', env.ADMIN_SECRET, { - path: '/', - httpOnly: true, - sameSite: 'strict', - secure: process.env.NODE_ENV === 'production', - maxAge: 60 * 60 * 24 * 7 - }); - - return json({ ok: true }); -}; +import { error, redirect } from '@sveltejs/kit'; +export const GET = () => redirect(303, '/login'); +export const POST = () => error(410, 'Use the central account login at /login'); diff --git a/src/routes/projects/animaldex/api/animals/+server.ts b/src/routes/projects/animaldex/api/animals/+server.ts index 49b5028..06c3857 100644 --- a/src/routes/projects/animaldex/api/animals/+server.ts +++ b/src/routes/projects/animaldex/api/animals/+server.ts @@ -3,8 +3,8 @@ import type { RequestHandler } from './$types'; import { db } from '$lib/server/db'; import { animals, sightings, photos } from '$lib/server/db/schema'; import { registerAnimalSchema } from '$lib/validation/sighting'; -import { sql } from 'drizzle-orm'; import { env } from '$env/dynamic/private'; +import { distanceMeters } from '$lib/geo'; const MAX_DISTANCE_METERS = 30_000; @@ -18,14 +18,7 @@ export const POST: RequestHandler = async ({ request }) => { const data = parsed.data; - const [distRow] = await db.execute(sql` - SELECT ST_Distance( - ST_MakePoint(${data.deviceLng}, ${data.deviceLat})::geography, - ST_MakePoint(${data.lng}, ${data.lat})::geography - ) AS dist - `); - - const dist = Number((distRow as Record).dist); + const dist = distanceMeters(data.deviceLat, data.deviceLng, data.lat, data.lng); if (dist > MAX_DISTANCE_METERS) { throw error(422, { message: `Location is ${Math.round(dist / 1000)}km from your device. Maximum is 30km.` diff --git a/src/routes/projects/animaldex/api/animals/[id]/moderate/+server.ts b/src/routes/projects/animaldex/api/animals/[id]/moderate/+server.ts index 7497f0d..142fcb5 100644 --- a/src/routes/projects/animaldex/api/animals/[id]/moderate/+server.ts +++ b/src/routes/projects/animaldex/api/animals/[id]/moderate/+server.ts @@ -9,6 +9,9 @@ import { requireAdmin } from '$lib/server/auth'; export const POST: RequestHandler = async (event) => { requireAdmin(event); + const id = Number(event.params.id); + if (!Number.isInteger(id) || id <= 0) throw error(404, { message: 'Not found' }); + const body = await event.request.json().catch(() => null); const parsed = moderationActionSchema.safeParse(body); @@ -26,14 +29,14 @@ export const POST: RequestHandler = async (event) => { acceptedAt: isAccept ? now : null, deniedAt: isAccept ? null : now }) - .where(eq(animals.id, event.params.id)) + .where(eq(animals.id, id)) .returning({ id: animals.id }); if (result.length && isAccept) { await tx .update(sightings) .set({ acceptedAt: now, deniedAt: null }) - .where(eq(sightings.animalId, event.params.id)); + .where(eq(sightings.animalId, id)); } return result; diff --git a/src/routes/projects/animaldex/api/animals/[id]/sightings/+server.ts b/src/routes/projects/animaldex/api/animals/[id]/sightings/+server.ts index eb9ff6e..932054b 100644 --- a/src/routes/projects/animaldex/api/animals/[id]/sightings/+server.ts +++ b/src/routes/projects/animaldex/api/animals/[id]/sightings/+server.ts @@ -5,20 +5,9 @@ import { animals, sightings, photos } from '$lib/server/db/schema'; import { addSightingSchema } from '$lib/validation/sighting'; import { eq } from 'drizzle-orm'; import { env } from '$env/dynamic/private'; +import { distanceMeters } from '$lib/geo'; const MAX_DISTANCE_METERS = 30_000; -const EARTH_RADIUS_METERS = 6_371_000; - -// Haversine distance between two lat/lng points, in meters. -function distanceMeters(lat1: number, lng1: number, lat2: number, lng2: number): number { - const toRad = (deg: number) => (deg * Math.PI) / 180; - const dLat = toRad(lat2 - lat1); - const dLng = toRad(lng2 - lng1); - const a = - Math.sin(dLat / 2) ** 2 + - Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLng / 2) ** 2; - return 2 * EARTH_RADIUS_METERS * Math.asin(Math.sqrt(a)); -} export const POST: RequestHandler = async ({ request, params }) => { const body = await request.json().catch(() => null); @@ -33,7 +22,7 @@ export const POST: RequestHandler = async ({ request, params }) => { const [animal] = await db .select({ id: animals.id, acceptedAt: animals.acceptedAt }) .from(animals) - .where(eq(animals.id, params.id)) + .where(eq(animals.id, data.animalId)) .limit(1); if (!animal) { diff --git a/src/routes/projects/animaldex/api/animals/[id]/sightings/[id]/moderate/+server.ts b/src/routes/projects/animaldex/api/animals/[id]/sightings/[id]/moderate/+server.ts index b1265e6..5810ecd 100644 --- a/src/routes/projects/animaldex/api/animals/[id]/sightings/[id]/moderate/+server.ts +++ b/src/routes/projects/animaldex/api/animals/[id]/sightings/[id]/moderate/+server.ts @@ -9,6 +9,9 @@ import { requireAdmin } from '$lib/server/auth'; export const POST: RequestHandler = async (event) => { requireAdmin(event); + const id = Number(event.params.id); + if (!Number.isInteger(id) || id <= 0) throw error(404, { message: 'Not found' }); + const body = await event.request.json().catch(() => null); const parsed = moderationActionSchema.safeParse(body); @@ -25,7 +28,7 @@ export const POST: RequestHandler = async (event) => { acceptedAt: isAccept ? now : null, deniedAt: isAccept ? null : now }) - .where(eq(sightings.id, event.params.id)) + .where(eq(sightings.id, id)) .returning({ id: sightings.id }); if (!updated) { diff --git a/src/routes/projects/animaldex/api/detect-breed/+server.ts b/src/routes/projects/animaldex/api/detect-breed/+server.ts index ac875c5..02035ce 100644 --- a/src/routes/projects/animaldex/api/detect-breed/+server.ts +++ b/src/routes/projects/animaldex/api/detect-breed/+server.ts @@ -12,6 +12,6 @@ export const POST: RequestHandler = async ({ request }) => { throw error(400, { message: 'imageUrl is required' }); } - // const result = await detectBreed(parsed.data.imageUrl); - return json(result ?? { breed: null, confidence: 0 }); + // Breed detection is not configured for this site yet. + return json({ breed: null, confidence: 0 }); }; diff --git a/src/routes/projects/animaldex/api/map/+server.ts b/src/routes/projects/animaldex/api/map/+server.ts index 7bee728..1815e99 100644 --- a/src/routes/projects/animaldex/api/map/+server.ts +++ b/src/routes/projects/animaldex/api/map/+server.ts @@ -57,14 +57,14 @@ export const GET: RequestHandler = async ({ url }) => { .orderBy(sightings.seenAt); const animalMap = new Map< - string, + number, { - animalId: string; + animalId: number; species: string; breed: string | null; animalName: string | null; sightings: Array<{ - id: string; + id: number; lat: number; lng: number; seenAt: Date; @@ -118,10 +118,5 @@ export const GET: RequestHandler = async ({ url }) => { }; }); - console.log( - `[map] query returned ${rows.length} rows for bbox ${q.minLng},${q.minLat} → ${q.maxLng},${q.maxLat}` - ); - console.log(`[map] built ${features.length} features`); - return json({ type: 'FeatureCollection', features }); }; diff --git a/src/routes/projects/animaldex/api/upload/+server.ts b/src/routes/projects/animaldex/api/upload/+server.ts index 8e34691..a8e2f90 100644 --- a/src/routes/projects/animaldex/api/upload/+server.ts +++ b/src/routes/projects/animaldex/api/upload/+server.ts @@ -1,22 +1,18 @@ import { json, error } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; -import { createPresignedUpload, isAllowedMimeType } from '$lib/server/r2'; -import { presignedUploadSchema } from '$lib/validation/sighting'; +import { uploadImage, isAllowedMimeType } from '$lib/server/r2'; export const POST: RequestHandler = async ({ request }) => { - const body = await request.json().catch(() => null); - const parsed = presignedUploadSchema.safeParse(body); - - if (!parsed.success) { - throw error(400, { message: 'Invalid request body' }); + const form = await request.formData().catch(() => null); + const photo = form?.get('photo'); + if (!(photo instanceof File) || !isAllowedMimeType(photo.type)) + throw error(400, 'Use a JPEG, PNG, WebP, or HEIC photo.'); + if (!photo.size || photo.size > 5 * 1024 * 1024) + throw error(400, 'Photos must be 5 MB or smaller.'); + try { + return json(await uploadImage(photo)); + } catch (cause) { + console.error('Animaldex image upload failed', cause); + throw error(503, 'Image storage is unavailable.'); } - - const { mimeType } = parsed.data; - - if (!isAllowedMimeType(mimeType)) { - throw error(400, { message: 'Unsupported image type' }); - } - - const result = await createPresignedUpload(mimeType); - return json(result); }; diff --git a/src/routes/projects/animaldex/layout.css b/src/routes/projects/animaldex/layout.css deleted file mode 100644 index d4b5078..0000000 --- a/src/routes/projects/animaldex/layout.css +++ /dev/null @@ -1 +0,0 @@ -@import 'tailwindcss'; diff --git a/src/routes/projects/animaldex/register/+page.svelte b/src/routes/projects/animaldex/register/+page.svelte index 0988c22..f957131 100644 --- a/src/routes/projects/animaldex/register/+page.svelte +++ b/src/routes/projects/animaldex/register/+page.svelte @@ -1,7 +1,7 @@ - Animaldex - Log a sighting -
    -
    + ← animaldex - ← -

    - {isNewSighting ? 'Log another sighting' : 'Register an animal'} -

    -
    +

    + {isNewSighting ? 'add a sighting' : 'add an animal'} +

    +

    + {isNewSighting ? 'mark where you saw this animal' : 'add a neighborhood animal to the map'} +

    -
    +
    {#if locationError} -
    -

    📍 Location required

    + {/if} -
    -

    - Photos +
    +

    + photos {#if isNewSighting} - (optional) + (optional) {:else} - * + (at least one) {/if}

    {#each photoPreviews as preview, i (i)} -
    +
    @@ -264,59 +284,36 @@ {/each} {#if photoFiles.length < 10} {/if}
    -

    Max 10 photos · JPEG, PNG, WebP, HEIC

    +

    + up to 10 photos · JPEG, PNG, WebP, HEIC · 5 MB each +

    - {#if aiLoading} -
    - ⟳ Identifying breed… -
    - {:else if aiSuggestion && !aiDismissed} -
    -

    - 🤖 AI thinks this is a {aiSuggestion.breed} - ({Math.round(aiSuggestion.confidence * 100)}% confident) -

    -
    - - -
    -
    - {/if} - {#if !isNewSighting} -
    -

    - Species * +
    +

    + Species *

    {#each COMMON_SPECIES as s (s)} @@ -325,107 +322,120 @@ species = s; customSpecies = ''; }} - class="rounded-full px-3 py-1.5 text-sm {species === s - ? 'bg-orange-500 text-white' - : 'bg-gray-100 text-gray-700 hover:bg-gray-200'}">{s}{s} {/each} Other…
    {#if species === '__custom__'} {/if}
    -
    -

    - Breed (optional) +
    +

    + Breed (optional)

    -
    +
    -

    - Animal name (optional) +

    + Animal name (optional)

    -

    - Description (optional) +

    + Description (optional)

    {/if} -
    +
    -

    - When did you see it? * +

    + When did you see it? *

    -

    - Your name (optional) +

    + Your name (optional)

    -
    -

    - Location * +
    +

    + Location *

    {#if locationLoading}
    Getting your location…
    {:else if lat !== null} -
    -

    Drag the pin to fine-tune (max 30 km from you).

    +
    + {#if mapError}{/if} +

    + Drag the pin to fine-tune (max 30 km from you). +

    {/if}
    {#if submitError} -
    + {/if} @@ -433,13 +443,13 @@ -

    +

    All submissions are reviewed before appearing on the map.

    -

    + diff --git a/src/routes/projects/catch-em-all/+layout.server.ts b/src/routes/projects/catch-em-all/+layout.server.ts index 54048b3..cb0ff5c 100644 --- a/src/routes/projects/catch-em-all/+layout.server.ts +++ b/src/routes/projects/catch-em-all/+layout.server.ts @@ -1,5 +1 @@ -import type { LayoutServerLoad } from './$types'; - -export const load: LayoutServerLoad = async ({ locals }) => { - return { user: locals.user ?? null }; -}; +export {}; diff --git a/src/routes/projects/catch-em-all/+layout.svelte b/src/routes/projects/catch-em-all/+layout.svelte index 801d902..82b01e0 100644 --- a/src/routes/projects/catch-em-all/+layout.svelte +++ b/src/routes/projects/catch-em-all/+layout.svelte @@ -1,30 +1,7 @@ -
    -
    -
    - {#if data.user} - Logged in as {data.user.name} -
    - -
    - {:else} - Log in - {/if} -
    -
    - -
    {@render children()}
    -
    +
    {@render children()}
    diff --git a/src/routes/projects/catch-em-all/+page.server.ts b/src/routes/projects/catch-em-all/+page.server.ts index 918f6fc..9cd3589 100644 --- a/src/routes/projects/catch-em-all/+page.server.ts +++ b/src/routes/projects/catch-em-all/+page.server.ts @@ -1,6 +1,12 @@ import { db } from '$lib/server/db'; -import { game, pokemonGameEntry, userEntry, userGame } from '$lib/server/db/schema'; -import { eq, inArray } from 'drizzle-orm'; +import { + games, + pokemonGameEntries, + userEntries, + userGames, + catchEmAllSettings +} from '$lib/server/db/schema'; +import { and, eq, inArray } from 'drizzle-orm'; import type { Actions, PageServerLoad } from './$types'; import { availabilityValues } from '$lib/availability'; import { fail } from '@sveltejs/kit'; @@ -11,7 +17,7 @@ export const load: PageServerLoad = async ({ locals }) => { with: { entry: true }, - orderBy: (pokemon) => pokemon.number + orderBy: { number: 'asc' } }); const pokemon = pokemonRows.map(({ entry, ...rest }) => ({ ...rest, @@ -21,27 +27,39 @@ export const load: PageServerLoad = async ({ locals }) => { }) })); - const games = await db.query.game.findMany({ - orderBy: (game) => [game.generation, game.id] + const gameRows = await db.query.games.findMany({ + orderBy: { generation: 'asc', id: 'asc' } }); let caughtIds: number[] = []; let selectedGameIds: number[] = []; + let gamesConfigured = false; if (locals.user) { + const [settings] = await db + .select() + .from(catchEmAllSettings) + .where(eq(catchEmAllSettings.userId, locals.user.id)); + gamesConfigured = !!settings; const caughtRows = await db - .select({ id: userEntry.pokemonGameEntryId }) - .from(userEntry) - .where(eq(userEntry.userId, locals.user.id)); + .select({ id: userEntries.pokemonGameEntryId }) + .from(userEntries) + .where(eq(userEntries.userId, locals.user.id)); caughtIds = caughtRows.map((r) => r.id); const gameRows = await db - .select({ id: userGame.gameId }) - .from(userGame) - .where(eq(userGame.userId, locals.user.id)); + .select({ id: userGames.gameId }) + .from(userGames) + .where(eq(userGames.userId, locals.user.id)); selectedGameIds = gameRows.map((r) => r.id); } - return { pokemon, games, caughtIds, selectedGameIds }; + return { + pokemon, + games: gameRows, + caughtIds, + selectedGameIds, + gamesConfigured: gamesConfigured || selectedGameIds.length > 0 + }; }; export const actions = { @@ -50,58 +68,71 @@ export const actions = { const data = await request.formData(); const entryId = Number(data.get('entryId')); - if (!Number.isInteger(entryId) || entryId <= 0) return fail(400, { message: 'Invalid entry' }); + if (!Number.isSafeInteger(entryId) || entryId <= 0 || entryId > 2147483647) + return fail(400, { message: 'Invalid entry' }); // only catchable entries can be toggled — the client disables these // checkboxes but we can't trust that const [entry] = await db - .select({ availability: pokemonGameEntry.availability }) - .from(pokemonGameEntry) - .where(eq(pokemonGameEntry.id, entryId)); + .select({ availability: pokemonGameEntries.availability }) + .from(pokemonGameEntries) + .where(eq(pokemonGameEntries.id, entryId)); if (!entry) return fail(404, { message: 'Unknown entry' }); if (entry.availability !== 'catchable') { - return fail(400, { message: 'This pokemon is not catchable in this game' }); + return fail(400, { message: 'This entry does not have confirmed encounter data' }); } + if (data.has('caught') && data.get('caught') !== 'on') + return fail(400, { message: 'Invalid caught state' }); const caught = data.get('caught') === 'on'; if (caught) { await db - .insert(userEntry) + .insert(userEntries) .values({ pokemonGameEntryId: entryId, userId: locals.user.id }) .onConflictDoNothing(); } else { await db - .delete(userEntry) + .delete(userEntries) .where( - and(eq(userEntry.pokemonGameEntryId, entryId), eq(userEntry.userId, locals.user.id)) + and(eq(userEntries.pokemonGameEntryId, entryId), eq(userEntries.userId, locals.user.id)) ); } + return { saved: true }; }, setGames: async ({ request, locals }) => { if (!locals.user) return fail(401, { message: 'Log in to set rules' }); const data = await request.formData(); - const gameIds = data - .getAll('gameIds') - .map(Number) - .filter((id) => Number.isInteger(id) && id > 0); + const submittedIds = data.getAll('gameIds').map(Number); + if ( + submittedIds.length > 200 || + submittedIds.some((id) => !Number.isSafeInteger(id) || id <= 0) + ) { + return fail(400, { message: 'Invalid game selection' }); + } + const gameIds = [...new Set(submittedIds)]; if (gameIds.length > 0) { const validGames = await db - .select({ id: game.id }) - .from(game) - .where(inArray(game.id, gameIds)); + .select({ id: games.id }) + .from(games) + .where(inArray(games.id, gameIds)); if (validGames.length !== gameIds.length) return fail(400, { message: 'Unknown game' }); } const userId = locals.user.id; await db.transaction(async (tx) => { - await tx.delete(userGame).where(eq(userGame.userId, userId)); + await tx + .insert(catchEmAllSettings) + .values({ userId }) + .onConflictDoUpdate({ target: catchEmAllSettings.userId, set: { userId } }); + await tx.delete(userGames).where(eq(userGames.userId, userId)); if (gameIds.length > 0) { - await tx.insert(userGame).values(gameIds.map((gameId) => ({ userId, gameId }))); + await tx.insert(userGames).values(gameIds.map((gameId) => ({ userId, gameId }))); } }); + return { saved: true }; } } satisfies Actions; diff --git a/src/routes/projects/catch-em-all/+page.svelte b/src/routes/projects/catch-em-all/+page.svelte index b3c8f37..a128475 100644 --- a/src/routes/projects/catch-em-all/+page.svelte +++ b/src/routes/projects/catch-em-all/+page.svelte @@ -1,59 +1,53 @@ - - catchemall - - -
    -

    Gotta catch 'em all!

    -
    - -
    -

    - Below are all {data.pokemon.length} Pokemon across {data.games.length} games. Play through all generations - and catch all catchable pokemon in each. Use the "Set rules" button to pick which games you want to - complete. -

    -
    - -{#if !data.user} -

    - Log in to save your progress. -

    -{/if} - -
    - - -

    {caughtCount}/{total} entries caught ({percentage} %)

    - 0 ? caughtCount / total : 0}> -
    - -
    (scrollTop = scrollEl?.scrollTop ?? 0)} - class="max-h-[75vh] overflow-auto rounded-xl border border-gray-300" -> - - - - - {#each visibleGames as game (game.id)} - - {/each} - - - - {#if startIndex > 0} - - - - {/if} - {#each visiblePokemon as pokemon (pokemon.id)} - - - {#each visibleGames as game (game.id)} - {@const entry = entryMap.get(pokemon.id)?.get(game.id)} - {@const reason = tooltip(entry, game)} - - {/each} - - {/each} - {#if endIndex < data.pokemon.length} - - - - {/if} - -
    Pokemon - {game.name} -
    -
    - - {pokemon.number} - {pokemon.name} - {pokemon.type1} - {#if pokemon.type2} - {pokemon.type2} - {/if} -
    -
    - {#if entry && reason === null} - toggleCaught(entry.id, e.currentTarget.checked)} - /> - {:else} - - - - {/if} -
    -
    - - -

    Set rules

    -

    - Pick the games you want to catch 'em all in. Only those show up in the table and count towards - your progress. -

    - -
    +
    +
    +
    +

    catchemall

    +

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

    +
    - set rules
    + {#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} +
    + + +
    -
    +
    {#each gamesByGeneration as [generation, games] (generation)} -
    - - draft.has(g.id))} - onchange={(e) => { - for (const g of games) { - if (e.currentTarget.checked) draft.add(g.id); - else draft.delete(g.id); - } - }} - /> - Gen {generation} - - {#each games as game (game.id)} - {/each}
    {/each}
    - -
    +
    + - save
    diff --git a/src/routes/projects/derby/+page.svelte b/src/routes/projects/derby/+page.svelte index 0598eb6..c31c456 100644 --- a/src/routes/projects/derby/+page.svelte +++ b/src/routes/projects/derby/+page.svelte @@ -2,6 +2,7 @@ import { onMount } from 'svelte'; import { horses, race, type Horse } from '$lib/derby/data'; import { scenarios } from '$lib/derby/practice'; + import { races } from '$lib/derby/races'; import { betValue, defaultWeights, @@ -48,7 +49,9 @@ const pl = $derived(placings(preds, w.lambda)); const favourite = $derived(preds[0]); const heatBest = $derived( - [1, 2].map((heat) => Math.min(...runners.filter((h) => h.trial.heat === heat).map((h) => h.trial.time))) + [1, 2].map((heat) => + Math.min(...runners.filter((h) => h.trial.heat === heat).map((h) => h.trial.time)) + ) ); const trialLabel = (h: Horse) => { const gap = h.trial.time - heatBest[h.trial.heat - 1]; @@ -84,10 +87,23 @@ const sum = exp.reduce((a, b) => a + b, 0); return exp.map((x) => x / sum); }); - const plFinal = $derived(placings(preds.map((r, i) => ({ ...r, p: final[i] })), w.lambda)); + const plFinal = $derived( + placings( + preds.map((r, i) => ({ ...r, p: final[i] })), + w.lambda + ) + ); const placeP = (i: number) => plFinal.top[i].win + plFinal.top[i].place2 + plFinal.top[i].place3; - type Bet = { type: 'Winnend' | 'Plaats'; r: Prediction; p: number; odds: number; edge: number; kelly: number; stake: number }; + type Bet = { + type: 'Winnend' | 'Plaats'; + r: Prediction; + p: number; + odds: number; + edge: number; + kelly: number; + stake: number; + }; const bets = $derived.by(() => { const list: Bet[] = []; preds.forEach((r, i) => { @@ -113,9 +129,12 @@ placeOdds = { ...(sc.place ?? {}) }; } else { // noteringen precies volgens het model, met 20% marge: fair / 1.2 - const rows = predict(horses.filter((h) => !sc.scratched.includes(h.n)), w); + const rows = predict( + horses.filter((h) => !sc.scratched.includes(h.n)), + w + ); const pl2 = placings(rows, w.lambda); - odds = Object.fromEntries(rows.map((r) => [r.horse.n, Math.round((10 / (r.p * 1.2)) ) / 10])); + odds = Object.fromEntries(rows.map((r) => [r.horse.n, Math.round(10 / (r.p * 1.2)) / 10])); placeOdds = Object.fromEntries( rows.slice(0, 4).map((r, i) => { const t = pl2.top[i]; @@ -136,14 +155,16 @@ const steps = $derived([ { title: 'Controleer de niet-starters', - detail: 'Staat er een paard op het bord of in de app als teruggetrokken? Vink het uit in de tabel.', + detail: + 'Staat er een paard op het bord of in de app als teruggetrokken? Vink het uit in de tabel.', done: scratchChecked, status: scratchChecked ? 'gecontroleerd' : `${scratched.length} uitgevinkt`, href: '#winkans' }, { title: 'Vul de win-noteringen in', - detail: 'Alle tien, uit de kolom "Winnend" op het bord of in de app. Zo laat mogelijk: de toto beweegt tot de start.', + detail: + 'Alle tien, uit de kolom "Winnend" op het bord of in de app. Zo laat mogelijk: de toto beweegt tot de start.', done: toto.complete, status: `${toto.entered} van ${preds.length}`, href: '#winkans' @@ -157,9 +178,15 @@ }, { title: 'Wed alleen op groen', - detail: 'De lijst "Waarde & inzet" is het antwoord. Rood = niet doen, ook niet de favoriet. Niets groen = niet wedden.', + detail: + 'De lijst "Waarde & inzet" is het antwoord. Rood = niet doen, ook niet de favoriet. Niets groen = niet wedden.', done: bets.length > 0, - status: bets.length === 0 ? 'nog geen noteringen' : goodBets.length === 0 ? 'niets groen: niet wedden' : `${goodBets.length} met waarde`, + status: + bets.length === 0 + ? 'nog geen noteringen' + : goodBets.length === 0 + ? 'niets groen: niet wedden' + : `${goodBets.length} met waarde`, href: '#waarde' } ]); @@ -173,17 +200,99 @@ }; const sexLabel: Record = { M: 'merrie', H: 'hengst', R: 'ruin' }; - const sliders: { key: keyof Weights; label: string; hint: string; min: number; max: number; step: number; fmt?: (v: number) => string }[] = [ - { key: 'form', label: 'Recente uitslagen', hint: 'De laatste vijf koersen. Winnen telt het zwaarst, een D (uit de draf gegaan) telt als nul.', min: 0, max: 2, step: 0.1 }, - { key: 'trial', label: 'Derbyproef', hint: 'De kwalificatiekoers van 4 september, waarin alle tien paarden liepen. Hoeveel seconden kwam een paard achter de winnaar van zijn heat binnen?', min: 0, max: 2, step: 0.1 }, - { key: 'record', label: 'Snelste tijd', hint: 'Beste kilometertijd ooit over 2600 m. Drie paarden hebben er geen; die krijgen het gemiddelde.', min: 0, max: 2, step: 0.1 }, - { key: 'draw', label: 'Startpositie', hint: 'Lage nummers starten aan de binnenkant en hebben de kortste weg. 9 en 10 starten op de tweede rij.', min: 0, max: 2, step: 0.1 }, - { key: 'market', label: 'Wedmarkt bij de proef', hint: 'Hoeveel geld er op elk paard werd ingezet bij de Derbyproef. De markt weet vaak meer dan de cijfers.', min: 0, max: 2, step: 0.1 }, - { key: 'risk', label: 'Straf voor uitvallen', hint: 'Paarden die eerder gediskwalificeerd werden of ver achteraan eindigden, krijgen aftrek.', min: 0, max: 3, step: 0.1 }, - { key: 'halfLife', label: 'Geheugen', hint: 'Hoe snel oudere uitslagen minder meetellen. Bij 2 koersen weegt de koers van drie keer geleden nog de helft.', min: 1, max: 5, step: 0.5, fmt: (v) => `${v} koersen` }, - { key: 'heatGap', label: 'Handicap merrieproef', hint: 'De merries liepen hun eigen, tragere proef (heat 2). Hoeveel seconden trek je daarvoor af?', min: 0, max: 2, step: 0.1, fmt: (v) => `${v.toFixed(1)} s` }, - { key: 'temperature', label: 'Voorzichtigheid', hint: 'Hoger = kansen dichter bij elkaar (de favoriet krijgt minder). Lager = het model is zekerder van zijn zaak.', min: 0.5, max: 2, step: 0.05, fmt: (v) => v.toFixed(2) }, - { key: 'lambda', label: 'Plaatskans-correctie', hint: 'Alleen voor 2e en 3e plaats. Lager = de favoriet eindigt minder vaak precies tweede, wat in de praktijk klopt.', min: 0.5, max: 1, step: 0.05, fmt: (v) => v.toFixed(2) } + const sliders: { + key: keyof Weights; + label: string; + hint: string; + min: number; + max: number; + step: number; + fmt?: (v: number) => string; + }[] = [ + { + key: 'form', + label: 'Recente uitslagen', + hint: 'De laatste vijf koersen. Winnen telt het zwaarst, een D (uit de draf gegaan) telt als nul.', + min: 0, + max: 2, + step: 0.1 + }, + { + key: 'trial', + label: 'Derbyproef', + hint: 'De kwalificatiekoers van 4 september, waarin alle tien paarden liepen. Hoeveel seconden kwam een paard achter de winnaar van zijn heat binnen?', + min: 0, + max: 2, + step: 0.1 + }, + { + key: 'record', + label: 'Snelste tijd', + hint: 'Beste kilometertijd ooit over 2600 m. Drie paarden hebben er geen; die krijgen het gemiddelde.', + min: 0, + max: 2, + step: 0.1 + }, + { + key: 'draw', + label: 'Startpositie', + hint: 'Lage nummers starten aan de binnenkant en hebben de kortste weg. 9 en 10 starten op de tweede rij.', + min: 0, + max: 2, + step: 0.1 + }, + { + key: 'market', + label: 'Wedmarkt bij de proef', + hint: 'Hoeveel geld er op elk paard werd ingezet bij de Derbyproef. De markt weet vaak meer dan de cijfers.', + min: 0, + max: 2, + step: 0.1 + }, + { + key: 'risk', + label: 'Straf voor uitvallen', + hint: 'Paarden die eerder gediskwalificeerd werden of ver achteraan eindigden, krijgen aftrek.', + min: 0, + max: 3, + step: 0.1 + }, + { + key: 'halfLife', + label: 'Geheugen', + hint: 'Hoe snel oudere uitslagen minder meetellen. Bij 2 koersen weegt de koers van drie keer geleden nog de helft.', + min: 1, + max: 5, + step: 0.5, + fmt: (v) => `${v} koersen` + }, + { + key: 'heatGap', + label: 'Handicap merrieproef', + hint: 'De merries liepen hun eigen, tragere proef (heat 2). Hoeveel seconden trek je daarvoor af?', + min: 0, + max: 2, + step: 0.1, + fmt: (v) => `${v.toFixed(1)} s` + }, + { + key: 'temperature', + label: 'Voorzichtigheid', + hint: 'Hoger = kansen dichter bij elkaar (de favoriet krijgt minder). Lager = het model is zekerder van zijn zaak.', + min: 0.5, + max: 2, + step: 0.05, + fmt: (v) => v.toFixed(2) + }, + { + key: 'lambda', + label: 'Plaatskans-correctie', + hint: 'Alleen voor 2e en 3e plaats. Lager = de favoriet eindigt minder vaak precies tweede, wat in de praktijk klopt.', + min: 0.5, + max: 1, + step: 0.05, + fmt: (v) => v.toFixed(2) + } ]; const pct = (p: number, d = 1) => `${(p * 100).toFixed(d)}%`; @@ -212,7 +321,17 @@ } function snapshot(): Saved { - return { w: { ...w }, scratched: [...scratched], odds: { ...odds }, placeOdds: { ...placeOdds }, blend, bankroll, fraction, help, practice }; + return { + w: { ...w }, + scratched: [...scratched], + odds: { ...odds }, + placeOdds: { ...placeOdds }, + blend, + bankroll, + fraction, + help, + practice + }; } function restore(s: Partial) { @@ -246,10 +365,17 @@ if (!p.has('w')) return null; const keys = Object.keys(defaultWeights) as (keyof Weights)[]; const vals = p.get('w')!.split(',').map(Number); - const wv = Object.fromEntries(keys.map((k, i) => [k, Number.isFinite(vals[i]) ? vals[i] : defaultWeights[k]])) as Weights; + const wv = Object.fromEntries( + keys.map((k, i) => [k, Number.isFinite(vals[i]) ? vals[i] : defaultWeights[k]]) + ) as Weights; const s = (p.get('s') ?? '').split(',').filter(Boolean).map(Number); const pairs = (key: string) => - Object.fromEntries((p.get(key) ?? '').split(',').filter(Boolean).map((x) => x.split(':').map(Number))); + Object.fromEntries( + (p.get(key) ?? '') + .split(',') + .filter(Boolean) + .map((x) => x.split(':').map(Number)) + ); return { w: wv, scratched: s, @@ -299,7 +425,6 @@ - Derby Lens — Duindigt 2026 @@ -308,11 +433,20 @@ + + {#if scenario}
    Oefenmodus · verzonnen noteringen — {scenario.title} @@ -325,7 +459,9 @@
    Kansmodel · 6 signalen

    DERBY
    R 2026

    -
    {race.distance.toLocaleString('nl')} m{race.start}
    +
    + {race.distance.toLocaleString('nl')} m{race.start} +
    €{(race.purse / 1000).toFixed(0)}KPrijzengeld
    {runners.length}Starters
    GoedSintelbaan
    @@ -351,7 +487,12 @@
    Zo gebruik je dit op de dag zelf

    Vier stappen, twintig minuten voor 17:40

    -

    De toto houdt ongeveer 20% van elke euro in. Structureel winnen lukt bijna niemand, ook dit model niet. Wat deze pagina wél doet: de weddenschappen die zéker verliezen eruit halen, en de rest klein en netjes doseren. Tijdens de koers zelf hoef je niets te doen — die duurt ruim drie minuten.

    +

    + De toto houdt ongeveer 20% van elke euro in. Structureel winnen lukt bijna niemand, ook + dit model niet. Wat deze pagina wél doet: de weddenschappen die zéker verliezen eruit + halen, en de rest klein en netjes doseren. Tijdens de koers zelf hoef je niets te doen — + die duurt ruim drie minuten. +

      {#each steps as st, i (st.title)} @@ -361,7 +502,9 @@ {st.title}

      {st.detail}

      {#if i === 0} - + {:else} {st.status} {/if} @@ -371,12 +514,21 @@
    Oefenen
    -

    Laad verzonnen noteringen en kijk wat er gebeurt. Wis daarna alles voordat je de echte invult.

    +

    + Laad verzonnen noteringen en kijk wat er gebeurt. Wis daarna alles voordat je de echte + invult. +

    {#each scenarios as sc (sc.key)} - + {/each} - +
    {#if scenario}
    @@ -391,17 +543,31 @@
    -

    Experimenteel model op openbare data, gemaakt door iemand zonder paardenkennis. Geen advies.

    +

    + Experimenteel model op openbare data, gemaakt door iemand zonder paardenkennis. Geen + advies. +

    -
    {runners.length} starters{#if scenario} · oefening{/if}

    Winkans

    +
    +
    + {runners.length} starters{#if scenario} + · oefening{/if} +
    +

    Winkans

    +
    - {#if help}

    Kans dat elk paard wint volgens het model, hoogste bovenaan. Fair is de notering waarbij een weddenschap precies quitte speelt. Vul bij Notering de echte toto-notering in: staat er dan een groene Waarde, dan schat het model dat paard hoger in dan de toto. Vink een paard uit als het niet start.
    Onder de naam: rijder en de laatste vijf uitslagen, nieuwste eerst. D = gediskwalificeerd.

    {/if} + {#if help}

    + Kans dat elk paard wint volgens het model, hoogste bovenaan. Fair is de notering + waarbij een weddenschap precies quitte speelt. Vul bij Notering de echte + toto-notering in: staat er dan een groene Waarde, dan schat het model dat paard + hoger in dan de toto. Vink een paard uit als het niet start.
    Onder de naam: rijder + en de laatste vijf uitslagen, nieuwste eerst. D = gediskwalificeerd. +

    {/if}
    #Paard - KansFairNoteringWaarde + KansFairNoteringWaarde
    {#each preds as r, i (r.horse.n)} {@const o = odds[r.horse.n]} {@const v = o && o > 1 ? betValue(r.p, o) : null}
    - toggleScratch(r.horse)} /> + toggleScratch(r.horse)} + />
    {r.horse.n}
    {r.horse.name}
    -
    {r.horse.driver} · {r.horse.form.join('-')}
    +
    + {r.horse.driver} · {r.horse.form.join('-')} +
    +
    +
    +
    -
    {pct(r.p)}
    {oddsFmt(fairOdds(r.p))}
    - -
    0} class:neg={v && v.edge <= 0}>{v ? signed(v.edge * 100, 0) + '%' : ''}
    + +
    0} class:neg={v && v.edge <= 0}> + {v ? signed(v.edge * 100, 0) + '%' : ''} +
    {/each} {#each horses.filter((h) => scratched.includes(h.n)) as h (h.n)}
    toggleScratch(h)} />
    {h.n}
    -
    {h.name}
    niet-starter
    +
    +
    {h.name}
    +
    niet-starter
    +
    {/each}
    @@ -453,11 +657,27 @@
    -
    Wedvormen naast winnen · {blending ? 'model + toto gemengd' : 'volgens het model'}
    +
    + Wedvormen naast winnen · {blending ? 'model + toto gemengd' : 'volgens het model'} +

    Plaats & combinaties

    - {#if help}

    Bij een plaatsweddenschap win je als het paard bij de eerste drie eindigt — kleinere uitbetaling, grotere kans. Vul bij Toto de plaatsnotering in om te zien of er waarde zit. Koppel: je kiest de eerste twee, volgorde maakt niet uit. Trio: de eerste drie in de juiste volgorde. Fair = notering waarbij je quitte speelt.

    {/if} + {#if help}

    + Bij een plaatsweddenschap win je als het paard bij de eerste drie eindigt — + kleinere uitbetaling, grotere kans. Vul bij Toto de plaatsnotering in om te zien + of er waarde zit. Koppel: je kiest de eerste twee, volgorde maakt niet uit. + Trio: de eerste drie in de juiste volgorde. Fair = notering waarbij je quitte + speelt. +

    {/if} - + {#each preds as r, i (r.horse.n)} {@const t = plFinal.top[i]} @@ -472,8 +692,20 @@ - - + + {/each} @@ -482,13 +714,21 @@
    Koppel · 1–2 elke volgorde
    {#each plFinal.koppel.slice(0, 6) as k (`${k.a}-${k.b}`)} -
    {name(k.a)} + {name(k.b)}{pct(k.p)}{oddsFmt(fairOdds(k.p))}
    +
    + {name(k.a)} + {name(k.b)}{pct(k.p)}{oddsFmt(fairOdds(k.p))} +
    {/each}
    Trio · 1–2–3 juiste volgorde
    {#each plFinal.trio.slice(0, 6) as t (`${t.a}-${t.b}-${t.c}`)} -
    {preds[t.a].horse.n} · {preds[t.b].horse.n} · {preds[t.c].horse.n}{pct(t.p)}{oddsFmt(fairOdds(t.p))}
    +
    + {preds[t.a].horse.n} · {preds[t.b].horse.n} · {preds[t.c].horse.n}{pct(t.p)}{oddsFmt(fairOdds(t.p))} +
    {/each}
    @@ -497,25 +737,65 @@
    Model vs. toto

    Waarde & inzet

    - {#if help}

    De toto is de mening van alle wedders samen en zit er meestal minder naast dan één model. Daarom wordt de eindkans gemengd: hoe hoger het vertrouwen in de toto, hoe sterker het model het oneens moet zijn voordat een paard waarde toont. Waarde is wat je per ingezette euro verwacht te winnen: +19% betekent €1,19 terug per €1. Inzet volgt uit Kelly: de wiskundig ideale inzet als deel van je bankroll, met een kwart als veilige fractie.

    {/if} + {#if help}

    + De toto is de mening van alle wedders samen en zit er meestal minder naast dan één + model. Daarom wordt de eindkans gemengd: hoe hoger het vertrouwen in de toto, hoe + sterker het model het oneens moet zijn voordat een paard waarde toont. Waarde is + wat je per ingezette euro verwacht te winnen: +19% betekent €1,19 terug per €1. + Inzet volgt uit Kelly: de wiskundig ideale inzet als deel van je bankroll, met een + kwart als veilige fractie. +

    {/if}
    - - + +
    - +
    {#if bets.length === 0} -

    Vul noteringen in bij de paarden (winnend hierboven, plaats hiernaast). Waarde = kans × notering − 1.

    +

    + Vul noteringen in bij de paarden (winnend hierboven, plaats hiernaast). Waarde = kans × + notering − 1. +

    {:else}
    {toto.entered}/{preds.length}noteringen
    -
    {toto.complete ? signed((toto.overround - 1) * 100, 0) + '%' : '—'}toto-marge
    +
    + {toto.complete ? signed((toto.overround - 1) * 100, 0) + '%' : '—'}toto-marge +
    {goodBets.length}met waarde
    #Paard1e2e3ePlaatsFairTotoWaarde
    #Paard1e2e3ePlaatsFairTotoWaarde
    {pct(t.place3, 0)} {pct(place, 0)} {oddsFmt(fairOdds(place))} 0} class:neg={v && v.edge <= 0}>{v ? signed(v.edge * 100, 0) + '%' : ''} 0} class:neg={v && v.edge <= 0} + >{v ? signed(v.edge * 100, 0) + '%' : ''}
    - + {#each bets as b (`${b.type}-${b.r.horse.n}`)} @@ -524,14 +804,19 @@ - + {/each}
    #PaardTypeTotoEindkansWaardeInzet
    #PaardTypeTotoEindkansWaardeInzet
    {b.type} {oddsFmt(b.odds)} {pct(b.p)} 0} class:neg={b.edge <= 0}>{signed(b.edge * 100, 0)}% 0} class:neg={b.edge <= 0} + >{signed(b.edge * 100, 0)}% {b.kelly > 0 ? euro(b.stake) : '—'}
    {#if goodBets.length === 0} -

    Geen enkele weddenschap heeft positieve waarde bij deze noteringen. Dat is een prima uitkomst: niet wedden is dan de beste zet.

    +

    + Geen enkele weddenschap heeft positieve waarde bij deze noteringen. Dat is een prima + uitkomst: niet wedden is dan de beste zet. +

    {/if} {/if}
    @@ -540,7 +825,12 @@
    Per signaal · groen = pluspunt · oranje = minpunt

    Waarom deze kansen

    - {#if help}

    Elk paard wordt per signaal vergeleken met de rest van het veld: beter dan gemiddeld is groen, slechter is oranje. Het grote getal is hoeveel het signaal bijdraagt aan de score (na weging), het kleine getal eronder is de ruwe waarde. De scores bij elkaar geven de kans.

    {/if} + {#if help}

    + Elk paard wordt per signaal vergeleken met de rest van het veld: beter dan gemiddeld is + groen, slechter is oranje. Het grote getal is hoeveel het signaal bijdraagt aan de score + (na weging), het kleine getal eronder is de ruwe waarde. De scores bij elkaar geven de + kans. +

    {/if}
    @@ -557,12 +847,28 @@ - - - - - - + + + + + + @@ -576,14 +882,42 @@ Begrippen voor wie nooit naar de draf kijkt
      -
    • Draverij — de paarden trekken een karretje (sulky) met de rijder erop en moeten in draf blijven. Gaat een paard in galop, dan wordt het gediskwalificeerd: de D in de uitslagen.
    • -
    • Autostart — de paarden starten achter een rijdende auto met uitklapbare hekken, op volgorde van startnummer: 1 aan de binnenkant, 1 t/m 8 op de eerste rij, 9 en 10 op de tweede rij.
    • -
    • Kilometertijd — gemiddelde tijd per 1000 m, de standaardmaat voor snelheid. 1'13"8 is 1 minuut 13,8 seconden per km. Lager is sneller; één seconde is ruim tien meter.
    • -
    • Derbyproef — de kwalificatiekoers van 4 september over 2000 m, in twee heats. Heat 1 (open) werd gewonnen door Rolleman Flevo; heat 2 (alleen merries) door Rose Starlake en was 3,5 s/km trager.
    • -
    • Derby — de belangrijkste koers van het jaar voor driejarigen. Alle tien starters zijn drie jaar en lopen 2600 m; hun namen beginnen met een R omdat het geboortejaar 2023 de letter R kreeg.
    • -
    • Notering — de uitbetaling per ingezette euro als het paard wint: bij 2,50 krijg je €2,50 terug. Hoe lager, hoe meer de toto in het paard gelooft.
    • -
    • Merrie / hengst / ruin — vrouwelijk, mannelijk, gecastreerd. Merries hadden in de proef een eigen heat.
    • -
    • Rijder / trainer — wie op de sulky zit tijdens de koers, en wie het paard dagelijks traint. Tesselaar doet bij Rolleman Flevo allebei.
    • +
    • + Draverij — de paarden trekken een karretje (sulky) met de rijder erop en moeten + in draf blijven. Gaat een paard in galop, dan wordt het gediskwalificeerd: de D in + de uitslagen. +
    • +
    • + Autostart — de paarden starten achter een rijdende auto met uitklapbare hekken, op + volgorde van startnummer: 1 aan de binnenkant, 1 t/m 8 op de eerste rij, 9 en 10 op de tweede + rij. +
    • +
    • + Kilometertijd — gemiddelde tijd per 1000 m, de standaardmaat voor snelheid. 1'13"8 + is 1 minuut 13,8 seconden per km. Lager is sneller; één seconde is ruim tien meter. +
    • +
    • + Derbyproef — de kwalificatiekoers van 4 september over 2000 m, in twee heats. Heat + 1 (open) werd gewonnen door Rolleman Flevo; heat 2 (alleen merries) door Rose Starlake en + was 3,5 s/km trager. +
    • +
    • + Derby — de belangrijkste koers van het jaar voor driejarigen. Alle tien starters zijn + drie jaar en lopen 2600 m; hun namen beginnen met een R omdat het geboortejaar 2023 de letter + R kreeg. +
    • +
    • + Notering — de uitbetaling per ingezette euro als het paard wint: bij 2,50 krijg je + €2,50 terug. Hoe lager, hoe meer de toto in het paard gelooft. +
    • +
    • + Merrie / hengst / ruin — vrouwelijk, mannelijk, gecastreerd. Merries hadden in de proef + een eigen heat. +
    • +
    • + Rijder / trainer — wie op de sulky zit tijdens de koers, en wie het paard dagelijks + traint. Tesselaar doet bij Rolleman Flevo allebei. +
    @@ -591,18 +925,47 @@
    Hoe het model rekent
    -

    logit = 0.55 · Σ gewicht × z(signaal) + risicostraf · ln(1 − P(uitval))  ·  kans = softmax(logit / T)

    +

    + logit = 0.55 · Σ gewicht × z(signaal) + risicostraf · ln(1 − P(uitval))  ·  kans + = softmax(logit / T) +

      -
    • Elk signaal wordt een z-score over het veld (hoeveel standaardafwijkingen boven of onder het gemiddelde), zodat seconden, punten en noteringen vergelijkbaar zijn.
    • -
    • Uitslagen — 1e = 1, 2e = 0,75, 3e = 0,6, 4e = 0,45, 5e = 0,35, 6e = 0,25, verder 0,1, D = 0; gewogen met halveringstijd.
    • -
    • Proef — minus de achterstand in seconden op de heatwinnaar, minus de merriehandicap voor heat 2.
    • -
    • Snelste tijd — minus de record-kilometertijd over 2600 m; onbekend = veldgemiddelde.
    • -
    • Startpositie — vaste curve: 2 en 3 het best, dan 1, aflopend naar 8; 9 en 10 negatief.
    • +
    • + Elk signaal wordt een z-score over het veld (hoeveel standaardafwijkingen boven of onder + het gemiddelde), zodat seconden, punten en noteringen vergelijkbaar zijn. +
    • +
    • + Uitslagen — 1e = 1, 2e = 0,75, 3e = 0,6, 4e = 0,45, 5e = 0,35, 6e = 0,25, verder 0,1, + D = 0; gewogen met halveringstijd. +
    • +
    • + Proef — minus de achterstand in seconden op de heatwinnaar, minus de merriehandicap + voor heat 2. +
    • +
    • + Snelste tijd — minus de record-kilometertijd over 2600 m; onbekend = veldgemiddelde. +
    • +
    • + Startpositie — vaste curve: 2 en 3 het best, dan 1, aflopend naar 8; 9 en 10 negatief. +
    • Wedmarkt — −ln(notering bij de proef).
    • -
    • Uitval — 3% + 10% per D + 3% per plek ≥ 7 in de laatste vijf; telt mee als ln(1 − kans).
    • -
    • Plaats & combinaties — Plackett–Luce, exact uitgerekend over alle 720 mogelijke top-3's; voor 2e en 3e plaats met pλ (Stern-correctie).
    • -
    • Eindkans — log-lineaire menging: ln p = (1 − v) · ln pmodel + v · ln ptoto, daarna genormaliseerd; ptoto = 1/notering gedeeld door de som (zo valt de toto-marge weg). Waarde en inzet gebruiken de eindkans.
    • -
    • De startpositie-curve en de merriehandicap zijn aannames, geen gemeten waarden. Daarom zijn ze instelbaar.
    • +
    • + Uitval — 3% + 10% per D + 3% per plek ≥ 7 in de laatste vijf; telt mee als ln(1 − kans). +
    • +
    • + Plaats & combinaties — Plackett–Luce, exact uitgerekend over alle 720 mogelijke + top-3's; voor 2e en 3e plaats met pλ (Stern-correctie). +
    • +
    • + Eindkans — log-lineaire menging: ln p = (1 − v) · ln pmodel + v · ln ptoto, daarna genormaliseerd; ptoto = 1/notering gedeeld door de som (zo valt de toto-marge + weg). Waarde en inzet gebruiken de eindkans. +
    • +
    • + De startpositie-curve en de merriehandicap zijn aannames, geen gemeten waarden. Daarom + zijn ze instelbaar. +
    diff --git a/src/routes/projects/derby/[race]/+page.svelte b/src/routes/projects/derby/[race]/+page.svelte new file mode 100644 index 0000000..36ad207 --- /dev/null +++ b/src/routes/projects/derby/[race]/+page.svelte @@ -0,0 +1,1638 @@ + + + + + + +
    +
    + + + + +
    +
    +
    Koers {race.number} · {race.conditions}
    +

    {race.short.toUpperCase()}

    +
    +
    + {race.distance.toLocaleString('nl')} m{race.start} +
    +
    + €{(race.purse / 1000).toFixed(race.purse % 1000 ? 2 : 0)}KPrijzengeld +
    +
    {runners.length}Starters
    +
    + {race.surface.split(' · ')[1] ?? race.surface}{race.surface.split(' · ')[0]} +
    +
    +
    + {#if favourite} +
    +
    Model favoriet · nr {favourite.horse.n}
    +
    {favourite.horse.name}
    +
    + {pct(favourite.p)} + + winkans · fair notering {oddsFmt(fairOdds(favourite.p))}
    + bij de eerste drie: {pct(pl.top[0].win + pl.top[0].place2 + pl.top[0].place3, 0)}
    + tips ZEturf: {race.tips.join(' · ')} +
    +
    +
    + {/if} +
    + +
    +
    +
    Voorbeschouwing · ZEturf
    +

    {race.preview}

    +
    +
    +
    Zo gebruik je dit
    +

    + Vink niet-starters uit, vul alle win-noteringen in (zo laat mogelijk), plaatsnoteringen + alleen voor je kandidaten, en wed alleen op groen in Waarde & inzet. + Dit model heeft hier minder houvast dan bij de Derby: geen gezamenlijke proef, wel tijden + van verschillende banen. Zet de toto-menging daarom niet te laag. +

    +
    +
    + +
    + + +
    +
    +
    +
    {runners.length} starters
    +

    Winkans

    +
    +
    + {#if help}

    + Kans dat elk paard wint volgens het model. Fair is de notering waarbij je quitte + speelt. Vul bij Notering de toto-notering in: groen bij Waarde betekent + dat het model het paard hoger inschat dan de toto. Vink een paard uit als het niet + start.
    Onder de naam: rijder en de laatste uitslagen, nieuwste eerst. D = + gediskwalificeerd. +

    {/if} +
    +
    + #Paard + KansFairNoteringWaarde +
    + {#each preds as r, i (r.horse.n)} + {@const o = odds[r.horse.n]} + {@const v = o && o > 1 ? betValue(r.p, o) : null} +
    + toggleScratch(r.horse)} + /> +
    {r.horse.n}
    +
    +
    {r.horse.name}
    +
    + {r.horse.driver} · + {r.horse.form.length ? r.horse.form.join('-') : 'debuut'}{#if r.horse.note} + · {r.horse.note}{/if} +
    +
    +
    +
    +
    +
    {pct(r.p)}
    +
    {oddsFmt(fairOdds(r.p))}
    + +
    0} class:neg={v && v.edge <= 0}> + {v ? signed(v.edge * 100, 0) + '%' : ''} +
    +
    + {/each} + {#each race.runners.filter((h) => scratched.includes(h.n)) as h (h.n)} +
    + toggleScratch(h)} /> +
    {h.n}
    +
    +
    {h.name}
    +
    niet-starter
    +
    +
    + {/each} +
    +
    +
    + +
    +
    +
    + Wedvormen naast winnen · {blending ? 'model + toto gemengd' : 'volgens het model'} +
    +

    Plaats & combinaties

    + {#if help}

    + Plaats = bij de eerste drie. Vul bij Toto de plaatsnotering in. + Koppel: eerste twee, volgorde vrij. Trio: eerste drie in juiste volgorde. +

    {/if} +
    {h.n} {h.name}{sexLabel[h.sex]} · tr. {h.trainer}{signed(r.contributions.form)}{f.form.toFixed(2)} van 1{signed(r.contributions.trial)}{trialLabel(h)}{signed(r.contributions.record)}{h.record ? formatTime(h.record) : 'onbekend'}{signed(r.contributions.draw)}nr {h.n}{h.n > 8 ? ' · 2e rij' : ''}{signed(r.contributions.market)}notering {h.trial.odds.toFixed(1)}{signed(r.riskPenalty)}{pct(f.pFail, 0)} kans op D{signed(r.contributions.form)}{f.form.toFixed(2)} van 1{signed(r.contributions.trial)}{trialLabel(h)}{signed(r.contributions.record)}{h.record ? formatTime(h.record) : 'onbekend'}{signed(r.contributions.draw)}nr {h.n}{h.n > 8 ? ' · 2e rij' : ''}{signed(r.contributions.market)}notering {h.trial.odds.toFixed(1)}{signed(r.riskPenalty)}{pct(f.pFail, 0)} kans op D {signed(r.logit)} {pct(r.p)}
    + + + {#each preds as r, i (r.horse.n)} + {@const t = plFinal.top[i]} + {@const place = placeP(i)} + {@const po = placeOdds[r.horse.n]} + {@const v = po && po > 1 ? betValue(place, po) : null} + + + + + + + + + + + + {/each} + +
    #Paard1e2e3ePlaatsFairTotoWaarde
    {r.horse.n}{r.horse.name}{pct(t.win, 0)}{pct(t.place2, 0)}{pct(t.place3, 0)}{pct(place, 0)}{oddsFmt(fairOdds(place))} 0} class:neg={v && v.edge <= 0} + >{v ? signed(v.edge * 100, 0) + '%' : ''}
    +
    +
    +
    Koppel · 1–2 elke volgorde
    + {#each plFinal.koppel.slice(0, 6) as k (`${k.a}-${k.b}`)} +
    + {name(k.a)} + {name(k.b)}{pct(k.p)}{oddsFmt(fairOdds(k.p))} +
    + {/each} +
    +
    +
    Trio · 1–2–3 juiste volgorde
    + {#each plFinal.trio.slice(0, 6) as t (`${t.a}-${t.b}-${t.c}`)} +
    + {preds[t.a].horse.n} · {preds[t.b].horse.n} · {preds[t.c].horse.n}{pct(t.p)}{oddsFmt(fairOdds(t.p))} +
    + {/each} +
    +
    +
    + +
    +
    Model vs. toto
    +

    Waarde & inzet

    + {#if help}

    + De eindkans mengt model en toto; hoe hoger het vertrouwen in de toto, hoe sterker + het model het oneens moet zijn voordat een paard waarde toont. Waarde = verwachte + winst per euro. Inzet volgt uit Kelly met een veilige fractie. +

    {/if} +
    + + +
    +
    + + +
    + {#if bets.length === 0} +

    + Vul noteringen in bij de paarden (winnend hierboven, plaats hiernaast). Waarde = kans × + notering − 1. +

    + {:else} +
    +
    {toto.entered}/{preds.length}noteringen
    +
    + {toto.complete ? signed((toto.overround - 1) * 100, 0) + '%' : '—'}toto-marge +
    +
    {goodBets.length}met waarde
    +
    + + + + {#each bets as b (`${b.type}-${b.r.horse.n}`)} + + + + + + + + + + {/each} + +
    #PaardTypeTotoEindkansWaardeInzet
    {b.r.horse.n}{b.r.horse.name}{b.type}{oddsFmt(b.odds)}{pct(b.p)} 0} class:neg={b.edge <= 0} + >{signed(b.edge * 100, 0)}%{b.kelly > 0 ? euro(b.stake) : '—'}
    + {#if goodBets.length === 0} +

    + Geen enkele weddenschap heeft positieve waarde bij deze noteringen. Niet wedden is dan + de beste zet. +

    + {/if} + {/if} +
    +
    + +
    +
    Per signaal · groen = pluspunt · oranje = minpunt
    +

    Waarom deze kansen

    + {#if help}

    + Elk paard wordt per signaal vergeleken met de rest van het veld. Het grote getal is de + bijdrage aan de score (na weging), het kleine getal de ruwe waarde. Geschat = geen data, + veldgemiddelde gebruikt. +

    {/if} +
    + + + + + {#each gFeatureKeys as k (k)}{#if k !== 'speed' || hasTimes}{/if}{/each} + + + + + {#each preds as r (r.horse.n)} + {@const h = r.horse} + + + + {#each gFeatureKeys as k (k)} + {#if k !== 'speed' || hasTimes} + + {/if} + {/each} + + + + + {/each} + +
    #Paard{featureLabel[k]}UitvalScoreKans
    {h.n}{h.name}{sexLabel[h.sex]} + {h.age} j · tr. {h.trainer}{#if h.kg} + · {h.kg} kg{/if}{#if h.record} + · rec. {formatTime(h.record)}{/if}{signed(r.contributions[k])}{rawLabel(r, k)}{signed(r.riskPenalty)}{pct(r.features.pFail, 0)} kans op D{signed(r.logit)}{pct(r.p)}
    +
    +
    + +
    + Hoe het model rekent +
    +

    + logit = 0.55 · Σ gewicht × z(signaal) + risicostraf · ln(1 − P(uitval))  ·  kans + = softmax(logit / T) +

    +
      +
    • + Uitslagen — 1e = 1, 2e = 0,75, 3e = 0,6, 4e = 0,45, 5e = 0,35, 6e = 0,25, verder 0,1, + D = 0; gewogen met halveringstijd. +
    • +
    • + Snelheid — minus de beste kilometertijd van de laatste starts. Tijden van andere banen + (Alkmaar, Emmeloord zijn traag) en afstanden zijn ruis; daarom het beste, niet het gemiddelde. +
    • +
    • + Niveau — gemiddelde van ln(prijzengeld) van de laatste starts. Wie in Zweden of in + de Sheikh Mansour Cup liep, scoort hoog, ook bij verlies. +
    • +
    • Startpositie — vaste curve: 2 en 3 het best, dan 1, aflopend naar 8.
    • +
    • + Uitval — 3% (debutant 12%) + 10% per D + 3% per plek ≥ 7 in de laatste vijf. +
    • +
    • + Ontbrekende signalen (debutanten, geen tijden) krijgen het veldgemiddelde: het model + weet dan niets en zegt dat ook. +
    • +
    • + Plaats & combinaties — Plackett–Luce met Stern-demping; eindkans — log-lineaire + menging met de toto, net als bij de Derby. +
    • +
    + +
    +
    + +
    + DERBY LENS · koers {race.number} · {race.name}SvelteKit +
    + +
    + + diff --git a/src/routes/projects/derby/[race]/+page.ts b/src/routes/projects/derby/[race]/+page.ts new file mode 100644 index 0000000..751b791 --- /dev/null +++ b/src/routes/projects/derby/[race]/+page.ts @@ -0,0 +1,11 @@ +import { error } from '@sveltejs/kit'; +import { raceBySlug, races } from '$lib/derby/races'; +import type { EntryGenerator, PageLoad } from './$types'; + +export const entries: EntryGenerator = () => races.map((r) => ({ race: r.slug })); + +export const load: PageLoad = ({ params }) => { + const race = raceBySlug(params.race); + if (!race) error(404, 'Onbekende koers'); + return { race }; +}; diff --git a/src/routes/projects/progress/[id]/+page.server.ts b/src/routes/projects/progress/[id]/+page.server.ts index 85892f2..cb83ac4 100755 --- a/src/routes/projects/progress/[id]/+page.server.ts +++ b/src/routes/projects/progress/[id]/+page.server.ts @@ -1,8 +1,11 @@ +import { isAdmin, requireAdmin } from '$lib/server/authorization'; +import type { Actions, PageServerLoad } from './$types'; import { db } from '$lib/server/db'; import { tasks, tasksToTopics, topics } from '$lib/server/db/schema'; import { eq, and } from 'drizzle-orm'; -export const load = async ({ cookies, params }) => { +export const load: PageServerLoad = async (event) => { + const { params } = event; return { task: await db.query.tasks.findFirst({ with: { @@ -17,28 +20,24 @@ export const load = async ({ cookies, params }) => { } }), topics: await db.query.topics.findMany(), - editable: cookies.get('token') + editable: isAdmin(event) }; }; -export const actions = { - createTopic: async ({ cookies, request, params }) => { - if (!cookies.get('token')) { - return { status: 401 }; - } +export const actions: Actions = { + createTopic: async (event) => { + requireAdmin(event); + const { request, params } = event; const data = await request.formData(); const topic = await db .insert(topics) - .values({ name: data.get('name') }) + .values({ name: String(data.get('name') ?? '').trim() }) .returning(); const existing = await db.query.tasksToTopics.findFirst({ - where: and( - eq(tasksToTopics.taskId, Number(params.id)), - eq(tasksToTopics.topicId, topic[0].id) - ) + where: { taskId: Number(params.id), topicId: topic[0].id } }); if (!existing) { @@ -48,21 +47,18 @@ export const actions = { .returning(); } }, - addTopic: async ({ cookies, request, params }) => { - if (!cookies.get('token')) { - return { status: 401 }; - } + addTopic: async (event) => { + requireAdmin(event); + const { request, params } = event; const data = await request.formData(); const topicId = Number(data.get('topic-id')); const existing = await db.query.tasksToTopics.findFirst({ - where: and(eq(tasksToTopics.taskId, Number(params.id)), eq(tasksToTopics.topicId, topicId)) + where: { taskId: Number(params.id), topicId } }); - console.log(existing); - if (!existing) { await db .insert(tasksToTopics) @@ -70,17 +66,16 @@ export const actions = { .returning(); } }, - removeTopic: async ({ cookies, request, params }) => { - if (!cookies.get('token')) { - return { status: 401 }; - } + removeTopic: async (event) => { + requireAdmin(event); + const { request, params } = event; const data = await request.formData(); const topicId = Number(data.get('topic-id')); const existing = await db.query.tasksToTopics.findFirst({ - where: and(eq(tasksToTopics.taskId, Number(params.id)), eq(tasksToTopics.topicId, topicId)) + where: { taskId: Number(params.id), topicId } }); if (existing) { @@ -91,10 +86,9 @@ export const actions = { ); } }, - updateProgress: async ({ cookies, request, params }) => { - if (!cookies.get('token')) { - return { status: 401 }; - } + updateProgress: async (event) => { + requireAdmin(event); + const { request, params } = event; const data = await request.formData(); @@ -112,10 +106,9 @@ export const actions = { }) .where(eq(tasks.id, Number(params.id))); }, - updateNotes: async ({ cookies, request, params }) => { - if (!cookies.get('token')) { - return { status: 401 }; - } + updateNotes: async (event) => { + requireAdmin(event); + const { request, params } = event; const data = await request.formData(); diff --git a/src/routes/projects/progress/create/+page.server.ts b/src/routes/projects/progress/create/+page.server.ts index 7a394ea..8476c85 100755 --- a/src/routes/projects/progress/create/+page.server.ts +++ b/src/routes/projects/progress/create/+page.server.ts @@ -1,20 +1,21 @@ +import { requireAdmin } from '$lib/server/authorization'; +import type { Actions } from './$types'; import { db } from '$lib/server/db'; import { tasks } from '$lib/server/db/schema'; import { redirect } from '@sveltejs/kit'; -export const actions = { - default: async ({ cookies, request }) => { - if (!cookies.get('token')) { - return { status: 401 }; - } +export const actions: Actions = { + default: async (event) => { + requireAdmin(event); + const { request } = event; const data = await request.formData(); const task = await db .insert(tasks) - .values({ name: data.get('name') }) + .values({ name: String(data.get('name') ?? '').trim() }) .returning(); - redirect(303, '/progress/' + task[0].id); + redirect(303, '/projects/progress/' + task[0].id); } }; diff --git a/src/routes/projects/spotify-beatmap-finder/+page.server.ts b/src/routes/projects/spotify-beatmap-finder/+page.server.ts new file mode 100644 index 0000000..8b664d6 --- /dev/null +++ b/src/routes/projects/spotify-beatmap-finder/+page.server.ts @@ -0,0 +1,75 @@ +import type { Actions } from './$types'; +import { fail } from '@sveltejs/kit'; +import { parseSpotifyInput } from '$lib/map-finder/input'; +import type { TrackMatchResult } from '$lib/map-finder/types'; +import { getSpotifyMetadata } from '$lib/server/spotify'; +import { getOsuMaps, MATCH_CONCURRENCY } from '$lib/server/osu'; +import { ApiError, publicError, logApiError, mapConcurrent } from '$lib/server/finder-http'; +import { acquireSearch } from '$lib/server/finder-limit'; +export const actions: Actions = { + default: async ({ request, fetch, getClientAddress }) => { + const data = await request.formData(); + const value = data.get('query'); + const query = typeof value === 'string' ? value.trim().slice(0, 501) : ''; + let input; + try { + input = parseSpotifyInput(query); + } catch (error) { + return fail(400, { query, error: (error as Error).message }); + } + if (input.kind === 'unsupported') + return fail(400, { + query, + error: `Unsupported Spotify resource: ${input.resource}. Use a track, playlist, or album.` + }); + let address: string; + try { + address = getClientAddress(); + } catch { + address = 'shared-unknown'; + } + const release = acquireSearch( + address, + input.kind === 'playlist' || input.kind === 'album' ? 6 : 1 + ); + if (!release) + return fail(429, { + query, + error: + 'Site search limit reached. Wait up to 10 minutes, and finish any pending search before trying again.' + }); + try { + const metadata = await getSpotifyMetadata(fetch, input); + const results = await mapConcurrent( + metadata.tracks, + MATCH_CONCURRENCY, + async (track): Promise => { + try { + const matches = await getOsuMaps(fetch, track); + return { + track, + matches, + status: matches.some((m) => m.confidence !== 'low') ? 'matched' : 'no_match' + }; + } catch (error) { + logApiError(error); + return { track, matches: [], status: 'error', error: publicError(error) }; + } + } + ); + return { query, results, collection: metadata.collection, truncated: metadata.truncated }; + } catch (error) { + logApiError(error); + return fail( + error instanceof ApiError && error.status === 429 + ? 429 + : error instanceof ApiError && [403, 404].includes(error.status) + ? 404 + : 502, + { query, error: publicError(error) } + ); + } finally { + release(); + } + } +}; diff --git a/src/routes/projects/spotify-beatmap-finder/+page.svelte b/src/routes/projects/spotify-beatmap-finder/+page.svelte new file mode 100644 index 0000000..c8a4fc5 --- /dev/null +++ b/src/routes/projects/spotify-beatmap-finder/+page.svelte @@ -0,0 +1,153 @@ + + +
    +
    +

    Spotify Map Finder

    +
    { + pending = true; + return async ({ update }) => { + try { + filter = 'all'; + await update({ reset: false }); + } finally { + pending = false; + } + }; + }} + > + + +

    + Search a song, or enter a Spotify track, playlist or album URL/URI. Up to 50 tracks. +

    + +
    +
    + {#if pending}

    + Searching for maps. Playlists and albums may take a few minutes. +

    {/if} +
    + {#if form?.error}{/if} + + {#if form?.results} +
    + {#if form.collection} +
    + +
    +

    {form.collection.name}

    + {#if form.collection.owner}

    + {form.collection.owner} +

    {/if} +

    {results.length} tracks processed · {matched} matched

    + Open in Spotify +
    +
    + {#if form.truncated}

    + Showing the first {results.length} usable tracks. The collection reached the processing + limit. +

    {/if} + + {/if} + {#if !results.length}

    + No usable tracks found. +

    {:else if !visible.length}

    No tracks in this filter.

    {/if} +
      + {#each visible as result (result.track.id)} +
    • +
      + +
      +

      + {result.track.artists.map((artist) => artist.name).join(', ')} – {result.track + .name} +

      +

      {result.track.album.name}

      + Open in Spotify +
      +
      + {#if result.status === 'error'}

      {result.error}

      {:else} + {#if result.status === 'no_match'}

      + No confident match found. +

      {/if} +
        + {#each result.matches.filter((map) => map.confidence !== 'low') as map (map.id)}
      • + +
      • {/each} +
      + {#if result.matches.some((map) => map.confidence === 'low')} +
      + Low-confidence candidates ({result.matches.filter( + (map) => map.confidence === 'low' + ).length}) +
        + {#each result.matches.filter((map) => map.confidence === 'low') as map (map.id)}
      • + +
      • {/each} +
      +
      + {/if} + {/if} +
    • + {/each} +
    +
    + {/if} +
    +
    diff --git a/src/routes/projects/spotify-beatmap-finder/action.test.ts b/src/routes/projects/spotify-beatmap-finder/action.test.ts new file mode 100644 index 0000000..7d7e3e0 --- /dev/null +++ b/src/routes/projects/spotify-beatmap-finder/action.test.ts @@ -0,0 +1,61 @@ +import { expect, it, vi } from 'vitest'; +vi.mock('$lib/server/spotify', () => ({ getSpotifyMetadata: vi.fn() })); +vi.mock('$lib/server/osu', () => ({ getOsuMaps: vi.fn(), MATCH_CONCURRENCY: 3 })); +import { actions } from './+page.server'; +import { getSpotifyMetadata } from '$lib/server/spotify'; +import { getOsuMaps } from '$lib/server/osu'; +import type { RequestEvent } from './$types'; +const event = (query: string, address = 'validation-test') => { + const data = new FormData(); + data.set('query', query); + return { + request: new Request('https://site.test', { method: 'POST', body: data }), + fetch: vi.fn(), + getClientAddress: () => address + } as unknown as RequestEvent; +}; +it.each(['', 'spotify:track:bad', 'https://open.spotify.com/artist/6PUzxtIHkv346yP89NzP9X'])( + 'validates before making API calls: %s', + async (query) => { + const result = await actions.default(event(query)); + expect(result).toMatchObject({ status: 400 }); + expect(getSpotifyMetadata).not.toHaveBeenCalled(); + } +); +it('keeps successful tracks when another match fails', async () => { + const track = { + id: '6PUzxtIHkv346yP89NzP9X', + name: 'Song', + artists: [{ name: 'Artist' }], + album: { name: '', images: [] } + }; + vi.mocked(getSpotifyMetadata).mockResolvedValue({ + tracks: [track, { ...track, id: '2PUzxtIHkv346yP89NzP9X' }], + truncated: false + }); + vi.mocked(getOsuMaps) + .mockResolvedValueOnce([ + { id: 1, title: 'Song', artist: 'Artist', score: 100, confidence: 'high', reasons: [] } + ]) + .mockRejectedValueOnce(new Error('sensitive upstream error')); + const log = vi.spyOn(console, 'error').mockImplementation(() => {}); + const result = await actions.default(event('Song', 'partial-test')); + expect(result).toMatchObject({ + results: [ + { status: 'matched' }, + { status: 'error', error: 'Search could not be completed. Please try again.' } + ] + }); + log.mockRestore(); +}); + +it('returns site-level 429 after the per-client budget is exhausted', async () => { + vi.mocked(getSpotifyMetadata).mockResolvedValue({ tracks: [], truncated: false }); + for (let i = 0; i < 2; i++) + await actions.default(event('spotify:album:6PUzxtIHkv346yP89NzP9X', 'limited-test')); + const result = await actions.default(event('Song', 'limited-test')); + expect(result).toMatchObject({ + status: 429, + data: { query: 'Song', error: expect.stringContaining('Site search limit') } + }); +}); diff --git a/src/routes/register/+page.server.ts b/src/routes/register/+page.server.ts new file mode 100644 index 0000000..7971d70 --- /dev/null +++ b/src/routes/register/+page.server.ts @@ -0,0 +1,9 @@ +import { authProviders } from '$lib/server/auth'; +import { safeReturnTo } from '$lib/auth-redirect'; +import { redirect } from '@sveltejs/kit'; +import type { PageServerLoad } from './$types'; +export const load: PageServerLoad = ({ url, locals }) => { + const returnTo = safeReturnTo(url.searchParams.get('returnTo')); + if (locals.user) redirect(303, returnTo); + return { providers: authProviders, returnTo, oauthError: url.searchParams.has('error') }; +}; diff --git a/src/routes/register/+page.svelte b/src/routes/register/+page.svelte new file mode 100644 index 0000000..347b8d0 --- /dev/null +++ b/src/routes/register/+page.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/routes/robots.txt/+server.ts b/src/routes/robots.txt/+server.ts new file mode 100644 index 0000000..d008139 --- /dev/null +++ b/src/routes/robots.txt/+server.ts @@ -0,0 +1,15 @@ +import { SITE_ORIGIN } from '$lib/seo'; +import type { RequestHandler } from './$types'; + +export const GET: RequestHandler = ({ url }) => { + const production = url.hostname === new URL(SITE_ORIGIN).hostname; + const body = production + ? `User-agent: *\nAllow: /\nSitemap: ${SITE_ORIGIN}/sitemap.xml\n` + : 'User-agent: *\nDisallow: /\n'; + return new Response(body, { + headers: { + 'content-type': 'text/plain; charset=utf-8', + 'cache-control': 'public, max-age=3600' + } + }); +}; diff --git a/src/routes/sitemap.xml/+server.ts b/src/routes/sitemap.xml/+server.ts new file mode 100644 index 0000000..5d228c0 --- /dev/null +++ b/src/routes/sitemap.xml/+server.ts @@ -0,0 +1,61 @@ +import { db } from '$lib/server/db'; +import { blogArticles } from '$lib/server/db/schema'; +import { SITE_ORIGIN } from '$lib/seo'; +import { races } from '$lib/derby/races'; +import { eq } from 'drizzle-orm'; +import type { RequestHandler } from './$types'; + +const staticPaths = [ + '/', + '/projects', + '/blog', + '/lists', + '/projects/catch-em-all', + '/projects/animaldex', + '/projects/derby', + '/projects/spotify-beatmap-finder' +]; + +function escapeXml(value: string): string { + return value.replace(/[<>&"']/g, (character) => { + const entities: Record = { + '<': '<', + '>': '>', + '&': '&', + '"': '"', + "'": ''' + }; + return entities[character]; + }); +} + +export const GET: RequestHandler = async () => { + const [articles, lists] = await Promise.all([ + db + .select({ slug: blogArticles.slug, updatedAt: blogArticles.updatedAt }) + .from(blogArticles) + .where(eq(blogArticles.status, 'published')), + db.query.lists.findMany({ columns: { slug: true } }) + ]); + const entries: { path: string; lastmod?: string }[] = [ + ...staticPaths.map((path) => ({ path })), + ...races.map((race) => ({ path: `/projects/derby/${race.slug}` })), + ...articles.map((article) => ({ + path: `/blog/${encodeURIComponent(article.slug)}`, + lastmod: article.updatedAt.toISOString() + })), + ...lists.map((list) => ({ path: `/lists/${encodeURIComponent(list.slug)}` })) + ]; + const body = `\n\n${entries + .map( + ({ path, lastmod }) => + ` ${escapeXml(new URL(path, SITE_ORIGIN).href)}${lastmod ? `${lastmod}` : ''}` + ) + .join('\n')}\n\n`; + return new Response(body, { + headers: { + 'content-type': 'application/xml; charset=utf-8', + 'cache-control': 'public, max-age=3600' + } + }); +}; diff --git a/static/site.webmanifest b/static/site.webmanifest index 45dc8a2..29b17f3 100755 --- a/static/site.webmanifest +++ b/static/site.webmanifest @@ -1 +1,11 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file +{ + "name": "Stan Runge", + "short_name": "Stan Runge", + "icons": [ + { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, + { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } + ], + "theme_color": "#000000", + "background_color": "#000000", + "display": "standalone" +} diff --git a/tests/auth.test.ts b/tests/auth.test.ts new file mode 100644 index 0000000..b5c82af --- /dev/null +++ b/tests/auth.test.ts @@ -0,0 +1,246 @@ +import { test, expect, type APIRequestContext } from '@playwright/test'; +import postgres from 'postgres'; +import { execFileSync } from 'node:child_process'; + +// Opt-in: these tests create and clean up their own rows in the configured dev DB. +test.skip( + !process.env.AUTH_E2E, + 'Run npm run test:auth against a migrated, seeded development database' +); +const origin = 'http://127.0.0.1:4174'; +const password = 'A-long-test-password-2026!'; +const createdUsers: string[] = []; +const createdEmails: string[] = []; +const createdLists: number[] = []; +const createdArticles: number[] = []; +let sql: ReturnType; + +test.beforeAll(() => { + if (!process.env.DB_URL) throw new Error('DB_URL is required'); + sql = postgres(process.env.DB_URL, { max: 1 }); +}); +test.afterAll(async () => { + if (!sql) return; + for (const id of createdLists) await sql`delete from lists where id = ${id}`; + for (const id of createdArticles) await sql`delete from blog_articles where id = ${id}`; + for (const id of createdUsers) await sql`delete from "user" where id = ${id}`; + for (const email of createdEmails) await sql`delete from "user" where email = ${email}`; + await sql.end(); +}); +async function register(request: APIRequestContext, name: string) { + const email = `auth-test-${crypto.randomUUID()}@example.com`; + createdEmails.push(email); + const response = await request.post('/api/auth/sign-up/email', { + headers: { Origin: origin }, + data: { name, email, password, role: 'admin' } + }); + expect(response.ok(), await response.text()).toBe(true); + const data = await response.json(); + createdUsers.push(data.user.id); + expect(data.user.role).toBe('user'); + return { id: data.user.id as string, email }; +} +async function action( + request: APIRequestContext, + path: string, + values: Record = {} +) { + const response = await request.post(path, { + headers: { Origin: origin, Accept: 'application/json', 'x-sveltekit-action': 'true' }, + form: values, + maxRedirects: 0 + }); + const result = await response.json().catch(() => null); + return { + status: () => result?.status ?? response.status(), + headers: () => ({ + ...response.headers(), + location: result?.location ?? response.headers().location + }) + }; +} + +test('register, persist progress, isolate users, enforce admin, revoke session', async ({ + page, + playwright +}) => { + const errors: string[] = []; + page.on('pageerror', (error) => errors.push(error.message)); + const email = `auth-test-${crypto.randomUUID()}@example.com`; + createdEmails.push(email); + await page.goto('/register?returnTo=/projects/catch-em-all'); + await page.getByLabel('Name', { exact: true }).fill('Browser Trainer'); + await page.getByRole('textbox', { name: 'Email', exact: true }).fill(email); + await page.getByLabel('Password', { exact: true }).fill(password); + await page.getByRole('button', { name: 'Create account', exact: true }).click(); + await expect(page).toHaveURL(`${origin}/projects/catch-em-all`); + const session = await (await page.request.get('/api/auth/get-session')).json(); + createdUsers.push(session.user.id); + expect(session.user.role).toBe('user'); + await expect(page.getByRole('link', { name: 'Browser Trainer', exact: true })).toBeVisible(); + await page.screenshot({ path: '/tmp/personal-website-catchemall.png' }); + const firstCatch = page.getByRole('checkbox', { name: /^Caught / }).first(); + await firstCatch.check(); + await expect(firstCatch).toBeEnabled(); + await page.reload(); + await expect(page.getByRole('checkbox', { name: /^Caught / }).first()).toBeChecked(); + const [caught] = + await sql`select pokemon_game_entry_id from user_entries where user_id = ${session.user.id}`; + expect(caught).toBeTruthy(); + const [{ count: beforeCount }] = await sql`select count(*) from pokemon_game_entries`; + execFileSync('bun', ['scripts/seed-catalog.ts'], { env: process.env }); + expect((await sql`select count(*) from pokemon_game_entries`)[0].count).toBe(beforeCount); + expect( + ( + await sql`select pokemon_game_entry_id from user_entries where user_id = ${session.user.id}` + )[0] + ).toEqual(caught); + const [game] = await sql`select id from games order by id limit 1`; + const selection = await action(page.request, '/projects/catch-em-all?/setGames', { + gameIds: String(game.id) + }); + expect(selection.status()).toBe(200); + await page.reload(); + await expect(page.locator('thead th')).toHaveCount(2); + // Explicitly selecting none must not revert to all games after a reload. + expect((await action(page.request, '/projects/catch-em-all?/setGames')).status()).toBe(200); + await page.reload(); + await expect(page.locator('thead th')).toHaveCount(1); + + const bob = await playwright.request.newContext({ baseURL: origin }); + try { + const other = await register(bob, 'Other Trainer'); + expect( + ( + await action(bob, '/projects/catch-em-all?/togglePokemonCaught', { + entryId: String(caught.pokemon_game_entry_id) + }) + ).status() + ).toBe(200); + expect((await sql`select * from user_entries where user_id = ${session.user.id}`).length).toBe( + 1 + ); + expect((await sql`select * from user_entries where user_id = ${other.id}`).length).toBe(0); + expect((await action(bob, '/lists?/newList')).status()).toBe(403); + expect((await action(bob, '/blog', { title: 'Not allowed' })).status()).toBe(403); + expect((await action(bob, '/projects/progress/create', { name: 'Not allowed' })).status()).toBe( + 403 + ); + expect( + ( + await bob.post('/projects/animaldex/api/animals/1/moderate', { + headers: { Origin: origin }, + data: { action: 'accept' } + }) + ).status() + ).toBe(403); + expect( + (await action(bob, '/projects/catch-em-all?/setGames', { gameIds: 'not-a-game' })).status() + ).toBe(400); + expect( + ( + await action(bob, '/projects/catch-em-all?/togglePokemonCaught', { entryId: '999999999' }) + ).status() + ).toBe(404); + } finally { + await bob.dispose(); + } + + await sql`update "user" set role = 'admin' where id = ${session.user.id}`; + await page.goto('/blog'); + await expect(page.getByRole('button', { name: 'Write new article' })).toBeVisible(); + const listResponse = await action(page.request, '/lists?/newList'); + expect(listResponse.status()).toBe(303); + const listId = Number(listResponse.headers().location?.split('/').pop()); + createdLists.push(listId); + await page.goto(`/lists/${listId}`); + await page.getByLabel('List name').fill('Auth test list'); + const renameResponse = page.waitForResponse( + (response) => response.url().includes('/lists/') && response.request().method() === 'POST' + ); + await page.getByRole('button', { name: 'Rename', exact: true }).click(); + const renamed = await renameResponse; + expect(renamed.status()).toBe(200); + expect((await sql`select name from lists where id = ${listId}`)[0].name).toBe('Auth test list'); + await page.screenshot({ path: '/tmp/personal-website-list.png' }); + await expect(page.getByRole('heading', { name: 'Auth test list' })).toBeVisible(); + const title = `Auth test article ${crypto.randomUUID()}`; + const articleResponse = await action(page.request, '/blog', { title }); + expect(articleResponse.status()).toBe(303); + const [article] = await sql`select id, slug from blog_articles where title = ${title}`; + createdArticles.push(article.id); + await page.goto(`/blog/${article.slug}/edit`); + await expect(page.getByRole('button', { name: 'Save draft', exact: true }).first()).toBeVisible(); + await sql`update "user" set role = 'user' where id = ${session.user.id}`; + expect((await action(page.request, '/lists?/newList')).status()).toBe(403); + + const oldCookies = await page.context().cookies(); + await page.goto('/account'); + await page.getByRole('button', { name: 'Log out', exact: true }).last().click(); + await expect(page).toHaveURL(/\/login$/); + const replay = await playwright.request.newContext({ + baseURL: origin, + extraHTTPHeaders: { Cookie: oldCookies.map((c) => `${c.name}=${c.value}`).join('; ') } + }); + try { + expect(await (await replay.get('/api/auth/get-session')).json()).toBeNull(); + } finally { + await replay.dispose(); + } + await page.getByRole('textbox', { name: 'Email', exact: true }).fill(email); + await page.getByLabel('Password', { exact: true }).fill(password); + await page.getByRole('button', { name: 'Log in', exact: true }).click(); + await expect(page).toHaveURL(/\/account$/); + expect(errors).toEqual([]); +}); + +test('anonymous/forged cookies, reserved identities, unsafe redirects, OAuth start', async ({ + page +}) => { + await page.context().addCookies([ + { name: 'admin_token', value: 'anything', url: origin }, + { name: 'token', value: 'anything', url: origin } + ]); + expect((await action(page.request, '/lists?/newList')).status()).toBe(401); + expect( + ( + await action(page.request, '/projects/catch-em-all?/togglePokemonCaught', { + entryId: '1', + caught: 'on' + }) + ).status() + ).toBe(401); + expect( + (await page.request.post('/admin/login', { data: { password: 'anything' } })).status() + ).toBe(410); + const reserved = await page.request.post('/api/auth/sign-up/email', { + headers: { Origin: origin }, + data: { name: 'Fake osu', email: '123@osu.invalid', password } + }); + expect(reserved.status()).toBe(400); + const crossOrigin = await page.request.post('/api/auth/sign-in/email', { + headers: { Origin: 'https://evil.example' }, + data: { name: 'Fake', email: 'cross-origin@example.com', password } + }); + expect(crossOrigin.status()).toBe(403); + expect( + (await page.request.post('/logout', { headers: { Origin: 'https://evil.example' } })).status() + ).toBe(403); + await page.goto('/login?returnTo=https://evil.example'); + await expect(page.getByRole('link', { name: 'Create an account' })).toHaveAttribute( + 'href', + '/register?returnTo=%2Faccount' + ); + if (process.env.OSU_CLIENT_ID && process.env.OSU_CLIENT_SECRET) { + const response = await page.request.post('/api/auth/sign-in/social', { + headers: { Origin: origin }, + data: { provider: 'osu', callbackURL: '/account', disableRedirect: true } + }); + expect(response.ok(), await response.text()).toBe(true); + const url = new URL((await response.json()).url); + expect(url.origin).toBe('https://osu.ppy.sh'); + expect(url.searchParams.get('scope')).toBe('identify'); + expect(url.searchParams.get('redirect_uri')).toBe(`${origin}/api/auth/callback/osu`); + expect(url.searchParams.get('state')).toBeTruthy(); + } +}); diff --git a/tests/finder.test.ts b/tests/finder.test.ts new file mode 100644 index 0000000..b22562d --- /dev/null +++ b/tests/finder.test.ts @@ -0,0 +1,28 @@ +import { expect, test } from '@playwright/test'; +const path = 'http://localhost:4173/projects/spotify-beatmap-finder'; +test('finder is responsive and validates enhanced submissions', async ({ page }) => { + await page.setViewportSize({ width: 390, height: 844 }); + await page.goto(path); + await expect( + page.getByRole('heading', { name: 'Spotify Map Finder', exact: true }) + ).toBeVisible(); + expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth)).toBe( + true + ); + await page.getByLabel('Song or Spotify URL').fill('spotify:artist:6PUzxtIHkv346yP89NzP9X'); + await page.getByRole('button', { name: 'Search' }).click(); + await expect(page.getByRole('alert')).toContainText('Unsupported Spotify resource'); + await expect(page.getByLabel('Song or Spotify URL')).toHaveValue( + 'spotify:artist:6PUzxtIHkv346yP89NzP9X' + ); +}); +test('finder retains native form behavior', async ({ browser }) => { + const context = await browser.newContext({ javaScriptEnabled: false }); + const page = await context.newPage(); + await page.goto(path); + await page.getByLabel('Song or Spotify URL').fill('spotify:album:invalid'); + await page.getByRole('button', { name: 'Search' }).click(); + await expect(page.getByRole('alert')).toContainText('Invalid Spotify ID'); + await expect(page.getByLabel('Song or Spotify URL')).toHaveValue('spotify:album:invalid'); + await context.close(); +}); diff --git a/vite.config.ts b/vite.config.ts index a4f2603..0d4c8c9 100755 --- a/vite.config.ts +++ b/vite.config.ts @@ -12,6 +12,9 @@ export default defineConfig({ server: { host: '127.0.0.1', allowedHosts: ['dev.stanrunge.dev'], - hmr: { host: 'dev.stanrunge.dev', protocol: 'wss', clientPort: 443 } + hmr: + process.env.AUTH_E2E === '1' + ? false + : { host: 'dev.stanrunge.dev', protocol: 'wss', clientPort: 443 } } });